Перейти к содержанию

Приложения

Esmerald работает на основе Lilya и поэтому включает в себя класс приложения Esmerald, который объединяет всю функциональность.

Класс Esmerald

from esmerald import (
    Esmerald,
    Gateway,
    Request,
    Response,
    Websocket,
    WebSocketGateway,
    get,
    websocket,
)


@get()
async def homepage(request: Request) -> Response:
    return Response("Hello, world!")


@get()
async def me(request: Request) -> Response:
    username = "John Doe"
    return Response("Hello, %s!" % username)


@get()
def user(request: Request) -> Response:
    username = request.path_params["username"]
    return Response("Hello, %s!" % username)


@websocket()
async def websocket_endpoint(socket: Websocket) -> None:
    await socket.accept()
    await socket.send_text("Hello, websocket!")
    await socket.close()


def startup():
    print("Up up we go!")


routes = [
    Gateway("/home", handler=homepage),
    Gateway("/me", handler=me),
    Gateway("/user/{username}", handler=user),
    WebSocketGateway("/ws", handler=websocket_endpoint),
]

app = Esmerald(routes=routes, on_startup=[startup])
from esmerald.applications import Esmerald
from esmerald.requests import Request
from esmerald.responses import Response
from esmerald.routing.handlers import get, websocket
from esmerald.routing.router import Gateway, WebSocketGateway
from esmerald.websockets import Websocket


@get()
async def homepage(request: Request) -> Response:
    return Response("Hello, world!")


@get()
async def me(request: Request) -> Response:
    username = "John Doe"
    return Response("Hello, %s!" % username)


@get()
def user(request: Request) -> Response:
    username = request.path_params["username"]
    return Response("Hello, %s!" % username)


@websocket()
async def websocket_endpoint(socket: Websocket) -> None:
    await socket.accept()
    await socket.send_text("Hello, websocket!")
    await socket.close()


def startup():
    print("Up up we go!")


routes = [
    Gateway("/home", handler=homepage),
    Gateway("/me", handler=me),
    Gateway("/user/{username}", handler=user),
    WebSocketGateway("/ws", handler=websocket_endpoint),
]

app = Esmerald(routes=routes, on_startup=[startup])
from esmerald.applications import Esmerald
from esmerald.requests import Request
from esmerald.responses import Response
from esmerald.routing.handlers import get, websocket
from esmerald.routing.router import Gateway, Include, WebSocketGateway
from esmerald.websockets import Websocket


@get()
async def homepage(request: Request) -> Response:
    return Response("Hello, world!")


@get()
async def me(request: Request) -> Response:
    username = "John Doe"
    return Response("Hello, %s!" % username)


@get()
def user(request: Request) -> Response:
    username = request.path_params["username"]
    return Response("Hello, %s!" % username)


@websocket()
async def websocket_endpoint(socket: Websocket) -> None:
    await socket.accept()
    await socket.send_text("Hello, websocket!")
    await socket.close()


def startup():
    print("Up up we go!")


routes = [
    Include(
        routes=[
            Gateway("/home", handler=homepage),
            Gateway("/me", handler=me),
            Gateway("/user/{username}", handler=user),
            WebSocketGateway("/ws", handler=websocket_endpoint),
        ]
    )
]

app = Esmerald(routes=routes, on_startup=[startup])

Быстрая заметка

Поскольку возможности Swagger и ReDoc ограничены, например, при использовании username = request.path_params["username"], вы не сможете протестировать это через документацию. Наилучший способ сделать это — вызывать API напрямую через любой предпочитаемый клиент или браузер.

Другими словами, параметр url может быть захвачен с помощью Request.path_params, но не может быть протестирован через Swagger UI.

Тестирование с использованием curl или insomnia

С помощью cURL:

$ curl -X GET http://localhost:8000/user/esmerald

С помощью Insomnia:

Insomnia

Note

Вы можете использовать что-то еще, кроме insomnia. Это было для примера.

Инициализация приложения

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

Параметры:

  • debug - Логическое значение, указывающее, должны ли возвращаться трассировки отладки при ошибках. В основном, режим отладки, очень полезен для разработки.
  • title - Заголовок для приложения. Используется для OpenAPI.
  • app_name - Название приложения. Также используется для OpenAPI.
  • description - Описание приложения. Используется для OpenAPI.
  • version - Версия приложения. Используется для OpenAPI.
  • contact - Контактные данные администратора. Используется для OpenAPI.
  • terms_of_service - Условия использования приложения. Используется для OpenAPI.
  • license - Информация о лицензии. Используется для OpenAPI.
  • servers - Серверы в формате словаря. Используется для OpenAPI.
  • secret_key - Секретный ключ, используемый для внутреннего шифрования (например, пароли пользователей).
  • allowed_hosts - Список разрешенных хостов. Включает встроенный middleware для разрешенных хостов.
  • allow_origins - Список разрешенных источников. Включает встроенный middleware CORS. Может быть только allow_origins или объект CORSConfig, но не оба.
  • routes - Список маршрутов для обслуживания входящих HTTP и WebSocket запросов. Список Gateway, WebSocketGateway или Include.
  • interceptors - Список interceptors для обслуживания входящих запросов приложения (HTTP и WebSocket).
  • permissions - Список permissions для обслуживания входящих запросов приложения (HTTP и WebSocket).
  • middleware - Список middleware, которые будут выполняться для каждого запроса. Приложение Esmerald всегда будет включать middleware из переданных конфигураций (CSRF, CORS, JWT...) и пользовательских middleware. Middleware может быть подклассом MiddlewareProtocol или Lilya Middleware. Узнайте больше о протоколах Python.
  • dependencies - Словарь строк и экземпляров Inject, позволяющий внедрение зависимостей на уровне приложения.
  • exception_handlers - Словарь типов исключений (или пользовательских исключений) и функций-обработчиков на верхнем уровне приложения. Обработчики исключений должны быть в форме handler(request, exc) -> response и могут быть как синхронными, так и асинхронными функциями.
  • csrf_config - Если установлен CSRFConfig, это включит middleware CSRF.
  • openapi_config - Если установлен OpenAPIConfig, это переопределит настройки документации OpenAPI по умолчанию.
  • cors_config - Если установлен CORSConfig, это включит middleware CORS.
  • static_files_config - Если установлен StaticFilesConfig, это включит конфигурацию статических файлов приложения.
  • template_config - Если установлен TemplateConfig, это включит шаблонный движок.
  • session_config - Если установлен SessionConfig, это включит middleware для сессий.
  • response_class - Пользовательский подкласс Response, который будет использоваться в качестве класса ответа приложения.
  • response_cookies - Список объектов cookie.
  • response_headers - Словарь объектов заголовков.
  • scheduler_config - Класс SchedulerConfig, используемый для планировщика приложения. Дополнительные конфигурации задач планировщика.
  • timezone - Часовой пояс по умолчанию для приложения. По умолчанию UTC.
  • on_shutdown - Список вызываемых функций при завершении работы приложения. Обработчики завершения работы не принимают никаких аргументов и могут быть как синхронными, так и асинхронными функциями.

  • on_startup - Список вызываемых функций при запуске приложения. Обработчики запуска не принимают никаких аргументов и могут быть как синхронными, так и асинхронными функциями.

  • lifespan - Функция контекста жизненного цикла - это более новый стиль, который заменяет обработчики on_startup / on_shutdown. Используйте один из них, а не оба.
  • tags - Список тегов для включения в схему OpenAPI.
  • include_in_schema - Логический флаг, указывающий, следует ли включать в схему или нет.
  • deprecated - Логический флаг для устаревания. Используется для OpenAPI.
  • security - Определение безопасности приложения. Используется для OpenAPI.
  • enable_openapi - Флаг для включения/выключения документации OpenAPI. По умолчанию включено.
  • redirect_slashes - Флаг для включения/выключения перенаправления слешей для обработчиков. По умолчанию включено.

Настройки приложения

Настройки - это еще один способ управления параметрами, переданными объекту Esmerald при создании. Ознакомьтесь с настройками для получения дополнительных сведений о том, как использовать их для улучшения вашего приложения.

Для доступа к настройкам приложения существует несколько способов:

from esmerald import Esmerald, Gateway, Request, get


@get()
async def app_name(request: Request) -> dict:
    settings = request.app.settings
    return {"app_name": settings.app_name}


app = Esmerald(routes=[Gateway(handler=app_name)])
from esmerald import Esmerald, Gateway, get, settings


@get()
async def app_name() -> dict:
    return {"app_name": settings.app_name}


app = Esmerald(routes=[Gateway(handler=app_name)])
from esmerald import Esmerald, Gateway, get
from esmerald.conf import settings


@get()
async def app_name() -> dict:
    return {"app_name": settings.app_name}


app = Esmerald(routes=[Gateway(handler=app_name)])

Состояние и экземпляр приложения

Вы можете хранить произвольное дополнительное состояние в экземпляре приложения, используя State.

Пример:

from esmerald import Esmerald
from esmerald.datastructures import State

app = Esmerald()

app.state = State({"ADMIN_EMAIL": "admin@example.com"})

Доступ к экземпляру приложения

К экземпляру приложения можно получить доступ через request, когда он доступен.

Пример:

from esmerald import Esmerald, Gateway, JSONResponse, Request, get


@get()
async def user(request: Request) -> JSONResponse:
    return JSONResponse({"app_name": request.app.settings.app_name})


app = Esmerald(routes=[Gateway(handler=user)])

Доступ к состоянию из экземпляра приложения

Состояние можно получить из request, когда он доступен.

Пример:

from esmerald import Esmerald, Gateway, JSONResponse, Request, get
from esmerald.datastructures import State


@get()
async def user(request: Request) -> JSONResponse:
    return JSONResponse({"admin_email": request.app.state["ADMIN_EMAIL"]})


app = Esmerald(routes=[Gateway(handler=user)])
app.state = State({"ADMIN_EMAIL": "admin@example.com"})