I'm building an application on AWS and well, this world is new to me.
I expose the problem
I have experience with Apache/PHP, Apache is the one that helps me to serve the HTTP requests and PHP is the Backend language.
The backend language that I am using in this new project is Python, but my question is what is the technology that helps me to serve the requests?
Can I install Apache/Python, or what would be the perfect duo?
I know that this can have many variants depending on each experience and needs of the project, but honestly I'm lost on what to install and what not.
Thanks for your guidance.
python part
For the python part, it is typical to use "micro-frameworks" that take care of routing the requests, according to the URL, to the appropriate functions. These functions receive parameters, execute functionality (typically database queries and transformation of the results to the form needed by the client).
If you want the result to be an HTML page, "template" mechanisms are usually used, which are something similar to what PHP does, that is, a file that looks like HTML but that in certain areas has markers that indicate where the values should be dumped of certain variables. Python reads one of those templates, sets the variables, and calls a function that returns the HTML that is returned to the client.
It is also possible that the service does not return HTML to be displayed in a browser, but only the data for the client to treat as it wishes. In this way the client could be a mobile application, for example. In this case, the trend is to return the data in JSON and design the API following the REST philosophy.
Among this type of microservices, the most popular is Flask , combined with jinja2 for HTML templates . It is also used in certain Bottle environments, which has the advantage of being a simple python file that is easier to install, but much more limited than Flask.
More similar frameworks are coming out lately, inspired by Flask but implemented using the asynchronous paradigm (for Python 3.6+), like Vibora .
In principle, these frameworks are capable of serving requests by themselves, that is, without the need to put a server like Apache "in front". They simply run with python and listen on the port you tell them, to which the client could connect directly, make its HTTP requests and receive the response, either in HTML or JSON. The response could simply be a static HTML file read from disk, so they can completely replace a standard web server.
Production server
Although this is usually used during development, as it makes it very easy to launch the server locally for testing, once you want to take it to production, the mini-server included in the framework is usually no longer used for performance reasons.
For example, if you use Flask, it is implemented in a single process and a single thread. This means that you can only serve one customer at a time. If a client makes a request that takes a while to resolve, the other clients who have arrived shortly after will have to wait their turn because until the first one has been attended to, the next one will not be served. This is especially a problem if we want to use some "push notification" mechanism towards the client, such as Long poll, Server Sent Events or WebSockets, since these technologies require a permanent connection with each client, therefore only having one connected client. Asynchronous approaches can handle multiple clients within a single thread, but are conceptually more complex to program and understand.
For this reason, it is typical for one of these applications to be executed by another environment, which can launch several in parallel, in several processes and several threads within each process.
WSGI
For many years now, python has had a "standard" called WSGI for how such a server should communicate with the underlying python application. The frameworks mentioned above are all compatible with this standard, which allows you to use any of them with the server of your choice (which also supports WSGI).
For example, gunicorn would be a possible server (in this case it is also written in python) that takes care of loading your application (Flask for example), and instantiating it several times, in several threads (it also supports "green threads", which are for so to say false threads, lighter, managed by gunicorn instead of being operational threads). All of this is transparent to your application, which would be programmed just as if it were going to run on its own, except for the way it starts up.
Another possible server is uwsgi , in this case written in C and therefore faster than gunicorn.
Proxy (nginx)
Whether you're using gunicorn or uwsgi or any other WSGI-compliant server, that server will listen for requests on a certain port. Although you could make that port 80 and therefore already be able to receive HTTP traffic from the internet, the usual thing is not to do it that way, but to add another intermediate layer. For example, your WSGI server would listen on port 5000 (or whatever you want), and would only allow connections from
localhost
, and not from the Internet.On the same machine you would have a standard web server (Apache, or more frequently nginx ), which would act as a proxy . It would be this server that would receive traffic from the internet (and could deal with certificates and the HTTPS protocol, for example), could serve static files in certain folders and would be configured so that, when requests arrive at a certain URL, they are redirected to localhost :5000, where your WSGI server would be listening.
All together
A fairly typical combination would be to have
nginx
the server "facing" the internet, serving HTTP requests on port 80 and/or HTTPS on 443. Behind it, for example, it would beuwsgi
listening on port 5000 andnginx
it would be configured so that all requests to the route/myapp
are redirected tolocalhost:5000
. There it receives themuwsgi
and passes them to one of the threads/processes that it launched during startup where Flask is waiting for requests (by the WSGI protocol). Flask parses the concrete path (eg:/myapp/usuario/22?q=foobar
) and passes the request to the appropriate function within your python code, which already receives the parameters like a normal python function. The function can return HTML or JSON, depending on your interest, and flask will collect that response, convert it to a valid HTTP response by adding the necessary headers indicating its type, and pass it touwsgi
, which in turn will decide the HTTP transport method appropriate and add any extra header that might be needed, sending all of it tonginx
, which simply sends it to the client (perhaps encrypting it first if we're using HTTPS).The scheme would therefore be:
I hope I have helped you to get an idea of the panorama, which as you can see is quite different from the PHP world in which it is more typical that the same web server (Apache) can execute the code (PHP) through a plugin or mod .
In Full Stack Python you have a lot more information about frameworks, WSGI, deployment, servers, etc.
Your question seemed interesting to me and I looked around the web to see what I could find. Now I'm working with Django, and it's the first thing I thought of, but to serve and consume requests it seems too big for me (I've only been in the world of Python and Django for a few months).
I have looked a bit and I have found a couple of technologies that help you the same, the first is "Flask" , a framework to facilitate the development of web applications following the MVC pattern, and the second "technology" that I have seen and that also What has caught my attention is to directly use some Python libraries called request and json . The latter will make you work harder and create a solid architecture since it will not abstract you from certain things (ORM, imports, controllers...) as frameworks do.
I have left the links for you to take a look, greetings!