fastapi-modular 0.2.0__tar.gz → 0.3.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.
- fastapi_modular-0.3.0/CHANGELOG.md +212 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/LICENSE +1 -1
- fastapi_modular-0.3.0/PKG-INFO +564 -0
- fastapi_modular-0.3.0/README.md +494 -0
- fastapi_modular-0.2.0/PKG-INFO → fastapi_modular-0.3.0/README.vi.md +189 -78
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/README.md +8 -4
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/architecture.md +49 -6
- fastapi_modular-0.3.0/docs/background.md +872 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/config.md +17 -1
- fastapi_modular-0.3.0/docs/database.md +2307 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/kafka.md +75 -29
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/migrations.md +13 -1
- fastapi_modular-0.3.0/docs/mongodb.md +540 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/mqtt.md +59 -27
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/operations.md +15 -2
- fastapi_modular-0.3.0/docs/providers.md +471 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/rabbitmq.md +339 -15
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/redis.md +55 -18
- fastapi_modular-0.3.0/docs/rpc.md +487 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/docs/websocket.md +368 -223
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/__init__.py +32 -1
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/clean.py +16 -16
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/configure_env.py +152 -129
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/info.py +21 -21
- fastapi_modular-0.3.0/fastapi_modular/cli/install.py +110 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/main.py +87 -74
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/new_module.py +11 -9
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/new_project.py +81 -50
- fastapi_modular-0.3.0/fastapi_modular/cli/new_provider.py +220 -0
- fastapi_modular-0.3.0/fastapi_modular/cli/requirements.py +162 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/serve.py +10 -10
- fastapi_modular-0.2.0/fastapi_modular/cli/cong_cu.py → fastapi_modular-0.3.0/fastapi_modular/cli/tools.py +34 -34
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/config.py +166 -12
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/container.py +50 -5
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/controller.py +27 -2
- fastapi_modular-0.3.0/fastapi_modular/core/cron.py +227 -0
- fastapi_modular-0.3.0/fastapi_modular/core/events.py +518 -0
- fastapi_modular-0.3.0/fastapi_modular/core/jobs.py +377 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/lifespan.py +83 -4
- fastapi_modular-0.3.0/fastapi_modular/core/locks.py +215 -0
- fastapi_modular-0.3.0/fastapi_modular/core/providers.py +300 -0
- fastapi_modular-0.3.0/fastapi_modular/core/rpc.py +445 -0
- fastapi_modular-0.3.0/fastapi_modular/core/scheduler.py +525 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/gateway.py +2 -2
- fastapi_modular-0.3.0/fastapi_modular/core/workers.py +791 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/discovery.py +3 -3
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/factory.py +19 -6
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/database/__init__.py +53 -0
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/database/base.py +469 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/database/circuit.py +10 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/database/factory.py +5 -2
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/database/memory.py +416 -0
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/database/mongo.py +468 -0
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/database/query.py +1843 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/database/repository.py +64 -2
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/database/sql.py +423 -14
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/kafka/__init__.py +8 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/kafka/broker.py +165 -3
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/kafka/consumers.py +19 -19
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/kafka/responders.py +372 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/mqtt/__init__.py +8 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/mqtt/client.py +124 -28
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/mqtt/consumers.py +9 -9
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/mqtt/patterns.py +31 -31
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/mqtt/responders.py +236 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/rabbitmq/__init__.py +8 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/rabbitmq/broker.py +408 -21
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/rabbitmq/consumers.py +78 -25
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/rabbitmq/patterns.py +159 -0
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/rabbitmq/responders.py +398 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/redis/__init__.py +8 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/redis/client.py +195 -40
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/redis/pubsub.py +23 -23
- fastapi_modular-0.3.0/fastapi_modular/infrastructure/redis/responders.py +280 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/pyproject.toml +19 -5
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/entities/device_model.py +2 -2
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/health/health_controller.py +2 -2
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/kafka_test/kafka_consumer.py +9 -9
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/kafka_test/kafka_controller.py +2 -2
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/mqtt_test/mqtt_controller.py +2 -2
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/mqtt_test/mqtt_listener.py +5 -5
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/rabbitmq_test/rabbitmq_consumer.py +5 -5
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/rabbitmq_test/rabbitmq_controller.py +3 -3
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/redis_test/redis_controller.py +11 -11
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/redis_test/redis_listener.py +7 -7
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/entities/user_model.py +2 -2
- fastapi_modular-0.3.0/tests/fixtures/cron_vectors.json +1802 -0
- fastapi_modular-0.3.0/tests/fixtures/nestjs_patterns.json +2605 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_cli.py +171 -86
- fastapi_modular-0.3.0/tests/test_configure_env.py +241 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_container.py +3 -3
- fastapi_modular-0.3.0/tests/test_controller_dong_bo.py +266 -0
- fastapi_modular-0.3.0/tests/test_cron.py +130 -0
- fastapi_modular-0.3.0/tests/test_enum_parity.py +121 -0
- fastapi_modular-0.3.0/tests/test_events.py +357 -0
- fastapi_modular-0.3.0/tests/test_foreign_keys.py +492 -0
- fastapi_modular-0.3.0/tests/test_injection.py +171 -0
- fastapi_modular-0.3.0/tests/test_jobs.py +265 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_kafka.py +50 -12
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_kafka_offline.py +72 -3
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_lifespan_rieng.py +3 -3
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_metrics.py +2 -2
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_module_generator.py +1 -0
- fastapi_modular-0.3.0/tests/test_mongo_query.py +277 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_mqtt.py +76 -14
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_mqtt_offline.py +50 -4
- fastapi_modular-0.3.0/tests/test_providers.py +482 -0
- fastapi_modular-0.3.0/tests/test_query_builder.py +1628 -0
- fastapi_modular-0.3.0/tests/test_rabbitmq.py +598 -0
- fastapi_modular-0.3.0/tests/test_rabbitmq_offline.py +715 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_redis.py +83 -14
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_redis_offline.py +59 -2
- fastapi_modular-0.3.0/tests/test_requirements_ghi_nho.py +259 -0
- fastapi_modular-0.3.0/tests/test_rpc.py +208 -0
- fastapi_modular-0.3.0/tests/test_scheduler.py +316 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_schema_evolution.py +24 -4
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_settings_mo_rong.py +8 -8
- fastapi_modular-0.3.0/tests/test_sqlite_pragmas.py +302 -0
- fastapi_modular-0.3.0/tests/test_transaction.py +279 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_tuong_thich_phien_ban.py +5 -5
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_uniqueness.py +2 -2
- fastapi_modular-0.3.0/tests/test_workers.py +534 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_ws_adapter.py +9 -9
- fastapi_modular-0.2.0/CHANGELOG.md +0 -58
- fastapi_modular-0.2.0/README.md +0 -314
- fastapi_modular-0.2.0/docs/database.md +0 -703
- fastapi_modular-0.2.0/fastapi_modular/cli/install.py +0 -83
- fastapi_modular-0.2.0/fastapi_modular/infrastructure/database/__init__.py +0 -8
- fastapi_modular-0.2.0/fastapi_modular/infrastructure/database/base.py +0 -228
- fastapi_modular-0.2.0/fastapi_modular/infrastructure/database/memory.py +0 -112
- fastapi_modular-0.2.0/fastapi_modular/infrastructure/database/mongo.py +0 -186
- fastapi_modular-0.2.0/fastapi_modular/infrastructure/rabbitmq/patterns.py +0 -64
- fastapi_modular-0.2.0/tests/test_configure_env.py +0 -187
- fastapi_modular-0.2.0/tests/test_rabbitmq.py +0 -236
- fastapi_modular-0.2.0/tests/test_rabbitmq_offline.py +0 -273
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/.gitignore +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/Makefile +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/alembic.ini +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/cli/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/clock.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/compat.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/context.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/error_handlers.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/exceptions.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/guards.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/logging.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/metrics.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/schemas.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/adapter.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/namespace.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/protocol.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/server.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/core/websocket/socket.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/kafka/metrics.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/mqtt/metrics.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/rabbitmq/metrics.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/infrastructure/redis/metrics.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/middleware/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/middleware/request_context.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/fastapi_modular/py.typed +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/migrations/env.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/migrations/script.py.mako +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/migrations/versions/.gitkeep +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/migrations/versions/20260821_1020_tao_bang_users_va_devices.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/pytest.ini +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/ruff.toml +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/chat/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/chat/chat_controller.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/chat/chat_gateway.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/chat/dto/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/chat/dto/chat_dto.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/device_controller.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/device_service.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/dto/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/dto/device_dto.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/devices/entities/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/health/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/kafka_test/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/metrics/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/metrics/metrics_controller.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/mqtt_test/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/rabbitmq_test/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/redis_test/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/dto/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/dto/user_dto.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/entities/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/user_controller.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/api/users/user_service.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/core/__init__.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/core/config.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/core/lifespan.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/src/main.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/conftest.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_circuit.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_cross_module.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_database.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_drivers.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_guards.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_ha_tang_that.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_health.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_resilience.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_schemas.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_users_api.py +0 -0
- {fastapi_modular-0.2.0 → fastapi_modular-0.3.0}/tests/test_websocket.py +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Thay đổi
|
|
2
|
+
|
|
3
|
+
Theo [Keep a Changelog](https://keepachangelog.com/vi/1.1.0/); phiên bản theo
|
|
4
|
+
[SemVer](https://semver.org/lang/vi/).
|
|
5
|
+
|
|
6
|
+
## [Chưa phát hành]
|
|
7
|
+
|
|
8
|
+
## [0.3.0] — 2026-08-27
|
|
9
|
+
|
|
10
|
+
Bản này thêm **query builder** (JOIN, khoá ngoại, transaction, dữ liệu lồng
|
|
11
|
+
nhau), **việc chạy nền** (`@worker`, `@interval`, `@cron`, `@job`, `@on_event`),
|
|
12
|
+
**RPC gửi-rồi-chờ-trả-lời** cho cả bốn hạ tầng, và **provider cắm được**.
|
|
13
|
+
|
|
14
|
+
Nâng cấp từ 0.2.x cần sửa ba chỗ, xem mục "Thay đổi phá vỡ" ở cuối.
|
|
15
|
+
|
|
16
|
+
### Thêm
|
|
17
|
+
|
|
18
|
+
- **Provider cắm được** — chọn bản hiện thực bằng TÊN lúc chạy, thứ mà container
|
|
19
|
+
(tra theo kiểu) không làm được: cổng thanh toán lấy từ cột trong đơn hàng, nhà
|
|
20
|
+
mạng SMS lấy từ cấu hình, hãng camera lấy từ bản ghi thiết bị.
|
|
21
|
+
|
|
22
|
+
Dùng đúng khuôn `Repository[User]` — service khai **năng lực** nó cần:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
def __init__(self, payments: Providers[PaymentGateway]) -> None: ...
|
|
26
|
+
|
|
27
|
+
cong = self._payments.get(don.cong_thanh_toan) # -> PaymentGateway
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Thêm bản hiện thực mới = thả một file mang `@provider("tên")` vào
|
|
31
|
+
`src/providers/<họ>/`. Không sửa service, không sửa `main.py`.
|
|
32
|
+
|
|
33
|
+
`get()` trả 404 nếu không có tên, **501** nếu có tên nhưng thiếu năng lực —
|
|
34
|
+
Hik không mở được cửa thì đó không phải bug của server. `names()` chỉ liệt kê
|
|
35
|
+
provider làm được việc của sổ đó. Xem `docs/providers.md`, trong đó có mục
|
|
36
|
+
"Viết năng lực cho dễ bảo trì": khi nào tách `capabilities.py` thành package,
|
|
37
|
+
và ba nguyên tắc đặt tên / chia nhỏ interface.
|
|
38
|
+
|
|
39
|
+
- **`fam provider <họ> <tên>`** — sinh khung. Lần đầu dựng cả họ; lần sau đọc
|
|
40
|
+
`capabilities.py` rồi sinh sẵn stub đúng chữ ký các method cần viết.
|
|
41
|
+
|
|
42
|
+
- **`container.build(cls, key=..., scope=...)`** — dựng một lớp có nối phụ thuộc
|
|
43
|
+
mà KHÔNG đăng ký vào sổ toàn cục. Cần cho provider: sổ toàn cục tra theo tên
|
|
44
|
+
class, trong khi hai họ có quyền cùng có một `OryzaProvider`.
|
|
45
|
+
|
|
46
|
+
### Thay đổi
|
|
47
|
+
|
|
48
|
+
- `fam p` giờ **nhập nhằng** giữa `publish` và `provider` nên `fam` hỏi lại. Viết
|
|
49
|
+
tắt mới: `fam pu` cho publish, `fam pr` cho provider.
|
|
50
|
+
- `create_app()` và `src/main.py` sinh sẵn gọi `register_providers()` trước khi
|
|
51
|
+
dựng route. Không có `src/providers/` thì bỏ qua, không lỗi.
|
|
52
|
+
|
|
53
|
+
### Thêm — query builder
|
|
54
|
+
|
|
55
|
+
- **`repo.query()`** sinh SQL thật: `join` / `left_join` / `right_join` /
|
|
56
|
+
`outer_join`, `where` nối tiếp là AND còn `or_where` mở nhánh OR, `group_by` +
|
|
57
|
+
`having`, `limit` / `offset` / `distinct`. Xem câu sinh ra bằng `.sql()`.
|
|
58
|
+
- **Toán tử thường trên cột**: `Camera.score >= 0.9` thay cho `score__gte=0.9`,
|
|
59
|
+
nhờ `class Camera(Entity)`. Bảy toán tử không có ký hiệu (`like`, `ilike`,
|
|
60
|
+
`in_`, `not_in`, `is_null`, `is_not_null`, `between`) có cả ở dạng method của
|
|
61
|
+
builder — `query().like(...)` — để IDE gợi ý được.
|
|
62
|
+
- **Khoá ngoại**: `field(metadata=reference(Camera, on_delete="CASCADE"))`, đủ
|
|
63
|
+
bốn hành vi `CASCADE` / `SET NULL` / `SET DEFAULT` / `RESTRICT`. Áp bởi chính
|
|
64
|
+
database với SQL; khung tự áp cho `memory` và `mongodb` để ba backend cùng
|
|
65
|
+
kết quả.
|
|
66
|
+
- **Transaction**: `async with db.transaction() as tx:` — khối lồng nhau thành
|
|
67
|
+
SAVEPOINT, `await tx.rollback()` huỷ mà không phải ném lỗi. HTTP handler đã
|
|
68
|
+
nằm sẵn trong một transaction của cả request.
|
|
69
|
+
- **Dữ liệu lồng nhau**: `include(X)` khai X trả về những cột nào,
|
|
70
|
+
`nest_under(A, B, C)` khai thứ tự lồng từ NGOÀI vào TRONG. Mỗi mức đúng một
|
|
71
|
+
câu lệnh, không phải một câu cho mỗi dòng.
|
|
72
|
+
- **`select(...)`** gộp cả `fields=` / `exclude=` / `rename=` / `add=`.
|
|
73
|
+
- **MongoDB** chạy được phần lớn builder (`docs/mongodb.md` liệt kê cái không có:
|
|
74
|
+
JOIN, `group_by`, `distinct`, transaction).
|
|
75
|
+
- **Chặn injection ở tầng dùng chung**: giá trị mang toán tử (`{"$ne": ""}` —
|
|
76
|
+
qua được cửa đăng nhập trên Mongo), khoá `$where` chạy JavaScript, và tên cột
|
|
77
|
+
không có thật (SQL trước đây âm thầm bỏ điều kiện, trả về cả bảng).
|
|
78
|
+
- **Soi khoá ngoại lúc khởi động** (`db.foreign_keys_stale`): thêm
|
|
79
|
+
`reference(...)` vào entity đã chạy rồi thì database không biết — cascade
|
|
80
|
+
dừng giữa chừng, cháu ở lại thành mồ côi, không lỗi không cảnh báo.
|
|
81
|
+
|
|
82
|
+
### Thêm — việc chạy nền
|
|
83
|
+
|
|
84
|
+
- `@worker` (vòng lặp sống mãi, N bản, mỗi bản một tham số), `@interval` /
|
|
85
|
+
`@cron` / `@timeout` (theo lịch), `@job` (hàng đợi trong tiến trình),
|
|
86
|
+
`@on_event` + `EventBus` (fanout trong tiến trình). Cả bốn nhận `thread=True`
|
|
87
|
+
cho hàm chặn, và `ctx: WorkerContext` để dừng đúng cách.
|
|
88
|
+
- Khoá `flock` / Redis để nhiều worker không cùng chạy một việc định kỳ.
|
|
89
|
+
|
|
90
|
+
### Thêm — RPC và hạ tầng
|
|
91
|
+
|
|
92
|
+
- **`emit` / `send` + `@*_responder`** cho RabbitMQ, Redis, MQTT, Kafka — khuôn
|
|
93
|
+
tin tương thích `@nestjs/microservices`, đã chạy đối chứng hai chiều với
|
|
94
|
+
NestJS 11.2.1.
|
|
95
|
+
- RabbitMQ: đủ 5 kiểu exchange, 3 dạng hạn dùng (TTL), `emit_many`.
|
|
96
|
+
- SQLite: mặc định WAL + `synchronous=NORMAL` — đo được nhanh gấp 20 lần
|
|
97
|
+
(68 → 1.269 ghi/s) mà vẫn không hỏng file khi mất điện.
|
|
98
|
+
|
|
99
|
+
### Thêm — CLI
|
|
100
|
+
|
|
101
|
+
- **`fam install` ghi nhớ thành phần vào `requirements.txt`**
|
|
102
|
+
(`fastapi-modular[redis,sqlite]>=0.3.0`), để người clone repo về chỉ cần
|
|
103
|
+
`pip install -r requirements.txt`. `fam init` sinh sẵn file này. Dự án dùng
|
|
104
|
+
`pyproject.toml` đã khai fastapi-modular thì sửa ngay dòng đó. `fam install
|
|
105
|
+
dev` đi vào `requirements-dev.txt`.
|
|
106
|
+
- `fam module` sinh entity kế thừa `Entity`.
|
|
107
|
+
|
|
108
|
+
### Sửa
|
|
109
|
+
|
|
110
|
+
- **Controller viết `def` thường** nổ `TypeError: object dict can't be used in
|
|
111
|
+
'await' expression`. Khung bọc mọi method thành endpoint async rồi await
|
|
112
|
+
thẳng, nên mất luôn luật của FastAPI: `def` phải chạy ở thread pool. Guard
|
|
113
|
+
đồng bộ cũng nổ y hệt. Đo lại sau khi sửa: 4 request chặn 0,3s xong trong
|
|
114
|
+
0,31s.
|
|
115
|
+
- **`fam install` chạy trước `fam init`** chỉ ghi khối database vào `.env`,
|
|
116
|
+
thiếu sạch `APP_NAME` / `APP_ENV` / `APP_DEBUG` / `APP_HOST` / `APP_PORT` —
|
|
117
|
+
app chạy bằng toàn giá trị mặc định, im lặng.
|
|
118
|
+
- **Lọc bằng `Enum` thường** (không phải `StrEnum`) chạy trên `memory` nhưng nổ
|
|
119
|
+
trên sqlite lẫn mongo. Chiều ngược lại cũng lệch: lọc bằng chuỗi `.value` thì
|
|
120
|
+
SQL khớp còn memory trượt.
|
|
121
|
+
- **`nest_under` + sắp theo cột của một lớp**: sqlite ném lỗi, memory và mongo
|
|
122
|
+
lặng lẽ bỏ qua.
|
|
123
|
+
- **Lồng ba tầng từ repo trong cùng**: `include(Camera)` ném lỗi dù chuỗi
|
|
124
|
+
`nest_under` nối được qua bảng giữa.
|
|
125
|
+
- **`include(X, name=...)`** bị bỏ qua khi X nằm trong chuỗi `nest_under`.
|
|
126
|
+
- **Hai transaction `memory` đồng thời**: task rollback cuốn luôn bản ghi task
|
|
127
|
+
khác vừa commit.
|
|
128
|
+
- **MongoDB cho ghi con trỏ tới cha không tồn tại**, trong khi SQL và memory từ
|
|
129
|
+
chối 409.
|
|
130
|
+
- `Ctrl+C` không thoát được khi có worker đang chạy; `@worker(thread=True)` mượn
|
|
131
|
+
pool dùng chung của event loop nên làm treo cả tiến trình.
|
|
132
|
+
|
|
133
|
+
### Thay đổi phá vỡ
|
|
134
|
+
|
|
135
|
+
| 0.2.x | 0.3.0 |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `.order_by("score")` | `.order_by_desc("score")` / `.order_by_asc("score")` — chiều nằm trong TÊN HÀM |
|
|
138
|
+
| `.fields([...])` · `.exclude([...])` | `.select(fields=[...], exclude=[...])` |
|
|
139
|
+
| `fam p` | nhập nhằng — `fam pu` (publish) hoặc `fam pr` (provider) |
|
|
140
|
+
|
|
141
|
+
Định danh trong thư viện đổi hết sang tiếng Anh; nếu bạn import hàm `_private`
|
|
142
|
+
nào của khung thì kiểm lại tên. API công khai không đổi.
|
|
143
|
+
|
|
144
|
+
## [0.2.1] — 2026-08-22
|
|
145
|
+
|
|
146
|
+
### Thay đổi
|
|
147
|
+
|
|
148
|
+
- Tác giả và chủ bản quyền: Oryza <developer@oryza.vn> -> quanglinh
|
|
149
|
+
<hackcoquanglinh2000@gmail.com>, ở cả `pyproject.toml` lẫn `LICENSE`.
|
|
150
|
+
- README tách làm hai bản song ngữ: `README.md` (tiếng Anh, là bản hiện trên
|
|
151
|
+
PyPI) và `README.vi.md` (tiếng Việt). Hai bản giữ cùng thứ tự mục.
|
|
152
|
+
- Metadata PyPI viết lại cho tìm kiếm: summary sang tiếng Anh, keywords từ 9 lên
|
|
153
|
+
39 từ, thêm 7 classifier.
|
|
154
|
+
|
|
155
|
+
### Tài liệu
|
|
156
|
+
|
|
157
|
+
- Viết lại `docs/websocket.md` theo hướng làm-theo thay vì tra-cứu: đưa "bốn
|
|
158
|
+
việc client bắt buộc phải làm" lên đầu trang, thêm client tối thiểu 30 dòng
|
|
159
|
+
chạy được ngay, giải thích cơ chế nhịp tim bằng sơ đồ thời gian, và thêm mục
|
|
160
|
+
tra sự cố theo triệu chứng.
|
|
161
|
+
|
|
162
|
+
## [0.2.0] — 2026-08-22
|
|
163
|
+
|
|
164
|
+
**Đổi tên toàn bộ.** Tên `pymodular` bị PyPI từ chối vì trùng với project
|
|
165
|
+
`py-modular` đã có, nên cả dự án đổi sang `fastapi-modular` cho thống nhất từ
|
|
166
|
+
PyPI, GitHub, thư mục nguồn cho tới tên lệnh.
|
|
167
|
+
|
|
168
|
+
### Phá vỡ
|
|
169
|
+
|
|
170
|
+
- Gói trên PyPI: `pymodular` -> **`fastapi-modular`**.
|
|
171
|
+
- Tên import: `import pymodular` -> **`import fastapi_modular`** (gạch dưới,
|
|
172
|
+
vì gạch ngang không hợp lệ trong tên module Python).
|
|
173
|
+
- Lệnh CLI: `pymodular` / `pym` -> **`fastapi-modular` / `fam`**.
|
|
174
|
+
- Thư mục nguồn `pymodular/` -> `fastapi_modular/`.
|
|
175
|
+
- `APP_NAME` mặc định: `pymodular` -> `fastapi-modular`.
|
|
176
|
+
- `APP_KAFKA__CLIENT_ID` mặc định: `pymodular` -> `fastapi-modular`.
|
|
177
|
+
|
|
178
|
+
Nâng cấp từ 0.1.0: gỡ gói cũ (`pip uninstall pymodular`), cài
|
|
179
|
+
`pip install fastapi-modular`, rồi đổi mọi `pymodular` trong import thành
|
|
180
|
+
`fastapi_modular` và mọi lệnh `pym` thành `fam`.
|
|
181
|
+
|
|
182
|
+
### Sửa
|
|
183
|
+
|
|
184
|
+
- `fam lint` không tham số trỏ vào thư mục `app` không tồn tại nên lỗi ngay;
|
|
185
|
+
mặc định đổi thành `src`, đúng thứ `fam init` sinh ra.
|
|
186
|
+
- `fam migrate-create` trong docs/migrations.md không phải lệnh có thật; lệnh
|
|
187
|
+
đúng là `fam migrate create`.
|
|
188
|
+
- Link trong README đổi sang URL tuyệt đối: README là trang hiển thị trên PyPI,
|
|
189
|
+
ở đó link tương đối `docs/...` phân giải sai và trả 404.
|
|
190
|
+
- Job đóng gói trong CI không bao giờ xanh được: import sai đường dẫn
|
|
191
|
+
(`src.api.main`) và liệt kê route bằng `r.path`, hỏng từ FastAPI 0.141.
|
|
192
|
+
|
|
193
|
+
## [0.1.0] — 2026-08-21
|
|
194
|
+
|
|
195
|
+
Bản đầu tiên. Cần **Python 3.10 trở lên**.
|
|
196
|
+
|
|
197
|
+
### Có gì
|
|
198
|
+
|
|
199
|
+
- **Kiến trúc module kiểu NestJS**: DI container (`@injectable`, `Lazy[...]`,
|
|
200
|
+
`Scope.REQUEST`), controller dạng class (`@controller`, `@get`/`@post`/...),
|
|
201
|
+
tự quét module — thêm thư mục là có route, không phải đăng ký ở đâu cả.
|
|
202
|
+
- **Repository dùng chung cho 4 backend**: memory, SQLite, PostgreSQL, MongoDB.
|
|
203
|
+
Đổi backend không phải sửa service. Kèm circuit breaker và hạn thời gian.
|
|
204
|
+
- **WebSocket**: `@gateway` / `@subscribe`, phòng, gửi thẳng tới một người,
|
|
205
|
+
nhịp tim, giới hạn tần suất, adapter Redis để phát tin xuyên worker.
|
|
206
|
+
- **Bốn lớp hạ tầng tuỳ chọn, cùng một khuôn**: RabbitMQ, Redis, MQTT, Kafka.
|
|
207
|
+
Mặc định TẮT; thư viện chỉ được import khi bật. Tất cả tự nối lại.
|
|
208
|
+
- **CLI** `fastapi-modular`, gõ tắt là `fam`: `init` (dựng dự án ngay trong thư mục
|
|
209
|
+
hiện tại) · `new` · `dev` / `run` · `module` · `env` · `info` · `migrate` ·
|
|
210
|
+
`test` / `lint`. `init` không bao giờ ghi đè file đã có.
|
|
211
|
+
- **Tài liệu tiếng Việt** trong `docs/`, viết theo lối tra cứu: mỗi hàm nói rõ
|
|
212
|
+
truyền gì, không truyền thì mặc định là gì.
|