fastapi-augment 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/PKG-INFO +22 -17
  2. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/README.md +21 -16
  3. fastapi_augment-0.1.4/VERSION +1 -0
  4. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/constants.py +2 -1
  5. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/exception_handlers.py +10 -10
  6. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/exceptions.py +18 -18
  7. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/utils/__init__.py +1 -1
  8. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/utils/paths.py +3 -3
  9. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/utils/strings.py +17 -4
  10. fastapi_augment-0.1.4/src/fastapi_augment/config/__init__.py +12 -0
  11. fastapi_augment-0.1.4/src/fastapi_augment/config/base_settings.py +253 -0
  12. fastapi_augment-0.1.4/src/fastapi_augment/config/database_settings.py +219 -0
  13. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/alembic/env.py +1 -1
  14. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/engine.py +9 -2
  15. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/migrate.py +7 -7
  16. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/mixins/__init__.py +1 -1
  17. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/mixins/audit.py +3 -3
  18. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/mixins/soft_delete.py +4 -4
  19. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/mixins/timestamp.py +3 -3
  20. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/query_parser.py +2 -2
  21. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/repository_base.py +8 -5
  22. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/session.py +5 -5
  23. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/factory.py +15 -7
  24. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/health/__init__.py +6 -6
  25. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/health/checker.py +13 -9
  26. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/health/checkers.py +38 -21
  27. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/health/router.py +13 -8
  28. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/lifespan.py +23 -21
  29. {fastapi_augment-0.1.3/src/fastapi_augment/log → fastapi_augment-0.1.4/src/fastapi_augment/logger}/__init__.py +9 -9
  30. {fastapi_augment-0.1.3/src/fastapi_augment/log → fastapi_augment-0.1.4/src/fastapi_augment/logger}/filters.py +3 -3
  31. {fastapi_augment-0.1.3/src/fastapi_augment/log → fastapi_augment-0.1.4/src/fastapi_augment/logger}/handlers.py +14 -15
  32. fastapi_augment-0.1.3/src/fastapi_augment/log/factory.py → fastapi_augment-0.1.4/src/fastapi_augment/logger/record_factory.py +5 -5
  33. fastapi_augment-0.1.3/src/fastapi_augment/log/config.py → fastapi_augment-0.1.4/src/fastapi_augment/logger/setup.py +17 -9
  34. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/middlewares/base.py +4 -4
  35. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/middlewares/request_id.py +3 -3
  36. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/openapi.py +6 -9
  37. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment.egg-info/PKG-INFO +22 -17
  38. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment.egg-info/SOURCES.txt +7 -6
  39. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_config.py +23 -23
  40. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_factory.py +2 -2
  41. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_log.py +21 -21
  42. fastapi_augment-0.1.4/tests/test_settings.py +128 -0
  43. fastapi_augment-0.1.3/VERSION +0 -1
  44. fastapi_augment-0.1.3/src/fastapi_augment/config/__init__.py +0 -8
  45. fastapi_augment-0.1.3/src/fastapi_augment/config/settings.py +0 -121
  46. fastapi_augment-0.1.3/tests/test_settings.py +0 -78
  47. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/pyproject.toml +0 -0
  48. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/setup.cfg +0 -0
  49. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/__init__.py +0 -0
  50. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/common/__init__.py +0 -0
  51. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/__init__.py +0 -0
  52. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/__init__.py +0 -0
  53. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/alembic/README +0 -0
  54. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/alembic/__init__.py +0 -0
  55. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/alembic/script.py.mako +0 -0
  56. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/base.py +0 -0
  57. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/db/sqlalchemy/model_base.py +0 -0
  58. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/middlewares/__init__.py +0 -0
  59. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/py.typed +0 -0
  60. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/schemas/__init__.py +0 -0
  61. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/schemas/base.py +0 -0
  62. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/schemas/pagination.py +0 -0
  63. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/schemas/request.py +0 -0
  64. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/schemas/response.py +0 -0
  65. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment/schemas/types.py +0 -0
  66. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment.egg-info/dependency_links.txt +0 -0
  67. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment.egg-info/entry_points.txt +0 -0
  68. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment.egg-info/requires.txt +0 -0
  69. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/src/fastapi_augment.egg-info/top_level.txt +0 -0
  70. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_constants.py +0 -0
  71. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_db_engine.py +0 -0
  72. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_db_repository.py +0 -0
  73. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_db_session_models.py +0 -0
  74. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_exception_handlers.py +0 -0
  75. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_exceptions.py +0 -0
  76. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_health.py +0 -0
  77. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_lifespan.py +0 -0
  78. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_middlewares.py +0 -0
  79. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_migrate.py +0 -0
  80. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_model_base.py +0 -0
  81. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_openapi.py +0 -0
  82. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_query_parser.py +0 -0
  83. {fastapi_augment-0.1.3 → fastapi_augment-0.1.4}/tests/test_schemas.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-augment
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: FastAPI 通用代码工具包,跨项目复用
5
5
  Author-email: zarkhan <hanguangzheng@qq.com>
6
6
  License-Expression: MIT
@@ -597,12 +597,12 @@ raise BadRequestError(detail='用户名不能为空')
597
597
  raise TooManyRequestsError(retry_after=60)
598
598
  ```
599
599
 
600
- ### 日志管理 — `log`
600
+ ### 日志管理 — `logger`
601
601
 
602
602
  导入即生效:自动注入 `request_id` 到每条日志、接管 uvicorn/fastapi 日志输出。
603
603
 
604
604
  ```python
605
- from fastapi_augment.log import setup_logger, set_log_level
605
+ from fastapi_augment.logger import setup_logger, set_log_level
606
606
 
607
607
  # 一键配置:控制台 + 按天轮转文件日志
608
608
  setup_logger(log_dir='./logs', rotation='day', backup_count=30)
@@ -691,26 +691,30 @@ app.include_router(create_health_router(
691
691
 
692
692
  ### 配置管理 — `config`
693
693
 
694
- 基于 `pydantic-settings`,通过 `from_env()` 直接传参,无需手动导入 `SettingsConfigDict`:
694
+ 基于 `pydantic-settings`,支持多种配置来源(环境变量、.env、JSON、YAML、TOML),通过不同类方法加载:
695
695
 
696
696
  ```python
697
- from fastapi_augment.config import EnvSettings
697
+ from fastapi_augment.config import AugmentBaseSettings
698
698
 
699
- class Settings(EnvSettings):
699
+ class Settings(AugmentBaseSettings):
700
700
  database_url: str
701
701
  redis_url: str = ''
702
702
  debug: bool = False
703
703
  secret_key: str = 'change-me'
704
704
 
705
- # 直接传入 .env 路径、前缀等
706
- settings = Settings.from_env(
707
- env_file='config/.env',
708
- env_prefix='APP_',
709
- env_nested_delimiter='__',
710
- )
705
+ # 从环境变量加载
706
+ cfg = Settings.from_env(env_prefix='APP_', env_nested_delimiter='__')
707
+
708
+ # 从 .env 文件加载
709
+ cfg = Settings.from_dotenv('.env', env_prefix='APP_')
710
+
711
+ # 从 JSON / YAML / TOML 文件加载
712
+ cfg = Settings.from_json('config.json')
713
+ cfg = Settings.from_yaml('config.yaml')
714
+ cfg = Settings.from_toml('config.toml')
711
715
  ```
712
716
 
713
- 支持 `SettingsConfigDict` 的所有参数(`env_file`、`env_prefix`、`secrets_dir`、`yaml_file` 等),
717
+ 支持 `SettingsConfigDict` 的所有参数(`env_prefix`、`secrets_dir`、`yaml_file` 等),
714
718
  与模型字段值自动区分,无需关心分类。
715
719
 
716
720
  ### 中间件 — `middlewares`
@@ -736,7 +740,8 @@ fastapi_augment/
736
740
  │ └── utils/
737
741
  │ └── strings.py # 字符串工具 / JSON 序列化
738
742
  ├── config/
739
- │ └── settings.py # EnvSettings 配置管理
743
+ │ ├── base_settings.py # AugmentBaseSettings 配置管理
744
+ │ └── database_settings.py # DatabaseSettings 数据库配置
740
745
  ├── db/
741
746
  │ └── sqlalchemy/
742
747
  │ ├── engine.py # EngineManager / NodeConfig / ClusterTopology
@@ -751,11 +756,11 @@ fastapi_augment/
751
756
  │ ├── checker.py # BaseChecker / CheckResult / HealthResponse
752
757
  │ ├── checkers.py # AppChecker / DatabaseChecker
753
758
  │ └── router.py # create_health_router()
754
- ├── log/
755
- │ ├── factory.py # request_id 注入工厂
759
+ ├── logger/
760
+ │ ├── record_factory.py # request_id 注入工厂
756
761
  │ ├── filters.py # UvicornNameRewriteFilter
757
762
  │ ├── handlers.py # 多进程安全轮转处理器
758
- │ └── config.py # setup_logger / set_log_level / set_log_format
763
+ │ └── setup.py # setup_logger / set_log_level / set_log_format
759
764
  ├── middlewares/
760
765
  │ ├── base.py # BaseASGIMiddleware
761
766
  │ └── request_id.py # RequestId 中间件
@@ -560,12 +560,12 @@ raise BadRequestError(detail='用户名不能为空')
560
560
  raise TooManyRequestsError(retry_after=60)
561
561
  ```
562
562
 
563
- ### 日志管理 — `log`
563
+ ### 日志管理 — `logger`
564
564
 
565
565
  导入即生效:自动注入 `request_id` 到每条日志、接管 uvicorn/fastapi 日志输出。
566
566
 
567
567
  ```python
568
- from fastapi_augment.log import setup_logger, set_log_level
568
+ from fastapi_augment.logger import setup_logger, set_log_level
569
569
 
570
570
  # 一键配置:控制台 + 按天轮转文件日志
571
571
  setup_logger(log_dir='./logs', rotation='day', backup_count=30)
@@ -654,26 +654,30 @@ app.include_router(create_health_router(
654
654
 
655
655
  ### 配置管理 — `config`
656
656
 
657
- 基于 `pydantic-settings`,通过 `from_env()` 直接传参,无需手动导入 `SettingsConfigDict`:
657
+ 基于 `pydantic-settings`,支持多种配置来源(环境变量、.env、JSON、YAML、TOML),通过不同类方法加载:
658
658
 
659
659
  ```python
660
- from fastapi_augment.config import EnvSettings
660
+ from fastapi_augment.config import AugmentBaseSettings
661
661
 
662
- class Settings(EnvSettings):
662
+ class Settings(AugmentBaseSettings):
663
663
  database_url: str
664
664
  redis_url: str = ''
665
665
  debug: bool = False
666
666
  secret_key: str = 'change-me'
667
667
 
668
- # 直接传入 .env 路径、前缀等
669
- settings = Settings.from_env(
670
- env_file='config/.env',
671
- env_prefix='APP_',
672
- env_nested_delimiter='__',
673
- )
668
+ # 从环境变量加载
669
+ cfg = Settings.from_env(env_prefix='APP_', env_nested_delimiter='__')
670
+
671
+ # 从 .env 文件加载
672
+ cfg = Settings.from_dotenv('.env', env_prefix='APP_')
673
+
674
+ # 从 JSON / YAML / TOML 文件加载
675
+ cfg = Settings.from_json('config.json')
676
+ cfg = Settings.from_yaml('config.yaml')
677
+ cfg = Settings.from_toml('config.toml')
674
678
  ```
675
679
 
676
- 支持 `SettingsConfigDict` 的所有参数(`env_file`、`env_prefix`、`secrets_dir`、`yaml_file` 等),
680
+ 支持 `SettingsConfigDict` 的所有参数(`env_prefix`、`secrets_dir`、`yaml_file` 等),
677
681
  与模型字段值自动区分,无需关心分类。
678
682
 
679
683
  ### 中间件 — `middlewares`
@@ -699,7 +703,8 @@ fastapi_augment/
699
703
  │ └── utils/
700
704
  │ └── strings.py # 字符串工具 / JSON 序列化
701
705
  ├── config/
702
- │ └── settings.py # EnvSettings 配置管理
706
+ │ ├── base_settings.py # AugmentBaseSettings 配置管理
707
+ │ └── database_settings.py # DatabaseSettings 数据库配置
703
708
  ├── db/
704
709
  │ └── sqlalchemy/
705
710
  │ ├── engine.py # EngineManager / NodeConfig / ClusterTopology
@@ -714,11 +719,11 @@ fastapi_augment/
714
719
  │ ├── checker.py # BaseChecker / CheckResult / HealthResponse
715
720
  │ ├── checkers.py # AppChecker / DatabaseChecker
716
721
  │ └── router.py # create_health_router()
717
- ├── log/
718
- │ ├── factory.py # request_id 注入工厂
722
+ ├── logger/
723
+ │ ├── record_factory.py # request_id 注入工厂
719
724
  │ ├── filters.py # UvicornNameRewriteFilter
720
725
  │ ├── handlers.py # 多进程安全轮转处理器
721
- │ └── config.py # setup_logger / set_log_level / set_log_format
726
+ │ └── setup.py # setup_logger / set_log_level / set_log_format
722
727
  ├── middlewares/
723
728
  │ ├── base.py # BaseASGIMiddleware
724
729
  │ └── request_id.py # RequestId 中间件
@@ -0,0 +1 @@
1
+ 0.1.4
@@ -1,7 +1,7 @@
1
1
  """
2
2
  @Author : hangu
3
3
  @CreateDate : 2026/9/4
4
- @Description :
4
+ @Description : 全局常量与统一默认错误文案
5
5
  """
6
6
  from starlette import status
7
7
 
@@ -21,6 +21,7 @@ DEFAULT_ERR_MSG: dict[int, str] = {
21
21
  status.HTTP_413_CONTENT_TOO_LARGE: 'Payload too large',
22
22
  status.HTTP_414_URI_TOO_LONG: 'URI too long',
23
23
  status.HTTP_415_UNSUPPORTED_MEDIA_TYPE: 'Unsupported media type',
24
+ status.HTTP_422_UNPROCESSABLE_CONTENT: 'Unprocessable entity',
24
25
  status.HTTP_423_LOCKED: 'Locked',
25
26
  status.HTTP_429_TOO_MANY_REQUESTS: 'Too many requests',
26
27
  }
@@ -27,11 +27,11 @@ async def base_http_error_handler(
27
27
  _request: Request,
28
28
  exc: BaseHttpError,
29
29
  ) -> JSONResponse:
30
- """处理 BaseHttpError 及其所有子类(统一业务异常)。
30
+ """处理 BaseHttpError 及其所有子类(统一业务异常)
31
31
 
32
32
  将业务异常转换为统一 APIResponse 格式,
33
33
  HTTP 状态码与 exc.status_code 一致,
34
- body.code 同样使用 HTTP 状态码,body.message 使用 exc.detail。
34
+ body.code 同样使用 HTTP 状态码,body.message 使用 exc.detail
35
35
 
36
36
  Args:
37
37
  _request: Starlette Request 对象
@@ -54,11 +54,11 @@ async def http_exception_handler(
54
54
  _request: Request,
55
55
  exc: HTTPException,
56
56
  ) -> JSONResponse:
57
- """处理 Starlette/FastAPI 原生 HTTPException。
57
+ """处理 Starlette/FastAPI 原生 HTTPException
58
58
 
59
- 覆盖 FastAPI 默认处理器,将响应格式统一为 APIResponse。
59
+ 覆盖 FastAPI 默认处理器,将响应格式统一为 APIResponse
60
60
  注意:BaseHttpError 继承自 HTTPException,但 FastAPI 会优先匹配
61
- 更具体的处理器(base_http_error_handler),所以此处不会拦截业务异常。
61
+ 更具体的处理器(base_http_error_handler),所以此处不会拦截业务异常
62
62
 
63
63
  Args:
64
64
  _request: Starlette Request 对象
@@ -84,9 +84,9 @@ async def validation_exception_handler(
84
84
  _request: Request,
85
85
  exc: RequestValidationError,
86
86
  ) -> JSONResponse:
87
- """处理 Pydantic 请求参数校验异常(422)。
87
+ """处理 Pydantic 请求参数校验异常(422)
88
88
 
89
- 将校验错误详情提取到 extra.errors 中,方便前端定位具体字段。
89
+ 将校验错误详情提取到 extra.errors 中,方便前端定位具体字段
90
90
 
91
91
  Args:
92
92
  _request: Starlette Request 对象
@@ -121,10 +121,10 @@ async def general_exception_handler(
121
121
  _request: Request,
122
122
  exc: Exception,
123
123
  ) -> JSONResponse:
124
- """处理所有未被捕获的异常(兜底)。
124
+ """处理所有未被捕获的异常(兜底)
125
125
 
126
126
  记录完整异常日志(含堆栈),但响应体只返回通用提示,
127
- 避免将内部实现细节(堆栈、SQL 等)暴露给客户端。
127
+ 避免将内部实现细节(堆栈、SQL 等)暴露给客户端
128
128
 
129
129
  Args:
130
130
  _request: Starlette Request 对象
@@ -144,7 +144,7 @@ async def general_exception_handler(
144
144
  # ===================== 一键注册 =====================
145
145
 
146
146
  def register_exception_handlers(app: FastAPI) -> None:
147
- """将全部统一异常处理器注册到 FastAPI 应用。
147
+ """将全部统一异常处理器注册到 FastAPI 应用
148
148
 
149
149
  注册后,以下异常会被转换为统一的 APIResponse 格式:
150
150
  - BaseHttpError 及子类 → 对应 HTTP 状态码
@@ -13,7 +13,7 @@ from .constants import DEFAULT_ERR_MSG
13
13
 
14
14
  # ===================== 通用基类:统一封装 detail + headers 逻辑 =====================
15
15
  class BaseHttpError(HTTPException):
16
- """统一HTTP异常基类,所有4xx异常继承此类,原生兼容starlette.HTTPException.
16
+ """统一HTTP异常基类,所有4xx异常继承此类,原生兼容starlette.HTTPException
17
17
 
18
18
  子类只需声明 ``_status_code`` 类变量,无需重写 __init__::
19
19
 
@@ -38,7 +38,7 @@ class BaseHttpError(HTTPException):
38
38
  detail: str | None = None,
39
39
  headers: dict[str, Any] | None = None,
40
40
  ):
41
- """初始化http业务异常.
41
+ """初始化http业务异常
42
42
 
43
43
  Args:
44
44
  status_code: http响应状态码,不传则读取子类的 _status_code 类变量
@@ -62,82 +62,82 @@ class BaseHttpError(HTTPException):
62
62
  # ===================== 各类4xx异常子类(极简声明,无重复__init__) =====================
63
63
  # 子类只需声明 _status_code 类变量,__init__ 由基类统一处理
64
64
  class BadRequestError(BaseHttpError):
65
- """400 请求错误."""
65
+ """400 请求错误"""
66
66
  _status_code = status.HTTP_400_BAD_REQUEST
67
67
 
68
68
 
69
69
  class UnauthorizedError(BaseHttpError):
70
- """401 未授权错误."""
70
+ """401 未授权错误"""
71
71
  _status_code = status.HTTP_401_UNAUTHORIZED
72
72
 
73
73
 
74
74
  class PaymentRequiredError(BaseHttpError):
75
- """402 需要付费错误."""
75
+ """402 需要付费错误"""
76
76
  _status_code = status.HTTP_402_PAYMENT_REQUIRED
77
77
 
78
78
 
79
79
  class ForbiddenError(BaseHttpError):
80
- """403 禁止访问错误."""
80
+ """403 禁止访问错误"""
81
81
  _status_code = status.HTTP_403_FORBIDDEN
82
82
 
83
83
 
84
84
  class NotFoundError(BaseHttpError):
85
- """404 未找到资源."""
85
+ """404 未找到资源"""
86
86
  _status_code = status.HTTP_404_NOT_FOUND
87
87
 
88
88
 
89
89
  class MethodNotAllowedError(BaseHttpError):
90
- """405 请求方法不允许."""
90
+ """405 请求方法不允许"""
91
91
  _status_code = status.HTTP_405_METHOD_NOT_ALLOWED
92
92
 
93
93
 
94
94
  class NotAcceptableError(BaseHttpError):
95
- """406 客户端不支持返回格式."""
95
+ """406 客户端不支持返回格式"""
96
96
  _status_code = status.HTTP_406_NOT_ACCEPTABLE
97
97
 
98
98
 
99
99
  class RequestTimeoutError(BaseHttpError):
100
- """408 请求超时."""
100
+ """408 请求超时"""
101
101
  _status_code = status.HTTP_408_REQUEST_TIMEOUT
102
102
 
103
103
 
104
104
  class ConflictError(BaseHttpError):
105
- """409 资源冲突."""
105
+ """409 资源冲突"""
106
106
  _status_code = status.HTTP_409_CONFLICT
107
107
 
108
108
 
109
109
  class GoneError(BaseHttpError):
110
- """410 资源已永久删除."""
110
+ """410 资源已永久删除"""
111
111
  _status_code = status.HTTP_410_GONE
112
112
 
113
113
 
114
114
  class PreconditionFailedError(BaseHttpError):
115
- """412 前置校验失败."""
115
+ """412 前置校验失败"""
116
116
  _status_code = status.HTTP_412_PRECONDITION_FAILED
117
117
 
118
118
 
119
119
  class PayloadTooLargeError(BaseHttpError):
120
- """413 请求体过大."""
120
+ """413 请求体过大"""
121
121
  _status_code = status.HTTP_413_CONTENT_TOO_LARGE
122
122
 
123
123
 
124
124
  class URITooLongError(BaseHttpError):
125
- """414 URI链接过长."""
125
+ """414 URI链接过长"""
126
126
  _status_code = status.HTTP_414_URI_TOO_LONG
127
127
 
128
128
 
129
129
  class UnsupportedMediaTypeError(BaseHttpError):
130
- """415 不支持的请求媒体类型."""
130
+ """415 不支持的请求媒体类型"""
131
131
  _status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE
132
132
 
133
133
 
134
134
  class LockedError(BaseHttpError):
135
- """423 资源锁定."""
135
+ """423 资源锁定"""
136
136
  _status_code = status.HTTP_423_LOCKED
137
137
 
138
138
 
139
139
  class TooManyRequestsError(BaseHttpError):
140
- """429 请求过于频繁(限流专用,支持retry_after快捷参数)."""
140
+ """429 请求过于频繁(限流专用,支持retry_after快捷参数)"""
141
141
  _status_code = status.HTTP_429_TOO_MANY_REQUESTS
142
142
 
143
143
  def __init__(
@@ -1,7 +1,7 @@
1
1
  """
2
2
  @Author : hangu
3
3
  @CreateDate : 2026/9/4
4
- @Description :
4
+ @Description : 通用工具函数(路径、字符串、JSON 序列化)
5
5
  """
6
6
  from .paths import get_root_dir
7
7
  from .strings import (
@@ -1,7 +1,7 @@
1
1
  """
2
2
  @Author : hangu
3
3
  @CreateDate : 2026/9/9
4
- @Description :
4
+ @Description : 项目路径工具函数
5
5
  """
6
6
  import sys
7
7
  from pathlib import Path
@@ -10,10 +10,10 @@ from pathlib import Path
10
10
  # 获取项目根目录路径
11
11
  def get_root_dir(reference_path: str | Path, parent_index: int) -> Path:
12
12
  """
13
- 动态获取项目根目录路径,兼容源码开发环境与 PyInstaller/Nuitka 打包二进制环境。
13
+ 动态获取项目根目录路径,兼容源码开发环境与 PyInstaller/Nuitka 打包二进制环境
14
14
 
15
15
  源码模式:以传入的参考路径为基准,向上回溯 parent_index 层目录得到项目根;
16
- 打包 frozen 模式:自动返回可执行文件(.exe/二进制)所在目录,忽略 reference_path、parent_index。
16
+ 打包 frozen 模式:自动返回可执行文件(.exe/二进制)所在目录,忽略 reference_path、parent_index
17
17
 
18
18
  Args:
19
19
  reference_path: 锚点参考路径,业务调用一般直接传入 __file__
@@ -1,7 +1,7 @@
1
1
  """
2
2
  @Author : hangu
3
3
  @CreateDate : 2026/9/4
4
- @Description :
4
+ @Description : 字符串工具函数——命名转换、随机串、JSON 序列化
5
5
  """
6
6
  import json
7
7
  import random
@@ -40,7 +40,11 @@ _ORJSON_OPT_INDENT_2 = 0x04
40
40
 
41
41
  # ── 字符串转换 ──
42
42
  def camel_to_snake(s: str) -> str:
43
- """驼峰转下划线(支持连续大写)"""
43
+ """驼峰转下划线(支持连续大写)
44
+
45
+ Returns:
46
+ 转换后的下划线命名字符串
47
+ """
44
48
  if not s:
45
49
  return s
46
50
  result: list[str] = []
@@ -58,7 +62,11 @@ def camel_to_snake(s: str) -> str:
58
62
 
59
63
 
60
64
  def snake_to_camel(s: str) -> str:
61
- """下划线转驼峰(首字母大写)"""
65
+ """下划线转驼峰(首字母大写)
66
+
67
+ Returns:
68
+ 转换后的驼峰命名字符串
69
+ """
62
70
  if not s:
63
71
  return s
64
72
  return ''.join(part.capitalize() for part in s.split('_'))
@@ -72,9 +80,14 @@ def random_string(
72
80
  ) -> str:
73
81
  """生成随机字符串,支持自定义字符集
74
82
 
83
+ Returns:
84
+ 指定长度的随机字符串
85
+
75
86
  Raises:
76
- ValueError: 字符集为空时(exclude 排除了所有字符)
87
+ ValueError: length 非正整数或字符集为空时(exclude 排除了所有字符)
77
88
  """
89
+ if length < 1:
90
+ raise ValueError(f'length 必须为正整数,当前值: {length}')
78
91
  if chars is None:
79
92
  chars = string.ascii_letters + string.digits
80
93
  if exclude:
@@ -0,0 +1,12 @@
1
+ """
2
+ @Author : zarkhan
3
+ @CreateDate : 2026/9/6
4
+ @Description : 配置管理模块
5
+ """
6
+ from .base_settings import AugmentBaseSettings
7
+ from .database_settings import DatabaseSettings
8
+
9
+ __all__ = [
10
+ 'AugmentBaseSettings',
11
+ 'DatabaseSettings'
12
+ ]