Рубрики
Без рубрики

Как сделать ваш код быстрым и асинхронным с Python и Sanic

Автор оригинала: FreeCodeCapm Team.

Давит Товмасян

Привет всем. В этой статье я расскажу о строительстве простых асинхронных проектов с саниновой структурой.

Вступление

Санич Это очень популярное веб-сервер с открытым исходным кодом Python и веб-каркас с более чем 10k звезды Это написано, чтобы пойти быстро. Это позволяет использовать Async/await Синтаксис добавлен в Python 3.5 ( Читать дальше ), который делает ваш код не блокировка и быстрый.

Санич имеет довольно хорошо Документация И это поддерживается сообществом, для сообщества.

Требования

Прежде чем начать, давайте установим некоторые пакеты и убедитесь, что у нас все готово к разработке этого проекта.

Примечание. Исходный код доступен в моем github.com Репозиторий. Для каждого шага есть соответствующий коммит.

Предпосылки:

  • Python3.6 +
  • Пипенв (Вы можете использовать любой другой установщик пакета)
  • PostgreSQL (для базы данных, также может быть MySQL или SQLite)

Пакеты:

  • Безопасный Это легкий пакет, который добавляет дополнительные заголовки безопасности и атрибуты Cookie для веб-каркасов Python.
  • Ориентиры это библиотека Python для переменных среды для анализа. Это позволяет хранить конфигурацию отдельно от вашего кода, согласно Приложение для двенадцати факторов Методология.
  • Sanic-Envconfig Есть и расширение, которое помогает вам принести переменные командной строки и среды в вашу Sanic Config.
  • Базы данных это пакет Python, который позволяет сделать запросы, используя мощный SQLALCHEMY CORE Язык экспрессии и обеспечивает поддержку PostgreSQL, MySQL и SQLite.

Давайте создадим пустой каталог и инициализируйте пустую Pipfile там.

pipenv  -- python python3.6

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

pipenv install sanic secure environs sanic-envconfig

Для базы данных:

pipenv install databases[postgresql]

Выбор – это postgresql, mysql, sqlite.

Состав

Теперь давайте создадим некоторые файлы и папки, где мы напишем наш фактический код.

├── .env├── Pipfile├── Pipfile.lock├── setup.py└── project    ├── __init__.py    ├── __main__.py    ├── main.py    ├── middlewares.py    ├── routes.py    ├── settings.py    └── tables.py

Мы будем использовать Setup.py Файл, чтобы сделать Проект Папка доступна в виде пакета в нашем коде.

from setuptools import setupsetup(    name='project',)

Установка …

pipenv install -e .

В .env Файл, мы будем хранить несколько глобальных переменных, таких как URL-адрес подключения к базе данных.

__main__.py создается для создания наших Проект Пакет исполняемый из командной строки.

pipenv run python -m project

Инициализация

Давайте сделаем наш первый звонок в __main__.py файл.

from project.main import initinit()

Это начало нашего приложения. Теперь нам нужно создать init Функция внутри main.py файл.

from sanic import Sanicapp = Sanic(__name__)def init():    app.run(host='0.0.0.0', port=8000, debug=True)

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

Бег…

pipenv run python -m project

Вот как успешной выход должен смотреть в ваше приложение SANIC. Если вы откроете http://0.0.0.0:8000 В вашем браузере вы увидите

Мы не создали ни одного маршруты Тем не менее, так что все в порядке. Мы добавим несколько маршрутов ниже.

Настройки

Теперь мы можем изменить окружающую среду и настройки. Нам нужно добавить некоторые переменные в .env Файл, прочитайте их и перейдите к конфигурации SANIC APP.

.env файл.

DEBUG=TrueHOST=0.0.0.0POST=8000

Конфигурация …

from sanic import Sanic
from environs import Envfrom project.settings import Settings
app = Sanic(__name__)
def init():    env = Env()    env.read_env()        app.config.from_object(Settings)    app.run(        host=app.config.HOST,         port=app.config.PORT,         debug=app.config.DEBUG,        auto_reload=app.config.DEBUG,        )

settings.py файл.

from sanic_envconfig import EnvConfigclass Settings(EnvConfig):    DEBUG: bool = True    HOST: str = '0.0.0.0'    PORT: int = 8000

Обратите внимание, что я добавил дополнительный auto_reload Аргумент, который активирует или деактивирует автоматический перезагрузчик.

База данных

Теперь пришло время настроить базу данных.

Одна маленькая заметка о Базы данных Пакет, прежде чем мы пойдем вперед:

Мы будем использовать двое из Sanic’s слушатели Откуда мы укажем база данных подключения и отключения операций. Вот слушатели, которые мы собираемся использовать:

  • allow_server_start.
  • all_server_stop.

main.py файл.

from sanic import Sanic
from databases import Database
from environs import Envfrom project.settings import Settings
app = Sanic(__name__)
def setup_database():    app.db = Database(app.config.DB_URL)    @app.listener('after_server_start')    async def connect_to_db(*args, **kwargs):        await app.db.connect()    @app.listener('after_server_stop')    async def disconnect_from_db(*args, **kwargs):        await app.db.disconnect()
def init():    env = Env()    env.read_env()        app.config.from_object(Settings)
    setup_database()
    app.run(        host=app.config.HOST,         port=app.config.PORT,         debug=app.config.DEBUG,        auto_reload=app.config.DEBUG,        )

Еще раз Нам нужно указать Db_url В настройках проекта и окружающей среде.

.env файл.

DEBUG=TrueHOST=0.0.0.0POST=8000DB_URL=postgresql://postgres:postgres@localhost/postgres

А также settings.py файл.

from sanic_envconfig import EnvConfigclass Settings(EnvConfig):    DEBUG: bool = True    HOST: str = '0.0.0.0'    PORT: int = 8000    DB_URL: str = ''

Убедитесь, что Db_url правильно, и ваша база данных работает. Теперь вы можете получить доступ к базе данных, используя app.db. См. Более подробную информацию в следующем разделе.

Столы

Теперь у нас есть связь с нашей базой данных, и мы можем попытаться сделать некоторые SQL-запросы.

Давайте объявим столик в Tables.py Файл с использованием SQLALCHEMY.

import sqlalchemymetadata = sqlalchemy.MetaData()books = sqlalchemy.Table(    'books',    metadata,    sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),    sqlalchemy.Column('title', sqlalchemy.String(length=100)),    sqlalchemy.Column('author', sqlalchemy.String(length=60)),)

Вот я предполагаю, что у вас уже есть Мигрировал База данных с Книги стол в нем. Для создания миграций базы данных я рекомендую использовать Алемический Какой легкий и простой в использовании инструмент, который вы можете использовать с помощью Toolkit баз данных SQLALCHEMY для Python.

Теперь мы можем использовать любой SQLALCHEMY CORE Запросы. Проверьте некоторые примеры ниже.

# Executing manyquery = books.insert()values = [    {"title": "No Highway", "author": "Nevil Shute"},    {"title": "The Daffodil", "author": "SkyH. E. Bates"},]await app.db.execute_many(query, values)# Fetching multiple rowsquery = books.select()rows = await app.db.fetch_all(query)# Fetch single rowquery = books.select()row = await app.db.fetch_one(query)

Маршруты

Теперь нам нужно настроить маршруты. Пойдем на Marross.py и добавить новый маршрут для книг.

from sanic.response import json
from project.tables import books
def setup_routes(app):    @app.route("/books")    async def book_list(request):        query = books.select()        rows = await request.app.db.fetch_all(query)        return json({            'books': [{row['title']: row['author']} for row in rows]        })

Конечно, нам нужно позвонить Setup_routes в init сделать это работать.

from project.routes import setup_routes
app = Sanic(__name__)
def init():    ...    app.config.from_object(Settings)    setup_database()    setup_routes(app)    ...

Запрос …

$ curl localhost:8000/books{"books":[{"No Highway":"Nevil Shute"},{"The Daffodil":"SkyH. E. Bates"}]}

Hiddrwares.

Как насчет проверки ответ заголовки и видя, что мы можем добавить или исправить там?

$ curl -I localhost:8000Connection: keep-aliveKeep-Alive: 5Content-Length: 32Content-Type: text/plain; charset=utf-8

Как видите, нам нужны некоторые улучшения безопасности. Есть некоторые недостающие заголовки, такие как X-XSS-защита, строгопередающая безопасность Итак, давайте позаботимся о них, используя комбинацию средние годы и Безопасный пакеты.

Hiddrwares.py файл.

from secure import SecureHeaderssecure_headers = SecureHeaders()def setup_middlewares(app):    @app.middleware('response')    async def set_secure_headers(request, response):        secure_headers.sanic(response)

Настройка подразгов в main.py файл.

from project.middlewares import setup_middlewares
app = Sanic(__name__)
def init():    ...    app.config.from_object(Settings)    setup_database()    setup_routes(app)    setup_middlewares(app)    ...

Результатом является:

$ curl -I localhost:8000/booksConnection: keep-aliveKeep-Alive: 5Strict-Transport-Security: max-age=63072000; includeSubdomainsX-Frame-Options: SAMEORIGINX-XSS-Protection: 1; mode=blockX-Content-Type-Options: nosniffReferrer-Policy: no-referrer, strict-origin-when-cross-originPragma: no-cacheExpires: 0Cache-control: no-cache, no-store, must-revalidate, max-age=0Content-Length: 32Content-Type: text/plain; charset=utf-8

Как я обещал в начале, есть Github Repository для каждого Раздел в этой статье. Надеюсь, что этот небольшой учебник помог вам начать с санином. Есть еще много неисследованных функций в саниновых рамках, которые вы можете найти и проверить в Документация Отказ

Давитовман/Санич-проект Goin ‘быстро и асинхронно с Python и Sanic! – Давитовмасан/Sanic-Project github.com.

Если у вас есть мысли об этом, обязательно оставьте комментарий.

Если вы нашли эту статью полезную, дайте мне несколько хлопьев?

Спасибо за прочтение. Идите быстро с санином и удачи !!!