diff --git a/docs/code_snippets/command/snippet2.py b/docs/code_snippets/command/snippet2.py index e2aa83d..d85d824 100644 --- a/docs/code_snippets/command/snippet2.py +++ b/docs/code_snippets/command/snippet2.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router router = Router(title="User Management") diff --git a/docs/code_snippets/command/snippet3.py b/docs/code_snippets/command/snippet3.py index 9be0b73..d75c6b5 100644 --- a/docs/code_snippets/command/snippet3.py +++ b/docs/code_snippets/command/snippet3.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags router = Router(title="Server Management") diff --git a/docs/code_snippets/flag/predefined_flags.py b/docs/code_snippets/flag/predefined_flags.py index 6602a33..fd7d352 100644 --- a/docs/code_snippets/flag/predefined_flags.py +++ b/docs/code_snippets/flag/predefined_flags.py @@ -1,5 +1,5 @@ -from argenta.command.flag.defaults import PredefinedFlags from argenta.command import Flags +from argenta.command.flag.defaults import PredefinedFlags # Использование предопределенных флагов при создании команды command_flags = Flags([ diff --git a/docs/code_snippets/flag/snippet.py b/docs/code_snippets/flag/snippet.py index 794cd63..cb3441c 100644 --- a/docs/code_snippets/flag/snippet.py +++ b/docs/code_snippets/flag/snippet.py @@ -1,6 +1,7 @@ -from argenta.command import Flag, PossibleValues import re +from argenta.command import Flag, PossibleValues + # Простой флаг с любыми значениями verbose_flag = Flag(name="verbose") diff --git a/docs/code_snippets/flag/snippet2.py b/docs/code_snippets/flag/snippet2.py index 4a08657..b36e87c 100644 --- a/docs/code_snippets/flag/snippet2.py +++ b/docs/code_snippets/flag/snippet2.py @@ -1,6 +1,7 @@ -from argenta.command.flag.models import Flag, PossibleValues import re +from argenta.command.flag.models import Flag, PossibleValues + # Флаг со списком допустимых значений format_flag = Flag(name="format", possible_values=["json", "xml", "csv"]) diff --git a/docs/code_snippets/flags/snippet.py b/docs/code_snippets/flags/snippet.py index 527b583..516488b 100644 --- a/docs/code_snippets/flags/snippet.py +++ b/docs/code_snippets/flags/snippet.py @@ -1,7 +1,7 @@ -from argenta.command import Flags, Flag -from argenta import Command import re +from argenta import Command +from argenta.command import Flag, Flags # Создание коллекции с флагами flags = Flags([ diff --git a/docs/code_snippets/flags/snippet2.py b/docs/code_snippets/flags/snippet2.py index 0f00ba3..4043302 100644 --- a/docs/code_snippets/flags/snippet2.py +++ b/docs/code_snippets/flags/snippet2.py @@ -1,4 +1,4 @@ -from argenta.command import Flags, Flag +from argenta.command import Flag, Flags # Создание коллекции flags: Flags = Flags() diff --git a/docs/code_snippets/flags/snippet3.py b/docs/code_snippets/flags/snippet3.py index 5946a99..958ea0d 100644 --- a/docs/code_snippets/flags/snippet3.py +++ b/docs/code_snippets/flags/snippet3.py @@ -1,4 +1,4 @@ -from argenta.command import Flags, Flag +from argenta.command import Flag, Flags from argenta.command.flag.defaults import PredefinedFlags # Начальная коллекция diff --git a/docs/code_snippets/flags/snippet4.py b/docs/code_snippets/flags/snippet4.py index 85c7830..bbcd81a 100644 --- a/docs/code_snippets/flags/snippet4.py +++ b/docs/code_snippets/flags/snippet4.py @@ -1,4 +1,4 @@ -from argenta.command import Flags, Flag +from argenta.command import Flag, Flags from argenta.command.flag.defaults import PredefinedFlags flags = Flags([ diff --git a/docs/code_snippets/flags/snippet5.py b/docs/code_snippets/flags/snippet5.py index 9f4d428..421c2c3 100644 --- a/docs/code_snippets/flags/snippet5.py +++ b/docs/code_snippets/flags/snippet5.py @@ -1,4 +1,4 @@ -from argenta.command import Flags, Flag +from argenta.command import Flag, Flags from argenta.command.flag.defaults import PredefinedFlags flags = Flags([ diff --git a/docs/code_snippets/flags/snippet6.py b/docs/code_snippets/flags/snippet6.py index 6143e9f..11d5bb1 100644 --- a/docs/code_snippets/flags/snippet6.py +++ b/docs/code_snippets/flags/snippet6.py @@ -1,4 +1,4 @@ -from argenta.command import Flags, Flag +from argenta.command import Flag, Flags flags = Flags([ Flag("first"), diff --git a/docs/code_snippets/input_flags/snippet1.py b/docs/code_snippets/input_flags/snippet1.py index 4a79340..b21b65d 100644 --- a/docs/code_snippets/input_flags/snippet1.py +++ b/docs/code_snippets/input_flags/snippet1.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags router = Router(title="Example") diff --git a/docs/code_snippets/input_flags/snippet10.py b/docs/code_snippets/input_flags/snippet10.py index 0942644..56da416 100644 --- a/docs/code_snippets/input_flags/snippet10.py +++ b/docs/code_snippets/input_flags/snippet10.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags from argenta.command.flag import ValidationStatus @@ -35,7 +35,7 @@ def validate_handler(response: Response): print(f" ? {flag.string_entity}: {flag.input_value} (UNDEFINED)") # Выводим сводку - print(f"\nSummary:") + print("\nSummary:") print(f" Valid flags: {len(valid_flags)}") print(f" Invalid flags: {len(invalid_flags)}") print(f" Undefined flags: {len(undefined_flags)}") diff --git a/docs/code_snippets/input_flags/snippet2.py b/docs/code_snippets/input_flags/snippet2.py index d711943..ed7ba3b 100644 --- a/docs/code_snippets/input_flags/snippet2.py +++ b/docs/code_snippets/input_flags/snippet2.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags router = Router(title="Get Flag Example") diff --git a/docs/code_snippets/input_flags/snippet3.py b/docs/code_snippets/input_flags/snippet3.py index 5c69149..ade3d04 100644 --- a/docs/code_snippets/input_flags/snippet3.py +++ b/docs/code_snippets/input_flags/snippet3.py @@ -1,5 +1,5 @@ -from argenta import Router, Command, Response -from argenta.command.flag import InputFlag, ValidationStatus, InputFlags +from argenta import Command, Response, Router +from argenta.command.flag import InputFlag, InputFlags, ValidationStatus router = Router(title="Add Flag Example") diff --git a/docs/code_snippets/input_flags/snippet4.py b/docs/code_snippets/input_flags/snippet4.py index eaebbc6..8217b73 100644 --- a/docs/code_snippets/input_flags/snippet4.py +++ b/docs/code_snippets/input_flags/snippet4.py @@ -1,4 +1,4 @@ -from argenta.command.flag import InputFlag, ValidationStatus, InputFlags +from argenta.command.flag import InputFlag, InputFlags, ValidationStatus # Создаём коллекцию InputFlags flags = InputFlags() diff --git a/docs/code_snippets/input_flags/snippet5.py b/docs/code_snippets/input_flags/snippet5.py index 2572dec..3c8cbed 100644 --- a/docs/code_snippets/input_flags/snippet5.py +++ b/docs/code_snippets/input_flags/snippet5.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags router = Router(title="Iterate Example") diff --git a/docs/code_snippets/input_flags/snippet6.py b/docs/code_snippets/input_flags/snippet6.py index ddc93d8..d33f508 100644 --- a/docs/code_snippets/input_flags/snippet6.py +++ b/docs/code_snippets/input_flags/snippet6.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags router = Router(title="Index Access Example") diff --git a/docs/code_snippets/input_flags/snippet7.py b/docs/code_snippets/input_flags/snippet7.py index 5833513..908da25 100644 --- a/docs/code_snippets/input_flags/snippet7.py +++ b/docs/code_snippets/input_flags/snippet7.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags router = Router(title="Bool Check Example") diff --git a/docs/code_snippets/input_flags/snippet8.py b/docs/code_snippets/input_flags/snippet8.py index 79e6aa0..3798101 100644 --- a/docs/code_snippets/input_flags/snippet8.py +++ b/docs/code_snippets/input_flags/snippet8.py @@ -1,5 +1,5 @@ -from argenta.command.flag.flags.models import InputFlags from argenta.command.flag import InputFlag, ValidationStatus +from argenta.command.flag.flags.models import InputFlags # Создаём первую коллекцию flags1 = InputFlags([ diff --git a/docs/code_snippets/input_flags/snippet9.py b/docs/code_snippets/input_flags/snippet9.py index db74241..800d5e6 100644 --- a/docs/code_snippets/input_flags/snippet9.py +++ b/docs/code_snippets/input_flags/snippet9.py @@ -1,6 +1,6 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags -from argenta.command.flag import InputFlag, ValidationStatus +from argenta.command.flag import InputFlag router = Router(title="Contains Example") diff --git a/docs/code_snippets/possible_values/combined.py b/docs/code_snippets/possible_values/combined.py index c9b825a..2e599f5 100644 --- a/docs/code_snippets/possible_values/combined.py +++ b/docs/code_snippets/possible_values/combined.py @@ -1,6 +1,7 @@ -from argenta.command import Flag, PossibleValues import re +from argenta.command import Flag, PossibleValues + # Флаг без значения verbose_flag = Flag( name="verbose", diff --git a/docs/code_snippets/quickstart/task_manager/handlers.py b/docs/code_snippets/quickstart/task_manager/handlers.py new file mode 100644 index 0000000..ddf5f0c --- /dev/null +++ b/docs/code_snippets/quickstart/task_manager/handlers.py @@ -0,0 +1,52 @@ +from typing import cast + +from argenta import Command, Response, Router +from argenta.command import Flag, Flags +from argenta.command.flag.models import ValidationStatus +from argenta.di import FromDishka + +from .repository import Priority, Task, TaskRepository + +router = Router(title="Task Manager") + +@router.command( + Command( + "add-task", + description="Add a new task", + flags=Flags([ + Flag("description"), + Flag("priority", possible_values=["low", "medium", "high"]), + ]) + ) +) +def add_task(response: Response, repo: FromDishka[TaskRepository]): + description_flag = response.input_flags.get_flag_by_name("description") + + if not description_flag or not description_flag.input_value: + print("Error: --description flag is required.") + return + task_description = description_flag.input_value + + priority_flag = response.input_flags.get_flag_by_name("priority") + + if priority_flag and priority_flag.status == ValidationStatus.VALID: + priority_value = priority_flag.input_value + else: + priority_value = "medium" + + priority = cast(Priority, priority_value) + + task = Task(description=task_description, priority=priority) + repo.add_task(task) + print(f"Added task: '{task.description}' with priority '{task.priority}'") + +@router.command(Command("list-tasks", description="List all tasks")) +def list_tasks(response: Response, repo: FromDishka[TaskRepository]): + tasks = repo.get_all_tasks() + if not tasks: + print("No tasks found.") + return + + print("Tasks:") + for i, task in enumerate(tasks, 1): + print(f" {i}. {task.description} (Priority: {task.priority})") diff --git a/docs/code_snippets/quickstart/task_manager/main.py b/docs/code_snippets/quickstart/task_manager/main.py new file mode 100644 index 0000000..09e758a --- /dev/null +++ b/docs/code_snippets/quickstart/task_manager/main.py @@ -0,0 +1,18 @@ +from argenta import App, Orchestrator + +from .handlers import router +from .provider import TaskProvider + +# 1. Создаем экземпляр приложения +app = App( + initial_message="Task Manager", + prompt="Enter a command: ", +) + +# 2. Подключаем роутер с нашими командами +app.include_router(router) + +# 3. Создаем и запускаем оркестратор +if __name__ == "__main__": + orchestrator = Orchestrator(custom_providers=[TaskProvider()]) + orchestrator.start_polling(app) diff --git a/docs/code_snippets/quickstart/task_manager/provider.py b/docs/code_snippets/quickstart/task_manager/provider.py new file mode 100644 index 0000000..11680af --- /dev/null +++ b/docs/code_snippets/quickstart/task_manager/provider.py @@ -0,0 +1,9 @@ +from dishka import Provider, Scope, provide + +from .repository import TaskRepository + + +class TaskProvider(Provider): + @provide(scope=Scope.APP) + def get_repository(self) -> TaskRepository: + return TaskRepository() diff --git a/docs/code_snippets/quickstart/task_manager/repository.py b/docs/code_snippets/quickstart/task_manager/repository.py new file mode 100644 index 0000000..df4ed77 --- /dev/null +++ b/docs/code_snippets/quickstart/task_manager/repository.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Literal + +Priority = Literal["low", "medium", "high"] + +@dataclass +class Task: + description: str + priority: Priority = "medium" + +class TaskRepository: + def __init__(self): + self._tasks: list[Task] = [] + + def add_task(self, task: Task): + self._tasks.append(task) + + def get_all_tasks(self) -> list[Task]: + return self._tasks diff --git a/docs/code_snippets/response/snippet1.py b/docs/code_snippets/response/snippet1.py index 7030edd..2b30f28 100644 --- a/docs/code_snippets/response/snippet1.py +++ b/docs/code_snippets/response/snippet1.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.response import ResponseStatus router = Router(title="Example") diff --git a/docs/code_snippets/response/snippet2.py b/docs/code_snippets/response/snippet2.py index f59c815..757620e 100644 --- a/docs/code_snippets/response/snippet2.py +++ b/docs/code_snippets/response/snippet2.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router router = Router(title="Data Example") diff --git a/docs/code_snippets/response/snippet3.py b/docs/code_snippets/response/snippet3.py index c7a6d09..3c8a80b 100644 --- a/docs/code_snippets/response/snippet3.py +++ b/docs/code_snippets/response/snippet3.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router router = Router(title="Get Data Example") diff --git a/docs/code_snippets/response/snippet4.py b/docs/code_snippets/response/snippet4.py index 52a735f..8519b05 100644 --- a/docs/code_snippets/response/snippet4.py +++ b/docs/code_snippets/response/snippet4.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router router = Router(title="Clear Data Example") diff --git a/docs/code_snippets/response/snippet5.py b/docs/code_snippets/response/snippet5.py index db09bb8..c735680 100644 --- a/docs/code_snippets/response/snippet5.py +++ b/docs/code_snippets/response/snippet5.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router router = Router(title="Delete Data Example") diff --git a/docs/code_snippets/response/snippet6.py b/docs/code_snippets/response/snippet6.py index f09ab36..4981b63 100644 --- a/docs/code_snippets/response/snippet6.py +++ b/docs/code_snippets/response/snippet6.py @@ -1,4 +1,4 @@ -from argenta import Router, Command, Response +from argenta import Command, Response, Router from argenta.command import Flag, Flags from argenta.response import ResponseStatus diff --git a/docs/code_snippets/validation_status/comprehensive.py b/docs/code_snippets/validation_status/comprehensive.py index de1f36b..a494e43 100644 --- a/docs/code_snippets/validation_status/comprehensive.py +++ b/docs/code_snippets/validation_status/comprehensive.py @@ -1,6 +1,8 @@ -from argenta.command.flag import Flag, InputFlag, ValidationStatus, PossibleValues import re +from argenta.command.flag import (Flag, InputFlag, PossibleValues, + ValidationStatus) + # Создаём различные типы флагов verbose_flag = Flag("verbose", possible_values=PossibleValues.NEITHER) output_flag = Flag("output", possible_values=PossibleValues.ALL) diff --git a/docs/code_snippets/validation_status/invalid.py b/docs/code_snippets/validation_status/invalid.py index d2eb50e..a924c92 100644 --- a/docs/code_snippets/validation_status/invalid.py +++ b/docs/code_snippets/validation_status/invalid.py @@ -1,4 +1,5 @@ -from argenta.command.flag import Flag, InputFlag, ValidationStatus, PossibleValues +from argenta.command.flag import (Flag, InputFlag, PossibleValues, + ValidationStatus) # Создание флага без значения help_flag = Flag("help", possible_values=PossibleValues.NEITHER) diff --git a/docs/code_snippets/validation_status/processing.py b/docs/code_snippets/validation_status/processing.py index e71a85b..ff0e9a7 100644 --- a/docs/code_snippets/validation_status/processing.py +++ b/docs/code_snippets/validation_status/processing.py @@ -1,5 +1,6 @@ from argenta import InputFlag, ValidationStatus + def process_input_flag(input_flag: InputFlag) -> None: """Обрабатывает входной флаг в зависимости от его статуса валидации""" diff --git a/docs/root/quickstart.rst b/docs/root/quickstart.rst index cb31646..0a1681c 100644 --- a/docs/root/quickstart.rst +++ b/docs/root/quickstart.rst @@ -3,26 +3,49 @@ Быстрый старт ******************** -1. **Установка** ``Argenta`` +В этом руководстве мы создадим простое, но полнофункциональное CLI-приложение «Менеджер задач», которое продемонстрирует ключевые возможности Argenta. + +1. **Установка** .. code-block:: shell pip install argenta -2. **Создание обработчиков**. Чтобы зарегистрировать функцию как обработчик команды, используйте декоратор ``@router.command``. Обработчик всегда должен принимать первым аргументом объект ``Response`` (подробнее в :ref:`документации `). +2. **Определение моделей данных и репозитория** -.. literalinclude:: ../code_snippets/quickstart/routers.py +Сначала определим модели данных для задачи и репозиторий для их хранения. Это будет наша "бизнес-логика". + +.. literalinclude:: ../code_snippets/quickstart/task_manager/repository.py :language: python :linenos: -3. **Настройка и запуск**. Чтобы подключить обработчики, вызовите метод ``.include_router()`` у экземпляра приложения и передайте в него ваш роутер. Затем создайте оркестратор и вызовите его метод ``.start_polling()``, передав ему приложение. +3. **Создание провайдера для DI** -.. literalinclude:: ../code_snippets/quickstart/main.py +Чтобы Argenta могла внедрять `TaskRepository` в наши обработчики, мы создадим провайдер для `dishka`. + +.. literalinclude:: ../code_snippets/quickstart/task_manager/provider.py :language: python :linenos: -4. **Запуск**. Теперь приложение можно запустить как обычный Python-скрипт. +4. **Создание обработчиков команд** +Теперь создадим обработчики для команд `add-task` и `list-tasks`. Обратите внимание, как мы используем флаги и внедряем `TaskRepository`. -.. image:: https://github.com/koloideal/Argenta/blob/docs/create_docs/imgs/mock_app_preview6.png?raw=true - :alt: Quickstart Example +.. literalinclude:: ../code_snippets/quickstart/task_manager/handlers.py + :language: python + :linenos: + +5. **Сборка и запуск приложения** + +Наконец, соберем все вместе: создадим экземпляр `App`, подключим роутер и провайдер, а затем запустим приложение. + +.. literalinclude:: ../code_snippets/quickstart/task_manager/main.py + :language: python + :linenos: + +6. **Результат** + +Теперь вы можете запустить `main.py` и взаимодействовать с вашим новым CLI-приложением. + +.. image:: https://github.com/koloideal/Argenta/blob/main/imgs/mock_app_preview4.png?raw=True + :alt: Task Manager Example