From b732036e875717fd646d87fd551fb0874648a9e7 Mon Sep 17 00:00:00 2001 From: kolo Date: Sun, 8 Feb 2026 19:23:15 +0300 Subject: [PATCH] cli module creating --- mock/local_test.py | 8 +--- src/argenta/_cli/__main__.py | 11 ++++- src/argenta/_cli/commands/__init__.py | 1 + src/argenta/_cli/commands/run.py | 62 +++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 src/argenta/_cli/commands/__init__.py create mode 100644 src/argenta/_cli/commands/run.py diff --git a/mock/local_test.py b/mock/local_test.py index f87e021..47afefa 100644 --- a/mock/local_test.py +++ b/mock/local_test.py @@ -1,5 +1,4 @@ -from argenta import App, Command, Response, Router - +from argenta import App, Command, Response, Router, Orchestrator app = App(override_system_messages=True) router = Router() @@ -12,7 +11,4 @@ def handler(_res: Response) -> None: def handler2(_res: Response) -> None: pass -app.include_routers(router) -app._pre_cycle_setup() - -assert app._most_similar_command('command_') == 'command' \ No newline at end of file +orch = Orchestrator() \ No newline at end of file diff --git a/src/argenta/_cli/__main__.py b/src/argenta/_cli/__main__.py index 39ae4d9..0414abb 100644 --- a/src/argenta/_cli/__main__.py +++ b/src/argenta/_cli/__main__.py @@ -1,6 +1,13 @@ +from typer import Typer + +from .commands import run_handler + + def main(): - print(f'run from {__name__}') - print('hello world') + app = Typer() + app.command("run")(run_handler) + app.command("init")(run_handler) + app() if __name__ == '__main__': main() \ No newline at end of file diff --git a/src/argenta/_cli/commands/__init__.py b/src/argenta/_cli/commands/__init__.py new file mode 100644 index 0000000..e6c21d7 --- /dev/null +++ b/src/argenta/_cli/commands/__init__.py @@ -0,0 +1 @@ +from .run import run_handler \ No newline at end of file diff --git a/src/argenta/_cli/commands/run.py b/src/argenta/_cli/commands/run.py new file mode 100644 index 0000000..e147da6 --- /dev/null +++ b/src/argenta/_cli/commands/run.py @@ -0,0 +1,62 @@ +__all__ = ["run_handler"] + +import importlib +from typing import Any + +from argenta import App, Orchestrator + + +class ImportFromStringError(Exception): + pass + + +def import_from_string(import_str: str) -> Any: + module_str, _, attrs_str = import_str.partition(":") + if not module_str or not attrs_str: + raise ImportFromStringError( + f'Import string "{import_str}" must be in format ":".' + ) + + try: + module = importlib.import_module(module_str) + except ModuleNotFoundError as exc: + if exc.name != module_str: + raise exc from None + raise ImportFromStringError(f'Could not import module "{module_str}".') + + instance = module + try: + for attr_str in attrs_str.split("."): + instance = getattr(instance, attr_str) + except AttributeError: + raise ImportFromStringError(f'Attribute "{attrs_str}" not found in module "{module_str}".') + + return instance + + +def run_handler(orchestrator_str: str, app_str: str | None = None) -> Any: + orchestrator = import_from_string(orchestrator_str) + + if not isinstance(orchestrator, Orchestrator): + raise TypeError(f"Not an Orchestrator: {type(orchestrator).__name__}") + + if app_str is not None: + app = import_from_string(app_str) + else: + module_str = orchestrator_str.partition(":")[0] + module = importlib.import_module(module_str) + + app = None + for attr_name in dir(module): + attr = getattr(module, attr_name) + if isinstance(attr, App): + app = attr + break + + if app is None: + raise ValueError(f'No App instance found in module "{module_str}"') + + if not isinstance(app, App): + raise TypeError(f"Not an App: {type(app).__name__}") + + return orchestrator.start_polling(app)