First steps at aiohttp

Introduction

Hi, my name is Artyom and I work as a backend in KTS… The company has been conducting summer and winter development courses for 3 years already, and in February of this year, another free backend school from KTS… Within its framework, students studied the tools and technologies used by the developers of our company, communicated with mentors and made the final project – a chat bot in the style of “My Game”, which they defended at the end of the course. After the course, the distinguished students were invited for an internship.

The school consisted of 6 lectures, step by step immersed students in the world of web development. They covered such topics as network protocols, backend and frontend interaction, web server components, and much more. The leitmotif of the course was the study of asynchronous web programming in Python, in particular, the study of the framework aiohttp

To enter the course, it was necessary to pass a comprehensive test for knowledge in the field of web and python, so students came to study with a good initial level of knowledge. However, during the course it became clear that not all topics are given equally easily. The most difficult topics to understand were:

  1. Asynchronous programming

  2. Working with DBMS

  3. Deploy the application

Students asked quite different questions in terms of understanding, ranging from “How to create a lazy task using only asyncio?” and ending with “Why can’t you use Django for asynchronous programming?” (meant a fully synchronous version of Django). In the code, our mentors also found errors related to a lack of understanding of the subject, for example, using a synchronous driver for a database in an asynchronous project.

Based on the results of the course, I decided to write a small tutorial about creating a basic aiohttp service from scratch and touching on the most difficult questions for students: how to make an asynchronous python application, how to work with a database and how to decompose your project on the Internet.

In this series of articles, we will cover the following topics:

  1. Web application architecture

  2. Asynchronous work with the database and automatic migrations

  3. Working with HTML templates using Jinja2

  4. Placing our application on the Internet using the service Heroku

  5. As well as signals, error handling, work with Docker and much more.

This article is the first of three and aims to help aspiring aiohttp programmers write their first “hello-world” application.

In this article, we will write a small web application on aiohttp – a feedback wall where a user can leave an opinion about a product.

We will go through the steps:

  • Project creation

  • Project structure

  • Creating a View

  • Route creation

  • Creating a template

  • Application launch

Project creation

All commands in this article were executed on the OSX operating system, but should also work on any * NIX system, such as Linux Ubuntu. During development, I will be using Python 3.7.

Let’s create a folder aiohttp_server, which in the future will be called the root of the projectIn it we will create a text file requirements.txt, which will contain all the dependencies necessary for the application to work and their versions. Let’s write the following modules into it:

aiohttp==3.7.3 # наш фрейворк
aiohttp-jinja2==1.4.2 # модуль для работы с HTML-шаблонами

Let’s create virtual environment – something like a sandbox that contains an application with its libraries, updating and changing which will not affect other applications, and install our dependencies into it:

cd {путь_до_папки}/aiohttp_server
python3 -m venv venv
source venv/bin/activate

After that, the inscription (venv) should appear at the beginning of the terminal line – this means that the virtual environment has been successfully activated. Install the required modules:

pip install -r requirements.txt

Project structure

Let’s create in the folder aiohttp_server the following structure:

├── app
│   ├── __init__.py
│   ├── forum
│   │   ├── __init__.py
│   │   ├── routes.py  # тут будут пути, по которым надо отправлять запросы
│   │   └── views.py  # тут будут функции, обрабатывающие запросы
│   ├── settings.py
├── main.py  # тут будет точка входа в приложение
├── requirements.txt
└── templates
   └── index.html  # тут будет html-шаблон страницым сайта

Now let’s open the main.py file and add the following to it:

from aiohttp import web  # основной модуль aiohttp
import jinja2  # шаблонизатор jinja2
import aiohttp_jinja2  # адаптация jinja2 к aiohttp

# в этой функции производится настройка url-путей для всего приложения
def setup_routes(application):
   from app.forum.routes import setup_routes as setup_forum_routes
   setup_forum_routes(application)  # настраиваем url-пути приложения forum

def setup_external_libraries(application: web.Application) -> None:
   # указываем шаблонизатору, что html-шаблоны надо искать в папке templates
   aiohttp_jinja2.setup(application, loader=jinja2.FileSystemLoader("templates"))

def setup_app(application):
   # настройка всего приложения состоит из:
   setup_external_libraries(application)  # настройки внешних библиотек, например шаблонизатора
   setup_routes(application)  # настройки роутера приложения

app = web.Application()  # создаем наш веб-сервер

if __name__ == "__main__":  # эта строчка указывает, что данный файл можно запустить как скрипт
   setup_app(app)  # настраиваем приложение
   web.run_app(app)  # запускаем приложение

After preconfiguration, you can create the first View.

First View

View is a callable object that accepts an HTTP request as input – Request and returns an HTTP response to the incoming request – Response.

An Http request contains useful information such as the request url and context, user-supplied data, and much more. The request context contains the data that we or aiohttp added to this request. For example, we pre-authorized the user – in order not to re-check the user authorization from the database in all Views and not to duplicate the code, we can add the user object to the request context. Then we can get our user in the View, for example, like this: request[‘user’]…

The HTTP response includes payloads like json data, headers and response status. In the simplest View, which is from the example above, the decorator @ aiohttp_jinja2.template (“index.html”) does all the work of generating the HTTP response. The decorator receives data from the View, which is returned in the form of a dictionary, finds the index.html template (see templates below), inserts the data from this dictionary there, converts the template to html-text and passes it in response to the request. The browser parses the html and displays the page with our content.

In file views.py in folder app / forum write the following code:

import aiohttp_jinja2
from aiohttp import web

# создаем функцию, которая будет отдавать html-файл
@aiohttp_jinja2.template("index.html")
async def index(request):
   return {'title': 'Пишем первое приложение на aiohttp'}

This is where a function-based View is created. The definition of “functional” means that the code is formatted as a function, not a class (in the next part we will touch on the class-based View).

Let’s consider the written function in more detail: the function is wrapped in a decorator @ aiohttp_jinja2.template (“index.html”)– this decorator passes the value returned by the function to the template engine Jinja2 and then returns the html page generated by the templating engine as an http response. In this case, the returned value will be a dictionary whose values ​​are substituted into the index.html html file.

Separately, it should be noted that the request object is passed as an argument to the index function. We do not use request in this function, but we will use it in the future.

The HTTP request is sent to a specific url. To send an HTTP request to the desired View, you need to set this connection in the application using Route.

First Route

Route is a link connecting the address to which the request was sent and the View code in which this request will be processed. That is, if the user goes to the root of our site (at /), then the request object will be passed to the View index and the response will be returned from there. You can read more about Route here

To file routes.py you need to add the following code:

from app.forum import views

# настраиваем пути, которые будут вести к нашей странице
def setup_routes(app):
   app.router.add_get("https://habr.com/", views.index)

First Template

Now all we need to do is add to templates / index.html the code for the layout of our page. It can be found by this link.

Template – this is an html-template into which the data obtained as a result of request processing is substituted. In the example in the View code, a dictionary with the title key is returned, the template engine Jinja2searches the specified html template for strings {{title}}and replaces them with the value from the dictionary for the given key. This is the simplest example, templates allow you to do a lot more: perform branching operations, loops, and other operations such as summation. Examples of use can be found in the documentation jinja2

Application launch

We have created the first version of our application! It remains to run it with the following command in the terminal (make sure you are in the folderaiohttp_server):

python3 main.py

You should see the following text in the console. It means that the server is running on port 8080.

======== Running on http://0.0.0.0:8080 ========

(Press CTRL+C to quit)

Let’s now see the results of our work! To do this, go to http://0.0.0.0:8080 in the browser. You should see the first version of our application. When you click on the “Submit” button, a message should appear stating that the review has been sent.

Congratulations! You have successfully created your first application on aiohttp!

Conclusion

This article describes how to create a simple aiohttp application that accepts a user request and returns an html page. We touched on:

  • Setting up the virtual environment

  • Basic project setup on aiohttp

  • Creating a View

  • Route creation

  • Using html templates

Our application is a simple web server that serves up an html page on demand – it does not have any interaction with databases, its structure is as simple as possible, and it is not available to users on the Internet. In the following articles, we will analyze how to grow a “real” web application on aiohttp from our blank and publish it on the Internet.

The entire article code can be found on github

I take this opportunity to invite all readers interested in web development to our free classes at KTS School. And for more experienced readers, there is now an enrollment in advanced courses for backend developers who want to improve their skills in asynchronous web development. All information about all schools can be found Onlineas well as in our telegram chat

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *