Kaynağa Gözat

调整项目结构

liujintao 1 ay önce
ebeveyn
işleme
8b01b02fdb

+ 7 - 4
README.md

@@ -17,10 +17,13 @@
 ```
 app/
 ├── main.py                    # FastAPI 入口、lifespan、leader 选举、健康检查
-├── config.py                  # 配置加载(按 APP_ENV 切换 .env / .env.dev)
-├── schemas.py                 # 请求/响应 Pydantic 模型
-├── response.py                # 统一响应类 + 业务错误码 + BusinessError
-├── exception_handlers.py      # 全局异常处理器
+├── schemas.py                 # 业务数据模型(SearchData、CacheStatus 等)
+├── core/                      # 框架级基础设施(与业务无关)
+│   ├── config.py              # 配置加载(按 APP_ENV 切换 .env / .env.dev)
+│   ├── response.py            # 统一响应类 + 业务错误码 + BusinessError
+│   ├── exception_handlers.py  # 全局异常处理器(统一 {code, data, msg})
+│   ├── openapi.py             # OpenAPI 文档错误响应统一覆写
+│   └── docs_auth.py           # Swagger/ReDoc HTTP Basic 认证
 ├── routers/
 │   └── search.py              # /search 接口
 └── services/

+ 0 - 0
app/core/__init__.py


+ 0 - 0
app/config.py → app/core/config.py


+ 2 - 2
app/docs_auth.py → app/core/docs_auth.py

@@ -4,7 +4,7 @@
 本模块关闭这些公开路由,改为注册受 HTTP Basic 认证保护的等价路由。
 
 用法(在 app/main.py 中):
-    from app.docs_auth import setup_protected_docs
+    from app.core.docs_auth import setup_protected_docs
 
     app = FastAPI(
         ...
@@ -22,7 +22,7 @@ from fastapi import Depends, FastAPI, HTTPException, status
 from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
 from fastapi.security import HTTPBasic, HTTPBasicCredentials
 
-from app.config import settings
+from app.core.config import settings
 
 # auto_error=False 让我们自己处理无凭据的情况,
 # 否则 FastAPI 抛出的 401 不带 WWW-Authenticate 头,浏览器不会弹登录框

+ 1 - 1
app/exception_handlers.py → app/core/exception_handlers.py

@@ -10,7 +10,7 @@ from fastapi.exceptions import RequestValidationError
 from starlette.exceptions import HTTPException as StarletteHTTPException
 from starlette.responses import JSONResponse
 
-from app.response import BusinessError, ResponseCode, error_response
+from app.core.response import BusinessError, ResponseCode, error_response
 
 logger = logging.getLogger(__name__)
 

+ 1 - 1
app/openapi.py → app/core/openapi.py

@@ -13,7 +13,7 @@ from typing import Any
 from fastapi import FastAPI
 from fastapi.openapi.utils import get_openapi
 
-from app.response import ResponseCode
+from app.core.response import ResponseCode
 
 # 需要在 OpenAPI 文档中替换的错误状态码 → (业务码, 描述, data 示例)
 # 与 app/exception_handlers.py 中的处理器返回值保持一致

+ 0 - 0
app/response.py → app/core/response.py


+ 5 - 7
app/main.py

@@ -1,4 +1,3 @@
-"""FastAPI 应用入口。"""
 from __future__ import annotations
 
 import asyncio
@@ -8,11 +7,11 @@ from typing import AsyncIterator
 
 from fastapi import FastAPI
 
-from app.config import settings
-from app.docs_auth import setup_protected_docs
-from app.exception_handlers import register_exception_handlers
-from app.openapi import setup_custom_openapi
-from app.response import ApiResponse
+from app.core.config import settings
+from app.core.docs_auth import setup_protected_docs
+from app.core.exception_handlers import register_exception_handlers
+from app.core.openapi import setup_custom_openapi
+from app.core.response import ApiResponse
 from app.routers import search
 from app.schemas import CacheRefreshResult, CacheStatus
 from app.services.cache import (
@@ -89,7 +88,6 @@ app = FastAPI(
     description="封装 Zendesk Help Center 搜索;FAQ",
     version="1.0.0",
     lifespan=lifespan,
-    # 关闭默认 docs,由 setup_protected_docs 注册受 HTTP Basic 保护的等价路由
     docs_url=None,
     redoc_url=None,
     openapi_url=None,

+ 1 - 2
app/routers/search.py

@@ -1,11 +1,10 @@
-"""搜索接口路由。"""
 from __future__ import annotations
 
 import logging
 
 from fastapi import APIRouter, Query
 
-from app.response import ApiResponse, BusinessError, ResponseCode
+from app.core.response import ApiResponse, BusinessError, ResponseCode
 from app.schemas import SearchData, SearchRequest
 from app.services.cache import get_snapshot
 from app.services.zendesk_client import ZendeskError, search_articles

+ 1 - 1
app/services/cache.py

@@ -16,7 +16,7 @@ import uuid
 from datetime import datetime, time, timedelta
 from typing import Any
 
-from app.config import settings
+from app.core.config import settings
 from app.services.redis_client import (
     KEY_CACHE_DATA,
     KEY_LOCK_LEADER,

+ 1 - 1
app/services/redis_client.py

@@ -9,7 +9,7 @@ from typing import Optional
 
 from redis.asyncio import Redis, from_url
 
-from app.config import settings
+from app.core.config import settings
 
 logger = logging.getLogger(__name__)
 

+ 1 - 1
app/services/zendesk_client.py

@@ -12,7 +12,7 @@ from typing import Any
 
 import httpx
 
-from app.config import settings
+from app.core.config import settings
 
 logger = logging.getLogger(__name__)