|  | 
|  | 1 | +from fastapi_django.conf.global_settings import MANAGEMENT | 
|  | 2 | + | 
| 1 | 3 | # Команды | 
| 2 | 4 | 
 | 
| 3 | 5 | Работа с командами реализована в модуле [management](../fastapi_django/management). Работают команды на [Typer](https://typer.tiangolo.com) | 
| 4 | 6 | 
 | 
| 5 |  | -В модуле [management/commands](../fastapi_django/management/commands) реализованы дефолтные команды runserver и echo. | 
|  | 7 | +## CLI | 
|  | 8 | + | 
|  | 9 | +Экземпляр Typer и команды созданы в модуле [management/cli.py](../fastapi_django/management/cli.py). Из-за особенностей работы с Typer необходимо, чтобы  | 
|  | 10 | +интерпретатор Python при импорте экземпляра Typer проходил также команды, обернутые декоратором `command()`.  | 
|  | 11 | + | 
|  | 12 | +## Дефолтные команды | 
|  | 13 | + | 
|  | 14 | +Реализованы дефолтные команды `echo` и `runserver` (см. [management/cli.py](../fastapi_django/management/cli.py)).  | 
|  | 15 | + | 
|  | 16 | +## Директория management/commands | 
| 6 | 17 | 
 | 
| 7 |  | -По сути manage.py является прокси к приложению на Typer.  | 
|  | 18 | +Дефолтные команды `echo` и `runserver` простые и вполне помещаются в функцию. Однако, если логика громоздкая, то возникает | 
|  | 19 | +потребность поместить ее в класс. В таком случае, предлагается размещать в каждый свой файл как это например показано  | 
|  | 20 | +по ссылке https://github.com/albertalexandrov/fastapi-django-example/blob/main/src/management/commands/calculator.py.  | 
|  | 21 | +Осталось эту логику запустить. Для этого в https://github.com/albertalexandrov/fastapi-django-example/blob/main/src/management/cli.py создается команда,  | 
|  | 22 | +которая запускает ее. | 
| 8 | 23 | 
 | 
| 9 | 24 | ## Кастомные команды | 
| 10 | 25 | 
 | 
| 11 |  | -Команда - это callable объект, который может находится в любом месте проекта. Но чтобы команда разаработала, ее необходимо | 
| 12 |  | -зарегистрировать. Предлагается регистрировать ее в том же модуле, в котором вызывается приложение Typer, то есть в модуле manage.py | 
| 13 |  | -при помоши функции management.utils.register_command. | 
|  | 26 | +Объект `typer` [management/cli.py](../fastapi_django/management/cli.py) является **корневым** CLI, в которому должны  | 
|  | 27 | +добавляться кастомные команды.  | 
| 14 | 28 | 
 | 
| 15 |  | -Пример кастомной команды https://github.com/albertalexandrov/fastapi-django-example/tree/main/src/commands. | 
| 16 |  | -Пример регистрации команды: https://github.com/albertalexandrov/fastapi-django-example/blob/main/src/manage.py#L10 | 
|  | 29 | +Вне зависимости от того, идет ли речь про код приложения FastAPI или некоторой библиотеки предлагается следующий алгоритм | 
|  | 30 | +создания кастомных команд.  | 
| 17 | 31 | 
 | 
| 18 |  | -## Команда runserver | 
|  | 32 | +1. В проекте/библиотеке создается структура папок и файлов: | 
| 19 | 33 | 
 | 
| 20 |  | -Данная команда запускает приложение FastAPI при помощи Uvicorn. Если взглянуть на ее реализацию, можно увидеть,  | 
| 21 |  | -как она понимает, с какими параметрами необходимо запустить приложение: | 
|  | 34 | +```python | 
|  | 35 | +management | 
|  | 36 | +├── commands (опционально) | 
|  | 37 | +    ├── __init__.py  | 
|  | 38 | +├── cli.py | 
|  | 39 | +``` | 
|  | 40 | + | 
|  | 41 | +2. в `cli.py` определяется, настраивается объект `Typer`, реализуются кастомные команды: | 
| 22 | 42 | 
 | 
| 23 | 43 | ```python | 
| 24 |  | -def runserver() -> None: | 
| 25 |  | -    params = {} | 
| 26 |  | -    uvicorn_settings = [setting for setting in dir(settings) if setting.startswith("UVICORN_")] | 
| 27 |  | -    for setting in uvicorn_settings: | 
| 28 |  | -        _, param = setting.split("_", 1) | 
| 29 |  | -        params[param.lower()] = getattr(settings, setting) | 
| 30 |  | -    uvicorn.run(**params) | 
|  | 44 | +# cli.py | 
|  | 45 | + | 
|  | 46 | +from typer import Typer | 
|  | 47 | + | 
|  | 48 | +typer = Typer(help="Команды проекта/библиотеки") | 
|  | 49 | + | 
|  | 50 | + | 
|  | 51 | +@typer.command() | 
|  | 52 | +def info(): | 
|  | 53 | +    print("Вот информация о проекте/библиотеке") | 
|  | 54 | + | 
| 31 | 55 | ``` | 
| 32 | 56 | 
 | 
| 33 |  | -Параметры запуска Uvicorn задаются в settings. Названия параметров должны иметь префикс UVICORN_ | 
| 34 |  | -Далее идут названия параметров функции uvicorn.run в верхнем регистре. Таким образом, параметр, | 
| 35 |  | -соответствующий параметру workers будет иметь название UVICORN_WORKERS, для port - UVICORN_PORT и тд | 
|  | 57 | +3. Подключение к корневому CLI | 
| 36 | 58 | 
 | 
| 37 |  | -## Список команд | 
|  | 59 | +Осталось подключить созданный объект typer, который содержит кастомные команды, к корневому CLI.  | 
|  | 60 | +Для этого необходимо в настройку MANAGEMENT прописать: | 
| 38 | 61 | 
 | 
| 39 |  | -Здесь https://github.com/albertalexandrov/fastapi-django-example/blob/main/src/manage.py#L10 была зарегистрирована  | 
| 40 |  | -кастомная команда. Убедится, команда была зарегистрирована можно введя в консоль список всех команд командой: | 
|  | 62 | +```python | 
|  | 63 | +# settings.py | 
| 41 | 64 | 
 | 
| 42 |  | -```shell | 
| 43 |  | -python manage.py --help | 
|  | 65 | +MANAGEMENT = [ | 
|  | 66 | +    { | 
|  | 67 | +        "typer": "management.cli:typer", | 
|  | 68 | +    } | 
|  | 69 | +] | 
| 44 | 70 | ``` | 
| 45 | 71 | 
 | 
| 46 |  | - | 
|  | 72 | +4. Проверка  | 
| 47 | 73 | 
 | 
| 48 |  | -## Примечание | 
|  | 74 | +Чтобы просмотреть список команд, необходимо выполнить команду `python manage.py --help`: | 
| 49 | 75 | 
 | 
| 50 |  | -Я рассчитывал, что объект [cli](../fastapi_django/management/__init__.py) будет импортироваться где нужно и  | 
| 51 |  | -команды будут автоматически регистрироваться. Однако, недостаточно обернуть функцию в декоратор cli.command,  | 
| 52 |  | -поэтому приходится делать так, что команда регистрируется аккурат перед тем, когда выполняется  | 
| 53 |  | -cli() ([в файле manage.py](https://github.com/albertalexandrov/fastapi-django-example/blob/main/src/manage.py#L10)) | 
|  | 76 | + | 
| 54 | 77 | 
 | 
| 55 |  | -Поэтому сторонние библиотеки (не проект) не смогут просто оборачивать свои собственные команды - в проекте придется | 
| 56 |  | -импортировать команды сторонних библиотек и регистрировать. | 
|  | 78 | +Можно видеть, что отобразились как дефолтные команды, так и кастомная команд. | 
|  | 79 | + | 
|  | 80 | +Если в настройке MANAGEMENT определить name, то команды будут объединены в субкоманды, доступ к которым будет через | 
|  | 81 | +name: | 
|  | 82 | + | 
|  | 83 | +```python | 
|  | 84 | +# settings.py | 
|  | 85 | + | 
|  | 86 | +MANAGEMENT = [ | 
|  | 87 | +    { | 
|  | 88 | +        "typer": "management.cli:typer", | 
|  | 89 | +        "name": "custom-commands", | 
|  | 90 | +    } | 
|  | 91 | +] | 
|  | 92 | +``` | 
| 57 | 93 | 
 | 
| 58 |  | -**Возможно у кого нибудь возникнут идеи как реализовать автоматическую регистрацию команд. Автодисковеринг как в Celery  | 
| 59 |  | -или типа того. Пишите.** | 
|  | 94 | + | 
0 commit comments