pycraftcore 2.0.1__tar.gz → 2.1.0__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.
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/PKG-INFO +124 -32
- pycraftcore-2.0.1/src/pycraftcore.egg-info/PKG-INFO → pycraftcore-2.1.0/Readme.md +35 -45
- pycraftcore-2.1.0/pyproject.toml +113 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/adapter/schema.py +4 -1
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/enum/operation_type.py +1 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/model/operation.py +12 -2
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/sqlite/adapter.py +2 -2
- pycraftcore-2.1.0/src/pycraftcore/serializer/__init__.py +0 -0
- pycraftcore-2.0.1/Readme.md → pycraftcore-2.1.0/src/pycraftcore.egg-info/PKG-INFO +137 -5
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore.egg-info/SOURCES.txt +1 -0
- pycraftcore-2.1.0/src/pycraftcore.egg-info/requires.txt +96 -0
- pycraftcore-2.0.1/pyproject.toml +0 -84
- pycraftcore-2.0.1/src/pycraftcore.egg-info/requires.txt +0 -26
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/LICENSE +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/setup.cfg +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/adapter/load_application_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/adapter/omega_configuration_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/enum/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/enum/connector_type.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/enum/file_operation_action.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/enum/run_type_application.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/enum/run_type_environment.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/model/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/model/configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/model/connector.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/port/configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/port/configuration_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/authentication/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/authentication/model/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/authentication/model/auth_type.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/authentication/model/basic_auth.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/authentication/model/no_auth.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/authentication/model/token_auth.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/adapter/aiobreaker_circuit_breaker_policy.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/configuration/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/configuration/circuit_breaker_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/enum/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/enum/circuit_breaker_status.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/exception/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/exception/circuit_breaker_open_exception.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/circuit_breaker/port/async_circuit_breaker.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/adapter/compute_engine.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/adapter/numpy_arithmetic_operation.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/adapter/scipy_calculus_operation.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/const_typing.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/port/arithmetic_operation.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/port/calculus_operation.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/computation_engine/port/engine.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/context/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/context/request_id_context.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/csv/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/csv/csv_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/csv/csv_writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/json/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/json/json_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/json/json_writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/markdown/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/markdown/markdown_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/markdown/markdown_writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/svg/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/svg/svg_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/svg/svg_writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/txt/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/txt/txt_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/txt/txt_writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/yml/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/yml/yml_reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/extension/yml/yml_writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/handler.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/adapter/strategy.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/enum/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/enum/read_chunk_mode.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/port/file_handler_factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/port/file_handler_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/port/reader.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/port/writer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/schema/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/file_handler/schema/file_manifest.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/adapter/aiohttp_client.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/adapter/httpx_client.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/configuration/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/configuration/client_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/configuration/http_client_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/configuration/limits_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/configuration/security_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/context/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/context/request_context.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/enum/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/enum/http_method.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/middleware/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/middleware/request_id_middleware.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/middleware/request_middleware.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/policy/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/policy/http_error_policy.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/http/port/async_http_client.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/logger/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/logger/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/logger/adapter/standard_logger.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/logger/configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/logger/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/logger/port/logger.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/profiler/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/profiler/profiled.py +0 -0
- /pycraftcore-2.0.1/src/pycraftcore/query_language/__init__.py → /pycraftcore-2.1.0/src/pycraftcore/py.typed +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/query_language/constants/sql → pycraftcore-2.1.0/src/pycraftcore/query_language}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/adapter/sql/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/adapter/sql/adapter.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/adapter/sql/factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/constants/__init__.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/repository → pycraftcore-2.1.0/src/pycraftcore/query_language/constants/sql}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/constants/sql/allowed_sql_root_statements.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/constants/sql/forbidden_sql_statements.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/query_language/port/query_handler.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/repository/adapter/no_sql → pycraftcore-2.1.0/src/pycraftcore/repository}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/repository/adapter/no_sql/mongodb → pycraftcore-2.1.0/src/pycraftcore/repository/adapter/no_sql}/__init__.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/repository/adapter/sql → pycraftcore-2.1.0/src/pycraftcore/repository/adapter/no_sql/mongodb}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/no_sql/mongodb/adapter.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/no_sql/mongodb/factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/no_sql/mongodb/mapper.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/no_sql/mongodb/schema.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/repository/adapter/sql/postgresql → pycraftcore-2.1.0/src/pycraftcore/repository/adapter/sql}/__init__.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/resilient_http → pycraftcore-2.1.0/src/pycraftcore/repository/adapter/sql/postgresql}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/postgresql/adapter.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/postgresql/factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/postgresql/mapper.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/postgresql/schema.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/sqlite/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/sqlite/factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/sqlite/mapper.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/sqlite/schema.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/port/repository.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/retry → pycraftcore-2.1.0/src/pycraftcore/resilient_http}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/adapter/resilient_client.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/adapter/resilient_http_client_factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/adapter/resilient_transport.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/adapter/resilient_transport_factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/configuration/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/configuration/resilient_http_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/resilient_http/port/async_resilient_http_client.py +0 -0
- {pycraftcore-2.0.1/src/pycraftcore/serializer → pycraftcore-2.1.0/src/pycraftcore/retry}/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/retry/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/retry/adapter/tenacity_retry_policy.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/retry/configuration/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/retry/configuration/retry_configuration.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/retry/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/retry/port/retry.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/adapter/python/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/adapter/python/adapter.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/adapter/python/factory.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/adapter/python/host_bridge_server.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/adapter/python/python_runner_template.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/port/code.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/schema/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/schema/code_result.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/schema/code_stdout.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/schema/host_bridge.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/runtime/schema/safe_code_settings.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/serializer/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/serializer/adapter/binary_serializer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/serializer/adapter/dictionary_serializer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/serializer/adapter/json_serializer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/serializer/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/serializer/port/serializer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/null_telemetry.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/open_telemetry.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/open_telemetry_logger_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/open_telemetry_meter_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/open_telemetry_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/adapter/open_telemetry_tracer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/port/__init__.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/port/logger_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/port/meter_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/port/telemetry.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/port/trace_provider.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/telemetry/port/tracer.py +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore.egg-info/dependency_links.txt +0 -0
- {pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore.egg-info/top_level.txt +0 -0
|
@@ -1,41 +1,103 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycraftcore
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Provides reusable technical infrastructure and adapter implementations for Python applications
|
|
5
5
|
Author-email: Toufik Saouchi <toufik.saouchi@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/s-toufik/pycraftcore
|
|
8
|
+
Project-URL: Repository, https://github.com/s-toufik/pycraftcore
|
|
9
|
+
Project-URL: Issues, https://github.com/s-toufik/pycraftcore/issues
|
|
10
|
+
Keywords: infrastructure,hexagonal-architecture,configuration,logging,opentelemetry,resilient-http,repository,sandbox,asyncio
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
8
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
9
17
|
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Typing :: Typed
|
|
10
20
|
Requires-Python: >=3.14
|
|
11
21
|
Description-Content-Type: text/markdown
|
|
12
22
|
License-File: LICENSE
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: msgpack
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
|
|
23
|
+
Provides-Extra: authentication
|
|
24
|
+
Provides-Extra: context
|
|
25
|
+
Provides-Extra: logger
|
|
26
|
+
Provides-Extra: profiler
|
|
27
|
+
Requires-Dist: pyinstrument; extra == "profiler"
|
|
28
|
+
Provides-Extra: query-language
|
|
29
|
+
Requires-Dist: sqlglot; extra == "query-language"
|
|
30
|
+
Provides-Extra: computation-engine
|
|
31
|
+
Requires-Dist: numpy; extra == "computation-engine"
|
|
32
|
+
Requires-Dist: scipy; extra == "computation-engine"
|
|
33
|
+
Provides-Extra: serializer
|
|
34
|
+
Requires-Dist: orjson; extra == "serializer"
|
|
35
|
+
Requires-Dist: msgpack; extra == "serializer"
|
|
36
|
+
Requires-Dist: pydantic>=2; extra == "serializer"
|
|
37
|
+
Provides-Extra: file-handler
|
|
38
|
+
Requires-Dist: orjson; extra == "file-handler"
|
|
39
|
+
Requires-Dist: pyyaml; extra == "file-handler"
|
|
40
|
+
Provides-Extra: runtime
|
|
41
|
+
Requires-Dist: pydantic>=2; extra == "runtime"
|
|
42
|
+
Provides-Extra: circuit-breaker
|
|
43
|
+
Requires-Dist: aiobreaker; extra == "circuit-breaker"
|
|
44
|
+
Requires-Dist: pycraftcore[logger]; extra == "circuit-breaker"
|
|
45
|
+
Provides-Extra: retry
|
|
46
|
+
Requires-Dist: tenacity; extra == "retry"
|
|
47
|
+
Requires-Dist: pycraftcore[logger]; extra == "retry"
|
|
48
|
+
Provides-Extra: http
|
|
49
|
+
Requires-Dist: aiohttp; extra == "http"
|
|
50
|
+
Requires-Dist: httpx; extra == "http"
|
|
51
|
+
Requires-Dist: orjson; extra == "http"
|
|
52
|
+
Requires-Dist: starlette; extra == "http"
|
|
53
|
+
Requires-Dist: pycraftcore[context,logger]; extra == "http"
|
|
54
|
+
Provides-Extra: resilient-http
|
|
55
|
+
Requires-Dist: aiohttp; extra == "resilient-http"
|
|
56
|
+
Requires-Dist: httpx; extra == "resilient-http"
|
|
57
|
+
Requires-Dist: pycraftcore[circuit_breaker,http,logger,retry,telemetry]; extra == "resilient-http"
|
|
58
|
+
Provides-Extra: application-configuration
|
|
59
|
+
Requires-Dist: omegaconf; extra == "application-configuration"
|
|
60
|
+
Requires-Dist: pydantic>=2; extra == "application-configuration"
|
|
61
|
+
Requires-Dist: python-dotenv; extra == "application-configuration"
|
|
62
|
+
Requires-Dist: pycraftcore[authentication,http,logger]; extra == "application-configuration"
|
|
63
|
+
Provides-Extra: telemetry
|
|
64
|
+
Requires-Dist: opentelemetry-api; extra == "telemetry"
|
|
65
|
+
Requires-Dist: opentelemetry-sdk; extra == "telemetry"
|
|
66
|
+
Requires-Dist: opentelemetry-exporter-otlp; extra == "telemetry"
|
|
67
|
+
Requires-Dist: opentelemetry-instrumentation-logging; extra == "telemetry"
|
|
68
|
+
Requires-Dist: pycraftcore[application_configuration,context]; extra == "telemetry"
|
|
69
|
+
Provides-Extra: repository
|
|
70
|
+
Requires-Dist: aiosqlite; extra == "repository"
|
|
71
|
+
Requires-Dist: pymongo; extra == "repository"
|
|
72
|
+
Requires-Dist: psycopg[binary]; extra == "repository"
|
|
73
|
+
Requires-Dist: psycopg-pool; extra == "repository"
|
|
74
|
+
Requires-Dist: orjson; extra == "repository"
|
|
75
|
+
Requires-Dist: pydantic>=2; extra == "repository"
|
|
76
|
+
Requires-Dist: pycraftcore[application_configuration,authentication]; extra == "repository"
|
|
77
|
+
Provides-Extra: runtime-sandbox
|
|
78
|
+
Requires-Dist: pandas; extra == "runtime-sandbox"
|
|
79
|
+
Requires-Dist: numpy; extra == "runtime-sandbox"
|
|
80
|
+
Requires-Dist: matplotlib; extra == "runtime-sandbox"
|
|
81
|
+
Requires-Dist: python-dateutil; extra == "runtime-sandbox"
|
|
82
|
+
Requires-Dist: pycraftcore[runtime]; extra == "runtime-sandbox"
|
|
83
|
+
Provides-Extra: all
|
|
84
|
+
Requires-Dist: pycraftcore[application_configuration]; extra == "all"
|
|
85
|
+
Requires-Dist: pycraftcore[authentication]; extra == "all"
|
|
86
|
+
Requires-Dist: pycraftcore[circuit_breaker]; extra == "all"
|
|
87
|
+
Requires-Dist: pycraftcore[computation_engine]; extra == "all"
|
|
88
|
+
Requires-Dist: pycraftcore[context]; extra == "all"
|
|
89
|
+
Requires-Dist: pycraftcore[file_handler]; extra == "all"
|
|
90
|
+
Requires-Dist: pycraftcore[http]; extra == "all"
|
|
91
|
+
Requires-Dist: pycraftcore[logger]; extra == "all"
|
|
92
|
+
Requires-Dist: pycraftcore[profiler]; extra == "all"
|
|
93
|
+
Requires-Dist: pycraftcore[query_language]; extra == "all"
|
|
94
|
+
Requires-Dist: pycraftcore[repository]; extra == "all"
|
|
95
|
+
Requires-Dist: pycraftcore[resilient_http]; extra == "all"
|
|
96
|
+
Requires-Dist: pycraftcore[retry]; extra == "all"
|
|
97
|
+
Requires-Dist: pycraftcore[runtime]; extra == "all"
|
|
98
|
+
Requires-Dist: pycraftcore[runtime-sandbox]; extra == "all"
|
|
99
|
+
Requires-Dist: pycraftcore[serializer]; extra == "all"
|
|
100
|
+
Requires-Dist: pycraftcore[telemetry]; extra == "all"
|
|
39
101
|
Dynamic: license-file
|
|
40
102
|
|
|
41
103
|
# pycraftcore
|
|
@@ -67,11 +129,40 @@ The shared technical foundation of the homelab's Python services: configuration,
|
|
|
67
129
|
|
|
68
130
|
### Install
|
|
69
131
|
|
|
132
|
+
Requires Python 3.14. Each module's third-party dependencies sit behind an extra of the same name, so a service installs only what it uses:
|
|
133
|
+
|
|
70
134
|
```bash
|
|
71
|
-
uv add pycraftcore
|
|
135
|
+
uv add "pycraftcore[http,repository]" # or: pip install "pycraftcore[http,repository]"
|
|
136
|
+
uv add "pycraftcore[all]" # every module
|
|
72
137
|
```
|
|
73
138
|
|
|
74
|
-
|
|
139
|
+
A bare `pycraftcore` installs no third-party packages: only `authentication`, `context` and `logger` work without an extra. For any other module, importing its adapters without the extra fails with `ModuleNotFoundError`.
|
|
140
|
+
|
|
141
|
+
| Extra | Third-party packages | Also brings in |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `authentication`, `context`, `logger` | none | — |
|
|
144
|
+
| `profiler` | pyinstrument | — |
|
|
145
|
+
| `query_language` | sqlglot | — |
|
|
146
|
+
| `computation_engine` | numpy, scipy | — |
|
|
147
|
+
| `serializer` | orjson, msgpack, pydantic | — |
|
|
148
|
+
| `file_handler` | orjson, pyyaml | — |
|
|
149
|
+
| `runtime` | pydantic | — |
|
|
150
|
+
| `runtime-sandbox` | pandas, numpy, matplotlib, python-dateutil | `runtime` |
|
|
151
|
+
| `circuit_breaker` | aiobreaker | `logger` |
|
|
152
|
+
| `retry` | tenacity | `logger` |
|
|
153
|
+
| `http` | aiohttp, httpx, orjson, starlette | `context`, `logger` |
|
|
154
|
+
| `application_configuration` | omegaconf, pydantic, python-dotenv | `http`, `logger`, `authentication` |
|
|
155
|
+
| `telemetry` | opentelemetry (api, sdk, otlp exporter, logging instrumentation) | `application_configuration`, `context` |
|
|
156
|
+
| `resilient_http` | aiohttp, httpx | `circuit_breaker`, `http`, `retry`, `telemetry` |
|
|
157
|
+
| `repository` | aiosqlite, pymongo, psycopg, psycopg-pool, orjson, pydantic | `application_configuration`, `authentication` |
|
|
158
|
+
|
|
159
|
+
List every module your code imports, even when one extra already brings in another. That way your service stays correct if these links change. For the Python sandbox, use `runtime-sandbox` rather than `runtime`: the sandboxed code runs on your service's interpreter, so the libraries it may import (pandas, numpy, matplotlib, dateutil) must be installed there.
|
|
160
|
+
|
|
161
|
+
Development builds are published to TestPyPI; use them for testing only. Their dependencies come from PyPI, so add it as an extra index:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ "pycraftcore[http]"
|
|
165
|
+
```
|
|
75
166
|
|
|
76
167
|
### What's inside
|
|
77
168
|
|
|
@@ -298,12 +389,13 @@ Not every module needs every folder: add a folder when it has something to hold.
|
|
|
298
389
|
1. Define the protocol in `<module>/port/`.
|
|
299
390
|
2. Implement it in `<module>/adapter/`, with its settings in `configuration/` and the data it exchanges in `schema/`.
|
|
300
391
|
3. Export the public names from the package's `__init__.py`.
|
|
301
|
-
4.
|
|
392
|
+
4. Declare its third-party packages as an extra named after the module in `[project.optional-dependencies]` (pull in other modules with `pycraftcore[<module>]`). Then add it to `all`, to the [Install](#install) table, and to the `extras` matrix in `.github/workflows/cicd.yml`, which installs each extra alone and imports its package.
|
|
393
|
+
5. Add tests under `tests/<module>/`, and the module to [What's inside](#whats-inside) — with a short example under Using pycraftcore if services will use it directly.
|
|
302
394
|
|
|
303
395
|
### Tests and checks
|
|
304
396
|
|
|
305
397
|
```bash
|
|
306
|
-
make install_dev # uv sync --group dev
|
|
398
|
+
make install_dev # uv sync --group dev --all-extras
|
|
307
399
|
make check # ruff + ty + pytest
|
|
308
400
|
make test
|
|
309
401
|
make lint / make fix / make format / make typecheck
|
|
@@ -321,6 +413,6 @@ uv run pre-commit install --hook-type pre-commit --hook-type pre-push
|
|
|
321
413
|
1. Bump `version` in `pyproject.toml`.
|
|
322
414
|
2. `make build`.
|
|
323
415
|
3. `make publish_dev` to TestPyPI (needs `TEST_PYPI_TOKEN`), try it in a service, then `make publish` to PyPI (needs `RELEASE_PYPI_TOKEN`).
|
|
324
|
-
4. Raise the minimum version in the services that need the change (`pycraftcore>=…` in their `pyproject.toml`), then `uv lock --upgrade-package pycraftcore`.
|
|
416
|
+
4. Raise the minimum version in the services that need the change (`pycraftcore[<extras>]>=…` in their `pyproject.toml`), then `uv lock --upgrade-package pycraftcore`.
|
|
325
417
|
|
|
326
418
|
To work on pycraftcore and a service at the same time, point the service at your checkout with an editable path dependency in its `pyproject.toml`: `pycraftcore = { path = "../pycraftcore", editable = true }` under `[tool.uv.sources]`.
|
|
@@ -1,43 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pycraftcore
|
|
3
|
-
Version: 2.0.1
|
|
4
|
-
Summary: Provides reusable technical infrastructure and adapter implementations for Python applications
|
|
5
|
-
Author-email: Toufik Saouchi <toufik.saouchi@gmail.com>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/s-toufik/pycraftcore
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Operating System :: OS Independent
|
|
10
|
-
Requires-Python: >=3.14
|
|
11
|
-
Description-Content-Type: text/markdown
|
|
12
|
-
License-File: LICENSE
|
|
13
|
-
Requires-Dist: numpy
|
|
14
|
-
Requires-Dist: aiohttp
|
|
15
|
-
Requires-Dist: orjson
|
|
16
|
-
Requires-Dist: pyyaml
|
|
17
|
-
Requires-Dist: omegaconf
|
|
18
|
-
Requires-Dist: opentelemetry-api
|
|
19
|
-
Requires-Dist: opentelemetry-sdk
|
|
20
|
-
Requires-Dist: opentelemetry-exporter-otlp
|
|
21
|
-
Requires-Dist: pyinstrument
|
|
22
|
-
Requires-Dist: asyncpg
|
|
23
|
-
Requires-Dist: pydantic>=2
|
|
24
|
-
Requires-Dist: python-dotenv
|
|
25
|
-
Requires-Dist: msgpack>=1.1.2
|
|
26
|
-
Requires-Dist: scipy>=1.17.1
|
|
27
|
-
Requires-Dist: httpx
|
|
28
|
-
Requires-Dist: tenacity
|
|
29
|
-
Requires-Dist: aiobreaker
|
|
30
|
-
Requires-Dist: aiosqlite
|
|
31
|
-
Requires-Dist: sqlglot
|
|
32
|
-
Requires-Dist: starlette
|
|
33
|
-
Requires-Dist: pandas
|
|
34
|
-
Requires-Dist: matplotlib
|
|
35
|
-
Requires-Dist: pymongo<4.18,>=4.9
|
|
36
|
-
Requires-Dist: psycopg[binary]
|
|
37
|
-
Requires-Dist: psycopg-pool
|
|
38
|
-
Requires-Dist: opentelemetry-instrumentation-logging>=0.65b0
|
|
39
|
-
Dynamic: license-file
|
|
40
|
-
|
|
41
1
|
# pycraftcore
|
|
42
2
|
|
|
43
3
|
The shared technical foundation of the homelab's Python services: configuration, logging, telemetry, resilient HTTP, database repositories, safe SQL and a sandbox for running untrusted Python. Small, swappable building blocks rather than a framework — every module is an interface (a port) plus the implementations behind it (adapters).
|
|
@@ -67,11 +27,40 @@ The shared technical foundation of the homelab's Python services: configuration,
|
|
|
67
27
|
|
|
68
28
|
### Install
|
|
69
29
|
|
|
30
|
+
Requires Python 3.14. Each module's third-party dependencies sit behind an extra of the same name, so a service installs only what it uses:
|
|
31
|
+
|
|
70
32
|
```bash
|
|
71
|
-
uv add pycraftcore
|
|
33
|
+
uv add "pycraftcore[http,repository]" # or: pip install "pycraftcore[http,repository]"
|
|
34
|
+
uv add "pycraftcore[all]" # every module
|
|
72
35
|
```
|
|
73
36
|
|
|
74
|
-
|
|
37
|
+
A bare `pycraftcore` installs no third-party packages: only `authentication`, `context` and `logger` work without an extra. For any other module, importing its adapters without the extra fails with `ModuleNotFoundError`.
|
|
38
|
+
|
|
39
|
+
| Extra | Third-party packages | Also brings in |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `authentication`, `context`, `logger` | none | — |
|
|
42
|
+
| `profiler` | pyinstrument | — |
|
|
43
|
+
| `query_language` | sqlglot | — |
|
|
44
|
+
| `computation_engine` | numpy, scipy | — |
|
|
45
|
+
| `serializer` | orjson, msgpack, pydantic | — |
|
|
46
|
+
| `file_handler` | orjson, pyyaml | — |
|
|
47
|
+
| `runtime` | pydantic | — |
|
|
48
|
+
| `runtime-sandbox` | pandas, numpy, matplotlib, python-dateutil | `runtime` |
|
|
49
|
+
| `circuit_breaker` | aiobreaker | `logger` |
|
|
50
|
+
| `retry` | tenacity | `logger` |
|
|
51
|
+
| `http` | aiohttp, httpx, orjson, starlette | `context`, `logger` |
|
|
52
|
+
| `application_configuration` | omegaconf, pydantic, python-dotenv | `http`, `logger`, `authentication` |
|
|
53
|
+
| `telemetry` | opentelemetry (api, sdk, otlp exporter, logging instrumentation) | `application_configuration`, `context` |
|
|
54
|
+
| `resilient_http` | aiohttp, httpx | `circuit_breaker`, `http`, `retry`, `telemetry` |
|
|
55
|
+
| `repository` | aiosqlite, pymongo, psycopg, psycopg-pool, orjson, pydantic | `application_configuration`, `authentication` |
|
|
56
|
+
|
|
57
|
+
List every module your code imports, even when one extra already brings in another. That way your service stays correct if these links change. For the Python sandbox, use `runtime-sandbox` rather than `runtime`: the sandboxed code runs on your service's interpreter, so the libraries it may import (pandas, numpy, matplotlib, dateutil) must be installed there.
|
|
58
|
+
|
|
59
|
+
Development builds are published to TestPyPI; use them for testing only. Their dependencies come from PyPI, so add it as an extra index:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ "pycraftcore[http]"
|
|
63
|
+
```
|
|
75
64
|
|
|
76
65
|
### What's inside
|
|
77
66
|
|
|
@@ -298,12 +287,13 @@ Not every module needs every folder: add a folder when it has something to hold.
|
|
|
298
287
|
1. Define the protocol in `<module>/port/`.
|
|
299
288
|
2. Implement it in `<module>/adapter/`, with its settings in `configuration/` and the data it exchanges in `schema/`.
|
|
300
289
|
3. Export the public names from the package's `__init__.py`.
|
|
301
|
-
4.
|
|
290
|
+
4. Declare its third-party packages as an extra named after the module in `[project.optional-dependencies]` (pull in other modules with `pycraftcore[<module>]`). Then add it to `all`, to the [Install](#install) table, and to the `extras` matrix in `.github/workflows/cicd.yml`, which installs each extra alone and imports its package.
|
|
291
|
+
5. Add tests under `tests/<module>/`, and the module to [What's inside](#whats-inside) — with a short example under Using pycraftcore if services will use it directly.
|
|
302
292
|
|
|
303
293
|
### Tests and checks
|
|
304
294
|
|
|
305
295
|
```bash
|
|
306
|
-
make install_dev # uv sync --group dev
|
|
296
|
+
make install_dev # uv sync --group dev --all-extras
|
|
307
297
|
make check # ruff + ty + pytest
|
|
308
298
|
make test
|
|
309
299
|
make lint / make fix / make format / make typecheck
|
|
@@ -321,6 +311,6 @@ uv run pre-commit install --hook-type pre-commit --hook-type pre-push
|
|
|
321
311
|
1. Bump `version` in `pyproject.toml`.
|
|
322
312
|
2. `make build`.
|
|
323
313
|
3. `make publish_dev` to TestPyPI (needs `TEST_PYPI_TOKEN`), try it in a service, then `make publish` to PyPI (needs `RELEASE_PYPI_TOKEN`).
|
|
324
|
-
4. Raise the minimum version in the services that need the change (`pycraftcore>=…` in their `pyproject.toml`), then `uv lock --upgrade-package pycraftcore`.
|
|
314
|
+
4. Raise the minimum version in the services that need the change (`pycraftcore[<extras>]>=…` in their `pyproject.toml`), then `uv lock --upgrade-package pycraftcore`.
|
|
325
315
|
|
|
326
316
|
To work on pycraftcore and a service at the same time, point the service at your checkout with an editable path dependency in its `pyproject.toml`: `pycraftcore = { path = "../pycraftcore", editable = true }` under `[tool.uv.sources]`.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pycraftcore"
|
|
7
|
+
version = "2.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Toufik Saouchi", email = "toufik.saouchi@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "Provides reusable technical infrastructure and adapter implementations for Python applications"
|
|
12
|
+
readme = "Readme.md"
|
|
13
|
+
requires-python = ">=3.14"
|
|
14
|
+
keywords = ["infrastructure", "hexagonal-architecture", "configuration", "logging", "opentelemetry", "resilient-http", "repository", "sandbox", "asyncio"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 5 - Production/Stable",
|
|
17
|
+
"Framework :: AsyncIO",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
license = "MIT"
|
|
27
|
+
dependencies = []
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
# Independent dependencies
|
|
31
|
+
authentication = []
|
|
32
|
+
context = []
|
|
33
|
+
logger = []
|
|
34
|
+
profiler = ["pyinstrument"]
|
|
35
|
+
query_language = ["sqlglot"]
|
|
36
|
+
computation_engine = ["numpy", "scipy"]
|
|
37
|
+
serializer = ["orjson", "msgpack", "pydantic>=2"]
|
|
38
|
+
file_handler = ["orjson", "pyyaml"]
|
|
39
|
+
runtime = ["pydantic>=2"]
|
|
40
|
+
|
|
41
|
+
# Dependent dependencies
|
|
42
|
+
circuit_breaker = ["aiobreaker", "pycraftcore[logger]"]
|
|
43
|
+
retry = ["tenacity", "pycraftcore[logger]"]
|
|
44
|
+
http = ["aiohttp", "httpx", "orjson", "starlette", "pycraftcore[context, logger]"]
|
|
45
|
+
resilient_http = ["aiohttp", "httpx", "pycraftcore[circuit_breaker, http, logger, retry, telemetry]"]
|
|
46
|
+
application_configuration = ["omegaconf", "pydantic>=2", "python-dotenv", "pycraftcore[logger, http, authentication]"]
|
|
47
|
+
telemetry = ["opentelemetry-api", "opentelemetry-sdk", "opentelemetry-exporter-otlp", "opentelemetry-instrumentation-logging", "pycraftcore[application_configuration, context]"]
|
|
48
|
+
repository = ["aiosqlite", "pymongo", "psycopg[binary]", "psycopg-pool", "orjson", "pydantic>=2", "pycraftcore[application_configuration, authentication]"]
|
|
49
|
+
runtime-sandbox = ["pandas", "numpy", "matplotlib", "python-dateutil", "pycraftcore[runtime]"]
|
|
50
|
+
|
|
51
|
+
all = [
|
|
52
|
+
"pycraftcore[application_configuration]",
|
|
53
|
+
"pycraftcore[authentication]",
|
|
54
|
+
"pycraftcore[circuit_breaker]",
|
|
55
|
+
"pycraftcore[computation_engine]",
|
|
56
|
+
"pycraftcore[context]",
|
|
57
|
+
"pycraftcore[file_handler]",
|
|
58
|
+
"pycraftcore[http]",
|
|
59
|
+
"pycraftcore[logger]",
|
|
60
|
+
"pycraftcore[profiler]",
|
|
61
|
+
"pycraftcore[query_language]",
|
|
62
|
+
"pycraftcore[repository]",
|
|
63
|
+
"pycraftcore[resilient_http]",
|
|
64
|
+
"pycraftcore[retry]",
|
|
65
|
+
"pycraftcore[runtime]",
|
|
66
|
+
"pycraftcore[runtime-sandbox]",
|
|
67
|
+
"pycraftcore[serializer]",
|
|
68
|
+
"pycraftcore[telemetry]",
|
|
69
|
+
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[dependency-groups]
|
|
73
|
+
dev = [
|
|
74
|
+
"pytest",
|
|
75
|
+
"hypothesis",
|
|
76
|
+
"pytest-asyncio",
|
|
77
|
+
"pytest-cov",
|
|
78
|
+
"ruff",
|
|
79
|
+
"ty",
|
|
80
|
+
"scipy-stubs",
|
|
81
|
+
"pre-commit"
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
[tool.ruff]
|
|
85
|
+
line-length = 100
|
|
86
|
+
target-version = "py314"
|
|
87
|
+
|
|
88
|
+
[tool.ruff.lint]
|
|
89
|
+
select = [
|
|
90
|
+
"E", # pycodestyle
|
|
91
|
+
"F", # pyflakes
|
|
92
|
+
"UP", # pyupgrade
|
|
93
|
+
]
|
|
94
|
+
ignore = [
|
|
95
|
+
"B017", # Blind exeception in tests
|
|
96
|
+
"BLE001", # Blind exception in code
|
|
97
|
+
"E501", # Line length
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
[tool.ty.src]
|
|
101
|
+
include = ["src", "tests/ducktype"]
|
|
102
|
+
exclude = [".venv"]
|
|
103
|
+
|
|
104
|
+
[tool.setuptools.packages.find]
|
|
105
|
+
where = ["src"]
|
|
106
|
+
|
|
107
|
+
[tool.setuptools.package-data]
|
|
108
|
+
pycraftcore = ["py.typed"]
|
|
109
|
+
|
|
110
|
+
[project.urls]
|
|
111
|
+
Homepage = "https://github.com/s-toufik/pycraftcore"
|
|
112
|
+
Repository = "https://github.com/s-toufik/pycraftcore"
|
|
113
|
+
Issues = "https://github.com/s-toufik/pycraftcore/issues"
|
{pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/adapter/schema.py
RENAMED
|
@@ -23,6 +23,7 @@ from pycraftcore.application_configuration.model.connector import (
|
|
|
23
23
|
from pycraftcore.application_configuration.model.operation import (
|
|
24
24
|
ApiOperation,
|
|
25
25
|
FileOperation,
|
|
26
|
+
McpOperation,
|
|
26
27
|
OperationRegistry,
|
|
27
28
|
)
|
|
28
29
|
|
|
@@ -41,7 +42,9 @@ _ConnectorSchemaTyping = Annotated[
|
|
|
41
42
|
]
|
|
42
43
|
|
|
43
44
|
_OperationSchemaTyping = Annotated[
|
|
44
|
-
Annotated[ApiOperation, Tag("api")]
|
|
45
|
+
Annotated[ApiOperation, Tag("api")]
|
|
46
|
+
| Annotated[FileOperation, Tag("file")]
|
|
47
|
+
| Annotated[McpOperation, Tag("mcp")],
|
|
45
48
|
Discriminator(_kind_tag),
|
|
46
49
|
]
|
|
47
50
|
|
{pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/application_configuration/model/operation.py
RENAMED
|
@@ -7,7 +7,7 @@ from pycraftcore.application_configuration.enum.file_operation_action import (
|
|
|
7
7
|
from pycraftcore.application_configuration.enum.operation_type import OperationType
|
|
8
8
|
from pycraftcore.application_configuration.model.connector import (
|
|
9
9
|
ApiConnector,
|
|
10
|
-
FileConnector,
|
|
10
|
+
FileConnector, McpConnector,
|
|
11
11
|
)
|
|
12
12
|
from pycraftcore.http.enum.http_method import HttpMethod
|
|
13
13
|
|
|
@@ -32,12 +32,19 @@ class FileOperation(BaseOperation):
|
|
|
32
32
|
action: FileOperationAction
|
|
33
33
|
parameters: dict[str, Any]
|
|
34
34
|
|
|
35
|
+
@dataclass(slots=True)
|
|
36
|
+
class McpOperation(BaseOperation):
|
|
37
|
+
connector: McpConnector
|
|
38
|
+
parameters: dict[str, Any]
|
|
39
|
+
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
|
|
42
|
+
OperationTyping = FileOperation | ApiOperation | McpOperation
|
|
37
43
|
|
|
38
44
|
_OPERATION_CLASS_BY_TYPE: dict[OperationType, type[OperationTyping]] = {
|
|
39
45
|
OperationType.api: ApiOperation,
|
|
40
46
|
OperationType.file: FileOperation,
|
|
47
|
+
OperationType.mcp: McpOperation,
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
|
|
@@ -62,6 +69,9 @@ class OperationRegistry:
|
|
|
62
69
|
def file(self, name: str) -> FileOperation:
|
|
63
70
|
return self._get(name, FileOperation)
|
|
64
71
|
|
|
72
|
+
def mcp(self, name: str) -> McpOperation:
|
|
73
|
+
return self._get(name, McpOperation)
|
|
74
|
+
|
|
65
75
|
def _get[T: OperationTyping](self, name: str, expected: type[T]) -> T:
|
|
66
76
|
try:
|
|
67
77
|
operation = self.by_name[name]
|
{pycraftcore-2.0.1 → pycraftcore-2.1.0}/src/pycraftcore/repository/adapter/sql/sqlite/adapter.py
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from collections.abc import
|
|
2
|
+
from collections.abc import AsyncGenerator, Iterable
|
|
3
3
|
from contextlib import asynccontextmanager
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ class SqliteRepository:
|
|
|
13
13
|
self._pool.put_nowait(connection)
|
|
14
14
|
|
|
15
15
|
@asynccontextmanager
|
|
16
|
-
async def _acquire(self) ->
|
|
16
|
+
async def _acquire(self) -> AsyncGenerator[Connection]:
|
|
17
17
|
connection = await self._pool.get()
|
|
18
18
|
try:
|
|
19
19
|
yield connection
|
|
File without changes
|