From f38da15bdb17454fab6c67230cbd5cd6f1f6fe99 Mon Sep 17 00:00:00 2001 From: kolo Date: Tue, 21 Oct 2025 22:56:29 +0300 Subject: [PATCH] docs and fix --- ...ple_sample.py => autocompleter_snippet.py} | 0 ...ple.py => dependency_injection_snippet.py} | 0 ...e2.py => dependency_injection_snippet2.py} | 0 ...e3.py => dependency_injection_snippet3.py} | 0 ...e4.py => dependency_injection_snippet4.py} | 0 ...le_sample.py => dividing_lines_snippet.py} | 0 ...le_sample.py => error_handling_snippet.py} | 0 ..._sample2.py => error_handling_snippet2.py} | 0 ..._sample3.py => error_handling_snippet3.py} | 0 ..._sample4.py => error_handling_snippet4.py} | 0 ..._sample5.py => error_handling_snippet5.py} | 0 ..._sample6.py => error_handling_snippet6.py} | 0 docs/code_snippets/orchestrator_snippet.py | 26 ++++++ docs/root/api/app/autocompleter.rst | 2 +- docs/root/api/app/dividing_lines.rst | 2 +- docs/root/api/orchestrator/argparser.rst | 91 ++++++++++++++++++- docs/root/api/orchestrator/index.rst | 64 ++++++++++++- docs/root/api/router.rst | 14 +-- docs/root/dependency_injection.rst | 8 +- docs/root/error_handling.rst | 12 +-- mock/mock_app/main.py | 8 +- mock/mock_app/routers.py | 17 ++-- src/argenta/di/providers.py | 2 +- src/argenta/orchestrator/argparser/entity.py | 12 ++- src/argenta/orchestrator/entity.py | 2 + 25 files changed, 215 insertions(+), 45 deletions(-) rename docs/code_snippets/{autocompleter_example_sample.py => autocompleter_snippet.py} (100%) rename docs/code_snippets/{dependency_injection_example_sample.py => dependency_injection_snippet.py} (100%) rename docs/code_snippets/{dependency_injection_example_sample2.py => dependency_injection_snippet2.py} (100%) rename docs/code_snippets/{dependency_injection_example_sample3.py => dependency_injection_snippet3.py} (100%) rename docs/code_snippets/{dependency_injection_example_sample4.py => dependency_injection_snippet4.py} (100%) rename docs/code_snippets/{dividing_lines_example_sample.py => dividing_lines_snippet.py} (100%) rename docs/code_snippets/{error_handling_example_sample.py => error_handling_snippet.py} (100%) rename docs/code_snippets/{error_handling_example_sample2.py => error_handling_snippet2.py} (100%) rename docs/code_snippets/{error_handling_example_sample3.py => error_handling_snippet3.py} (100%) rename docs/code_snippets/{error_handling_example_sample4.py => error_handling_snippet4.py} (100%) rename docs/code_snippets/{error_handling_example_sample5.py => error_handling_snippet5.py} (100%) rename docs/code_snippets/{error_handling_example_sample6.py => error_handling_snippet6.py} (100%) create mode 100644 docs/code_snippets/orchestrator_snippet.py diff --git a/docs/code_snippets/autocompleter_example_sample.py b/docs/code_snippets/autocompleter_snippet.py similarity index 100% rename from docs/code_snippets/autocompleter_example_sample.py rename to docs/code_snippets/autocompleter_snippet.py diff --git a/docs/code_snippets/dependency_injection_example_sample.py b/docs/code_snippets/dependency_injection_snippet.py similarity index 100% rename from docs/code_snippets/dependency_injection_example_sample.py rename to docs/code_snippets/dependency_injection_snippet.py diff --git a/docs/code_snippets/dependency_injection_example_sample2.py b/docs/code_snippets/dependency_injection_snippet2.py similarity index 100% rename from docs/code_snippets/dependency_injection_example_sample2.py rename to docs/code_snippets/dependency_injection_snippet2.py diff --git a/docs/code_snippets/dependency_injection_example_sample3.py b/docs/code_snippets/dependency_injection_snippet3.py similarity index 100% rename from docs/code_snippets/dependency_injection_example_sample3.py rename to docs/code_snippets/dependency_injection_snippet3.py diff --git a/docs/code_snippets/dependency_injection_example_sample4.py b/docs/code_snippets/dependency_injection_snippet4.py similarity index 100% rename from docs/code_snippets/dependency_injection_example_sample4.py rename to docs/code_snippets/dependency_injection_snippet4.py diff --git a/docs/code_snippets/dividing_lines_example_sample.py b/docs/code_snippets/dividing_lines_snippet.py similarity index 100% rename from docs/code_snippets/dividing_lines_example_sample.py rename to docs/code_snippets/dividing_lines_snippet.py diff --git a/docs/code_snippets/error_handling_example_sample.py b/docs/code_snippets/error_handling_snippet.py similarity index 100% rename from docs/code_snippets/error_handling_example_sample.py rename to docs/code_snippets/error_handling_snippet.py diff --git a/docs/code_snippets/error_handling_example_sample2.py b/docs/code_snippets/error_handling_snippet2.py similarity index 100% rename from docs/code_snippets/error_handling_example_sample2.py rename to docs/code_snippets/error_handling_snippet2.py diff --git a/docs/code_snippets/error_handling_example_sample3.py b/docs/code_snippets/error_handling_snippet3.py similarity index 100% rename from docs/code_snippets/error_handling_example_sample3.py rename to docs/code_snippets/error_handling_snippet3.py diff --git a/docs/code_snippets/error_handling_example_sample4.py b/docs/code_snippets/error_handling_snippet4.py similarity index 100% rename from docs/code_snippets/error_handling_example_sample4.py rename to docs/code_snippets/error_handling_snippet4.py diff --git a/docs/code_snippets/error_handling_example_sample5.py b/docs/code_snippets/error_handling_snippet5.py similarity index 100% rename from docs/code_snippets/error_handling_example_sample5.py rename to docs/code_snippets/error_handling_snippet5.py diff --git a/docs/code_snippets/error_handling_example_sample6.py b/docs/code_snippets/error_handling_snippet6.py similarity index 100% rename from docs/code_snippets/error_handling_example_sample6.py rename to docs/code_snippets/error_handling_snippet6.py diff --git a/docs/code_snippets/orchestrator_snippet.py b/docs/code_snippets/orchestrator_snippet.py new file mode 100644 index 0000000..13f9de3 --- /dev/null +++ b/docs/code_snippets/orchestrator_snippet.py @@ -0,0 +1,26 @@ +import sqlite3 +from sqlite3 import Connection +from typing import Iterable + +from dishka import Provider, Scope, provide + +from argenta import App, Orchestrator + + +class ConnectionProvider(Provider): + @provide(scope=Scope.REQUEST) + def new_connection(self) -> Iterable[Connection]: + conn = sqlite3.connect(":memory:") + yield conn + conn.close() + +# 2. Создаем и настраиваем App +app = App() +# ... здесь можно добавить роутеры ... + +# 3. Создаем Orchestrator, передавая наш провайдер +orchestrator = Orchestrator(custom_providers=[ConnectionProvider()]) + +# 4. Запускаем приложение +if __name__ == "__main__": + orchestrator.start_polling(app) \ No newline at end of file diff --git a/docs/root/api/app/autocompleter.rst b/docs/root/api/app/autocompleter.rst index 3ee1e0b..caf30b6 100644 --- a/docs/root/api/app/autocompleter.rst +++ b/docs/root/api/app/autocompleter.rst @@ -46,6 +46,6 @@ AutoCompleter ``AutoCompleter`` передается как аргумент при инициализации `App`. -.. literalinclude:: ../../../code_snippets/autocompleter_example_sample.py +.. literalinclude:: ../../../code_snippets/autocompleter_snippet.py :language: python :linenos: diff --git a/docs/root/api/app/dividing_lines.rst b/docs/root/api/app/dividing_lines.rst index e5f6110..aef77d1 100644 --- a/docs/root/api/app/dividing_lines.rst +++ b/docs/root/api/app/dividing_lines.rst @@ -70,6 +70,6 @@ Dividing Lines Пример конфигурации -------------------- -.. literalinclude:: ../../../code_snippets/dividing_lines_example_sample.py +.. literalinclude:: ../../../code_snippets/dividing_lines_snippet.py :language: python :linenos: diff --git a/docs/root/api/orchestrator/argparser.rst b/docs/root/api/orchestrator/argparser.rst index 6786488..53bb514 100644 --- a/docs/root/api/orchestrator/argparser.rst +++ b/docs/root/api/orchestrator/argparser.rst @@ -1,6 +1,93 @@ .. _root_api_orchestrator_argparser: Argparser -**************** +========== + +Объект ``ArgParser`` в ``Argenta`` предназначен для разбора и обработки **аргументов командной строки**, которые передаются вашему приложению при его запуске. Важно не путать их с командами, которые пользователь вводит в интерактивном режиме работы приложения. `ArgParser` позволяет вашему приложению получать внешнюю конфигурацию в момент старта, например, путь к файлу настроек, флаги для отладки или режим запуска. + +----- + +Инициализация +------------- + +.. code-block:: python + + def __init__(self, processed_args: list[argenta.orchestrator.InputArgument] = []) -> None + +Создает экземпляр парсера аргументов командной строки. + +* ``processed_args``: Список аргументов, которые будут обрабатываться и парситься при запуске приложения. + +Основные методы +--------------- + +.. py:method:: parse(self) -> dict[str, str | list[str]] + + Основной метод, который выполняет разбор списка `processed_args`. Он анализирует аргументы и преобразует их в структурированный словарь. + + * Аргументы, имеющие вид флага (например, `--verbose`), получают значение `True`. + * Аргументы, за которыми следует значение (например, `--config settings.yaml`), сохраняются как пара "ключ-значение". + * Если один и тот же аргумент встречается несколько раз, его значения могут быть собраны в список. + + :returns: Словарь, где ключи — это имена аргументов, а значения — их соответствующие значения. + +.. py:method:: get(self, key: str, default: str | None = None) -> str | None + + Удобный метод для получения значения конкретного аргумента по его имени (ключу). Если аргумент не был найден, возвращается значение `default`. + + :param key: Имя аргумента (например, `"--config"`). + :param default: Значение, которое будет возвращено, если аргумент `key` отсутствует. По умолчанию `None`. + :returns: Значение аргумента или значение по умолчанию. + +.. py:method:: all_args(self) -> list[str] + + Возвращает список всех имен (ключей) аргументов, которые были распознаны парсером после вызова метода `parse()`. + +Назначение и интеграция +------------------------ + +`ArgParser` является неотъемлемой частью `Orchestrator`. При создании `Orchestrator` ему передается экземпляр `ArgParser`, который обычно инициализируется с `sys.argv[1:]`. + +После этого `Orchestrator` помещает `ArgParser` в DI-контейнер. Это означает, что любой ваш сервис или обработчик команды может запросить `ArgParser` через внедрение зависимостей и получить доступ к стартовым аргументам приложения. Это предпочтительный способ для конфигурации компонентов на основе параметров запуска. + +Пример использования +-------------------- + +.. code-block:: python + + import sys + from argenta.orchestrator import Orchestrator + from argenta.orchestrator.argparser import ArgParser + from argenta.app import App + from dishka import Provider, Scope, provide + + # 1. Создаем парсер на основе реальных аргументов командной строки + # Например, если запустить: python main.py --config prod.json --debug + arg_parser = ArgParser(processed_args=sys.argv[1:]) + + # 2. Определяем сервис, который будет использовать эти аргументы + class Settings: + def __init__(self, config_path: str, is_debug: bool): + self.config_path = config_path + self.is_debug = is_debug + + class SettingsProvider(Provider): + @provide(scope=Scope.APP) + def get_settings(self, parser: ArgParser) -> Settings: + # Запрашиваем ArgParser из DI и используем его для конфигурации + path = parser.get('--config', default='default.json') + debug_mode = bool(parser.get('--debug')) + return Settings(config_path=path, is_debug=debug_mode) + + # 3. Создаем Orchestrator, передавая ему парсер и провайдер + app = App() + orchestrator = Orchestrator( + arg_parser=arg_parser, + custom_providers=[SettingsProvider()] + ) + + # 4. Запускаем приложение + if __name__ == "__main__": + orchestrator.start_polling(app) + -nu diff --git a/docs/root/api/orchestrator/index.rst b/docs/root/api/orchestrator/index.rst index 6a94e9f..c95e028 100644 --- a/docs/root/api/orchestrator/index.rst +++ b/docs/root/api/orchestrator/index.rst @@ -1,7 +1,69 @@ .. _root_api_orchestrator_index: Orchestrator -**************** +==================== + +Объект ``Orchestrator`` в ``Argenta`` представляет собой высокоуровневый компонент, который стоит над ``App`` и отвечает за "оркестрацию" всего приложения. Его главная задача — инициализация и конфигурация сложных систем, таких как внедрение зависимостей (``di``), парсинг аргументов командной строки при запуске, и запуск основного цикла приложения. + +В то время как ``App`` отвечает за интерактивную сессию (ввод команд, роутинг), ``Orchestrator`` подготавливает окружение, в котором ``App`` будет работать. Он является точкой входа для приложений. + +----- + +Инициализация +------------- + +.. code-block:: rust + :linenos: + + DEFAULT_ARGPARSER: ArgParser = ArgParser(processed_args=[]) + + +.. code-block:: python + :linenos: + + def __init__(self, arg_parser: ArgParser = DEFAULT_ARGPARSER, + custom_providers: list[Provider] = [], + auto_inject_handlers: bool = True) -> None + +Создает и конфигурирует экземпляр ``Orchestrator``. + +* ``arg_parser``: Экземпляр :class:`argenta.orchestrator.argparser.ArgParser`, который отвечает за парсинг аргументов, переданных скрипту при запуске из командной строки (не путать с командами, вводимыми в интерактивном режиме). +* ``custom_providers``: Список пользовательских провайдеров ``dishka.Provider``. Это основной механизм для добавления ваших собственных сервисов (например, подключений к базе данных, клиентов API) в контейнер внедрения зависимостей. +* ``auto_inject_handlers``: Если **True** (по умолчанию), ``dishka`` будет автоматически инспектировать сигнатуры обработчиков команд и внедрять в них требуемые зависимости из контейнера. + +----- + +Основные методы +-------------- + +.. py:method:: start_polling(self, app: App) -> None + + Это главный метод, который запускает все приложение. Он выполняет следующие шаги: + + 1. **Настройка DI**: На основе системного провайдера (``SystemProvider``, который предоставляет ``ArgParser``) и списка ``custom_providers`` создается ``ioc`` - контейнер и настраивается внедрение зависимостей. + + 3. **Запуск основного цикла**: Запускает бесконечный цикл ожидания и обработки пользовательского ввода. + + :param app: Экземпляр класса :class:`~argenta.app.models.App`, который будет запущен. + +----- + +Назначение и использование +-------------------------- + +``Orchestrator`` абстрагирует от вас всю сложность, связанную с настройкой внедрения зависимостей и парсингом стартовых аргументов. Типичный сценарий использования ``Argenta`` выглядит следующим образом: + +1. Создать экземпляр ``App`` и настроить его (добавить роутеры). +2. Создать экземпляр ``Orchestrator``, передав в него необходимые DI-провайдеры и, возможно, парсер аргументов. +3. Вызвать ``orchestrator.start_polling(app)``, чтобы запустить приложение. + +Такой подход позволяет сохранить код чистым и разделяет ответственность: ``App`` отвечает за логику интерактивной сессии, а ``Orchestrator`` — за подготовку и запуск окружения. + +Пример использования +-------------------- + +.. literalinclude:: ../../../code_snippets/orchestrator_snippet.py + :language: python .. toctree:: :hidden: diff --git a/docs/root/api/router.rst b/docs/root/api/router.rst index 60cd500..366cfc7 100644 --- a/docs/root/api/router.rst +++ b/docs/root/api/router.rst @@ -13,6 +13,7 @@ Router ------------- .. code-block:: python + :linenos: __init__(self, title: str | None = None, disable_redirect_stdout: bool = False) -> None @@ -38,6 +39,7 @@ Router **Пример использования:** .. literalinclude:: ../../code_snippets/router_snippet.py + :linenos: :language: python ----- @@ -62,7 +64,7 @@ Router .. py:exception:: TriggerContainSpacesException - Выбрасывается, если триггер команды, передаваемый в `Command`, содержит пробелы. Триггеры команд должны быть одним словом. + Выбрасывается, если триггер команды, передаваемый в ``Command``, содержит пробелы. Триггеры команд должны быть одним словом. **Неправильно:** ``Command("add user")`` **Правильно:** ``Command("add-user")`` @@ -74,16 +76,14 @@ Router **Пример, вызывающий исключение:** .. code-block:: python + :linenos: Command("send", flags=[ - Flag("message", short_name="m"), - Flag("recipient", short_name="m") # Ошибка: short_name 'm' повторяется + Flag("recipient"), + Flag("recipient") ]) .. py:exception:: RequiredArgumentNotPassedException - Это исключение выбрасывается на этапе выполнения, а не регистрации. Оно возникает, если обработчик команды ожидает обязательный аргумент, который не был предоставлен при вызове. - - .. note:: - Это исключение, как правило, должно перехватываться и обрабатываться внутри `Orchestrator` для вывода пользователю сообщения об ошибке, а не приводить к падению всего приложения. + Это исключение возникает, если какой-либо обработчик команды не ожидает обязательный аргумент, которым является объект ответа(``Response``). diff --git a/docs/root/dependency_injection.rst b/docs/root/dependency_injection.rst index e3e3d44..c9c8e88 100644 --- a/docs/root/dependency_injection.rst +++ b/docs/root/dependency_injection.rst @@ -18,19 +18,19 @@ .. note:: ``argenta.di.FromDishka`` это алиас к ``dishka.FromDishka``, они полностью взаимозаменяемы. -.. literalinclude:: ../code_snippets/dependency_injection_example_sample.py +.. literalinclude:: ../code_snippets/dependency_injection_snippet.py :language: python :linenos: ``Argenta`` -> ``dishka`` зарезолвит тайпхинты и внедрит зависимость с возвращаемым типом ``Connection``, прежде чем использовать зависимость её нужно создать, для этого нужно создать соответствующий провайдер. -.. literalinclude:: ../code_snippets/dependency_injection_example_sample2.py +.. literalinclude:: ../code_snippets/dependency_injection_snippet2.py :language: python :linenos: После создания провайдера, его нужно зарегистрировать в оркестраторе. -.. literalinclude:: ../code_snippets/dependency_injection_example_sample3.py +.. literalinclude:: ../code_snippets/dependency_injection_snippet3.py :language: python :linenos: @@ -49,7 +49,7 @@ Краткий сэмпл кода, который получает объект ``ArgSpace`` и выводит в консоль аргумент с именем "type": -.. literalinclude:: ../code_snippets/dependency_injection_example_sample4.py +.. literalinclude:: ../code_snippets/dependency_injection_snippet4.py :language: python :linenos: diff --git a/docs/root/error_handling.rst b/docs/root/error_handling.rst index aa333d8..28bcac4 100644 --- a/docs/root/error_handling.rst +++ b/docs/root/error_handling.rst @@ -17,7 +17,7 @@ Краткий сэмпл кода, переопределяющего хэндлер ввода пустой команды -.. literalinclude:: ../code_snippets/error_handling_example_sample.py +.. literalinclude:: ../code_snippets/error_handling_snippet.py :language: python :linenos: @@ -46,7 +46,7 @@ Сэмпл кода, переопределяющего хэндлер ввода команды с некорректным синтаксисом: -.. literalinclude:: ../code_snippets/error_handling_example_sample2.py +.. literalinclude:: ../code_snippets/error_handling_snippet2.py :language: python :linenos: @@ -73,7 +73,7 @@ Сэмпл кода, переопределяющего хэндлер ввода команды с повторяющимися флагами: -.. literalinclude:: ../code_snippets/error_handling_example_sample3.py +.. literalinclude:: ../code_snippets/error_handling_snippet3.py :language: python :linenos: @@ -96,7 +96,7 @@ Сэмпл кода, переопределяющего хэндлер ввода пустой команды: -.. literalinclude:: ../code_snippets/error_handling_example_sample4.py +.. literalinclude:: ../code_snippets/error_handling_snippet4.py :language: python :linenos: @@ -120,7 +120,7 @@ Сэмпл кода, переопределяющего хэндлер ввода неизвестной команды: -.. literalinclude:: ../code_snippets/error_handling_example_sample5.py +.. literalinclude:: ../code_snippets/error_handling_snippet5.py :language: python :linenos: @@ -143,6 +143,6 @@ Сэмпл кода, переопределяющего хэндлер ввода команды выхода: -.. literalinclude:: ../code_snippets/error_handling_example_sample6.py +.. literalinclude:: ../code_snippets/error_handling_snippet6.py :language: python :linenos: diff --git a/mock/mock_app/main.py b/mock/mock_app/main.py index ba7ddd3..6e5aafe 100644 --- a/mock/mock_app/main.py +++ b/mock/mock_app/main.py @@ -4,14 +4,8 @@ from argenta import App, Orchestrator from argenta.app import PredefinedMessages, DynamicDividingLine, AutoCompleter from argenta.orchestrator import ArgParser from argenta.orchestrator.argparser import BooleanArgument, ValueArgument -from dishka import Provider, provide, Scope # type: ignore -class temProvider(Provider): - @provide(scope=Scope.APP) - def get_apace(self) -> int: - return 1234 - arg_parser: ArgParser = ArgParser( processed_args=[ BooleanArgument(name="repeat", is_deprecated=True), @@ -22,7 +16,7 @@ app: App = App( dividing_line=DynamicDividingLine(), autocompleter=AutoCompleter(), ) -orchestrator: Orchestrator = Orchestrator(arg_parser, custom_providers=[temProvider()]) +orchestrator: Orchestrator = Orchestrator(arg_parser) def main(): diff --git a/mock/mock_app/routers.py b/mock/mock_app/routers.py index 2295b3b..dc2a1c3 100644 --- a/mock/mock_app/routers.py +++ b/mock/mock_app/routers.py @@ -1,7 +1,9 @@ -from argenta.command import Command, PredefinedFlags, Flags, Flag, PossibleValues +from argenta.command import Flag, PossibleValues +from argenta.orchestrator.argparser import ArgSpace from argenta.response import Response from argenta import Router from argenta.router.defaults import system_router +from dishka import FromDishka work_router: Router = Router(title="Work points:", disable_redirect_stdout=True) @@ -9,16 +11,9 @@ work_router: Router = Router(title="Work points:", disable_redirect_stdout=True) flag = Flag("csdv", possible_values=PossibleValues.NEITHER) -@work_router.command( - Command( - "get", - description="Get Help", - aliases=["help", "Get_help"], - flags=Flags([PredefinedFlags.PORT, PredefinedFlags.HOST]), - ) -) -def command_help(response: Response): - response.update_data({"data": [_ for _ in range(9999999)]}) +@work_router.command("get") +def command_help(response: Response, argspace: FromDishka[ArgSpace]): + print(argspace.all_arguments) @system_router.command("run") diff --git a/src/argenta/di/providers.py b/src/argenta/di/providers.py index baad0c4..8cd4d47 100644 --- a/src/argenta/di/providers.py +++ b/src/argenta/di/providers.py @@ -15,4 +15,4 @@ class SystemProvider(Provider): @provide(scope=Scope.APP) def get_argspace(self) -> ArgSpace: - return self._arg_parser.parse_args() + return self._arg_parser.parsed_argspace diff --git a/src/argenta/orchestrator/argparser/entity.py b/src/argenta/orchestrator/argparser/entity.py index 2d4fb9c..28ef573 100644 --- a/src/argenta/orchestrator/argparser/entity.py +++ b/src/argenta/orchestrator/argparser/entity.py @@ -57,9 +57,17 @@ class ArgParser: self.description: str = description self.epilog: str = epilog self.processed_args: list[ValueArgument | BooleanArgument] = processed_args + + self.parsed_argspace: ArgSpace = ArgSpace([]) self._core: ArgumentParser = ArgumentParser(prog=name, description=description, epilog=epilog) + self._register_args(processed_args) + def _parse_args(self) -> None: + self.parsed_argspace = ArgSpace.from_namespace(namespace=self._core.parse_args(), + processed_args=self.processed_args) + + def _register_args(self, processed_args: list[ValueArgument | BooleanArgument]) -> None: for arg in processed_args: if isinstance(arg, BooleanArgument): _ = self._core.add_argument(arg.string_entity, @@ -74,7 +82,3 @@ class ArgParser: choices=arg.possible_values, required=arg.is_required, deprecated=arg.is_deprecated) - - def parse_args(self) -> ArgSpace: - return ArgSpace.from_namespace(namespace=self._core.parse_args(), - processed_args=self.processed_args) diff --git a/src/argenta/orchestrator/entity.py b/src/argenta/orchestrator/entity.py index 7745ad9..1d2b3db 100644 --- a/src/argenta/orchestrator/entity.py +++ b/src/argenta/orchestrator/entity.py @@ -22,6 +22,8 @@ class Orchestrator: self._arg_parser: ArgParser = arg_parser self._custom_providers: list[Provider] = custom_providers self._auto_inject_handlers: bool = auto_inject_handlers + + self._arg_parser._parse_args() def start_polling(self, app: App) -> None: """