main.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import logging
  2. import uuid
  3. from logging.handlers import RotatingFileHandler
  4. from fastapi import FastAPI, Request, Response, status
  5. from typing import Optional, Set
  6. # 导入FastAPI及相关模块
  7. import os
  8. import uvicorn
  9. from router.nodes_api import nodes_api_router
  10. # 配置日志
  11. logging.basicConfig(
  12. level=logging.INFO,
  13. format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
  14. handlers=[
  15. logging.StreamHandler(),
  16. RotatingFileHandler('app.log', maxBytes=10485760, backupCount=5, encoding='utf-8')
  17. ]
  18. )
  19. logger = logging.getLogger(__name__)
  20. logger.propagate = True
  21. # 创建FastAPI应用
  22. app = FastAPI(title="知识图谱")
  23. app.include_router(nodes_api_router)
  24. # 需要拦截的 URL 列表(支持通配符)
  25. INTERCEPT_URLS = {
  26. "/v1/knowledge/*"
  27. }
  28. # 白名单 URL(不需要拦截的路径)
  29. WHITE_LIST = {
  30. "/api/public",
  31. "/admin/login"
  32. }
  33. async def verify_token(authorization: str) -> Optional[dict]:
  34. """
  35. 验证 token 有效性
  36. 返回:验证成功返回用户信息字典,失败返回 None
  37. """
  38. if not authorization.startswith("Bearer "):
  39. return None
  40. token = authorization[7:]
  41. # 这里添加实际的 token 验证逻辑
  42. # 示例:简单验证 token 是否等于 secret-token
  43. if token == "3xY7-p9Kq-2FmR-8LzN":
  44. return {"id": 1, "username": "admin", "role": "admin"}
  45. return None
  46. def should_intercept(path: str) -> bool:
  47. """
  48. 判断是否需要拦截当前路径
  49. """
  50. if path in WHITE_LIST:
  51. return False
  52. for pattern in INTERCEPT_URLS:
  53. # 处理通配符匹配
  54. if pattern.endswith("/*"):
  55. if path.startswith(pattern[:-1]):
  56. return True
  57. # 精确匹配
  58. elif path == pattern:
  59. return True
  60. return False
  61. @app.middleware("http")
  62. async def interceptor_middleware(request: Request, call_next):
  63. path = request.url.path
  64. if not should_intercept(path):
  65. return await call_next(request)
  66. # 权限校验
  67. auth_header = request.headers.get("Authorization")
  68. if not auth_header:
  69. return Response(
  70. content="Missing Authorization header",
  71. status_code=status.HTTP_401_UNAUTHORIZED
  72. )
  73. user_info = await verify_token(auth_header)
  74. if not user_info:
  75. return Response(
  76. content="Invalid token",
  77. status_code=status.HTTP_401_UNAUTHORIZED
  78. )
  79. # 初始化操作:将用户信息添加到请求状态中
  80. request.state.user = user_info
  81. # 添加请求上下文(示例)
  82. request.state.context = {
  83. "request_id": request.headers.get("request-id", str(uuid.uuid4())),
  84. "client_ip": request.client.host
  85. }
  86. # 继续处理请求
  87. response = await call_next(request)
  88. # 可以在返回前添加统一响应处理(如添加头信息)
  89. response.headers["request-id"]=request.state.context["request_id"]
  90. return response
  91. if __name__ == "__main__":
  92. logger.info('Starting uvicorn server...2222')
  93. #uvicorn main:app --host 0.0.0.0 --port 8000 --reload
  94. uvicorn.run("main:app", host="0.0.0.0", port=8008, reload=False)