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.
Files changed (274) hide show
  1. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/PKG-INFO +1 -1
  2. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/generator_app.py +4 -4
  3. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/run/run_app.py +5 -1
  4. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/__init__.py +5 -1
  5. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/_transport.py +1 -1
  6. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/client.py +81 -20
  7. ascender_framework-2.0.4/ascender/common/http/types/file.py +15 -0
  8. ascender_framework-2.0.4/ascender/common/http/types/formdata.py +87 -0
  9. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/interceptors.py +2 -2
  10. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/runtime.py +4 -5
  11. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/stub.json +1 -1
  12. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/engine.py +0 -3
  13. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/overrider.py +3 -3
  14. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/logger/_logger.py +25 -21
  15. ascender_framework-2.0.4/ascender/core/logger/formatter.py +56 -0
  16. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/guard.py +0 -1
  17. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/paramguard.py +5 -8
  18. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/ascender.json.asctpl +2 -0
  19. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/pyproject.toml +1 -1
  20. ascender_framework-2.0.2/ascender/core/logger/formatter.py +0 -36
  21. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/LICENSE +0 -0
  22. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/README.md +0 -0
  23. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/__init__.py +0 -0
  24. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/abc/__init__.py +0 -0
  25. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/abc/middleware.py +0 -0
  26. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/__init__.py +0 -0
  27. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/__init__.py +0 -0
  28. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/build_app.py +0 -0
  29. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/build_message_service.py +0 -0
  30. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/builder/build_service.py +0 -0
  31. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/__init__.py +0 -0
  32. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/create_generator_service.py +0 -0
  33. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/generator/edit_generator_service.py +0 -0
  34. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/new/__init__.py +0 -0
  35. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/new/new_app.py +0 -0
  36. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/new/new_service.py +0 -0
  37. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/run/__init__.py +0 -0
  38. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/serve/__init__.py +0 -0
  39. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/serve/serve_app.py +0 -0
  40. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/serve/serve_service.py +0 -0
  41. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/tests/__init__.py +0 -0
  42. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/tests/tests_app.py +0 -0
  43. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/tests/tests_cli_service.py +0 -0
  44. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/clis/version/version_app.py +0 -0
  45. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/__init__.py +0 -0
  46. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/__init__.py +0 -0
  47. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/base_http_middleware.py +0 -0
  48. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/cors_middleware.py +0 -0
  49. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api/relational_middleware.py +0 -0
  50. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/api_docs.py +0 -0
  51. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/base/__init__.py +0 -0
  52. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/base/dto.py +0 -0
  53. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/base/response.py +0 -0
  54. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/awaitables/awaitable.py +0 -0
  55. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/provider.py +0 -0
  56. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/__init__.py +0 -0
  57. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/http/types/http_options.py +0 -0
  58. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/injectable.py +0 -0
  59. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/__init__.py +0 -0
  60. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/__init__.py +0 -0
  61. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/client_proxy.py +0 -0
  62. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/context.py +0 -0
  63. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/event_bus.py +0 -0
  64. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/event_transport.py +0 -0
  65. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/rpc_transport.py +0 -0
  66. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/abc/transporter.py +0 -0
  67. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/callback_manager.py +0 -0
  68. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/exceptions/__init__.py +0 -0
  69. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/exceptions/rpc_exception.py +0 -0
  70. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/__init__.py +0 -0
  71. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/bus.py +0 -0
  72. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/client_factory.py +0 -0
  73. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/client_proxy.py +0 -0
  74. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/__init__.py +0 -0
  75. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/client.py +0 -0
  76. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/context.py +0 -0
  77. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/event.py +0 -0
  78. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/metadata.py +0 -0
  79. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/rpc.py +0 -0
  80. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/kafka/transporter.py +0 -0
  81. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/__init__.py +0 -0
  82. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/client.py +0 -0
  83. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/context.py +0 -0
  84. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/event.py +0 -0
  85. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/rpc.old.py +0 -0
  86. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/rpc.py +0 -0
  87. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/redis/transporter.py +0 -0
  88. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/__init__.py +0 -0
  89. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/client.py +0 -0
  90. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/context.py +0 -0
  91. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/event.py +0 -0
  92. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/rpc.py +0 -0
  93. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/tcp/transporter.py +0 -0
  94. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/instances/transport.py +0 -0
  95. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/patterns/__init__.py +0 -0
  96. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/patterns/event_pattern.py +0 -0
  97. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/patterns/message_pattern.py +0 -0
  98. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/provider.py +0 -0
  99. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/transport_manager.py +0 -0
  100. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/__init__.py +0 -0
  101. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/consumer_metadata.py +0 -0
  102. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/ctx.py +0 -0
  103. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/options.py +0 -0
  104. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/types/transport.py +0 -0
  105. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/__init__.py +0 -0
  106. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/consumers.py +0 -0
  107. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/data_parser.py +0 -0
  108. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/defer_mapping.py +0 -0
  109. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/microservices/utils/redis_tools.py +0 -0
  110. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/common/serializer.py +0 -0
  111. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/contrib/__init__.py +0 -0
  112. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/contrib/middlewares.py +0 -0
  113. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/__init__.py +0 -0
  114. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/build.py +0 -0
  115. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/dockerfile_generator.py +0 -0
  116. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/file_builder.py +0 -0
  117. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/minifier.py +0 -0
  118. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_builder/obfuscator.py +0 -0
  119. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/asc_config.py +0 -0
  120. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/environment.py +0 -0
  121. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/interface/main.py +0 -0
  122. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/_config/static_files.py +0 -0
  123. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/__init__.py +0 -0
  124. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/_create_internal.py +0 -0
  125. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/application.py +0 -0
  126. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/configure_imports.py +0 -0
  127. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/create_application.py +0 -0
  128. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/applications/root_injector.py +0 -0
  129. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/__init__.py +0 -0
  130. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/application.py +0 -0
  131. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/async_module.py +0 -0
  132. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/injectable.py +0 -0
  133. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/loaders/base_loader.py +0 -0
  134. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/loaders/generic_loader.py +0 -0
  135. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/main.py +0 -0
  136. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/models.py +0 -0
  137. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/processor.py +0 -0
  138. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli/provider.py +0 -0
  139. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/__init__.py +0 -0
  140. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/decorators/__init__.py +0 -0
  141. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/decorators/command.py +0 -0
  142. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/decorators/handler.py +0 -0
  143. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/__init__.py +0 -0
  144. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/boolean.py +0 -0
  145. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/const.py +0 -0
  146. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/parameters/parameter.py +0 -0
  147. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/protos/__init__.py +0 -0
  148. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/protos/basic_cli.py +0 -0
  149. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/protos/generic_cli.py +0 -0
  150. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/provider.py +0 -0
  151. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/__init__.py +0 -0
  152. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/command_metadata.py +0 -0
  153. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/handler_metadata.py +0 -0
  154. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/parameter.py +0 -0
  155. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/parameter_kind.py +0 -0
  156. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/types/undefined.py +0 -0
  157. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/__init__.py +0 -0
  158. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/argparser.py +0 -0
  159. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/metadata_from_class.py +0 -0
  160. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/signature_from_callable.py +0 -0
  161. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/cli_engine/utils/valiidator.py +0 -0
  162. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/__init__.py +0 -0
  163. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/constructor.py +0 -0
  164. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/dbcontext.py +0 -0
  165. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/engine.py +0 -0
  166. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/entity.py +0 -0
  167. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/errors/wrong_orm.py +0 -0
  168. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/orms/sqlalchemy.py +0 -0
  169. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/orms/tortoise.py +0 -0
  170. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/provider.py +0 -0
  171. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/__init__.py +0 -0
  172. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/orm_enum.py +0 -0
  173. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/sqlalchemy_configuration.py +0 -0
  174. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/database/types/tortoise_configuration.py +0 -0
  175. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/__init__.py +0 -0
  176. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/abc/__init__.py +0 -0
  177. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/abc/base_injector.py +0 -0
  178. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/create.py +0 -0
  179. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/forward_ref.py +0 -0
  180. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/inject.py +0 -0
  181. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/injectfn.py +0 -0
  182. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/injector.py +0 -0
  183. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/__init__.py +0 -0
  184. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/consts.py +0 -0
  185. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/injection_metadata.py +0 -0
  186. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/injector.py +0 -0
  187. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/provider.py +0 -0
  188. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/interface/record.py +0 -0
  189. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/none_injector.py +0 -0
  190. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/test_injector.py +0 -0
  191. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/__init__.py +0 -0
  192. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/forward_ref.py +0 -0
  193. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/graph.py +0 -0
  194. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/injection_def.py +0 -0
  195. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/providers.py +0 -0
  196. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/di/utils/record.py +0 -0
  197. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/authentication.py +0 -0
  198. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/base.py +0 -0
  199. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/config_error.py +0 -0
  200. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/not_standalone.py +0 -0
  201. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/errors/scope_error.py +0 -0
  202. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/logger/rotation.py +0 -0
  203. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/registries/container.py +0 -0
  204. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/registries/service.py +0 -0
  205. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/repositories.py +0 -0
  206. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/root.py +0 -0
  207. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/__init__.py +0 -0
  208. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/graph.py +0 -0
  209. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/interface/route.py +0 -0
  210. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/provide.py +0 -0
  211. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/router.py +0 -0
  212. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/router_module.py +0 -0
  213. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/utils/controller.py +0 -0
  214. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/router/utils/from_controllers.py +0 -0
  215. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/services.py +0 -0
  216. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/__init__.py +0 -0
  217. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/controller.py +0 -0
  218. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/controller_hook.py +0 -0
  219. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/controller_ref.py +0 -0
  220. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/module.py +0 -0
  221. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/module_ref.py +0 -0
  222. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/struct/routes.py +0 -0
  223. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/types.py +0 -0
  224. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/utils/hydrate_consumer.py +0 -0
  225. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/utils/module.py +0 -0
  226. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/core/utils/repository.py +0 -0
  227. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/__init__.py +0 -0
  228. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/guards/use_guards.py +0 -0
  229. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/base/create.py +0 -0
  230. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/base/edit.py +0 -0
  231. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/controller/create.py +0 -0
  232. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/controller/files/controller.py.asctpl +0 -0
  233. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/guard/create.py +0 -0
  234. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/guard/files/guard.py.asctpl +0 -0
  235. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/guard/files/param-guard.py.asctpl +0 -0
  236. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/create.py +0 -0
  237. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/edit.py +0 -0
  238. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/files/module.py.asctpl +0 -0
  239. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/module/files/update-module.py.asctpl +0 -0
  240. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/create.py +0 -0
  241. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/.gitignore +0 -0
  242. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/LICENSE +0 -0
  243. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/README.md +0 -0
  244. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/app_module.py.asctpl +0 -0
  245. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/bootstrap.py.asctpl +0 -0
  246. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/main.py.asctpl +0 -0
  247. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/routes.py.asctpl +0 -0
  248. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/settings-connectiontypes/sqlalchemy.asctpl +0 -0
  249. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/settings-connectiontypes/tortoise.asctpl +0 -0
  250. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/project/files/settings.py.asctpl +0 -0
  251. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/create.py +0 -0
  252. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/edit.py +0 -0
  253. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/files/repository.py.asctpl +0 -0
  254. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/files/sa-repository-record.py.asctpl +0 -0
  255. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/repository/files/to-repository-record.py.asctpl +0 -0
  256. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/service/create.py +0 -0
  257. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/service/files/service.py.asctpl +0 -0
  258. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/create.py +0 -0
  259. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/files/pytest.ini.asctpl +0 -0
  260. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/files/tests/conftest.py.asctpl +0 -0
  261. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/tests/files/tests/test_initial.py.asctpl +0 -0
  262. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/utilities/case_filters.py +0 -0
  263. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/utilities/entity_filters.py +0 -0
  264. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/schematics/utilities/namespace_maker.py +0 -0
  265. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/start.py +0 -0
  266. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/__init__.py +0 -0
  267. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/lifecycle.py +0 -0
  268. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/mixer.py +0 -0
  269. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/mock_dependency.py +0 -0
  270. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/test_client.py +0 -0
  271. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/utils/__init__.py +0 -0
  272. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/utils/metadata/__init__.py +0 -0
  273. {ascender_framework-2.0.2 → ascender_framework-2.0.4}/ascender/testing/utils/metadata/faker_field.py +0 -0
  274. {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.2
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
@@ -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", default=None)
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", default=None),
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
- return subprocess.call(f"poetry run python {source}/main.py {' '.join(self.extra)}", shell=True)
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
- from contextlib import _GeneratorContextManager
2
- from threading import Thread
3
- from typing import Any, Literal, TypeVar, cast
4
- from httpx import AsyncClient, Response, stream
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]: An observable that emits the response from the server.
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
- resposne = stream(method, url, **request_payload, **cast(HTTPOptions, payload_options)) # type: ignore
224
+ response_ctx = self.client.stream(method, url, **request_payload, **cast(HTTPOptions, payload_options)) # type: ignore
194
225
 
195
- return create(cast(abc.Subscription[T], self.__handle_streaming(_resp, response=resposne)))
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: _GeneratorContextManager[Response]
250
+ response: _AsyncGeneratorContextManager[Response]
214
251
  ):
215
252
  def observable_response(observer: Observer[T], _):
216
- def handle_request():
217
- with response as item:
218
- for line in item.iter_text():
219
- observer.on_next(cast(T, line))
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
- Thread(target=handle_request).start()
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
+ }
@@ -3,7 +3,7 @@ from typing import Awaitable, Callable
3
3
  from httpx import Request, Response
4
4
 
5
5
  InterceptorIn = Request
6
- InterceptorFn = Awaitable[Callable[[Request], Request]]
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
@@ -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
- rotation: Optional[LoggingRotationConfig] = Field(
23
- None, description="Log rotation settings."
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
-
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "project": {
3
3
  "name": "Ascender Framework",
4
- "version": "1.3.0-b6",
4
+ "version": "2.0.4",
5
5
  "description": "A backend project powered by Ascender Framework"
6
6
  },
7
7
  "paths": {
@@ -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 __aenter__(self) -> Self:
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 __aexit__(self, exc_type, exc_val, exc_tb) -> Literal[False]:
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.environment import EnvironmentConfig
8
- from ascender.core._config.interface.runtime import LoggingConfig, ServerConfig
9
- from ascender.core.logger.formatter import AscenderFormatter
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 # Avoid duplicate logs if root logger is configured
28
-
29
- rich_formatter = AscenderFormatter()
22
+ logger.propagate = False
30
23
 
31
- # Create stream handler for console output
24
+ # Console handler
32
25
  if config.console:
33
- rich_handler = RichHandler(rich_tracebacks=True, markup=True)
34
- rich_handler.setFormatter(rich_formatter)
35
- logger.addHandler(rich_handler)
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
- # Optional: Create file handler for logging to a file
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(os.path.abspath(os.path.join(logs_path, config.file)), rotation_config)
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)
@@ -15,7 +15,6 @@ class Guard(ABC):
15
15
  __di_module__: AscModuleRef | None = None
16
16
  __declaration_type__: str = "guard"
17
17
 
18
- @abstractmethod
19
18
  def __init__(self):
20
19
  """
21
20
  For Guard configurations and parameters
@@ -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
@@ -13,6 +13,8 @@
13
13
  "logging": {
14
14
  "level": "debug",
15
15
  "file": "logs/ascender.log",
16
+ "console_format": "rich",
17
+ "file_format": "rich",
16
18
  "console": true,
17
19
  "rotation": {
18
20
  "enabled": true,