ascender-framework 2.0.2__tar.gz → 2.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/PKG-INFO +1 -1
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/generator_app.py +4 -4
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/run/run_app.py +5 -1
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/__init__.py +5 -1
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/_transport.py +1 -1
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/client.py +81 -20
- ascender_framework-2.0.4/ascender/common/http/types/file.py +15 -0
- ascender_framework-2.0.4/ascender/common/http/types/formdata.py +87 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/interceptors.py +2 -2
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/runtime.py +4 -5
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/stub.json +1 -1
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/engine.py +0 -3
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/overrider.py +3 -3
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/logger/_logger.py +25 -21
- ascender_framework-2.0.4/ascender/core/logger/formatter.py +56 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/guard.py +0 -1
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/paramguard.py +5 -8
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/ascender.json.asctpl +2 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/pyproject.toml +1 -1
- ascender_framework-2.0.2/ascender/core/logger/formatter.py +0 -36
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/LICENSE +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/README.md +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/abc/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/abc/middleware.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/build_app.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/build_message_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/build_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/create_generator_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/edit_generator_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/new/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/new/new_app.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/new/new_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/run/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/serve/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/serve/serve_app.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/serve/serve_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/tests/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/tests/tests_app.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/tests/tests_cli_service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/version/version_app.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/base_http_middleware.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/cors_middleware.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/relational_middleware.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api_docs.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/base/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/base/dto.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/base/response.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/awaitables/awaitable.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/provider.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/http_options.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/injectable.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/client_proxy.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/context.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/event_bus.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/event_transport.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/rpc_transport.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/transporter.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/callback_manager.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/exceptions/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/exceptions/rpc_exception.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/bus.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/client_factory.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/client_proxy.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/client.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/context.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/event.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/metadata.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/rpc.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/transporter.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/client.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/context.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/event.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/rpc.old.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/rpc.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/transporter.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/client.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/context.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/event.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/rpc.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/transporter.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/transport.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/patterns/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/patterns/event_pattern.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/patterns/message_pattern.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/provider.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/transport_manager.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/consumer_metadata.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/ctx.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/options.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/transport.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/consumers.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/data_parser.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/defer_mapping.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/redis_tools.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/serializer.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/contrib/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/contrib/middlewares.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/build.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/dockerfile_generator.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/file_builder.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/minifier.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/obfuscator.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/asc_config.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/environment.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/main.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/static_files.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/_create_internal.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/application.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/configure_imports.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/create_application.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/root_injector.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/application.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/async_module.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/injectable.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/loaders/base_loader.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/loaders/generic_loader.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/main.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/models.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/processor.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/provider.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/decorators/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/decorators/command.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/decorators/handler.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/boolean.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/const.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/parameter.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/protos/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/protos/basic_cli.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/protos/generic_cli.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/provider.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/command_metadata.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/handler_metadata.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/parameter.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/parameter_kind.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/undefined.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/argparser.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/metadata_from_class.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/signature_from_callable.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/valiidator.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/constructor.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/dbcontext.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/engine.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/entity.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/errors/wrong_orm.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/orms/sqlalchemy.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/orms/tortoise.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/provider.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/orm_enum.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/sqlalchemy_configuration.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/tortoise_configuration.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/abc/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/abc/base_injector.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/forward_ref.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/inject.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/injectfn.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/injector.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/consts.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/injection_metadata.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/injector.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/provider.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/record.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/none_injector.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/test_injector.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/forward_ref.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/graph.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/injection_def.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/providers.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/record.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/authentication.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/base.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/config_error.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/not_standalone.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/scope_error.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/logger/rotation.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/registries/container.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/registries/service.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/repositories.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/root.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/graph.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/interface/route.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/provide.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/router.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/router_module.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/utils/controller.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/utils/from_controllers.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/services.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/controller.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/controller_hook.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/controller_ref.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/module.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/module_ref.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/routes.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/types.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/utils/hydrate_consumer.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/utils/module.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/utils/repository.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/use_guards.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/base/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/base/edit.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/controller/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/controller/files/controller.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/guard/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/guard/files/guard.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/guard/files/param-guard.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/edit.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/files/module.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/files/update-module.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/.gitignore +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/LICENSE +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/README.md +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/app_module.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/bootstrap.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/main.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/routes.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/settings-connectiontypes/sqlalchemy.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/settings-connectiontypes/tortoise.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/settings.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/edit.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/files/repository.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/files/sa-repository-record.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/files/to-repository-record.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/service/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/service/files/service.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/create.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/files/pytest.ini.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/files/tests/conftest.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/files/tests/test_initial.py.asctpl +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/utilities/case_filters.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/utilities/entity_filters.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/utilities/namespace_maker.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/start.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/lifecycle.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/mixer.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/mock_dependency.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/test_client.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/utils/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/utils/metadata/__init__.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/utils/metadata/faker_field.py +0 -0
- {ascender_framework-2.0.2 → ascender_framework-2.0.4}/logo.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ascender-framework
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: The Ascender Framework is a sophisticated and structured FastAPI-based framework, inspired by the principles of NestJS. It stands out for its modular and organized architecture, offering developers a streamlined and efficient way to build web applications
|
|
5
5
|
Author: AscenderTeam
|
|
6
6
|
Requires-Python: >=3.11,<3.14
|
{ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/generator_app.py
RENAMED
|
@@ -43,7 +43,7 @@ class GeneratorCLI(GenericCLI):
|
|
|
43
43
|
def generate_service(
|
|
44
44
|
self,
|
|
45
45
|
name: str,
|
|
46
|
-
module: str | None = Parameter(names=["-m", "--module"], description="Module to generate the service in"),
|
|
46
|
+
module: str | None = Parameter(default=None, names=["-m", "--module"], description="Module to generate the service in"),
|
|
47
47
|
):
|
|
48
48
|
module_update, file_info = self.create_generator_service.generate_service(name, module)
|
|
49
49
|
rprint(f"[green]{file_info['schematic_type']}[/green] {file_info['file_path']} [cyan]({file_info['write_size']} bytes)[/cyan]")
|
|
@@ -54,7 +54,7 @@ class GeneratorCLI(GenericCLI):
|
|
|
54
54
|
def generate_module(
|
|
55
55
|
self,
|
|
56
56
|
name: str,
|
|
57
|
-
module: str | None = Parameter(names=["-m", "--module"], description="Module to generate the module in"),
|
|
57
|
+
module: str | None = Parameter(default=None, names=["-m", "--module"], description="Module to generate the module in"),
|
|
58
58
|
):
|
|
59
59
|
module_update, file_info = self.create_generator_service.generate_module(name, module)
|
|
60
60
|
rprint(f"[green]{file_info['schematic_type']}[/green] {file_info['file_path']} [cyan]({file_info['write_size']} bytes)[/cyan]")
|
|
@@ -68,7 +68,7 @@ class GeneratorCLI(GenericCLI):
|
|
|
68
68
|
name: str,
|
|
69
69
|
entities: tuple[str] | None = Parameter(None, names=["-e", "--entities"], description="List of entities to include in the repository", nargs="*"),
|
|
70
70
|
orm_mode: str = Parameter("default", names=["--orm-mode"], description="ORM mode to use for the repository"),
|
|
71
|
-
module: str | None = Parameter(names=["-m", "--module"], description="Module to generate the repository in"
|
|
71
|
+
module: str | None = Parameter(default=None, names=["-m", "--module"], description="Module to generate the repository in")
|
|
72
72
|
):
|
|
73
73
|
repository = self.create_generator_service.generate_repository(
|
|
74
74
|
name,
|
|
@@ -89,7 +89,7 @@ class GeneratorCLI(GenericCLI):
|
|
|
89
89
|
self,
|
|
90
90
|
name: str,
|
|
91
91
|
guard_type: Literal["single", "parametrized"] = Parameter("single", names=["--type"], description="Type of guard to generate"),
|
|
92
|
-
module: str | None = Parameter(names=["-m", "--module"], description="Module to generate the guard in"
|
|
92
|
+
module: str | None = Parameter(default=None, names=["-m", "--module"], description="Module to generate the guard in"),
|
|
93
93
|
guards: tuple[str] | None = Parameter(None, names=["--guards"], description="List of guards to include", nargs="+", action="extend")
|
|
94
94
|
):
|
|
95
95
|
guard_update, file_info = self.create_generator_service.generate_guard(
|
|
@@ -23,7 +23,11 @@ class RunCLI(BasicCLI):
|
|
|
23
23
|
|
|
24
24
|
if "relax" in self.extra: return self.get_cow()
|
|
25
25
|
source = _AscenderConfig().config.paths.source
|
|
26
|
-
|
|
26
|
+
try:
|
|
27
|
+
return subprocess.call(f"poetry run python {source}/main.py {' '.join(self.extra)}", shell=True)
|
|
28
|
+
except KeyboardInterrupt:
|
|
29
|
+
rprint("\n[yellow]Exiting ascender run mode...[/yellow]")
|
|
30
|
+
rprint("\n[cyan]Gracefully shutting down the Ascender application...[/cyan]")
|
|
27
31
|
|
|
28
32
|
def get_cow(self):
|
|
29
33
|
relax_replicas = [
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from .types.file import FileData
|
|
2
|
+
from .types.formdata import FormData
|
|
1
3
|
from .client import HTTPClient
|
|
2
4
|
from .provider import provideHTTPClient
|
|
3
5
|
from .types.http_options import HTTPOptions, HeaderTypes
|
|
@@ -12,5 +14,7 @@ __all__ = [
|
|
|
12
14
|
"_await",
|
|
13
15
|
"Interceptor",
|
|
14
16
|
"InterceptorFn",
|
|
15
|
-
"InterceptorIn"
|
|
17
|
+
"InterceptorIn",
|
|
18
|
+
"FormData",
|
|
19
|
+
"FileData"
|
|
16
20
|
]
|
|
@@ -58,7 +58,7 @@ class AscHTTPTransport(AsyncBaseTransport):
|
|
|
58
58
|
modified_request = request
|
|
59
59
|
# Handle class interceptors based on dependency injection
|
|
60
60
|
class_interceptors: list[Interceptor] | Interceptor = RootInjector().get(
|
|
61
|
-
"HTTP_INTERCEPTOR", not_found_value=[], options={"optional": True})
|
|
61
|
+
"HTTP_INTERCEPTOR", not_found_value=[], options={"optional": True}) # type: ignore
|
|
62
62
|
|
|
63
63
|
modified_request = await self.request_class_interceptors(modified_request, class_interceptors)
|
|
64
64
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from
|
|
4
|
-
from
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
from contextlib import _AsyncGeneratorContextManager
|
|
4
|
+
from typing import Any, Literal, TypeVar, cast, overload
|
|
5
|
+
from httpx import AsyncClient, Response
|
|
5
6
|
from pydantic import BaseModel
|
|
6
7
|
from reactivex import create, Observer, abc, Observable
|
|
7
8
|
|
|
9
|
+
from ascender.common.http.types.formdata import FormData
|
|
10
|
+
|
|
8
11
|
from ._transport import AscHTTPTransport
|
|
9
12
|
from .types.http_options import HTTPOptions
|
|
10
13
|
|
|
@@ -54,7 +57,7 @@ class HTTPClient:
|
|
|
54
57
|
_resp: type[T] | T = dict,
|
|
55
58
|
*,
|
|
56
59
|
url: str,
|
|
57
|
-
content: Any | BaseModel | None,
|
|
60
|
+
content: Any | BaseModel | FormData | None,
|
|
58
61
|
options: HTTPOptions | None = None
|
|
59
62
|
) -> T:
|
|
60
63
|
"""Send a POST request to a desired endpoint.
|
|
@@ -83,7 +86,7 @@ class HTTPClient:
|
|
|
83
86
|
_resp: type[T] | T = dict,
|
|
84
87
|
*,
|
|
85
88
|
url: str,
|
|
86
|
-
content: Any | BaseModel | None,
|
|
89
|
+
content: Any | BaseModel | FormData | None,
|
|
87
90
|
options: HTTPOptions | None = None
|
|
88
91
|
) -> T:
|
|
89
92
|
"""Send a PUT request to a desired endpoint.
|
|
@@ -112,7 +115,7 @@ class HTTPClient:
|
|
|
112
115
|
_resp: type[T] | T = dict,
|
|
113
116
|
*,
|
|
114
117
|
url: str,
|
|
115
|
-
content: Any | BaseModel | None,
|
|
118
|
+
content: Any | BaseModel | FormData | None,
|
|
116
119
|
options: HTTPOptions | None = None
|
|
117
120
|
) -> T:
|
|
118
121
|
"""Send a PATCH request to a desired endpoint.
|
|
@@ -163,15 +166,42 @@ class HTTPClient:
|
|
|
163
166
|
|
|
164
167
|
return cast(T, self.__handle_response(_resp, response=response))
|
|
165
168
|
|
|
169
|
+
@overload
|
|
166
170
|
def stream(
|
|
167
171
|
self,
|
|
168
172
|
_resp: type[T] | T = dict,
|
|
169
173
|
*,
|
|
170
174
|
method: Literal["GET", "POST", "PUT", "DELETE", "PATCH"],
|
|
171
175
|
url: str,
|
|
172
|
-
content: Any | BaseModel | None = None,
|
|
173
|
-
options: HTTPOptions | None = None
|
|
176
|
+
content: Any | BaseModel | FormData | None = None,
|
|
177
|
+
options: HTTPOptions | None = None,
|
|
178
|
+
as_observable: Literal[True] = True,
|
|
174
179
|
) -> Observable[T]:
|
|
180
|
+
...
|
|
181
|
+
|
|
182
|
+
@overload
|
|
183
|
+
def stream(
|
|
184
|
+
self,
|
|
185
|
+
_resp: type[T] | T = dict,
|
|
186
|
+
*,
|
|
187
|
+
method: Literal["GET", "POST", "PUT", "DELETE", "PATCH"],
|
|
188
|
+
url: str,
|
|
189
|
+
content: Any | BaseModel | FormData | None = None,
|
|
190
|
+
options: HTTPOptions | None = None,
|
|
191
|
+
as_observable: Literal[False],
|
|
192
|
+
) -> _AsyncGeneratorContextManager[Response]:
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
def stream(
|
|
196
|
+
self,
|
|
197
|
+
_resp: type[T] | T = dict,
|
|
198
|
+
*,
|
|
199
|
+
method: Literal["GET", "POST", "PUT", "DELETE", "PATCH"],
|
|
200
|
+
url: str,
|
|
201
|
+
content: Any | BaseModel | FormData | None = None,
|
|
202
|
+
options: HTTPOptions | None = None,
|
|
203
|
+
as_observable: bool = True,
|
|
204
|
+
) -> Observable[T] | _AsyncGeneratorContextManager[Response]:
|
|
175
205
|
"""Send a streaming request to a desired endpoint.
|
|
176
206
|
|
|
177
207
|
Args:
|
|
@@ -180,9 +210,10 @@ class HTTPClient:
|
|
|
180
210
|
url (str): The URL to send the request to.
|
|
181
211
|
content (Any | BaseModel | None, optional): The content to include in the request body (supports pydantic models). Defaults to None.
|
|
182
212
|
options (HTTPOptions | None, optional): Additional options for the request. Defaults to None.
|
|
213
|
+
as_observable (bool, optional): When True (default), returns an Observable; when False, returns an async context manager for manual streaming.
|
|
183
214
|
|
|
184
215
|
Returns:
|
|
185
|
-
Observable[T]:
|
|
216
|
+
Observable[T] | _AsyncGeneratorContextManager[Response]: Stream subscription helper or the raw streaming context manager.
|
|
186
217
|
|
|
187
218
|
Raises:
|
|
188
219
|
httpx.HTTPError: If an error occurs during the HTTP request.
|
|
@@ -190,9 +221,12 @@ class HTTPClient:
|
|
|
190
221
|
payload_options = {} if not options else options
|
|
191
222
|
request_payload = self.__prepare_request_body(content)
|
|
192
223
|
|
|
193
|
-
|
|
224
|
+
response_ctx = self.client.stream(method, url, **request_payload, **cast(HTTPOptions, payload_options)) # type: ignore
|
|
194
225
|
|
|
195
|
-
|
|
226
|
+
if not as_observable:
|
|
227
|
+
return response_ctx
|
|
228
|
+
|
|
229
|
+
return create(cast(abc.Subscription[T], self.__handle_streaming(_resp, response=response_ctx)))
|
|
196
230
|
|
|
197
231
|
def __prepare_request_body(
|
|
198
232
|
self,
|
|
@@ -203,26 +237,53 @@ class HTTPClient:
|
|
|
203
237
|
|
|
204
238
|
if isinstance(content, BaseModel):
|
|
205
239
|
return {"json": cast(BaseModel, content).model_dump(mode="json")}
|
|
206
|
-
|
|
240
|
+
|
|
241
|
+
if isinstance(content, FormData):
|
|
242
|
+
return content._construct()
|
|
243
|
+
|
|
207
244
|
return {"json": content}
|
|
208
245
|
|
|
209
246
|
def __handle_streaming(
|
|
210
247
|
self,
|
|
211
248
|
_resp: type[T] | T = dict,
|
|
212
249
|
*,
|
|
213
|
-
response:
|
|
250
|
+
response: _AsyncGeneratorContextManager[Response]
|
|
214
251
|
):
|
|
215
252
|
def observable_response(observer: Observer[T], _):
|
|
216
|
-
def handle_request():
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
253
|
+
async def handle_request():
|
|
254
|
+
try:
|
|
255
|
+
async with response as item:
|
|
256
|
+
async for line in item.aiter_text():
|
|
257
|
+
parsed = self.__parse_stream_chunk(_resp, line)
|
|
258
|
+
observer.on_next(parsed)
|
|
259
|
+
|
|
221
260
|
observer.on_completed()
|
|
261
|
+
except Exception as exc:
|
|
262
|
+
observer.on_error(exc)
|
|
222
263
|
|
|
223
|
-
|
|
264
|
+
asyncio.create_task(handle_request())
|
|
224
265
|
return observable_response
|
|
225
266
|
|
|
267
|
+
def __parse_stream_chunk(self, _resp: type[T] | T, chunk: str) -> T:
|
|
268
|
+
if isinstance(_resp, BaseModel):
|
|
269
|
+
return cast(T, type(_resp).model_validate_json(chunk))
|
|
270
|
+
|
|
271
|
+
if isinstance(_resp, type) and issubclass(_resp, BaseModel):
|
|
272
|
+
return cast(T, cast(type[BaseModel], _resp).model_validate_json(chunk))
|
|
273
|
+
|
|
274
|
+
try:
|
|
275
|
+
data = json.loads(chunk)
|
|
276
|
+
except Exception:
|
|
277
|
+
return cast(T, chunk)
|
|
278
|
+
|
|
279
|
+
if isinstance(_resp, type):
|
|
280
|
+
try:
|
|
281
|
+
return cast(T, _resp(data)) # type: ignore[arg-type]
|
|
282
|
+
except Exception:
|
|
283
|
+
return cast(T, data)
|
|
284
|
+
|
|
285
|
+
return cast(T, data)
|
|
286
|
+
|
|
226
287
|
def __handle_response(
|
|
227
288
|
self,
|
|
228
289
|
_resp: type[T] | T = dict,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class FileData:
|
|
5
|
+
def __init__(self, filename: str, content: bytes | BytesIO, content_type: str) -> None:
|
|
6
|
+
self.filename = filename
|
|
7
|
+
self.content = content
|
|
8
|
+
self.content_type = content_type
|
|
9
|
+
|
|
10
|
+
def seek(self, position: int) -> None:
|
|
11
|
+
if isinstance(self.content, BytesIO):
|
|
12
|
+
self.content.seek(position)
|
|
13
|
+
|
|
14
|
+
def construct(self) -> tuple[str, bytes | BytesIO, str]:
|
|
15
|
+
return (self.filename, self.content, self.content_type)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
from typing import Any, Iterable
|
|
3
|
+
|
|
4
|
+
from fastapi import UploadFile
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from ascender.common.http.types.file import FileData
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FormData:
|
|
11
|
+
"""A form data container for HTTP multipart/form-data requests.
|
|
12
|
+
|
|
13
|
+
This class provides an interface similar to the JavaScript FormData API for building
|
|
14
|
+
multipart form data. It supports string values and file uploads via FileData.
|
|
15
|
+
|
|
16
|
+
Note:
|
|
17
|
+
UploadFile values cannot be passed directly to the constructor. They must be added
|
|
18
|
+
using the append() or set() methods, which handle the conversion to FileData internally.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, **entries: str | FileData) -> None:
|
|
22
|
+
"""Initialize FormData with key-value pairs.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
**entries: Key-value pairs where values can be strings or FileData objects.
|
|
26
|
+
Note: UploadFile values are not accepted here. Use append() or set() instead.
|
|
27
|
+
"""
|
|
28
|
+
self.fields = entries
|
|
29
|
+
|
|
30
|
+
def append_from_dto(self, data: BaseModel) -> None:
|
|
31
|
+
self.fields.update(data.model_dump(mode="json"))
|
|
32
|
+
|
|
33
|
+
def append(self, name: str, value: str | FileData | UploadFile) -> None:
|
|
34
|
+
if isinstance(value, UploadFile):
|
|
35
|
+
if not value.content_type or not value.filename:
|
|
36
|
+
raise ValueError("UploadFile must have content_type and filename")
|
|
37
|
+
|
|
38
|
+
file_content = value.file.read()
|
|
39
|
+
file_data = FileData(
|
|
40
|
+
filename=value.filename,
|
|
41
|
+
content_type=value.content_type,
|
|
42
|
+
content=BytesIO(file_content)
|
|
43
|
+
)
|
|
44
|
+
self.fields[name] = file_data
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
self.fields[name] = value
|
|
48
|
+
|
|
49
|
+
def entries(self) -> Iterable[tuple[str, Any]]:
|
|
50
|
+
return iter(self.fields.items())
|
|
51
|
+
|
|
52
|
+
def get(self, name: str) -> str | FileData | None:
|
|
53
|
+
return self.fields.get(name)
|
|
54
|
+
|
|
55
|
+
def get_all(self) -> dict[str, str | FileData]:
|
|
56
|
+
return self.fields.copy()
|
|
57
|
+
|
|
58
|
+
def has(self, name: str) -> bool:
|
|
59
|
+
return name in self.fields
|
|
60
|
+
|
|
61
|
+
def keys(self) -> Iterable[str]:
|
|
62
|
+
return self.fields.keys()
|
|
63
|
+
|
|
64
|
+
def set(self, name: str, value: str | FileData | UploadFile) -> None:
|
|
65
|
+
self.append(name, value)
|
|
66
|
+
|
|
67
|
+
def values(self) -> Iterable[Any]:
|
|
68
|
+
return self.fields.values()
|
|
69
|
+
|
|
70
|
+
def delete(self, name: str) -> None:
|
|
71
|
+
if name in self.fields:
|
|
72
|
+
del self.fields[name]
|
|
73
|
+
|
|
74
|
+
def _construct(self):
|
|
75
|
+
files: dict[str, Any] = {}
|
|
76
|
+
data: dict[str, Any] = {}
|
|
77
|
+
|
|
78
|
+
for key, value in self.fields.items():
|
|
79
|
+
if isinstance(value, FileData):
|
|
80
|
+
files[key] = value.construct()
|
|
81
|
+
else:
|
|
82
|
+
data[key] = str(value)
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
"data": data,
|
|
86
|
+
"files": files
|
|
87
|
+
}
|
{ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/interceptors.py
RENAMED
|
@@ -3,7 +3,7 @@ from typing import Awaitable, Callable
|
|
|
3
3
|
from httpx import Request, Response
|
|
4
4
|
|
|
5
5
|
InterceptorIn = Request
|
|
6
|
-
InterceptorFn =
|
|
6
|
+
InterceptorFn = Callable[[Request], Awaitable[Request]]
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class Interceptor(ABC):
|
|
@@ -13,4 +13,4 @@ class Interceptor(ABC):
|
|
|
13
13
|
raise NotImplementedError("Handle request is not implemented")
|
|
14
14
|
|
|
15
15
|
async def handle_response(self, response: Response):
|
|
16
|
-
return response
|
|
16
|
+
return response
|
{ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/runtime.py
RENAMED
|
@@ -19,9 +19,9 @@ class LoggingConfig(BaseModel):
|
|
|
19
19
|
level: Literal["debug", "info", "warn", "error", "critical"] = Field("info", description="Logging level.")
|
|
20
20
|
file: Optional[str] = Field(None, description="Path to the log file.")
|
|
21
21
|
console: bool = Field(True, description="Whether to enable console logging.")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
22
|
+
console_format: Literal["rich", "json"] = Field("rich", description="Console log format.")
|
|
23
|
+
file_format: Literal["rich", "json"] = Field("json", description="File log format.")
|
|
24
|
+
rotation: Optional[LoggingRotationConfig] = Field(None, description="Log rotation settings.")
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class BuildConfig(BaseModel):
|
|
@@ -49,7 +49,7 @@ class DependencyInjectionConfig(BaseModel):
|
|
|
49
49
|
"warn", description="Action to take when circular dependencies are detected."
|
|
50
50
|
)
|
|
51
51
|
overrides: OverrideConfig = Field(
|
|
52
|
-
OverrideConfig(enabled=False, injector="ascender.core.di.injector.AscenderInjector"),
|
|
52
|
+
OverrideConfig(enabled=False, injector="ascender.core.di.injector.AscenderInjector"),
|
|
53
53
|
description="Dependency injection settings for this environment."
|
|
54
54
|
)
|
|
55
55
|
|
|
@@ -59,4 +59,3 @@ class FeaturesConfig(BaseModel):
|
|
|
59
59
|
runtimeMonitoring: bool = Field(True, description="Whether to enable runtime monitoring.")
|
|
60
60
|
autoMigrations: bool = Field(False, description="Whether to enable automatic migrations.")
|
|
61
61
|
staticFileServing: bool = Field(True, description="Whether to enable serving of static files.")
|
|
62
|
-
|
|
@@ -152,15 +152,12 @@ class CLIEngine:
|
|
|
152
152
|
subcommand_args = {k: v for k, v in arguments.items() if k in handler_info.parameters}
|
|
153
153
|
|
|
154
154
|
method = getattr(command_instance, handler_info._functionname)
|
|
155
|
-
if iscoroutinefunction(method):
|
|
156
|
-
return asyncio.run(call_parsed_method(method, subcommand_args))
|
|
157
155
|
|
|
158
156
|
return call_parsed_method(method, subcommand_args)
|
|
159
157
|
|
|
160
158
|
else:
|
|
161
159
|
raise TypeError(f"Unknown command type: {type(command_instance)}")
|
|
162
160
|
|
|
163
|
-
|
|
164
161
|
def parse_and_execute(self, argv: list[str] | None = None) -> Any:
|
|
165
162
|
"""
|
|
166
163
|
Parse command line arguments and execute the appropriate command.
|
|
@@ -9,7 +9,7 @@ class InjectionOverriderContext:
|
|
|
9
9
|
self.token: Token[Provider | None] | None = None
|
|
10
10
|
self.providers = providers
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def __enter__(self) -> Self:
|
|
13
13
|
self.token = StaticOverrider.override(self.providers)
|
|
14
14
|
return self
|
|
15
15
|
|
|
@@ -31,8 +31,8 @@ class InjectionOverriderContext:
|
|
|
31
31
|
|
|
32
32
|
StaticOverrider.reset(self.token)
|
|
33
33
|
self.token = StaticOverrider.override(self.providers)
|
|
34
|
-
|
|
35
|
-
def
|
|
34
|
+
|
|
35
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> Literal[False]:
|
|
36
36
|
StaticOverrider.reset(self.token)
|
|
37
37
|
return False
|
|
38
38
|
|
|
@@ -1,44 +1,48 @@
|
|
|
1
|
-
from logging import Logger, getLogger
|
|
2
|
-
from rich.logging import RichHandler
|
|
3
1
|
import logging
|
|
4
2
|
import os
|
|
3
|
+
from logging import getLogger
|
|
4
|
+
|
|
5
|
+
from rich.logging import RichHandler
|
|
5
6
|
|
|
6
7
|
from ascender.core._config.asc_config import _AscenderConfig
|
|
7
|
-
from ascender.core._config.interface.
|
|
8
|
-
from ascender.core.
|
|
9
|
-
|
|
8
|
+
from ascender.core._config.interface.runtime import LoggingConfig
|
|
9
|
+
from ascender.core.logger.formatter import (AscenderFormatter,
|
|
10
|
+
JsonAscenderFormatter)
|
|
10
11
|
|
|
11
12
|
from .rotation import configure_file_logging
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def configure_logger(config: LoggingConfig):
|
|
15
|
-
"""
|
|
16
|
-
Configures a logger with the AscenderFormatter.
|
|
17
|
-
"""
|
|
18
|
-
# Disable root logger's bad stuff
|
|
19
16
|
root_logger = getLogger()
|
|
20
17
|
root_logger.setLevel(logging.WARNING)
|
|
21
18
|
root_logger.propagate = False
|
|
22
19
|
|
|
23
|
-
# Create logger
|
|
24
20
|
logger = getLogger("Ascender Framework")
|
|
25
|
-
|
|
26
21
|
logger.setLevel(config.level.upper())
|
|
27
|
-
logger.propagate = False
|
|
28
|
-
|
|
29
|
-
rich_formatter = AscenderFormatter()
|
|
22
|
+
logger.propagate = False
|
|
30
23
|
|
|
31
|
-
#
|
|
24
|
+
# Console handler
|
|
32
25
|
if config.console:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
if config.console_format == "json":
|
|
27
|
+
console_handler = logging.StreamHandler()
|
|
28
|
+
console_handler.setFormatter(JsonAscenderFormatter())
|
|
29
|
+
logger.addHandler(console_handler)
|
|
30
|
+
else:
|
|
31
|
+
rich_handler = RichHandler(rich_tracebacks=True, markup=True)
|
|
32
|
+
rich_handler.setFormatter(AscenderFormatter())
|
|
33
|
+
logger.addHandler(rich_handler)
|
|
36
34
|
|
|
37
|
-
#
|
|
35
|
+
# File handler
|
|
38
36
|
if config.file:
|
|
39
37
|
rotation_config = config.rotation
|
|
40
38
|
logs_path = _AscenderConfig().config.paths.logs
|
|
41
|
-
file_handler = configure_file_logging(
|
|
39
|
+
file_handler = configure_file_logging(
|
|
40
|
+
os.path.abspath(os.path.join(logs_path, config.file)), rotation_config
|
|
41
|
+
)
|
|
42
|
+
if config.file_format == "json":
|
|
43
|
+
file_handler.setFormatter(JsonAscenderFormatter())
|
|
44
|
+
else:
|
|
45
|
+
file_handler.setFormatter(AscenderFormatter())
|
|
42
46
|
logger.addHandler(file_handler)
|
|
43
47
|
|
|
44
48
|
return logger
|
|
@@ -63,5 +67,5 @@ def configure_logger(config: LoggingConfig):
|
|
|
63
67
|
# # rotation_config = config.rotation
|
|
64
68
|
# # file_handler = configure_file_logging(os.path.abspath(config.file), rotation_config)
|
|
65
69
|
# # uvicorn_access.addHandler(file_handler)
|
|
66
|
-
|
|
70
|
+
|
|
67
71
|
# return uvicorn_access
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AscenderFormatter(logging.Formatter):
|
|
9
|
+
def format(self, record: logging.LogRecord) -> str:
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
# Extract log details
|
|
13
|
+
timestamp = self.formatTime(record, "%H:%M:%S")
|
|
14
|
+
level = record.levelname
|
|
15
|
+
logger_name = record.name
|
|
16
|
+
message = record.getMessage()
|
|
17
|
+
|
|
18
|
+
# Color-code log levels
|
|
19
|
+
level_markup = {
|
|
20
|
+
"DEBUG": "[cyan]DEBUG[/cyan]",
|
|
21
|
+
"INFO": "[green]INFO[/green]",
|
|
22
|
+
"WARNING": "[yellow]WARNING[/yellow]",
|
|
23
|
+
"ERROR": "[red]ERROR[/red]",
|
|
24
|
+
"CRITICAL": "[bold red]CRITICAL[/bold red]",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Format log message
|
|
28
|
+
markup_message = (
|
|
29
|
+
f"[dim]{timestamp}[/dim] ┆ "
|
|
30
|
+
f"{level_markup.get(level, level)} ┆ "
|
|
31
|
+
f"[magenta]{logger_name}[/magenta] ┆ "
|
|
32
|
+
f"{message}"
|
|
33
|
+
) # Message content
|
|
34
|
+
|
|
35
|
+
return markup_message
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class JsonAscenderFormatter(logging.Formatter):
|
|
39
|
+
def __init__(self, service: str | None = None):
|
|
40
|
+
super().__init__()
|
|
41
|
+
self.service = service
|
|
42
|
+
|
|
43
|
+
def format(self, record: logging.LogRecord) -> str:
|
|
44
|
+
log_obj = {
|
|
45
|
+
"ts": datetime.utcfromtimestamp(record.created).isoformat() + "Z",
|
|
46
|
+
"severity": record.levelname,
|
|
47
|
+
"service": self.service or record.name,
|
|
48
|
+
"message": record.getMessage(),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
reserved = set(vars(logging.LogRecord("", 0, "", 0, "", (), None)))
|
|
52
|
+
for key, value in record.__dict__.items():
|
|
53
|
+
if key not in reserved and key not in log_obj:
|
|
54
|
+
log_obj[key] = value
|
|
55
|
+
|
|
56
|
+
return json.dumps(log_obj)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from abc import abstractmethod
|
|
2
1
|
from functools import wraps
|
|
3
2
|
from typing import final
|
|
4
3
|
from typing import Any, Callable
|
|
@@ -11,33 +10,31 @@ from ascender.core.utils.module import load_module
|
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class ParamGuard:
|
|
14
|
-
__di_module__: AscModuleRef = None
|
|
13
|
+
__di_module__: AscModuleRef | None = None
|
|
15
14
|
__declaration_type__: str = "guard"
|
|
16
15
|
|
|
17
|
-
@abstractmethod
|
|
18
16
|
def __init__(self):
|
|
19
17
|
...
|
|
20
18
|
|
|
21
|
-
@abstractmethod
|
|
22
19
|
def __post_init__(self):
|
|
23
20
|
...
|
|
24
21
|
|
|
25
22
|
@final
|
|
26
23
|
def handle_di(self):
|
|
27
24
|
if not self.__di_module__:
|
|
28
|
-
RootInjector().injector.inject_factory_def(self.__post_init__)()
|
|
25
|
+
RootInjector().injector.inject_factory_def(self.__post_init__)() # type: ignore
|
|
29
26
|
return
|
|
30
27
|
|
|
31
28
|
di_module = self.__di_module__
|
|
32
29
|
|
|
33
30
|
# Load module or if it's already loaded then just use it and ignore `RuntimeError: module is already loaded`
|
|
34
31
|
try:
|
|
35
|
-
di_module = load_module(di_module)
|
|
32
|
+
di_module = load_module(di_module) # type: ignore
|
|
36
33
|
except RuntimeError:
|
|
37
34
|
pass
|
|
38
35
|
|
|
39
36
|
# Execute `self.__post_init__` method
|
|
40
|
-
self.__di_module__._injector.inject_factory_def(self.__post_init__)()
|
|
37
|
+
self.__di_module__._injector.inject_factory_def(self.__post_init__)() # type: ignore
|
|
41
38
|
|
|
42
39
|
def _define_dependencies(self, executable: Callable[..., None]):
|
|
43
40
|
"""
|
|
@@ -78,6 +75,6 @@ class ParamGuard:
|
|
|
78
75
|
|
|
79
76
|
@wraps(executable)
|
|
80
77
|
async def wrapper(*args, **kwargs):
|
|
81
|
-
return await _updatedfunc(*args, **kwargs)
|
|
78
|
+
return await _updatedfunc(*args, **kwargs) # type: ignore
|
|
82
79
|
|
|
83
80
|
return wrapper
|