Django test client on an actual server - django

I'm testing deploying my first Django project using Apache.
I use Django's test client to perform an "internal" GET from my own server, which worked OK locally, but not runnning on the actual server.
The client ends up getting Django error messages, like
Page not found (404) Request Method: GET Request
URL: http://testserver/polls/forms/test1/
How can I get the client's GET to work on the actual server, having the it be performed on the actual http: //my_actual_server_name.something/polls/forms/test1 instead of "testserver" ?
I tried setting SERVER_NAME= ‘my_actual_server_name.something’ in the settings.py file but that's not it.

Django's test client doesn't actually make HTTP requests, it just makes a request object and passes it to your middleware/views.
If your goal is to make an http request to your own server, an easy way is to install requests and do something like
# Some server on the network
requests.get("http://myserver.com/polls/forms/test1/")
# or some server running on the same machine
requests.get("http://12.0.0.1:8000/polls/forms/test1/")
If you just want to use the functionality of some view, you should move that logic into a function and call that from both the view and your other code.
Very tangential side note:
If you're curious about how the test client doesn't make http requests, you can look at the test client's code in the django source (client.get() calls client.generic() which calls client.request() which instantiates WSGIRequest() and then passes that object to your app - which is the request that you receive in your views).

Related

Django in Docker on Nginx request to self fails when in the context of another request

I have a Django application deployed inside a container on top of Nginx using Dokku. One of the view functions of the Django application includes a request:
views.py
def foo(request):
...
response = requests.get(url)
...
It is probably noteworthy that url is the url of the Django application itself, so the request is from the application to itself. The request is to one of the API endpoints (the reasons for doing this are historical). When the view is called then the request to url fails with 504 gateway timeout.
I cannot reproduce this in any other context specifically:
There is no error when running on localhost with the development server, where url is then the url of the development app (localhost to itself works).
There is no error when running on localhost with the development server, where I manually make the url the production url (localhost to production works).
There is no error when running this request on the production server but outside of the view. Specifically, I did a docker exec into the container, started the Django environment (manage.py shell), and ran the exact request that the view was making, and it worked! (production to production works)
It seems that only when the request is made in the context of a view which itself is answering another request I get an issue.
Any ideas?

How does Web Browser open offline ip address just like Jupyter notebook?

I was using Jupyter notebook and was wandering how does it works offline. Where does server is? How TCP connection is made? How does htpp request is sent?
Similarly when we are working on some website project (eg: making one website in django) when you compile that html code in your terminal, it provides you an output with an ip address and when you run that ip address in your browser, browser will show you your website. So how does this work and how that ip address it generated? Can anybody please explain me?
The browser sends a Http request to the server.
The server does its magic and dumps the request via the CGI to django.
Some part of django receives the request and turns it into a django request object.
The request object wanders on some nebulous paths through the middleware which does strange things with it.
The request object finally ends up in some function which looks at the urls, takes the patterns out of urls.py and calls up a view function.
The view functions do their magic (with models and templates as partners) in, this is probably where I have the strongest illusion of understanding (well, apart from the database abstraction magic, that is... ;)
The view functions returns an HttpResponse object, I guess this is returned on some nebulous paths to the CGI.
Webserver takes over again and sends the Http response to the client.

Redirecting API requests in Django Rest Framework

I have a two-layer backend architecture:
a "front" server, which serves web clients. This server's codebase is shared with a 3rd party developer
a "back" server, which holds top-secret-proprietary-kick-ass-algorithms, and has a single endpoint to do its calculation
When a client sends a request to a specific endpoint in the "front" server, the server should pass the request to the "back" server. The back server then crunches some numbers, and returns the result.
One way of achieving it is to use the requests library. A simpler way would be to have the "front" server simply redirect the request to the "back" server. I'm using DRF throughout both servers.
Is redirecting an ajax request possible using DRF?
You don't even need the DRF to add a redirection to urlconf. All you need to redirect is a simple rule:
urlconf = [
url("^secret-computation/$",
RedirectView.as_view(url=settings.BACKEND_SECRET_COMPUTATION_URL))),
url("^", include(your_drf_router.urls)),
]
Of course, you may extend this to a proper DRF view, register it with the DRF's router (instead of directly adding url to urlconf), etc etc - but there isn't much sense in doing so to just return a redirect response.
However, the code above would only work for GET requests. You may subclass HttpResponseRedirect to return HTTP 307 (replacing RedirectView with your own simple view class or function), and depending on your clients, things may or may not work. If your clients are web browsers and those may include IE9 (or worse) then 307 won't help.
So, unless your clients are known to be all well-behaving (and on non-hostile networks without any weird way-too-smart proxies - you'll never believe what kinds of insanity those may do to HTTP requests), I'd suggest to actually proxy the request.
Proxying can be done either in Django - write a GenericViewSet subclass that uses requests library - or by using something in front of it, e.g. nginx or Caddy (or any other HTTP server/load balancer that you know best).
For production purposes, as you probably have a fronting webserver, I suggest to use that. This would save implementation time and also a little bit of server resources, as your "front" Django project won't even have to handle the request and keep the worker busy as it waits for the response.
For development purposes, your options may vary. If you use bare runserver then a proxy view may be your best option. If you use e.g. Docker, you may just throw in an HTTP server container in front of your Django container.
For example, I currently have a two-project setup (legacy Django 1.6 project and newer Django 1.11 project, sharing the same database) and a Caddy server in front of those, routing on per-URL basis. With a simple 9-line Caddyfile things just work:
:80
tls off
log / stdout "{common}"
proxy /foo project1:8000 {
transparent
}
proxy / project2:8000 {
transparent
}
(This is a development-mode config.) If you can have something similar, then, I guess, that would be the simplest option.

Stub generated using Axis2 Webservice forming new connection for redirect URL...Need same TCP connection...!

I am badly stuck with a SOAP based integration using Axis2 framework for generation of client stubs from the Server WSDL. The scenario is as follows :
There is always a login API call first, which gives a Success response in SOAP body and Temporary Redirect in HTTP header. Also provides a URL which contains the session ID in the Location field of HTTP Header.
The next API call is required to be made at this redirect location. IN THE SAME TCP CONNECTION, for getting a proper response.
Now, the problem is, as a part of Webservice implementation using Axis2 generated stubs, I need to reload this redirect URL and re-instantiate it as --- "stub=new Stub(newurl)"
As soon as this is done, it creates a new TCP connection and so, the next request gives the response as "session ID invalid" because it goes out-of-sync with login API.
I have tried everything mentioned as a solution in this forum and nothing is working out.
For e.g --
MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
HttpClient httpClient = new HttpClient(httpConnectionManager);
ServiceClient serviceClient = stub._getServiceClient();
Options opts = stub._getServiceClient().getOptions();
opts.setTo(new EndpointReference(prop.getProperty("target_end_point_url")));
opts.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE);
opts.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
serviceClient.setOptions(opts);
stub._setServiceClient(serviceClient);
Similarly, I have tried many other options too. But it's not helpful at all.
Faced exactly the same issue.
Following steps solved the issue.
1. Using HttpClient, perform login. Don't use stub object to perform login.
2. Use the Location Header URL, to create new stub object i.e. stub = new Stub(locationURL). (Your existing options setting should be retained.)
3. There is a default timeout, by which server disconnects the TCP connection. In my case it was 50 seconds. Hence as soon as i performed login in step 1, i execute a timer every 40 seconds, to send an empty requests to new Location URL using HeadMethod of same HttpClient object.

Connecting a desktop application with a website

I made an application using Qt/C++ that reads some values every 5-7 seconds and sends them to a website.
My approach is very simple. I am just reading the values i want to send and then i make an HTTP POST to the website. I also send the username and password to the website.
The problem is that i cannot find out if the request is successful. I mean that if i send the request and server gets it, i will get an HTTP:200 always. For example if the password is not correct, there is no way to know it. It is the way HTTP works.
Now i think i will need some kind of a protocol to take care the communication between the application and the website.
The question is what protocol to use?
If the action performed completes before the response header is sent you have the option of adding a custom status to it. If your website is built on PHP you can call header() to add the custom status of the operation.
header('XAppRequest-Status: complete');
if you can modify the server side script you could do the following
on one end :
You can make the HTTP post request via ajax
and evaluate the result of the ajax request.
On the serve side
On the HTTP request you do your process and if everything goes accordingly you can send data back to the ajax script that called it.
solves your problem .. ?