archipy 3.14.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.
- archipy-3.14.4/.cursor/rules/checks.mdc +296 -0
- archipy-3.14.4/.cursorignore +7 -0
- archipy-3.14.4/.dockerignore +174 -0
- archipy-3.14.4/.env.example +327 -0
- archipy-3.14.4/.env.test +61 -0
- archipy-3.14.4/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
- archipy-3.14.4/.github/ISSUE_TEMPLATE/custom.md +26 -0
- archipy-3.14.4/.github/ISSUE_TEMPLATE/documentation-improvement.md +29 -0
- archipy-3.14.4/.github/ISSUE_TEMPLATE/feature_request.md +39 -0
- archipy-3.14.4/.github/dependabot.yml +38 -0
- archipy-3.14.4/.github/pull_request_template.md +39 -0
- archipy-3.14.4/.github/workflows/bandit.yml +52 -0
- archipy-3.14.4/.github/workflows/deploy-docs.yml +49 -0
- archipy-3.14.4/.github/workflows/lint.yml +39 -0
- archipy-3.14.4/.github/workflows/publish.yml +37 -0
- archipy-3.14.4/.github/workflows/tests.yml +39 -0
- archipy-3.14.4/.gitignore +243 -0
- archipy-3.14.4/.pre-commit-config.yaml +88 -0
- archipy-3.14.4/.readthedocs.yaml +45 -0
- archipy-3.14.4/CLAUDE.md +61 -0
- archipy-3.14.4/CODE_OF_CONDUCT.md +122 -0
- archipy-3.14.4/CONTRIBUTING.md +197 -0
- archipy-3.14.4/LICENSE +201 -0
- archipy-3.14.4/Makefile +201 -0
- archipy-3.14.4/PKG-INFO +489 -0
- archipy-3.14.4/README.md +207 -0
- archipy-3.14.4/SECURITY.md +96 -0
- archipy-3.14.4/SPONSORS.md +54 -0
- archipy-3.14.4/archipy/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/base/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/base/sqlalchemy/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/base/sqlalchemy/adapters.py +821 -0
- archipy-3.14.4/archipy/adapters/base/sqlalchemy/ports.py +266 -0
- archipy-3.14.4/archipy/adapters/base/sqlalchemy/session_manager_ports.py +78 -0
- archipy-3.14.4/archipy/adapters/base/sqlalchemy/session_manager_registry.py +104 -0
- archipy-3.14.4/archipy/adapters/base/sqlalchemy/session_managers.py +398 -0
- archipy-3.14.4/archipy/adapters/elasticsearch/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/elasticsearch/adapters.py +531 -0
- archipy-3.14.4/archipy/adapters/elasticsearch/ports.py +489 -0
- archipy-3.14.4/archipy/adapters/email/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/email/adapters.py +331 -0
- archipy-3.14.4/archipy/adapters/email/ports.py +105 -0
- archipy-3.14.4/archipy/adapters/internet_payment_gateways/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/internet_payment_gateways/ir/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/internet_payment_gateways/ir/parsian/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/internet_payment_gateways/ir/parsian/adapters.py +254 -0
- archipy-3.14.4/archipy/adapters/kafka/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/kafka/adapters.py +587 -0
- archipy-3.14.4/archipy/adapters/kafka/ports.py +191 -0
- archipy-3.14.4/archipy/adapters/keycloak/__init__.py +1 -0
- archipy-3.14.4/archipy/adapters/keycloak/adapters.py +2884 -0
- archipy-3.14.4/archipy/adapters/keycloak/ports.py +522 -0
- archipy-3.14.4/archipy/adapters/minio/__init__.py +1 -0
- archipy-3.14.4/archipy/adapters/minio/adapters.py +606 -0
- archipy-3.14.4/archipy/adapters/minio/ports.py +101 -0
- archipy-3.14.4/archipy/adapters/postgres/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/postgres/sqlalchemy/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/postgres/sqlalchemy/adapters.py +73 -0
- archipy-3.14.4/archipy/adapters/postgres/sqlalchemy/session_manager_registry.py +112 -0
- archipy-3.14.4/archipy/adapters/postgres/sqlalchemy/session_managers.py +146 -0
- archipy-3.14.4/archipy/adapters/redis/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/redis/adapters.py +2167 -0
- archipy-3.14.4/archipy/adapters/redis/mocks.py +145 -0
- archipy-3.14.4/archipy/adapters/redis/ports.py +2272 -0
- archipy-3.14.4/archipy/adapters/sqlite/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/sqlite/sqlalchemy/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/sqlite/sqlalchemy/adapters.py +73 -0
- archipy-3.14.4/archipy/adapters/sqlite/sqlalchemy/session_manager_registry.py +94 -0
- archipy-3.14.4/archipy/adapters/sqlite/sqlalchemy/session_managers.py +138 -0
- archipy-3.14.4/archipy/adapters/starrocks/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/starrocks/sqlalchemy/__init__.py +0 -0
- archipy-3.14.4/archipy/adapters/starrocks/sqlalchemy/adapters.py +76 -0
- archipy-3.14.4/archipy/adapters/starrocks/sqlalchemy/session_manager_registry.py +114 -0
- archipy-3.14.4/archipy/adapters/starrocks/sqlalchemy/session_managers.py +146 -0
- archipy-3.14.4/archipy/adapters/temporal/__init__.py +16 -0
- archipy-3.14.4/archipy/adapters/temporal/adapters.py +441 -0
- archipy-3.14.4/archipy/adapters/temporal/base.py +591 -0
- archipy-3.14.4/archipy/adapters/temporal/ports.py +364 -0
- archipy-3.14.4/archipy/adapters/temporal/worker.py +471 -0
- archipy-3.14.4/archipy/configs/__init__.py +0 -0
- archipy-3.14.4/archipy/configs/base_config.py +224 -0
- archipy-3.14.4/archipy/configs/config_template.py +880 -0
- archipy-3.14.4/archipy/configs/environment_type.py +94 -0
- archipy-3.14.4/archipy/helpers/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/decorators/__init__.py +38 -0
- archipy-3.14.4/archipy/helpers/decorators/cache.py +65 -0
- archipy-3.14.4/archipy/helpers/decorators/deprecation_exception.py +101 -0
- archipy-3.14.4/archipy/helpers/decorators/deprecation_warnings.py +97 -0
- archipy-3.14.4/archipy/helpers/decorators/retry.py +79 -0
- archipy-3.14.4/archipy/helpers/decorators/singleton.py +80 -0
- archipy-3.14.4/archipy/helpers/decorators/sqlalchemy_atomic.py +375 -0
- archipy-3.14.4/archipy/helpers/decorators/timeout.py +64 -0
- archipy-3.14.4/archipy/helpers/decorators/timing.py +45 -0
- archipy-3.14.4/archipy/helpers/decorators/tracing.py +249 -0
- archipy-3.14.4/archipy/helpers/interceptors/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/fastapi/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/fastapi/rate_limit/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/fastapi/rate_limit/fastapi_rest_rate_limit_handler.py +257 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/base/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/base/client_interceptor.py +299 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/base/server_interceptor.py +205 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/exception/__init__.py +8 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/exception/server_interceptor.py +227 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/metric/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/metric/server_interceptor.py +185 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/trace/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/trace/client_interceptor.py +188 -0
- archipy-3.14.4/archipy/helpers/interceptors/grpc/trace/server_interceptor.py +250 -0
- archipy-3.14.4/archipy/helpers/metaclasses/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/metaclasses/singleton.py +90 -0
- archipy-3.14.4/archipy/helpers/utils/__init__.py +0 -0
- archipy-3.14.4/archipy/helpers/utils/app_utils.py +407 -0
- archipy-3.14.4/archipy/helpers/utils/base_utils.py +148 -0
- archipy-3.14.4/archipy/helpers/utils/datetime_utils.py +358 -0
- archipy-3.14.4/archipy/helpers/utils/error_utils.py +229 -0
- archipy-3.14.4/archipy/helpers/utils/file_utils.py +101 -0
- archipy-3.14.4/archipy/helpers/utils/jwt_utils.py +300 -0
- archipy-3.14.4/archipy/helpers/utils/keycloak_utils.py +606 -0
- archipy-3.14.4/archipy/helpers/utils/password_utils.py +170 -0
- archipy-3.14.4/archipy/helpers/utils/string_utils.py +463 -0
- archipy-3.14.4/archipy/helpers/utils/string_utils_constants.py +277 -0
- archipy-3.14.4/archipy/helpers/utils/totp_utils.py +194 -0
- archipy-3.14.4/archipy/models/__init__.py +0 -0
- archipy-3.14.4/archipy/models/dtos/__init__.py +0 -0
- archipy-3.14.4/archipy/models/dtos/base_dtos.py +24 -0
- archipy-3.14.4/archipy/models/dtos/base_protobuf_dto.py +55 -0
- archipy-3.14.4/archipy/models/dtos/email_dtos.py +71 -0
- archipy-3.14.4/archipy/models/dtos/error_dto.py +71 -0
- archipy-3.14.4/archipy/models/dtos/fastapi_exception_response_dto.py +117 -0
- archipy-3.14.4/archipy/models/dtos/pagination_dto.py +79 -0
- archipy-3.14.4/archipy/models/dtos/range_dtos.py +182 -0
- archipy-3.14.4/archipy/models/dtos/search_input_dto.py +24 -0
- archipy-3.14.4/archipy/models/dtos/sort_dto.py +71 -0
- archipy-3.14.4/archipy/models/entities/__init__.py +29 -0
- archipy-3.14.4/archipy/models/entities/sqlalchemy/__init__.py +27 -0
- archipy-3.14.4/archipy/models/entities/sqlalchemy/base_entities.py +584 -0
- archipy-3.14.4/archipy/models/errors/__init__.py +191 -0
- archipy-3.14.4/archipy/models/errors/auth_errors.py +147 -0
- archipy-3.14.4/archipy/models/errors/base_error.py +344 -0
- archipy-3.14.4/archipy/models/errors/business_errors.py +122 -0
- archipy-3.14.4/archipy/models/errors/database_errors.py +197 -0
- archipy-3.14.4/archipy/models/errors/keycloak_errors.py +176 -0
- archipy-3.14.4/archipy/models/errors/network_errors.py +124 -0
- archipy-3.14.4/archipy/models/errors/resource_errors.py +239 -0
- archipy-3.14.4/archipy/models/errors/system_errors.py +237 -0
- archipy-3.14.4/archipy/models/errors/temporal_errors.py +41 -0
- archipy-3.14.4/archipy/models/errors/validation_errors.py +229 -0
- archipy-3.14.4/archipy/models/types/__init__.py +15 -0
- archipy-3.14.4/archipy/models/types/base_types.py +64 -0
- archipy-3.14.4/archipy/models/types/email_types.py +35 -0
- archipy-3.14.4/archipy/models/types/error_message_types.py +774 -0
- archipy-3.14.4/archipy/models/types/keycloak_error_message_types.py +122 -0
- archipy-3.14.4/archipy/models/types/language_type.py +16 -0
- archipy-3.14.4/archipy/models/types/sort_order_type.py +16 -0
- archipy-3.14.4/archipy/models/types/time_interval_unit_type.py +19 -0
- archipy-3.14.4/docs/api_reference/adapters.md +409 -0
- archipy-3.14.4/docs/api_reference/configs.md +488 -0
- archipy-3.14.4/docs/api_reference/helpers.md +255 -0
- archipy-3.14.4/docs/api_reference/index.md +109 -0
- archipy-3.14.4/docs/api_reference/models.md +474 -0
- archipy-3.14.4/docs/api_reference/utils.md +215 -0
- archipy-3.14.4/docs/architecture.md +793 -0
- archipy-3.14.4/docs/assets/logo.jpg +0 -0
- archipy-3.14.4/docs/changelog.md +2367 -0
- archipy-3.14.4/docs/contributing-docs.md +77 -0
- archipy-3.14.4/docs/contributing.md +164 -0
- archipy-3.14.4/docs/development.md +84 -0
- archipy-3.14.4/docs/examples/adapters/email.md +303 -0
- archipy-3.14.4/docs/examples/adapters/index.md +73 -0
- archipy-3.14.4/docs/examples/adapters/kafka.md +300 -0
- archipy-3.14.4/docs/examples/adapters/keycloak.md +385 -0
- archipy-3.14.4/docs/examples/adapters/minio.md +311 -0
- archipy-3.14.4/docs/examples/adapters/parsian_payment.md +391 -0
- archipy-3.14.4/docs/examples/adapters/postgres.md +208 -0
- archipy-3.14.4/docs/examples/adapters/redis.md +453 -0
- archipy-3.14.4/docs/examples/adapters/sqlite.md +365 -0
- archipy-3.14.4/docs/examples/adapters/starrocks.md +448 -0
- archipy-3.14.4/docs/examples/adapters/temporal.md +632 -0
- archipy-3.14.4/docs/examples/bdd_testing.md +150 -0
- archipy-3.14.4/docs/examples/config_management.md +266 -0
- archipy-3.14.4/docs/examples/error_handling.md +311 -0
- archipy-3.14.4/docs/examples/helpers/decorators.md +294 -0
- archipy-3.14.4/docs/examples/helpers/index.md +15 -0
- archipy-3.14.4/docs/examples/helpers/interceptors.md +145 -0
- archipy-3.14.4/docs/examples/helpers/metaclasses.md +400 -0
- archipy-3.14.4/docs/examples/helpers/utils.md +274 -0
- archipy-3.14.4/docs/examples/index.md +62 -0
- archipy-3.14.4/docs/examples/models/protobuf_dtos.md +468 -0
- archipy-3.14.4/docs/features.md +83 -0
- archipy-3.14.4/docs/index.md +37 -0
- archipy-3.14.4/docs/installation.md +119 -0
- archipy-3.14.4/docs/license.md +5 -0
- archipy-3.14.4/docs/mkdocs-fast.yml +34 -0
- archipy-3.14.4/docs/mkdocs-full.yml +32 -0
- archipy-3.14.4/docs/mkdocs.yml +164 -0
- archipy-3.14.4/docs/source/requirements.txt +6 -0
- archipy-3.14.4/docs/usage.md +197 -0
- archipy-3.14.4/features/app_utils.feature +26 -0
- archipy-3.14.4/features/atomic_transactions.feature +63 -0
- archipy-3.14.4/features/base_config.feature +28 -0
- archipy-3.14.4/features/base_utils.feature +43 -0
- archipy-3.14.4/features/custom_exceptions.feature +24 -0
- archipy-3.14.4/features/datetime_utils.feature +80 -0
- archipy-3.14.4/features/elastic_adapter.feature +137 -0
- archipy-3.14.4/features/environment.py +156 -0
- archipy-3.14.4/features/exception_utils.feature +26 -0
- archipy-3.14.4/features/file_utils.feature +30 -0
- archipy-3.14.4/features/jwt_utils.feature +35 -0
- archipy-3.14.4/features/kafka_adapters.feature +38 -0
- archipy-3.14.4/features/keycloak_adapter.feature +297 -0
- archipy-3.14.4/features/minio_adapter.feature +40 -0
- archipy-3.14.4/features/password_utils.feature +37 -0
- archipy-3.14.4/features/redis_mock.feature +86 -0
- archipy-3.14.4/features/scenario_context.py +79 -0
- archipy-3.14.4/features/scenario_context_pool_manager.py +34 -0
- archipy-3.14.4/features/steps/app_utils_steps.py +141 -0
- archipy-3.14.4/features/steps/atomic_transaction_steps.py +1256 -0
- archipy-3.14.4/features/steps/base_config_steps.py +88 -0
- archipy-3.14.4/features/steps/base_utils_steps.py +129 -0
- archipy-3.14.4/features/steps/common_steps.py +81 -0
- archipy-3.14.4/features/steps/custom_exceptions_steps.py +61 -0
- archipy-3.14.4/features/steps/datetime_utils_steps.py +315 -0
- archipy-3.14.4/features/steps/elastic_adapter_steps.py +824 -0
- archipy-3.14.4/features/steps/exception_utils_steps.py +140 -0
- archipy-3.14.4/features/steps/file_utils_steps.py +69 -0
- archipy-3.14.4/features/steps/jwt_utils_steps.py +127 -0
- archipy-3.14.4/features/steps/kafka_adapter_steps.py +255 -0
- archipy-3.14.4/features/steps/keycloak_adapter_steps.py +1716 -0
- archipy-3.14.4/features/steps/minio_adapter_steps.py +208 -0
- archipy-3.14.4/features/steps/password_utils_steps.py +162 -0
- archipy-3.14.4/features/steps/redis_mock_steps.py +626 -0
- archipy-3.14.4/features/steps/string_utils_steps.py +235 -0
- archipy-3.14.4/features/steps/totp_utils_steps.py +99 -0
- archipy-3.14.4/features/string_utils.feature +81 -0
- archipy-3.14.4/features/test_containers.py +547 -0
- archipy-3.14.4/features/test_entity.py +245 -0
- archipy-3.14.4/features/test_entity_factory.py +230 -0
- archipy-3.14.4/features/test_helpers.py +136 -0
- archipy-3.14.4/features/totp_utils.feature +23 -0
- archipy-3.14.4/pyproject.toml +439 -0
- archipy-3.14.4/scripts/__init__.py +0 -0
- archipy-3.14.4/scripts/bump_version.py +146 -0
- archipy-3.14.4/scripts/generate_unreleased_changelog.py +239 -0
- archipy-3.14.4/scripts/project_tree.py +100 -0
- archipy-3.14.4/uv.lock +3316 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Architectural principles and practices for clean, modular, and business-aligned design in ArchiPy
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ArchiPy Cursor IDE Rules for Code Generation
|
|
8
|
+
|
|
9
|
+
## General Guidelines
|
|
10
|
+
|
|
11
|
+
**Small, Behavior-Preserving Steps**: Generate code in small, incremental changes that preserve existing functionality, validated via end-to-end Behave tests.
|
|
12
|
+
|
|
13
|
+
**Clear Naming**: Use descriptive, intention-revealing names for variables, functions, and classes, following Pydantic naming conventions (e.g., CAMEL_CASE for BaseConfig fields) and domain terms (e.g., ParsianShaparakConfig).
|
|
14
|
+
|
|
15
|
+
**No Duplication**: Eliminate duplicated code by extracting shared logic into reusable functions, methods, or Pydantic models in archipy.helpers.utils.
|
|
16
|
+
|
|
17
|
+
**Single Responsibility**: Ensure functions, classes, and Pydantic models have a single, clear purpose. Split large components into smaller units.
|
|
18
|
+
|
|
19
|
+
**Minimize Mutable Data**: Prefer immutable data structures (e.g., frozen=True in BaseDTO) and encapsulate mutable data to limit scope.
|
|
20
|
+
|
|
21
|
+
**Avoid Over-Engineering**: Do not add speculative generality or unnecessary abstractions unless required.
|
|
22
|
+
|
|
23
|
+
**Consistent Formatting**: Follow PEP 8, Black (line length 120 characters), and project-specific style (e.g., Pydantic Field descriptions). Use double quotes for strings.
|
|
24
|
+
|
|
25
|
+
**Modular Design**: Organize code into modules (e.g., archipy.configs, archipy.helpers.utils) to minimize coupling and avoid divergent changes.
|
|
26
|
+
|
|
27
|
+
**Documentation**: Use Pydantic field description attributes and Google-style docstrings for public APIs. Avoid redundant comments.
|
|
28
|
+
|
|
29
|
+
## Python 3.13 Type Hints
|
|
30
|
+
|
|
31
|
+
Use modern Python 3.13 type hints to ensure type safety and IDE support.
|
|
32
|
+
|
|
33
|
+
**Rules**:
|
|
34
|
+
- Use `|` for union types instead of `Union` (e.g., `BaseEntity | None`)
|
|
35
|
+
- Use lowercase built-in types (e.g., `str` not `String`)
|
|
36
|
+
- Use `@override` decorator for interface implementations
|
|
37
|
+
- Use `type` instead of `Type` for class types
|
|
38
|
+
- Use `Any` only for truly dynamic types
|
|
39
|
+
- Avoid `Optional`; use `| None` instead
|
|
40
|
+
- Use `X | Y` in isinstance calls instead of `(X, Y)`
|
|
41
|
+
- Keep type hints simple and readable
|
|
42
|
+
|
|
43
|
+
**Example**:
|
|
44
|
+
```python
|
|
45
|
+
from typing import Any, override
|
|
46
|
+
from uuid import UUID
|
|
47
|
+
|
|
48
|
+
def get_by_uuid(self, entity_type: type, entity_uuid: UUID) -> BaseEntity | None:
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
@override
|
|
52
|
+
async def create(self, entity: BaseEntity) -> BaseEntity | None:
|
|
53
|
+
...
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Exception Handling
|
|
57
|
+
|
|
58
|
+
**Exception Chaining**: Always use `raise ... from exception` to preserve original error context for proper debugging.
|
|
59
|
+
|
|
60
|
+
**Try-Except-Else Pattern**: When the try block returns a value on success, use an else block to make the success path explicit.
|
|
61
|
+
|
|
62
|
+
**Rules**:
|
|
63
|
+
- Preserve original exception context with `from e`
|
|
64
|
+
- Use specific exception types (e.g., `InvalidEntityTypeError`)
|
|
65
|
+
- For type validation, include clear error messages with expected and actual types
|
|
66
|
+
- Use else block to separate exception handling from success path when returning values
|
|
67
|
+
|
|
68
|
+
**Example with else**:
|
|
69
|
+
```python
|
|
70
|
+
try:
|
|
71
|
+
result = session.get(entity_type, entity_uuid)
|
|
72
|
+
except DatabaseQueryError as e:
|
|
73
|
+
raise DatabaseQueryError() from e
|
|
74
|
+
else:
|
|
75
|
+
return result
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Example without else (acceptable)**:
|
|
79
|
+
```python
|
|
80
|
+
try:
|
|
81
|
+
validate_config(config)
|
|
82
|
+
except ValidationError as e:
|
|
83
|
+
logger.error(f"Config validation failed: {e}")
|
|
84
|
+
raise ConfigurationError() from e
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Pydantic Integration
|
|
88
|
+
|
|
89
|
+
**Model Consistency**: Generate Pydantic models inheriting from `BaseModel` or `BaseSettings`, aligning with `BaseDTO` (frozen=True) and `BaseConfig` (env_nested_delimiter="__").
|
|
90
|
+
|
|
91
|
+
**Settings Source Priority**: pyproject.toml → configs.toml → .env → OS env vars → class defaults
|
|
92
|
+
|
|
93
|
+
**Validation Logic**: Use `@model_validator` for complex validation
|
|
94
|
+
|
|
95
|
+
**Secret Handling**: Use `SecretStr` for sensitive fields and avoid exposing in logs
|
|
96
|
+
|
|
97
|
+
**Type Safety**: Use strict typing (Generic, Literal, TypeVar)
|
|
98
|
+
|
|
99
|
+
**Example**:
|
|
100
|
+
```python
|
|
101
|
+
from pydantic import BaseModel, Field, SecretStr, model_validator
|
|
102
|
+
|
|
103
|
+
class ElasticsearchConfig(BaseModel):
|
|
104
|
+
"""Elasticsearch connection configuration."""
|
|
105
|
+
|
|
106
|
+
HOSTS: list[str] = Field(
|
|
107
|
+
default=["http://localhost:9200"],
|
|
108
|
+
description="List of Elasticsearch node URLs",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
@model_validator(mode='after')
|
|
112
|
+
def validate_hosts(self) -> 'ElasticsearchConfig':
|
|
113
|
+
if not self.HOSTS:
|
|
114
|
+
raise ValueError("At least one host required")
|
|
115
|
+
return self
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Architectural Design Patterns
|
|
119
|
+
|
|
120
|
+
### Core Patterns
|
|
121
|
+
|
|
122
|
+
**1. Ports & Adapters**: Define ports in `ports.py`, implement in `adapters.py`, provide `mocks.py`
|
|
123
|
+
|
|
124
|
+
**2. Repository Pattern**: Abstract data access (e.g., PostgresSQLAlchemyAdapter)
|
|
125
|
+
|
|
126
|
+
**3. Unit of Work**: Use atomic decorators (@postgres_sqlalchemy_atomic_decorator)
|
|
127
|
+
|
|
128
|
+
**4. Service Layer**: Orchestrate business logic, keep framework-agnostic
|
|
129
|
+
|
|
130
|
+
**5. Configuration**: Inherit from BaseConfig, use Pydantic Settings
|
|
131
|
+
|
|
132
|
+
**6. Bounded Contexts**: Separate modules by domain (configs/, adapters/, models/, helpers/)
|
|
133
|
+
|
|
134
|
+
### Anti-Patterns to Avoid
|
|
135
|
+
- ❌ Tight coupling between adapters and business logic
|
|
136
|
+
- ❌ Framework-dependent domain models
|
|
137
|
+
- ❌ Configuration scattered across files
|
|
138
|
+
- ❌ Circular dependencies
|
|
139
|
+
- ❌ Excessive mocks in tests (prefer real implementations)
|
|
140
|
+
|
|
141
|
+
## BDD Testing with Behave
|
|
142
|
+
|
|
143
|
+
**Gherkin Scenarios**: Generate .feature files in features/ mapping to steps/
|
|
144
|
+
|
|
145
|
+
**Test Philosophy**:
|
|
146
|
+
- End-to-end focus at architectural boundaries
|
|
147
|
+
- Minimize mocks, prefer testcontainers
|
|
148
|
+
- Test behavior, not implementation
|
|
149
|
+
- Independent, isolated scenarios
|
|
150
|
+
|
|
151
|
+
**Running Tests**:
|
|
152
|
+
- All: `make behave`
|
|
153
|
+
- Single: `uv run --extra behave behave features/file_name.feature`
|
|
154
|
+
- Scenario: `uv run --extra behave behave features/file_name.feature:line_number`
|
|
155
|
+
|
|
156
|
+
## MyPy Compliance
|
|
157
|
+
|
|
158
|
+
**Strict Mode**: disallow_untyped_defs, disallow_untyped_calls, strict_optional, warn_return_any
|
|
159
|
+
|
|
160
|
+
**Pragmatic Overrides**: Allow Any for untyped third-party libs (confluent_kafka, zeep, minio), dynamic adapters (Redis, Keycloak, gRPC, Temporal), decorators, protobuf
|
|
161
|
+
|
|
162
|
+
**Type Annotations**: Explicit for all parameters, return types, variables
|
|
163
|
+
|
|
164
|
+
**Pydantic Plugin**: Enabled for proper model type checking
|
|
165
|
+
|
|
166
|
+
## Ruff Compliance
|
|
167
|
+
|
|
168
|
+
**Target**: Python 3.13, line length 120
|
|
169
|
+
|
|
170
|
+
**Enabled Rules**:
|
|
171
|
+
- A: flake8-builtins
|
|
172
|
+
- ANN: flake8-annotations
|
|
173
|
+
- ASYNC: flake8-async
|
|
174
|
+
- B: flake8-bugbear
|
|
175
|
+
- D: pydocstyle (Google-style, except D100, D104, D107)
|
|
176
|
+
- E/W: pycodestyle (except E501)
|
|
177
|
+
- ERA: eradicate
|
|
178
|
+
- F: pyflakes (except F811 in steps)
|
|
179
|
+
- G: logging (allow G004 f-strings)
|
|
180
|
+
- I: isort (future → stdlib → third-party → first-party → local)
|
|
181
|
+
- RUF: Ruff rules (except RUF001/RUF003 for Persian)
|
|
182
|
+
- S: Bandit (allow S101 assert, S301/S403 pickle)
|
|
183
|
+
- TRY: tryceratops (except TRY003, TRY301)
|
|
184
|
+
- UP: pyupgrade
|
|
185
|
+
|
|
186
|
+
**Ignored**:
|
|
187
|
+
- BLE001: Allow Exception in adapters
|
|
188
|
+
- C901: McCabe max 10
|
|
189
|
+
- F811: Redefinition in steps
|
|
190
|
+
- G004: f-strings in logging
|
|
191
|
+
|
|
192
|
+
## Development Tools
|
|
193
|
+
|
|
194
|
+
**Package Management**: `uv sync --all-extras --all-groups` or `make install-dev`
|
|
195
|
+
|
|
196
|
+
**Workflow**:
|
|
197
|
+
- Format: `make format` (Black, 120 chars)
|
|
198
|
+
- Lint: `make lint` (Ruff + MyPy)
|
|
199
|
+
- Test: `make behave`
|
|
200
|
+
- Security: `make security` (Bandit)
|
|
201
|
+
- All checks: `make check`
|
|
202
|
+
- Pre-commit: `make pre-commit`
|
|
203
|
+
|
|
204
|
+
**Documentation**: `make docs-serve`, `make docs-build`, `make docs-deploy`
|
|
205
|
+
|
|
206
|
+
## Version Control
|
|
207
|
+
|
|
208
|
+
**Commit Format**: Conventional Commits (feat:, fix:, refactor:, docs:, test:, chore:)
|
|
209
|
+
|
|
210
|
+
**Workflow**:
|
|
211
|
+
1. Feature branch from master
|
|
212
|
+
2. Incremental changes with tests
|
|
213
|
+
3. Run `make check`
|
|
214
|
+
4. Run `make pre-commit`
|
|
215
|
+
5. Commit with conventional message
|
|
216
|
+
6. Create PR
|
|
217
|
+
|
|
218
|
+
**Version Bump**: `make bump-patch/minor/major message="description"`
|
|
219
|
+
|
|
220
|
+
**ADRs**: Create for significant changes in docs/adr/
|
|
221
|
+
|
|
222
|
+
## Documentation Standards
|
|
223
|
+
|
|
224
|
+
- Google-style docstrings for public APIs
|
|
225
|
+
- Pydantic Field descriptions
|
|
226
|
+
- Type hints as inline documentation
|
|
227
|
+
- Avoid redundant comments
|
|
228
|
+
- Examples in docs/examples/ with real code
|
|
229
|
+
- API reference auto-generated from docstrings
|
|
230
|
+
|
|
231
|
+
## AI Code Generation
|
|
232
|
+
|
|
233
|
+
### Context Awareness
|
|
234
|
+
|
|
235
|
+
Read before generating:
|
|
236
|
+
- archipy/configs/base_config.py
|
|
237
|
+
- archipy/models/dtos/base_dtos.py
|
|
238
|
+
- archipy/helpers/utils/base_utils.py
|
|
239
|
+
- Existing adapter implementations
|
|
240
|
+
- pyproject.toml for dependencies and config
|
|
241
|
+
|
|
242
|
+
### Principles
|
|
243
|
+
|
|
244
|
+
1. Start small, iterate
|
|
245
|
+
2. Follow existing patterns exactly
|
|
246
|
+
3. Type safety first
|
|
247
|
+
4. Test-driven (update .feature files)
|
|
248
|
+
5. No API invention - use what exists or ask
|
|
249
|
+
6. Explain decisions with rule references
|
|
250
|
+
|
|
251
|
+
### New Adapter Workflow
|
|
252
|
+
|
|
253
|
+
1. Create ports.py with interface
|
|
254
|
+
2. Implement adapters.py
|
|
255
|
+
3. Provide mocks.py
|
|
256
|
+
4. Add config class
|
|
257
|
+
5. Create .feature file
|
|
258
|
+
6. Implement steps
|
|
259
|
+
7. Update docs/examples/adapters/
|
|
260
|
+
|
|
261
|
+
### Error Recovery
|
|
262
|
+
|
|
263
|
+
- Fix linter errors immediately
|
|
264
|
+
- Analyze test failures, suggest fixes
|
|
265
|
+
- Ask if uncertain
|
|
266
|
+
|
|
267
|
+
### Proactive Behavior
|
|
268
|
+
|
|
269
|
+
- Identify code smells
|
|
270
|
+
- Suggest architectural improvements
|
|
271
|
+
- Point out security issues
|
|
272
|
+
- Reference rules when explaining choices
|
|
273
|
+
|
|
274
|
+
### Large Refactorings
|
|
275
|
+
|
|
276
|
+
- Break into small steps
|
|
277
|
+
- Ensure BaseConfig/BaseDTO consistency
|
|
278
|
+
- Test after each step
|
|
279
|
+
- Commit incrementally
|
|
280
|
+
|
|
281
|
+
## Summary Checklist
|
|
282
|
+
|
|
283
|
+
Before completing tasks, verify:
|
|
284
|
+
|
|
285
|
+
- ✅ Python 3.13 type hints with `|` unions
|
|
286
|
+
- ✅ Line length ≤ 120 characters
|
|
287
|
+
- ✅ Google-style docstrings for public APIs
|
|
288
|
+
- ✅ Pydantic Field descriptions
|
|
289
|
+
- ✅ Exception chaining with `raise ... from e`
|
|
290
|
+
- ✅ Ruff and MyPy compliant
|
|
291
|
+
- ✅ Behave tests created/updated
|
|
292
|
+
- ✅ Documentation updated
|
|
293
|
+
- ✅ Conventional Commits message ready
|
|
294
|
+
- ✅ No linter errors
|
|
295
|
+
- ✅ No security issues
|
|
296
|
+
- ✅ Tests pass
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# CMake
|
|
2
|
+
cmake-build-*/
|
|
3
|
+
|
|
4
|
+
# File-based project format
|
|
5
|
+
*.iws
|
|
6
|
+
|
|
7
|
+
# IntelliJ
|
|
8
|
+
out/
|
|
9
|
+
|
|
10
|
+
# mpeltonen/sbt-idea plugin
|
|
11
|
+
.idea_modules/
|
|
12
|
+
|
|
13
|
+
# JIRA plugin
|
|
14
|
+
atlassian-ide-plugin.xml
|
|
15
|
+
|
|
16
|
+
# Cursive Clojure plugin
|
|
17
|
+
.idea/replstate.xml
|
|
18
|
+
|
|
19
|
+
# SonarLint plugin
|
|
20
|
+
.idea/sonarlint/
|
|
21
|
+
|
|
22
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
23
|
+
com_crashlytics_export_strings.xml
|
|
24
|
+
crashlytics.properties
|
|
25
|
+
crashlytics-build.properties
|
|
26
|
+
fabric.properties
|
|
27
|
+
|
|
28
|
+
# Editor-based Rest Client
|
|
29
|
+
.idea/httpRequests
|
|
30
|
+
|
|
31
|
+
# Android studio 3.1+ serialized cache file
|
|
32
|
+
.idea/caches/build_file_checksums.ser
|
|
33
|
+
|
|
34
|
+
### Python template
|
|
35
|
+
# Byte-compiled / optimized / DLL files
|
|
36
|
+
__pycache__/
|
|
37
|
+
*.py[cod]
|
|
38
|
+
*$py.class
|
|
39
|
+
|
|
40
|
+
# C extensions
|
|
41
|
+
*.so
|
|
42
|
+
|
|
43
|
+
# Distribution / packaging
|
|
44
|
+
.Python
|
|
45
|
+
build/
|
|
46
|
+
develop-eggs/
|
|
47
|
+
dist/
|
|
48
|
+
downloads/
|
|
49
|
+
eggs/
|
|
50
|
+
.eggs/
|
|
51
|
+
lib/
|
|
52
|
+
lib64/
|
|
53
|
+
parts/
|
|
54
|
+
sdist/
|
|
55
|
+
var/
|
|
56
|
+
wheels/
|
|
57
|
+
share/python-wheels/
|
|
58
|
+
*.egg-info/
|
|
59
|
+
.installed.cfg
|
|
60
|
+
*.egg
|
|
61
|
+
MANIFEST
|
|
62
|
+
|
|
63
|
+
# PyInstaller
|
|
64
|
+
# Usually these files are written by a python script from a template
|
|
65
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
66
|
+
*.manifest
|
|
67
|
+
*.spec
|
|
68
|
+
|
|
69
|
+
# Installer logs
|
|
70
|
+
pip-log.txt
|
|
71
|
+
pip-delete-this-directory.txt
|
|
72
|
+
|
|
73
|
+
# Unit test / coverage reports
|
|
74
|
+
htmlcov/
|
|
75
|
+
.tox/
|
|
76
|
+
.nox/
|
|
77
|
+
.coverage
|
|
78
|
+
.coverage.*
|
|
79
|
+
.cache
|
|
80
|
+
nosetests.xml
|
|
81
|
+
coverage.xml
|
|
82
|
+
*.cover
|
|
83
|
+
*.py,cover
|
|
84
|
+
.hypothesis/
|
|
85
|
+
.pytest_cache/
|
|
86
|
+
cover/
|
|
87
|
+
|
|
88
|
+
# Translations
|
|
89
|
+
*.mo
|
|
90
|
+
*.pot
|
|
91
|
+
|
|
92
|
+
# Django stuff:
|
|
93
|
+
*.log
|
|
94
|
+
local_settings.py
|
|
95
|
+
db.sqlite3
|
|
96
|
+
db.sqlite3-journal
|
|
97
|
+
|
|
98
|
+
# Flask stuff:
|
|
99
|
+
instance/
|
|
100
|
+
.webassets-cache
|
|
101
|
+
|
|
102
|
+
# Scrapy stuff:
|
|
103
|
+
.scrapy
|
|
104
|
+
|
|
105
|
+
# Sphinx documentation
|
|
106
|
+
docs/_build/
|
|
107
|
+
|
|
108
|
+
# PyBuilder
|
|
109
|
+
.pybuilder/
|
|
110
|
+
target/
|
|
111
|
+
|
|
112
|
+
# Jupyter Notebook
|
|
113
|
+
.ipynb_checkpoints
|
|
114
|
+
|
|
115
|
+
# IPython
|
|
116
|
+
profile_default/
|
|
117
|
+
ipython_config.py
|
|
118
|
+
|
|
119
|
+
# poetry
|
|
120
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
121
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
122
|
+
# commonly ignored for libraries.
|
|
123
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
124
|
+
#poetry.lock
|
|
125
|
+
|
|
126
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
127
|
+
__pypackages__/
|
|
128
|
+
|
|
129
|
+
# Celery stuff
|
|
130
|
+
celerybeat-schedule
|
|
131
|
+
celerybeat.pid
|
|
132
|
+
|
|
133
|
+
# SageMath parsed files
|
|
134
|
+
*.sage.py
|
|
135
|
+
|
|
136
|
+
# Environments
|
|
137
|
+
.env
|
|
138
|
+
.venv
|
|
139
|
+
env/
|
|
140
|
+
venv/
|
|
141
|
+
ENV/
|
|
142
|
+
env.bak/
|
|
143
|
+
venv.bak/
|
|
144
|
+
|
|
145
|
+
# Spyder project settings
|
|
146
|
+
.spyderproject
|
|
147
|
+
.spyproject
|
|
148
|
+
|
|
149
|
+
# Rope project settings
|
|
150
|
+
.ropeproject
|
|
151
|
+
|
|
152
|
+
# mkdocs documentation
|
|
153
|
+
/site
|
|
154
|
+
|
|
155
|
+
# mypy
|
|
156
|
+
.mypy_cache/
|
|
157
|
+
.dmypy.json
|
|
158
|
+
dmypy.json
|
|
159
|
+
|
|
160
|
+
# Pyre type checker
|
|
161
|
+
.pyre/
|
|
162
|
+
|
|
163
|
+
# pytype static type analyzer
|
|
164
|
+
.pytype/
|
|
165
|
+
|
|
166
|
+
# Cython debug symbols
|
|
167
|
+
cython_debug/
|
|
168
|
+
|
|
169
|
+
# PyCharm
|
|
170
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
171
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
172
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
173
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
174
|
+
.idea/
|