python

RealWorld: aiohttp, Tortoise ORM

  • понедельник, 10 февраля 2020 г. в 00:24:02
https://habr.com/ru/post/487610/
  • Разработка веб-сайтов
  • Python


RealWorld: aiohttp, Tortoise ORM


На Real World отсутствует пример для aiohttp, и я решил его сделать. Опытным разработчикам, похоже, некогда этим заниматься, а начинающим в aiohttp непонятно как делать правильно. Я начал его делать с помощью Tortoise ORM. Пока начал делать аутентификацию.


Хочется сделать этот проект правильно, поэтому под катом очень много вопросов опытным aiohttp разработчкам.


Установка проекта


Репозиторий


Склонируйте репозиторий:


git clone git@github.com:nomhoi/aiohttp-realworld-example-app.git

При разработке я использовал Python 3.8. Установите зависимости:


pip install -r requirements.txt

Инициализируем базу данных:


python init_db.py

Запускаем сервер:


python -m conduit

В репозитории присутствует Postman коллекция RealWorld.postman_collection.json. Импортируйте ее в Postman и можете попробовать получившийся API.


PostgreSQL


По умолчанию используется база данных SQLite.


Для использования PostrgeSQL нужно изменить переменную DB_URL в /conduit/settings.py.


DB_URL = "postgres://postgres:postgres@0.0.0.0:5432/postgres"

Запустить сервис базы данных:


docker-compose up -d

После этого инициализировать базу данных:


python init_db.py

Файловая структура проекта


Структура проекта выполнена в соответствии с современным подходом принятым в Django: все приложения находятся на том же уровне что и папка проекта. Это позволяет повторно использовать созданные приложения без их изменения в других проектах.


Аутентификация, профили и статьи будут выполнены в виде отдельных приложений, как и в примере RealWorld для Django.


Папка проекта — conduit.


Реализованное API


Спецификация API здесь


POST /api/users — регистрация пользователя


POST /api/users/login — аутентификация пользователя


GET /api/user — получение данных текущего пользователя


Обработчики этих запросов находятся в /authentication/views.py.


CORS


Использована библиотека aiohttp_cors.


# Configure default CORS settings.
cors = aiohttp_cors.setup(app, defaults={
    "*": aiohttp_cors.ResourceOptions(
        allow_credentials=True,
        expose_headers="*",
        allow_headers="*",
    )
})

# Configure CORS on all routes.
for route in list(app.router.routes()):
    cors.add(route)

Как видим, все включено и разрешено для всех ориджинов, и выполнена общая настройка для всех роутов.


Здесь можете подсказать, как лучше настроить.


JWT


Используется aiohttp_jwt:


    app = web.Application(
        middlewares=[
            JWTMiddleware(
                settings.SECRET_KEY,
                whitelist=[
                    r'/api/users',
                ]
            )
        ]
    )

JWT работает, только в заголовке Authorizstion вместо Token ставится слово Bearer. В примере для Django — Token. Будет ли работать нормально с фронтэндами пока не проверял.


Модель User


Используется Tortoise ORM


class TimestampedMixin:
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

class AbstractBaseModel(Model):
    id = fields.IntField(pk=True)

    class Meta:
        abstract = True

class User(TimestampedMixin, AbstractBaseModel):
    username = fields.CharField(db_index=True, max_length=255, unique=True)
    email = fields.CharField(db_index=True, max_length=255, unique=True)
    password = fields.CharField(max_length=128)

    class Meta:
        table = "user"

    def __str__(self):
        return self.username

Пока не нашел, как сделать сортировку как в Django примере:


ordering = ['-created_at', '-updated_at']

Думаю, что лучше всего вычисление токена из вьюхи переместить в модель User. Оформить его в виде свойства.


Хранение паролей планирую выполнить как в Django: хэш + соль с алгоритмом PBKDF2. Пока не выполнено.


Миграции


У Tortoise ORM отсутствуют автоматические миграции. По условиям задачи такое требование отсутствует, поэтому реализовывать не буду.


Сериализаторы


Пока сделал без сериализаторов. Нашел такой проект, но там старая версия Tortoise ORM.


Существуют и другие реализации сериализаторов. Наверное, с ними разработка ведется идиоматичнее и быстрее. Надо попробовать. ORM прицепили, теперь надо и сериализаторы добавить. А может и рендеров еще добавить?


Тесты


Пока не добавил. По условиям задачи тесты можно сделать, но они не обязательны.


Заключение


Нужно еще добавить поддержку профилей, статей и еще много чего. Приглашаются к проекту все желающие прославить свое имя на века и тысячелетия. Приветствуются подсказки и замечания опытных разработчиков.