Всем привет. В этой статье я расскажу о создании простых асинхронных проектов с саническими рамками.
Введение
Sanic Это очень похожий на флянку веб-сервер Python Python и веб-структуру с более чем 10K звезд Это написано, чтобы идти быстро. Это позволяет использовать Асинхрон/жду
Синтаксис добавлен в Python 3.5 (читать далее) , что делает ваш код не блокировка и быстрым.
Sanic имеет довольно хорошее Документация И это поддерживается сообществом для сообщества.
Целью проекта является предоставление простого способа создания и запуска высокопрофессионального HTTP -сервера, который легко построить, расширить и в конечном итоге масштабировать.
Требования
Прежде чем начать, давайте установим несколько пакетов и убедитесь, что у нас есть все готово для разработки этого проекта.
Примечание: исходный код доступен в моем github.com репозиторий. Для каждого шага есть соответствующий коммит.
Предварительные условия:
Python3.6+
пипенв
(Вы можете использовать любой другой установщик пакета)Postgresql
(Для базы данных также может быть MySQL или SQLite)
Пакеты:
Безопасно
это легкий пакет, который добавляет дополнительные заголовки безопасности и атрибуты cookie для веб -фреймворков Python.Окружение
это библиотека Python для переменных среды разбора. Это позволяет сохранить конфигурацию отдельно от вашего кода, согласно Двенадцатифакторное приложение методология.SANIC-ENVCONFIG
это расширение, которое помогает вам внести командную строку и переменные среды в саническую конфигурацию.Базы данных
это пакет Python, который позволяет вам задавать запросы, используя мощныеSQLALCHEMY
Основной язык выражения и обеспечивает поддержку PostgreSQL, MySQL и SQLite.
Давайте создадим пустой каталог и инициализируем там пустой Pipfile.
Pipenv-Python Python3.6
Установите все необходимые пакеты с помощью Pipenv
команды ниже.
Pipenv Установите Sanic Secure Environs Sanic-envconfig
Для базы данных:
Pipenv установить базы данных [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 setup setup( name='project', )
Установка…
Pipenv Установка -e.
В .env
Файл, мы сохраним некоторые глобальные переменные, такие как URL -адрес подключения базы данных.
__main__.py
создан для выполнения исполняемого пакета проекта из командной строки.
Pipenv Run Python -M Project
Инициализация
Давайте сделаем наш первый звонок в __main__.py
файл.
from project.main import init init()
Это начало нашего приложения. Теперь нам нужно создать функцию init внутри main.py
файл.
from sanic import Sanic app = Sanic(__name__) def init(): app.run(host='0.0.0.0', port=8000, debug=True)
Просто создать приложение из санического класса, мы можем запустить его, указав хост, порт и необязательный аргумент ключевого слова отладки.
Бег…
Pipenv Run Python -M Project
Если вы откроете http://0.0.0.0:8000 В вашем браузере вы увидите
Ошибка: запрошенный URL/не найден
Мы еще не создали никаких маршрутов, так что сейчас все в порядке. Мы добавим несколько маршрутов ниже.
Настройки
Теперь мы можем изменить среду и настройки. Нам нужно определить некоторые переменные в .env
файл, прочитайте их и передайте в Sanic App Config.
.env
файл.
DEBUG=True HOST=0.0.0.0 POST=8000
Конфигурация…
from sanic import Sanic from environs import Env from 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, )
настройки.py
файл.
from sanic_envconfig import EnvConfig class Settings(EnvConfig): DEBUG: bool = True HOST: str = '0.0.0.0' PORT: int = 8000
Обратите внимание, что я добавил необязательный AUTO_RELOAD
Аргумент, который будет активировать или деактивировать автоматический перезагрузитель.
База данных
Теперь пришло время настроить базу данных.
Одна маленькая заметка о пакете баз данных, прежде чем мы продолжим:
Базы данных Пакет использует Asyncpg
которая является асинхронной библиотекой интерфейса для PostgreSQL. Это довольно быстро. См. Результаты ниже.
Мы будем использовать два из саника Слушатели
где мы будем указать операции Connect и отключение базы данных. Вот слушатели, которые мы собираемся использовать:
After_server_start
After_server_stop
main.py
файл.
from sanic import Sanic from databases import Database # <- this line from environs import Env from project.settings import Settings app = Sanic(__name__) def setup_database(): # <- this function 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() # <- this line app.run( host=app.config.HOST, port=app.config.PORT, debug=app.config.DEBUG, auto_reload=app.config.DEBUG, )
Еще раз. Нам нужно указать DB_URL
В настройках проекта и среде.
.env
файл.
DEBUG=True HOST=0.0.0.0 POST=8000 DB_URL=postgresql://postgres:postgres@localhost/postgres # <- this line
И в настройки.py
файл.
from sanic_envconfig import EnvConfig class Settings(EnvConfig): DEBUG: bool = True HOST: str = '0.0.0.0' PORT: int = 8000 DB_URL: str = '' # <- this line
Убедитесь, что DB_URL
это правильно, и ваша база данных работает. Теперь вы можете получить доступ к базе данных, используя app.db
Анкет Смотрите более подробную информацию в следующем разделе.
Столы
Теперь у нас есть соединение с нашей базой данных, и мы можем попытаться сделать несколько запросов SQL.
Давайте объявим таблицу в tables.py
Файл с использованием sqlalchemy.
import sqlalchemy metadata = 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)), )
Здесь я предполагаю, что у вас уже есть мигрированная база данных с таблицей книг.
Для создания миграций базы данных я рекомендую вам использовать Алембик
Это легкий и простой в использовании инструмент, который вы можете использовать с инструментом базы данных SQLALCHEMY для Python.
Теперь мы можем использовать любые сердечные запросы SQLalchemy. Проверьте несколько примеров ниже.
# Executing many query = 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 rows query = books.select() rows = await app.db.fetch_all(query) # Fetch single row query = books.select() row = await app.db.fetch_one(query)
Маршруты
Теперь нам нужно настроить маршруты. Пойдем в routes.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 # <- this line app = Sanic(__name__) def init(): ... app.config.from_object(Settings) setup_database() setup_routes(app) # <- this line ...
Запрашивая…
$ curl localhost:8000/books {"books":[{"No Highway":"Nevil Shute"},{"The Daffodil":"SkyH. E. Bates"}]}
Средние войны
Как насчет проверки заголовков ответов и увидеть, что мы можем добавить или исправить там?
$ curl -I localhost:8000 Connection: keep-alive Keep-Alive: 5 Content-Length: 32 Content-Type: text/plain; charset=utf-8
Как вы можете видеть, нам нужны некоторые улучшения безопасности. Есть некоторые недостающие заголовки, такие как X-xss-protection
, Строго-транспортный-безопасность
… Итак, давайте позаботимся о них, используя комбинацию Middlewares
и безопасные пакеты.
Middlewares.py
файл.
from secure import SecureHeaders secure_headers = SecureHeaders() def setup_middlewares(app): @app.middleware('response') async def set_secure_headers(request, response): secure_headers.sanic(response)
Настройка Middlewares в 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) # <- this line ...
Результат:
$ curl -I localhost:8000/books Connection: keep-alive Keep-Alive: 5 Strict-Transport-Security: max-age=63072000; includeSubdomains X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Referrer-Policy: no-referrer, strict-origin-when-cross-origin Pragma: no-cache Expires: 0 Cache-control: no-cache, no-store, must-revalidate, max-age=0 Content-Length: 32 Content-Type: text/plain; charset=utf-8
Надеюсь, этот небольшой учебник помог вам начать с саником. Есть еще много неисследованных функций в Sanic Framework, которые вы можете найти и проверить в документации.
Давитовмаян/Саниский Проект
Спасибо за чтение. Быстро иди с саникой и удачи !!!
Оригинал: “https://dev.to/davitovmasyan/how-to-make-your-code-fast-and-asynchronous-with-python-and-sanic-1947”