Asynchrony can be implemented in many programming languages, including Python. However, asynchrony in early Python was not as widely used as Javascript or C# because of its difficult implementation. In this article, I will introduce the history of asynchronous programming in Python and its growth at the present time.
When people solved the "c10k problem" and then the advent of Nginx, asynchronous programming was more interesting and improved to make it easier to install than its original version.
In the original version, you must know concepts such as non-blocking socket, multiplexer, selector, ... of the OS to be able to implement an asynchronous processing application:
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
last_fd = sockfd;
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
}
fcntl(last_fd, F_SETFL, O_NONBLOCK); /* Change the socket into non-blocking state */
fcntl(new_fd, F_SETFL, O_NONBLOCK); /* Change the socket into non-blocking state */
while(1){
for (i=sockfd;i<=last_fd;i++){
printf("Round number %d\n",i);
if (i = sockfd){
...
Now, using asynchronous in Python is a peace of cake because of the syntactic improvement. The async/await
syntax was first introduced by C# and then implemented by many other programming languages like Javascript, Python, Java, C++, Rust, Swift,...
Asynchronous "programmable technique" switches to "the syntence of a programming language".
Asynchronous in Python is completely possible because Python supports non-blocking socket APIs of OS such as selector, and multiplexing,... However, using these APIs to deploy an asynchronous application is quite difficult.
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("0.0.0.0", port_number))
server_socket.listen(max_clients)
inputs = [server_socket]
outputs = []
while True:
readable, writable, exceptional = select.select(inputs, outputs, inputs, 1)
for s in readable:
if s is server_socket:
connection, client_address = s.accept()
connection.setblocking(0)
inputs.append(connection)
threading.Thread(target=handle_client, args=(connection, client_address)).start()
As a result, programmers have combined those APIs with coroutines to perform asynchronous implementations.
Coroutine is a common concept in many programming languages and was first introduced in Python with PEP 342 by Guido van Rossum and Phillip J. Eby proposed in 2005, in Python version 2.5.
If you want to better understand how to use a coroutine to implement asynchronous programming, you can read your 2 articles below for more detail:
One of the famous frameworks that implement asynchronous is Tornado.
Tornado is a networking framework that implements asynchronous on coroutine for the following purposes:
In 2015, PEP 492 was born and proposed by Yury Selivanov. By using coroutine to implement the syntax of async/await, Python has been able to make asynchronous operators much easier for programmers.
Instead of having to work with low-level APIs, working with a pure coroutine, now, we only need to know two extremely popular keywords: async/await
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.setblocking(False)
listener.bind((host, port))
listener.listen(1024)
loop = asyncio.get_event_loop()
while True:
client, addr = await loop.sock_accept(listener)
loop.create_task(handle_client(client))
The author also said reasons for the async/await
syntactic in his proposal:
The growth of the Internet and general connectivity has triggered the proportionate need for responsive and scalable code. This proposal aims to answer that need by making writing explicitly asynchronous, concurrent Python code easier and more Pythonic.
As mentioned above, async/await
itself is just a syntax designed to make the code more readable. What is actually processed behind it is the coroutine, so it is not wrong to say that Python's asynchronous functionality is implemented by coroutines.
Before ASGI was born, WSGI was the popular standard for web applications to communicate with web servers. This standard was introduced by PEP 333 in late 2003. It focuses on developing an interface based on the synchronous API of the network: blocking. Therefore, to implement scale performance, multi-thread is used in combination, similar to the case of Apache HTTP Server.
We have web servers implementing this standard such as Gunicorn, uWSGI or Nginx with the support of ngx_http_uwsgi_module module.
Some web frameworks implement this standard such as Django, Flask, Bottle,...
In September - 2018, version 1.0 of ASGI was released, opening a new era of web development. With the birth of ASGI, a series of asynchronous support libraries and frameworks were born such as Uvicorn, Hypercorn, Django v3, Fastapi, Starlette, Quart, Sanic,...
People gradually know and use asynchronous frameworks more thanks to the support of these web frameworks.
With the database, we have:
With the HTTP client, we can use httpx, it has a completely similar interface to requests.
For a web framework, we have:
For web servers, there are:
There are many other libraries that support asynchrony that we can use.
Currently, on Github, some groups worth paying attention to this trending can be mentioned such as:
Some notable individuals such as:
Python is really changing a lot in web development in general and the stack handles asynchronous - scalable applications in general. Let's take a look at a few milestones before ending the article
I hope that through this article, you can better understand the development history of the Python real estate ecosystem in general and the development and trends in web development in particular of Python.