how to set http request timeout in python flask - flask

How can I set a request timeout using Python Flask? I'm trying to compare Flask to some other framework and need to configure the timeouts to be equivalent.
Thanks!

As Martijn Pieters said in their comment on the question, this isn't something you want to do because the Flask development server isn't a good choice for production. It would be better to run your flask application on a server like Gunicorn and set the timeout there instead.
But to answer the question anyway, Flask.run has an options parameter allowing you to pass options through to the underlying Werkzeug server:
run(host=None, port=None, debug=None, load_dotenv=True, **options)
The relevant werkzeug method in turn has a request_handler parameter allowing you to specify what request handler is to be used:
werkzeug.serving.run_simple(hostname,
port,
application,
use_reloader=False,
use_debugger=False,
use_evalex=True,
extra_files=None,
reloader_interval=1,
reloader_type='auto',
threaded=False,
processes=1,
request_handler=None,
static_files=None,
passthrough_errors=False,
ssl_context=None
)
This is your hook for supplying a request handler object that implements the timeout policy you want (a subject explored in this question: How to implement Timeout in BaseHTTPServer.BaseHTTPRequestHandler Python).

WSGI server
WSGI is the protocol, a facade separating your code from the actual web server which runs it.
In the flask, you only create the logic of the server. On run, your Flask application is served by the WSGI server. The most common is uWSGI ( & nGinx proxy to the secure border between the outer world and your server). But you can use whichever WSGI server suits you best without need to change your code (nichol.as/benchmark-of-python-web-servers)*.
Flask itself ships only with the Development WSGI flask server. It means the server uses a lot of features to help the developer debug their application. These features make the server very slow. So when you do a benchmark of your app on the Development WSGI flask server, results have no value for you.
On the other hand, specialized production-ready WSGI servers (including uWSGI) are well optimized, tested and production-proven. Most of the features are usually turned off by default and allow you to fine-tune these powerful beasts for your application.
Deployment tutorials:
flask+wsgi: https://flask.palletsprojects.com/en/1.1.x/tutorial/deploy/
flask+uwsgi+nginx:
http://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/
Timeout
Now when I explained the context, back to your original question. I would set requests timeout in your:
test client :
import requests
requests.get('https://api.myapp.com', timeout=3)
<Response [200]>
nGinx proxy cofing:
http
{
server
{
…
location /
{
…
proxy_read_timeout 120s;
…
}
}
}

If the question is related to the Flask timeout while waiting for the completion of the browser data request after a TCP socket connection is set-up by the browser and accepted by Flask (i.e., werkzeug, where each line sent by the browser resets the timer), a trivial solution would be to add this before app.run(...):
import socket
socket.setdefaulttimeout(10) # seconds
Setting it once at the beginning of the program affects all new socket connections.
A timed out request generates the BaseHTTPRequestHandler error Request timed out: TimeoutError('timed out').
This configuration does not appear to control the time Flask takes to process a valid request, which should be implemented inside the function decorated with #app.route(...).

Related

Daphne server unable to handle http requests

I have a django application that I want to deploy using daphne.
Django application supports both websockets and http requests. I've converted the django to support ASGI.
I'm starting the server using :
daphne <project_name>.asgi:application
The server is able to accept websocket connections but unable to handle the incoming HTTP requests (throws 404).
Where am I going wrong over here?
P.S.: I'm not using django channels.
I had forgotten to instantiate 'get_asgi_application' while creating the django application. Hence, it wasn't able to accept HTTP requests.

How does django work with websocket server and webserver simultaneously?

I think I have some confusion in the understanding of websocket server and webserver.
So I followed the tutorial of django channels, where I created a little app that listens on a channel and returns some response.
At the same time, I can still serve webpages with normal view functions, so how does django do this magic so that it works without me modifying anything in the nginx server config?
The documentation mentions how this works:
It separates Django into two process types:
One that handles HTTP and WebSockets
One that runs views, websocket handlers and background tasks (consumers)
They communicate via a protocol called ASGI, which is similar to WSGI but runs over a network and allows for more protocol types. [...] probably Daphne

Is it possible to make Django send data over tls protocol?

I am currently working on a web project in django and there is a requirement to ensure the safety of transmitting data over a network (passwords, usernames etc.).
I've read on owasp cheat sheet about authenication that for safety reasons all passwords should be sent from a client to a server over tsl protocol.
https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Transmit_Passwords_Only_Over_TLS_or_Other_Strong_Transport
Django framework sends these over http protocol. Is it possible to make django send it over tsl or work around it in another way?
When you run a Django application on the Internet, it's usually looking something like this:
[Django Application] <-> [uWSGI] <-> [nginx] <-> [web browser]
You can use different components, e.g. Gunicorn instead of uWSGI or Apache instead of nginx.
The thing is, you simply configure the webserver (Apache or nginx or whatever) with an SSL certificate and listen for https instead of http.
I think you're using Django runserver command for server your app over HTTP. It is absolutely not made for production and is a really HTTP (only) server for development.
For serve your app across SSL/TLS, you must use a frontend as described in henrikstroem's response

Handle request over TCP connection using django

I'm developing a server using django. There are numbers of devices that connect to this server and send request periodically. How can I handle these requests properly?
You'll probably want to look into django signals to setup webhooks to listen for certain things to call other things etc... signals was built to keep your app in sync with changes being made throughout. https://docs.djangoproject.com/en/dev/topics/signals/

Django Socketio Nginx proxy & session cookie issue

I have followed this tutorial: http://www.stephendiehl.com/?p=309 describing how to run a gevent pywsgi server serving Django with socketio behind a nginx front-end.
As this tutorial says, Nginx doesn't support websocket unless using a tcp proxy module. This proxy module doesn't support the use of the same port for socketio and classic serving, from what I understood the configuration look like that:
nginx listen on port 80
nginx tcp proxy listen on port 7000
Everything is forwarded to port 8000
Problem: the resulting socketio request doesn't include the django cookie containing the session id so I have no information on the requesting user in my django view.
I guess it's caused by the fact that the request is made to another port (7000) causing the browser to identify the request as cross-domain ?
What would be the cleanest way to include the django cookie into the request ?
Most answers in this question seem to indicate that port doesn't matter.
Also checked and supposedly WebSockets is regarded as HTTP, so HTTPOnly cookies should still be sent.
SocketIO seems to be using a custom Session manager to track users. Maybe try and link that up?