fastapi-modular 0.1.0__tar.gz → 0.2.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.2.0/CHANGELOG.md +58 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/Makefile +30 -30
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/PKG-INFO +95 -95
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/README.md +89 -89
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/README.md +11 -11
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/architecture.md +15 -15
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/config.md +12 -12
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/database.md +24 -24
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/kafka.md +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/migrations.md +9 -9
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/mqtt.md +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/operations.md +8 -8
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/rabbitmq.md +13 -13
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/redis.md +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/docs/websocket.md +16 -16
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/__init__.py +15 -15
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/clean.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/configure_env.py +7 -7
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/cong_cu.py +5 -5
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/info.py +7 -7
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/install.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/main.py +38 -38
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/new_module.py +21 -21
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/new_project.py +45 -45
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/serve.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/clock.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/config.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/container.py +2 -2
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/controller.py +2 -2
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/error_handlers.py +5 -5
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/exceptions.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/guards.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/lifespan.py +11 -11
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/logging.py +2 -2
- fastapi_modular-0.2.0/fastapi_modular/core/websocket/__init__.py +31 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/websocket/adapter.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/websocket/gateway.py +11 -11
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/websocket/namespace.py +2 -2
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/websocket/protocol.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/websocket/server.py +7 -7
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/websocket/socket.py +5 -5
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/discovery.py +5 -5
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/factory.py +7 -7
- fastapi_modular-0.2.0/fastapi_modular/infrastructure/database/__init__.py +8 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/base.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/circuit.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/factory.py +6 -6
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/memory.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/mongo.py +2 -2
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/repository.py +6 -6
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/database/sql.py +4 -4
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/kafka/__init__.py +2 -2
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/kafka/broker.py +6 -6
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/kafka/consumers.py +6 -6
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/kafka/metrics.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/mqtt/__init__.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/mqtt/client.py +8 -8
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/mqtt/consumers.py +7 -7
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/mqtt/metrics.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/mqtt/patterns.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/rabbitmq/__init__.py +3 -3
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/rabbitmq/broker.py +10 -7
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/rabbitmq/consumers.py +7 -7
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/rabbitmq/metrics.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/rabbitmq/patterns.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/redis/__init__.py +2 -2
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/redis/client.py +5 -5
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/redis/metrics.py +1 -1
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/redis/pubsub.py +6 -6
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/middleware/request_context.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/migrations/env.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/pyproject.toml +12 -12
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/ruff.toml +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/chat/chat_controller.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/chat/chat_gateway.py +5 -5
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/chat/dto/chat_dto.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/device_controller.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/device_service.py +5 -5
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/dto/device_dto.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/entities/device_model.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/health/health_controller.py +8 -8
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/kafka_test/kafka_consumer.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/kafka_test/kafka_controller.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/metrics/metrics_controller.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/mqtt_test/mqtt_controller.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/mqtt_test/mqtt_listener.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/rabbitmq_test/rabbitmq_consumer.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/rabbitmq_test/rabbitmq_controller.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/redis_test/redis_controller.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/redis_test/redis_listener.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/dto/user_dto.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/entities/user_model.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/user_controller.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/user_service.py +5 -5
- fastapi_modular-0.2.0/src/core/__init__.py +4 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/core/config.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/core/lifespan.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/main.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/conftest.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_circuit.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_cli.py +42 -42
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_configure_env.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_container.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_database.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_drivers.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_guards.py +7 -7
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_ha_tang_that.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_kafka.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_kafka_offline.py +5 -5
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_lifespan_rieng.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_metrics.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_module_generator.py +2 -2
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_mqtt.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_mqtt_offline.py +7 -7
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_rabbitmq.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_rabbitmq_offline.py +7 -7
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_redis.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_redis_offline.py +6 -6
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_resilience.py +7 -7
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_schema_evolution.py +5 -5
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_schemas.py +1 -1
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_settings_mo_rong.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_tuong_thich_phien_ban.py +3 -3
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_uniqueness.py +4 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_websocket.py +14 -8
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_ws_adapter.py +5 -5
- fastapi_modular-0.1.0/CHANGELOG.md +0 -32
- fastapi_modular-0.1.0/pymodular/core/websocket/__init__.py +0 -31
- fastapi_modular-0.1.0/pymodular/infrastructure/database/__init__.py +0 -8
- fastapi_modular-0.1.0/src/core/__init__.py +0 -4
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/.gitignore +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/LICENSE +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/alembic.ini +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/cli/__init__.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/__init__.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/compat.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/context.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/metrics.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/core/schemas.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/infrastructure/__init__.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/middleware/__init__.py +0 -0
- {fastapi_modular-0.1.0/pymodular → fastapi_modular-0.2.0/fastapi_modular}/py.typed +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/migrations/script.py.mako +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/migrations/versions/.gitkeep +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/migrations/versions/20260821_1020_tao_bang_users_va_devices.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/pytest.ini +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/chat/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/chat/dto/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/dto/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/devices/entities/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/health/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/kafka_test/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/metrics/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/mqtt_test/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/rabbitmq_test/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/redis_test/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/dto/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/src/api/users/entities/__init__.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_cross_module.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_health.py +0 -0
- {fastapi_modular-0.1.0 → fastapi_modular-0.2.0}/tests/test_users_api.py +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
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.2.0] — 2026-08-22
|
|
9
|
+
|
|
10
|
+
**Đổi tên toàn bộ.** Tên `pymodular` bị PyPI từ chối vì trùng với project
|
|
11
|
+
`py-modular` đã có, nên cả dự án đổi sang `fastapi-modular` cho thống nhất từ
|
|
12
|
+
PyPI, GitHub, thư mục nguồn cho tới tên lệnh.
|
|
13
|
+
|
|
14
|
+
### Phá vỡ
|
|
15
|
+
|
|
16
|
+
- Gói trên PyPI: `pymodular` -> **`fastapi-modular`**.
|
|
17
|
+
- Tên import: `import pymodular` -> **`import fastapi_modular`** (gạch dưới,
|
|
18
|
+
vì gạch ngang không hợp lệ trong tên module Python).
|
|
19
|
+
- Lệnh CLI: `pymodular` / `pym` -> **`fastapi-modular` / `fam`**.
|
|
20
|
+
- Thư mục nguồn `pymodular/` -> `fastapi_modular/`.
|
|
21
|
+
- `APP_NAME` mặc định: `pymodular` -> `fastapi-modular`.
|
|
22
|
+
- `APP_KAFKA__CLIENT_ID` mặc định: `pymodular` -> `fastapi-modular`.
|
|
23
|
+
|
|
24
|
+
Nâng cấp từ 0.1.0: gỡ gói cũ (`pip uninstall pymodular`), cài
|
|
25
|
+
`pip install fastapi-modular`, rồi đổi mọi `pymodular` trong import thành
|
|
26
|
+
`fastapi_modular` và mọi lệnh `pym` thành `fam`.
|
|
27
|
+
|
|
28
|
+
### Sửa
|
|
29
|
+
|
|
30
|
+
- `fam lint` không tham số trỏ vào thư mục `app` không tồn tại nên lỗi ngay;
|
|
31
|
+
mặc định đổi thành `src`, đúng thứ `fam init` sinh ra.
|
|
32
|
+
- `fam migrate-create` trong docs/migrations.md không phải lệnh có thật; lệnh
|
|
33
|
+
đúng là `fam migrate create`.
|
|
34
|
+
- Link trong README đổi sang URL tuyệt đối: README là trang hiển thị trên PyPI,
|
|
35
|
+
ở đó link tương đối `docs/...` phân giải sai và trả 404.
|
|
36
|
+
- Job đóng gói trong CI không bao giờ xanh được: import sai đường dẫn
|
|
37
|
+
(`src.api.main`) và liệt kê route bằng `r.path`, hỏng từ FastAPI 0.141.
|
|
38
|
+
|
|
39
|
+
## [0.1.0] — 2026-08-21
|
|
40
|
+
|
|
41
|
+
Bản đầu tiên. Cần **Python 3.10 trở lên**.
|
|
42
|
+
|
|
43
|
+
### Có gì
|
|
44
|
+
|
|
45
|
+
- **Kiến trúc module kiểu NestJS**: DI container (`@injectable`, `Lazy[...]`,
|
|
46
|
+
`Scope.REQUEST`), controller dạng class (`@controller`, `@get`/`@post`/...),
|
|
47
|
+
tự quét module — thêm thư mục là có route, không phải đăng ký ở đâu cả.
|
|
48
|
+
- **Repository dùng chung cho 4 backend**: memory, SQLite, PostgreSQL, MongoDB.
|
|
49
|
+
Đổi backend không phải sửa service. Kèm circuit breaker và hạn thời gian.
|
|
50
|
+
- **WebSocket**: `@gateway` / `@subscribe`, phòng, gửi thẳng tới một người,
|
|
51
|
+
nhịp tim, giới hạn tần suất, adapter Redis để phát tin xuyên worker.
|
|
52
|
+
- **Bốn lớp hạ tầng tuỳ chọn, cùng một khuôn**: RabbitMQ, Redis, MQTT, Kafka.
|
|
53
|
+
Mặc định TẮT; thư viện chỉ được import khi bật. Tất cả tự nối lại.
|
|
54
|
+
- **CLI** `fastapi-modular`, gõ tắt là `fam`: `init` (dựng dự án ngay trong thư mục
|
|
55
|
+
hiện tại) · `new` · `dev` / `run` · `module` · `env` · `info` · `migrate` ·
|
|
56
|
+
`test` / `lint`. `init` không bao giờ ghi đè file đã có.
|
|
57
|
+
- **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õ
|
|
58
|
+
truyền gì, không truyền thì mặc định là gì.
|
|
@@ -16,85 +16,85 @@ help: ## Danh sách lệnh
|
|
|
16
16
|
@grep -hE '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
|
|
17
17
|
| awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}'
|
|
18
18
|
|
|
19
|
-
# Makefile này chỉ là lối tắt cho `
|
|
20
|
-
# viện không có nó, nên mọi lệnh đều phải chạy được qua `
|
|
19
|
+
# Makefile này chỉ là lối tắt cho `fam` khi làm việc TRONG repo. Người dùng thư
|
|
20
|
+
# viện không có nó, nên mọi lệnh đều phải chạy được qua `fam` — và cách chắc
|
|
21
21
|
# chắn nhất để giữ điều đó đúng là ở đây không tự viết gì cả, chỉ gọi lại.
|
|
22
|
-
|
|
22
|
+
FAM := $(PY) -m fastapi_modular.cli.main
|
|
23
23
|
|
|
24
24
|
dev: ## Chạy API kèm autoreload
|
|
25
|
-
$(
|
|
25
|
+
$(FAM) dev
|
|
26
26
|
|
|
27
27
|
run: ## Chạy API chế độ production (nhiều worker — cần driver DB thật)
|
|
28
|
-
$(
|
|
28
|
+
$(FAM) run --workers $(or $(WORKERS),4)
|
|
29
29
|
|
|
30
30
|
module: ## Sinh khung module mới — dùng: make module name=alerts [entity=alert] [ws=1] [mq=1]
|
|
31
31
|
@test -n "$(name)" || { echo 'Thiếu tên. Dùng: make module name=alerts'; exit 1; }
|
|
32
|
-
$(
|
|
32
|
+
$(FAM) module $(name) $(if $(entity),--entity $(entity),) $(if $(ws),--gateway,) $(if $(mq),--consumer,)
|
|
33
33
|
|
|
34
34
|
gateway: ## Thêm gateway WebSocket vào module đã có — dùng: make gateway name=alerts
|
|
35
35
|
@test -n "$(name)" || { echo 'Thiếu tên. Dùng: make gateway name=alerts'; exit 1; }
|
|
36
|
-
$(
|
|
36
|
+
$(FAM) module $(name) --gateway-only $(if $(entity),--entity $(entity),)
|
|
37
37
|
|
|
38
38
|
consumer: ## Thêm consumer RabbitMQ vào module đã có — dùng: make consumer name=alerts
|
|
39
39
|
@test -n "$(name)" || { echo 'Thiếu tên. Dùng: make consumer name=alerts'; exit 1; }
|
|
40
|
-
$(
|
|
40
|
+
$(FAM) module $(name) --consumer-only $(if $(entity),--entity $(entity),)
|
|
41
41
|
|
|
42
42
|
migrate: ## Chạy migration lên bản mới nhất
|
|
43
|
-
$(
|
|
43
|
+
$(FAM) migrate up
|
|
44
44
|
|
|
45
45
|
migrate-create: ## Sinh migration từ thay đổi entity — dùng: make migrate-create m="them cot phone"
|
|
46
46
|
@test -n "$(m)" || { echo 'Thiếu tên. Dùng: make migrate-create m="mô tả thay đổi"'; exit 1; }
|
|
47
|
-
$(
|
|
47
|
+
$(FAM) migrate create -m "$(m)"
|
|
48
48
|
|
|
49
49
|
migrate-down: ## Lùi lại một bản
|
|
50
|
-
$(
|
|
50
|
+
$(FAM) migrate down
|
|
51
51
|
|
|
52
52
|
migrate-history: ## Lịch sử migration và bản đang áp dụng
|
|
53
|
-
@$(
|
|
53
|
+
@$(FAM) migrate history
|
|
54
54
|
|
|
55
55
|
migrate-sql: ## In câu SQL thay vì chạy (để DBA duyệt trước)
|
|
56
|
-
$(
|
|
56
|
+
$(FAM) migrate sql
|
|
57
57
|
|
|
58
58
|
lint: ## Soi lỗi tĩnh
|
|
59
|
-
$(
|
|
59
|
+
$(FAM) lint fastapi_modular src tests
|
|
60
60
|
|
|
61
61
|
lint-fix: ## Soi và tự sửa những lỗi sửa được
|
|
62
|
-
$(
|
|
62
|
+
$(FAM) lint --fix fastapi_modular src tests
|
|
63
63
|
|
|
64
64
|
test: ## Chạy test
|
|
65
|
-
$(
|
|
65
|
+
$(FAM) test
|
|
66
66
|
|
|
67
67
|
install: ## Cài khung ở chế độ chỉnh sửa được (chưa có driver database)
|
|
68
68
|
$(PIP) install -e .
|
|
69
69
|
|
|
70
70
|
install-dev: ## Cài kèm công cụ phát triển (pytest, httpx, ruff, build, twine)
|
|
71
71
|
$(PIP) install -e .
|
|
72
|
-
$(
|
|
72
|
+
$(FAM) install dev
|
|
73
73
|
$(PIP) install build twine
|
|
74
74
|
|
|
75
75
|
install-sqlite: ## Cài driver SQLite + ghi biến vào .env
|
|
76
|
-
$(
|
|
76
|
+
$(FAM) install sqlite
|
|
77
77
|
|
|
78
78
|
install-postgres: ## Cài driver PostgreSQL + ghi biến vào .env
|
|
79
|
-
$(
|
|
79
|
+
$(FAM) install postgres
|
|
80
80
|
|
|
81
81
|
install-mongo: ## Cài driver MongoDB + ghi biến vào .env
|
|
82
|
-
$(
|
|
82
|
+
$(FAM) install mongodb
|
|
83
83
|
|
|
84
84
|
install-redis: ## Cài Redis (cache, đếm, pub/sub) + ghi biến vào .env
|
|
85
|
-
$(
|
|
85
|
+
$(FAM) install redis
|
|
86
86
|
|
|
87
87
|
install-ws-redis: ## Bật adapter Redis cho WebSocket nhiều worker + ghi biến vào .env
|
|
88
|
-
$(
|
|
88
|
+
$(FAM) install ws-redis
|
|
89
89
|
|
|
90
90
|
install-rabbitmq: ## Cài client RabbitMQ + ghi biến vào .env
|
|
91
|
-
$(
|
|
91
|
+
$(FAM) install rabbitmq
|
|
92
92
|
|
|
93
93
|
install-mqtt: ## Cài client MQTT + ghi biến vào .env
|
|
94
|
-
$(
|
|
94
|
+
$(FAM) install mqtt
|
|
95
95
|
|
|
96
96
|
install-kafka: ## Cài client Kafka + ghi biến vào .env
|
|
97
|
-
$(
|
|
97
|
+
$(FAM) install kafka
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
|
|
@@ -103,16 +103,16 @@ install-kafka: ## Cài client Kafka + ghi biến vào .env
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
info: ## Đang nối vào đâu, thư viện nào đã cài
|
|
106
|
-
@$(
|
|
106
|
+
@$(FAM) info
|
|
107
107
|
|
|
108
108
|
build: ## Dựng wheel + sdist vào dist/
|
|
109
|
-
$(
|
|
109
|
+
$(FAM) build
|
|
110
110
|
|
|
111
111
|
publish-test: build ## Đẩy lên TestPyPI (thử trước khi đẩy thật)
|
|
112
|
-
$(
|
|
112
|
+
$(FAM) publish --test
|
|
113
113
|
|
|
114
114
|
publish: build ## Đẩy lên PyPI
|
|
115
|
-
$(
|
|
115
|
+
$(FAM) publish
|
|
116
116
|
|
|
117
117
|
clean: ## Xoá cache và bản dựng
|
|
118
|
-
$(
|
|
118
|
+
$(FAM) clean
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fastapi-modular
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: FastAPI theo kiến trúc module kiểu NestJS: DI container, controller dạng class, WebSocket, RabbitMQ/Redis/MQTT/Kafka
|
|
5
|
-
Project-URL: Homepage, https://github.com/quanglinh2909/
|
|
6
|
-
Project-URL: Documentation, https://github.com/quanglinh2909/
|
|
7
|
-
Project-URL: Source, https://github.com/quanglinh2909/
|
|
8
|
-
Project-URL: Issues, https://github.com/quanglinh2909/
|
|
9
|
-
Project-URL: Changelog, https://github.com/quanglinh2909/
|
|
5
|
+
Project-URL: Homepage, https://github.com/quanglinh2909/fastapi-modular
|
|
6
|
+
Project-URL: Documentation, https://github.com/quanglinh2909/fastapi-modular/tree/main/docs
|
|
7
|
+
Project-URL: Source, https://github.com/quanglinh2909/fastapi-modular
|
|
8
|
+
Project-URL: Issues, https://github.com/quanglinh2909/fastapi-modular/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/quanglinh2909/fastapi-modular/blob/main/CHANGELOG.md
|
|
10
10
|
Author-email: Oryza <developer@oryza.vn>
|
|
11
11
|
License-Expression: MIT
|
|
12
12
|
License-File: LICENSE
|
|
@@ -61,13 +61,13 @@ Requires-Dist: alembic>=1.13.0; extra == 'sqlite'
|
|
|
61
61
|
Requires-Dist: sqlalchemy[asyncio]<3.0.0,>=2.0.30; extra == 'sqlite'
|
|
62
62
|
Description-Content-Type: text/markdown
|
|
63
63
|
|
|
64
|
-
#
|
|
64
|
+
# fastapi-modular
|
|
65
65
|
|
|
66
66
|
FastAPI theo kiến trúc module kiểu NestJS: DI container, controller dạng class,
|
|
67
67
|
repository chung cho nhiều loại database, gateway WebSocket có phòng, và bốn lớp
|
|
68
68
|
hạ tầng tuỳ chọn: RabbitMQ, Redis, MQTT, Kafka.
|
|
69
69
|
|
|
70
|
-
> **In English:**
|
|
70
|
+
> **In English:** fastapi-modular brings NestJS-style modular architecture to FastAPI —
|
|
71
71
|
> a DI container, class-based controllers, auto-discovered modules, a shared
|
|
72
72
|
> repository over four databases, a WebSocket gateway with rooms, and optional
|
|
73
73
|
> RabbitMQ / Redis / MQTT / Kafka layers that stay dormant until enabled.
|
|
@@ -81,119 +81,119 @@ Cần **Python 3.10+**.
|
|
|
81
81
|
python -m venv .venv && . .venv/bin/activate
|
|
82
82
|
pip install fastapi-modular
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
fam init # đổ file vào THƯ MỤC HIỆN TẠI, không tạo thêm cấp
|
|
85
|
+
fam dev
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Mở http://localhost:8000/docs — đã có sẵn một module `health` chạy được.
|
|
89
89
|
|
|
90
|
-
`
|
|
91
|
-
`
|
|
92
|
-
trong thư mục đang có sẵn code. Muốn nó tự tạo thư mục thì `
|
|
90
|
+
`fam init` lấy tên dự án theo **tên thư mục hiện tại**; đặt tên khác bằng
|
|
91
|
+
`fam init --name ten-khac`. Nó không ghi đè file nào đã có, nên chạy được cả
|
|
92
|
+
trong thư mục đang có sẵn code. Muốn nó tự tạo thư mục thì `fam new <tên>`.
|
|
93
93
|
|
|
94
94
|
Lõi **không kéo theo** driver database hay client hàng đợi nào. Cần cái gì thì
|
|
95
95
|
thêm cái đó:
|
|
96
96
|
|
|
97
97
|
```bash
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
fam install sqlite # hoặc postgres, mongodb
|
|
99
|
+
fam install rabbitmq # hoặc redis, mqtt, kafka
|
|
100
|
+
fam install all # tất cả
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
`
|
|
103
|
+
`fam install` vừa cài thư viện vừa ghi biến vào `.env`. Muốn tự cài bằng pip
|
|
104
104
|
cũng được: `pip install "fastapi-modular[sqlite,rabbitmq]"`.
|
|
105
105
|
|
|
106
106
|
## Lệnh
|
|
107
107
|
|
|
108
|
-
Một chương trình, hai tên: `
|
|
109
|
-
`
|
|
108
|
+
Một chương trình, hai tên: `fastapi-modular` (đầy đủ) và `fam` (gõ tắt). Dưới đây dùng
|
|
109
|
+
`fam` cho gọn.
|
|
110
110
|
|
|
111
|
-
Tên lệnh rút gọn được tới khi nào tiền tố còn chỉ đúng một lệnh — `
|
|
112
|
-
chạy y hệt `
|
|
111
|
+
Tên lệnh rút gọn được tới khi nào tiền tố còn chỉ đúng một lệnh — `fam mo alerts`
|
|
112
|
+
chạy y hệt `fam module alerts`. Nhập nhằng thì `fam` hỏi lại chứ không đoán:
|
|
113
113
|
|
|
114
114
|
```
|
|
115
|
-
$
|
|
116
|
-
|
|
115
|
+
$ fam m
|
|
116
|
+
fam: lệnh 'm' chưa rõ — khớp với migrate, module. Gõ thêm vài chữ cho rõ.
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
| Lệnh | Rút gọn | Làm gì |
|
|
120
120
|
|---|---|---|
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
121
|
+
| `fam init [--name <tên>]` | `fam ini` | dựng dự án **trong thư mục hiện tại**, không ghi đè file nào đã có; tên dự án mặc định lấy theo tên thư mục |
|
|
122
|
+
| `fam new <tên>` | `fam n` | dựng dự án trong một thư mục mới |
|
|
123
|
+
| `fam dev` | `fam d` | chạy kèm autoreload |
|
|
124
|
+
| `fam run --workers 4` | `fam r` | chạy chế độ production |
|
|
125
|
+
| `fam module <tên>` | `fam mo` | sinh module: controller + service + dto + entity |
|
|
126
|
+
| `fam module <tên> --gateway` | | kèm gateway WebSocket (`--consumer` cho RabbitMQ) |
|
|
127
|
+
| `fam module <tên> --gateway-only` | | chỉ thêm gateway vào module **đã có** (`--consumer-only` cho RabbitMQ) |
|
|
128
|
+
| `fam module <tên> --entity <Tên>` | | đặt tên lớp entity; mặc định đoán từ tên module |
|
|
129
|
+
| `fam env <thành-phần>` | `fam e` | chỉ ghi biến cấu hình vào `.env` (không cài gì) |
|
|
130
|
+
| `fam clean` | `fam c` | xoá cache và bản dựng (không đụng `data/`) |
|
|
131
|
+
| `fam build` · `fam publish [--test]` | `fam b` · `fam p` | dựng wheel/sdist · đẩy lên PyPI |
|
|
132
|
+
| `fam info` | `fam inf` | đang nối vào đâu, thư viện nào đã cài, cảnh báo cấu hình prod |
|
|
133
|
+
| `fam migrate [up\|down\|history\|sql\|create]` | `fam mi` | Alembic |
|
|
134
|
+
| `fam test` · `fam lint [--fix]` | `fam t` · `fam l` | pytest · ruff. `fam lint` không tham số soi `src`; truyền đường dẫn để soi chỗ khác |
|
|
135
135
|
| **Thêm database** | | *cài thư viện **rồi** ghi biến vào `.env`* |
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
136
|
+
| `fam install sqlite` | `fam ins s` | file `.db`, không cần server |
|
|
137
|
+
| `fam install postgres` | `fam ins p` | PostgreSQL |
|
|
138
|
+
| `fam install mongodb` | `fam ins mo` | MongoDB |
|
|
139
139
|
| **Thêm hàng đợi** | | *cài thư viện **rồi** ghi biến vào `.env`* |
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
140
|
+
| `fam install rabbitmq` | `fam ins ra` | hàng đợi bền, thử lại + DLQ |
|
|
141
|
+
| `fam install redis` | `fam ins re` | cache, đếm nguyên tử, pub/sub |
|
|
142
|
+
| `fam install mqtt` | `fam ins mq` | thiết bị IoT |
|
|
143
|
+
| `fam install kafka` | `fam ins k` | nhật ký sự kiện đọc lại được |
|
|
144
|
+
| `fam install ws-redis` | `fam ins w` | phát tin WebSocket xuyên nhiều worker |
|
|
145
|
+
| `fam install dev` | `fam ins d` | pytest · pytest-asyncio · httpx · ruff — cần cho `fam test` / `fam lint` |
|
|
146
|
+
| `fam install all` | `fam ins a` | tất cả những thứ trên, **trừ** `dev` |
|
|
147
147
|
|
|
148
|
-
Tham số dạng danh sách cũng rút gọn theo cùng luật đó: `
|
|
149
|
-
`
|
|
150
|
-
`
|
|
148
|
+
Tham số dạng danh sách cũng rút gọn theo cùng luật đó: `fam ins sq`,
|
|
149
|
+
`fam e post`, `fam mi h`. Còn giá trị bạn tự đặt thì không bị đụng tới —
|
|
150
|
+
`fam mo ins` tạo module tên đúng là `ins`.
|
|
151
151
|
|
|
152
|
-
Host và cổng lấy từ `APP_HOST` / `APP_PORT` trong `.env`, nên `
|
|
153
|
-
tham số. `
|
|
152
|
+
Host và cổng lấy từ `APP_HOST` / `APP_PORT` trong `.env`, nên `fam dev` không cần
|
|
153
|
+
tham số. `fam --help` cho danh sách đầy đủ.
|
|
154
154
|
|
|
155
155
|
## Thêm module
|
|
156
156
|
|
|
157
157
|
```bash
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
fam module alerts # controller + service + dto + entities
|
|
159
|
+
fam module alerts --gateway # kèm gateway WebSocket
|
|
160
|
+
fam module alerts --consumer # kèm consumer RabbitMQ
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
Route xuất hiện ngay, bảng được tạo ngay, validate chạy ngay — chỉ thân hàm là
|
|
164
164
|
chưa viết (gọi vào trả 501 kèm tên hàm). Việc của bạn: thêm trường vào entity và
|
|
165
165
|
DTO, rồi viết thân hàm trong service.
|
|
166
166
|
|
|
167
|
-
Không phải sửa file nào khác. Chi tiết: [docs/architecture.md](docs/architecture.md#thêm-module-mới).
|
|
167
|
+
Không phải sửa file nào khác. Chi tiết: [docs/architecture.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/architecture.md#thêm-module-mới).
|
|
168
168
|
|
|
169
169
|
## Chọn database
|
|
170
170
|
|
|
171
|
-
`
|
|
171
|
+
`fam install sqlite` (hoặc `postgres`, `mongodb`) làm cả hai việc: cài thư viện
|
|
172
172
|
của đúng driver đó, rồi ghi biến vào `.env`. Chỉ muốn ghi `.env` mà không cài gì
|
|
173
|
-
thì dùng `
|
|
173
|
+
thì dùng `fam env sqlite`.
|
|
174
174
|
|
|
175
|
-
`
|
|
176
|
-
**mặc định là gì** nếu xoá dòng đi. `
|
|
175
|
+
`fam env` ghi mỗi biến kèm giải thích, cho biết nó **bắt buộc hay tuỳ chọn** và
|
|
176
|
+
**mặc định là gì** nếu xoá dòng đi. `fam info` cho biết hiện đang nối vào đâu.
|
|
177
177
|
|
|
178
|
-
Chi tiết: [docs/database.md](docs/database.md).
|
|
178
|
+
Chi tiết: [docs/database.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/database.md).
|
|
179
179
|
|
|
180
180
|
## Cấu hình của riêng bạn
|
|
181
181
|
|
|
182
182
|
Kế thừa `Settings` là thêm được biến vào `.env`, không phải sửa gì trong khung:
|
|
183
183
|
|
|
184
184
|
```python
|
|
185
|
-
# src/core/config.py —
|
|
185
|
+
# src/core/config.py — fam init sinh sẵn file này
|
|
186
186
|
class AppSettings(Settings):
|
|
187
187
|
team_name: str = Field(default="", alias="APP_TEAM_NAME")
|
|
188
188
|
jwt: JwtSettings = Field(default_factory=JwtSettings, alias="APP_JWT") # -> APP_JWT__SECRET
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
Service nhận `AppSettings` qua DI với gợi ý kiểu đầy đủ.
|
|
192
|
-
Chi tiết: [docs/config.md](docs/config.md).
|
|
192
|
+
Chi tiết: [docs/config.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/config.md).
|
|
193
193
|
|
|
194
194
|
## Điểm vào là file của bạn
|
|
195
195
|
|
|
196
|
-
`
|
|
196
|
+
`fam init` sinh ra `src/main.py` với từng bước lắp ráp bày ra hết — thêm
|
|
197
197
|
middleware, đổi CORS, gắn router bên thứ ba thì sửa thẳng ở đó:
|
|
198
198
|
|
|
199
199
|
```python
|
|
@@ -240,18 +240,18 @@ class AlertGateway:
|
|
|
240
240
|
```
|
|
241
241
|
|
|
242
242
|
```bash
|
|
243
|
-
|
|
243
|
+
fam dev
|
|
244
244
|
# ws://localhost:8000/ws/chat?client_id=an
|
|
245
245
|
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
fam module alerts --gateway-only # thêm gateway vào module đã có
|
|
247
|
+
fam install ws-redis # bắt buộc khi chạy nhiều worker
|
|
248
248
|
```
|
|
249
249
|
|
|
250
250
|
Đẩy tin từ REST hay tác vụ nền: nhận `WebSocketServer` qua `__init__` rồi gọi
|
|
251
251
|
`to_room` / `to_user` / `to_socket`.
|
|
252
252
|
|
|
253
253
|
Hướng dẫn đầy đủ (kèm cách dùng bằng **Postman** và client **Next.js**):
|
|
254
|
-
[docs/websocket.md](docs/websocket.md).
|
|
254
|
+
[docs/websocket.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/websocket.md).
|
|
255
255
|
|
|
256
256
|
## Hàng đợi (RabbitMQ — tuỳ chọn)
|
|
257
257
|
|
|
@@ -269,12 +269,12 @@ async def gui_mail(self, payload: AlertCreated) -> None: ...
|
|
|
269
269
|
```
|
|
270
270
|
|
|
271
271
|
```bash
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
fam install rabbitmq # cài aio-pika + ghi APP_RABBITMQ__* vào .env
|
|
273
|
+
fam module alerts --consumer # module mới kèm consumer
|
|
274
274
|
```
|
|
275
275
|
|
|
276
276
|
Không cài, không bật thì mọi thứ chạy y như chưa từng có nó. Broker rớt thì app
|
|
277
|
-
vẫn phục vụ và tự nối lại. Chi tiết: [docs/rabbitmq.md](docs/rabbitmq.md).
|
|
277
|
+
vẫn phục vụ và tự nối lại. Chi tiết: [docs/rabbitmq.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/rabbitmq.md).
|
|
278
278
|
|
|
279
279
|
## Redis, MQTT, Kafka (cũng tuỳ chọn)
|
|
280
280
|
|
|
@@ -283,9 +283,9 @@ biến `APP_<TÊN>__*`, mặc định **tắt**, thư viện chỉ import khi b
|
|
|
283
283
|
nối lại.
|
|
284
284
|
|
|
285
285
|
```bash
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
fam install redis # cache, đếm, pub/sub -> docs/redis.md
|
|
287
|
+
fam install mqtt # thiết bị IoT -> docs/mqtt.md
|
|
288
|
+
fam install kafka # nhật ký sự kiện -> docs/kafka.md
|
|
289
289
|
```
|
|
290
290
|
|
|
291
291
|
```python
|
|
@@ -311,16 +311,16 @@ await kafka.publish("don-hang", don, key=don.ma_don) # cùng key = cùng thứ
|
|
|
311
311
|
curl localhost:8000/api/health # liveness
|
|
312
312
|
curl localhost:8000/api/health/ready # readiness, có ping database
|
|
313
313
|
curl localhost:8000/api/metrics # số đo dạng Prometheus
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
fam migrate # chạy migration (SQL)
|
|
315
|
+
fam info # cấu hình đang dùng + cảnh báo prod
|
|
316
316
|
```
|
|
317
317
|
|
|
318
|
-
Chi tiết: [docs/operations.md](docs/operations.md).
|
|
318
|
+
Chi tiết: [docs/operations.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/operations.md).
|
|
319
319
|
|
|
320
320
|
## Cấu trúc repo này
|
|
321
321
|
|
|
322
322
|
```
|
|
323
|
-
|
|
323
|
+
fastapi_modular/ THƯ VIỆN — thứ được đóng gói và cài về
|
|
324
324
|
core/ DI, controller, config, WebSocket, guard, số đo
|
|
325
325
|
infrastructure/ database, rabbitmq, redis, mqtt, kafka (mỗi thứ một package)
|
|
326
326
|
cli/ init · new · module · dev · run · install · env · info
|
|
@@ -336,42 +336,42 @@ tests/ 341 test chạy không cần hạ tầng, 40 test nữa bậ
|
|
|
336
336
|
docs/ tài liệu tra cứu
|
|
337
337
|
```
|
|
338
338
|
|
|
339
|
-
`
|
|
339
|
+
`fastapi_modular/` không import gì từ `src/`. Nó chỉ biết "có một package tên
|
|
340
340
|
`src.api`, quét nó đi" — nên dự án xếp khác cũng được, khai một lần trong
|
|
341
341
|
`src/main.py`: `register_routes(app, package="cong_ty.dich_vu")`.
|
|
342
342
|
|
|
343
343
|
## Đóng góp
|
|
344
344
|
|
|
345
345
|
```bash
|
|
346
|
-
git clone <repo> && cd
|
|
346
|
+
git clone <repo> && cd fastapi-modular
|
|
347
347
|
pip install -e ".[all,dev]"
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
348
|
+
fam dev # chạy ứng dụng mẫu trong src/
|
|
349
|
+
fam test
|
|
350
|
+
fam lint fastapi_modular src tests
|
|
351
351
|
```
|
|
352
352
|
|
|
353
353
|
Nhóm test cần hạ tầng thật chỉ chạy khi có biến môi trường tương ứng:
|
|
354
354
|
|
|
355
355
|
```bash
|
|
356
356
|
docker run -d -p 6379:6379 redis:7-alpine
|
|
357
|
-
TEST_REDIS_URL=redis://localhost:6379/0
|
|
357
|
+
TEST_REDIS_URL=redis://localhost:6379/0 fam test
|
|
358
358
|
```
|
|
359
359
|
|
|
360
360
|
Xem đầu mỗi file `tests/test_<tên>.py` để biết lệnh Docker và biến cần đặt.
|
|
361
361
|
|
|
362
362
|
## Giấy phép
|
|
363
363
|
|
|
364
|
-
MIT — xem [LICENSE](LICENSE).
|
|
364
|
+
MIT — xem [LICENSE](https://github.com/quanglinh2909/fastapi-modular/blob/main/LICENSE).
|
|
365
365
|
|
|
366
366
|
## Tài liệu
|
|
367
367
|
|
|
368
|
-
- [docs/architecture.md](docs/architecture.md) — cấu trúc module, DI, đối chiếu NestJS
|
|
369
|
-
- [docs/config.md](docs/config.md) — Settings, thứ tự ưu tiên, thêm biến của riêng bạn
|
|
370
|
-
- [docs/database.md](docs/database.md) — memory / SQLite / PostgreSQL / MongoDB
|
|
371
|
-
- [docs/migrations.md](docs/migrations.md) — Alembic: sinh, chạy, lùi migration
|
|
372
|
-
- [docs/websocket.md](docs/websocket.md) — gateway WebSocket, phòng, Postman, Next.js
|
|
373
|
-
- [docs/rabbitmq.md](docs/rabbitmq.md) — exchange, topic, consumer nền, `.retry` / `.dlq`
|
|
374
|
-
- [docs/redis.md](docs/redis.md) — cache, đếm nguyên tử, pub/sub
|
|
375
|
-
- [docs/mqtt.md](docs/mqtt.md) — QoS, retain, luật khớp topic `+` và `#`
|
|
376
|
-
- [docs/kafka.md](docs/kafka.md) — nhóm consumer, phân vùng, `.dlt`
|
|
377
|
-
- [docs/operations.md](docs/operations.md) — guard, circuit breaker, metrics, trace
|
|
368
|
+
- [docs/architecture.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/architecture.md) — cấu trúc module, DI, đối chiếu NestJS
|
|
369
|
+
- [docs/config.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/config.md) — Settings, thứ tự ưu tiên, thêm biến của riêng bạn
|
|
370
|
+
- [docs/database.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/database.md) — memory / SQLite / PostgreSQL / MongoDB
|
|
371
|
+
- [docs/migrations.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/migrations.md) — Alembic: sinh, chạy, lùi migration
|
|
372
|
+
- [docs/websocket.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/websocket.md) — gateway WebSocket, phòng, Postman, Next.js
|
|
373
|
+
- [docs/rabbitmq.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/rabbitmq.md) — exchange, topic, consumer nền, `.retry` / `.dlq`
|
|
374
|
+
- [docs/redis.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/redis.md) — cache, đếm nguyên tử, pub/sub
|
|
375
|
+
- [docs/mqtt.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/mqtt.md) — QoS, retain, luật khớp topic `+` và `#`
|
|
376
|
+
- [docs/kafka.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/kafka.md) — nhóm consumer, phân vùng, `.dlt`
|
|
377
|
+
- [docs/operations.md](https://github.com/quanglinh2909/fastapi-modular/blob/main/docs/operations.md) — guard, circuit breaker, metrics, trace
|