From 86b030930c9d2efb5521ef4230d8201696590ab4 Mon Sep 17 00:00:00 2001 From: Zayden Jung Date: Tue, 19 May 2026 01:39:57 +0800 Subject: [PATCH] fix bugs for launch: postgresql url for sqlalchemy; auto loading env --- app/auth/__init__.py | 15 +++++++++++++++ app/auth/deps.py | 2 +- app/auth/jwt.py | 2 +- app/db.py | 14 ++++++++++++++ app/main.py | 7 ++----- pyproject.toml | 2 ++ uv.lock | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 71 insertions(+), 7 deletions(-) diff --git a/app/auth/__init__.py b/app/auth/__init__.py index e69de29..941a26b 100644 --- a/app/auth/__init__.py +++ b/app/auth/__init__.py @@ -0,0 +1,15 @@ +from fastapi import APIRouter +from .deps import get_current_user +from .jwt import create_jwt_token, create_refresh_token, verify_access_token + +# 统一创建并导出路由器,满足 main.py 的 include_router 需求 +router = APIRouter(tags=["Authentication"]) + +# 显式声明这个包对外暴露的接口 +__all__ = [ + "router", + "get_current_user", + "create_jwt_token", + "create_refresh_token", + "verify_access_token", +] \ No newline at end of file diff --git a/app/auth/deps.py b/app/auth/deps.py index e9f625b..4e4061d 100644 --- a/app/auth/deps.py +++ b/app/auth/deps.py @@ -1,6 +1,6 @@ from fastapi import Request, HTTPException -import app.auth.jwt as jwt import os +from . import jwt JWT_SECRET = os.getenv("JWT_SECRET") JWT_ALGORITHM = os.getenv("JWT_ALGORITHM", "HS256") diff --git a/app/auth/jwt.py b/app/auth/jwt.py index 4f485b9..c955d31 100644 --- a/app/auth/jwt.py +++ b/app/auth/jwt.py @@ -1,6 +1,6 @@ -import app.auth.jwt as jwt from datetime import datetime, timedelta, timezone import os +import jwt from fastapi import HTTPException, status JWT_SECRET = os.getenv("JWT_SECRET") diff --git a/app/db.py b/app/db.py index 7ebdf59..7c22dd1 100644 --- a/app/db.py +++ b/app/db.py @@ -1,8 +1,22 @@ import os from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker +from dotenv import load_dotenv + +# 加载 .env 文件 +load_dotenv() DATABASE_URL = os.getenv("DATABASE_URL") +# 自动将旧版的 postgres:// 替换为 SQLAlchemy 强要求的 postgresql:// +if DATABASE_URL and DATABASE_URL.startswith("postgres://"): + DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1) +elif DATABASE_URL and DATABASE_URL.startswith("postgres+"): + DATABASE_URL = DATABASE_URL.replace("postgres+", "postgresql+", 1) + +# 如果环境变量彻底缺失,做一个安全的报错提示 +if not DATABASE_URL: + raise ValueError("DATABASE_URL environment variable is not set or empty.") + engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(bind=engine) \ No newline at end of file diff --git a/app/main.py b/app/main.py index 452f3cf..6e766c2 100644 --- a/app/main.py +++ b/app/main.py @@ -24,8 +24,5 @@ schema = Schema(query=Query, mutation=Mutation) graphql_router = GraphQLRouter(schema, context_getter=get_context) # 挂载路由 -# 保留现有的 auth 路由供 Google OAuth 回调使用 -app.include_router(auth_router) - -# 挂载 GraphQL 终点,前端以后只需要请求 /graphql -app.include_router(graphql_router, prefix="/graphql") \ No newline at end of file +app.include_router(auth_router) # 保留现有的 auth 路由供 Google OAuth 回调使用 +app.include_router(graphql_router, prefix="/graphql") # 挂载 GraphQL 终点,前端以后只需要请求 /graphql \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 2deab75..42028ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,8 +7,10 @@ requires-python = ">=3.14" dependencies = [ "alembic>=1.18.4", "boto3>=1.43.9", + "dotenv>=0.9.9", "fastapi>=0.136.1", "httpx>=0.28.1", + "jwt>=1.4.0", "oss2>=2.19.1", "psycopg2-binary>=2.9.12", "python-jose>=3.5.0", diff --git a/uv.lock b/uv.lock index e572a49..2c9dfc7 100644 --- a/uv.lock +++ b/uv.lock @@ -145,8 +145,10 @@ source = { virtual = "." } dependencies = [ { name = "alembic" }, { name = "boto3" }, + { name = "dotenv" }, { name = "fastapi" }, { name = "httpx" }, + { name = "jwt" }, { name = "oss2" }, { name = "psycopg2-binary" }, { name = "python-jose" }, @@ -160,8 +162,10 @@ dependencies = [ requires-dist = [ { name = "alembic", specifier = ">=1.18.4" }, { name = "boto3", specifier = ">=1.43.9" }, + { name = "dotenv", specifier = ">=0.9.9" }, { name = "fastapi", specifier = ">=0.136.1" }, { name = "httpx", specifier = ">=0.28.1" }, + { name = "jwt", specifier = ">=1.4.0" }, { name = "oss2", specifier = ">=2.19.1" }, { name = "psycopg2-binary", specifier = ">=2.9.12" }, { name = "python-jose", specifier = ">=3.5.0" }, @@ -304,6 +308,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" }, ] +[[package]] +name = "dotenv" +version = "0.9.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dotenv" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/b7/545d2c10c1fc15e48653c91efde329a790f2eecfbbf2bd16003b5db2bab0/dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9", size = 1892, upload-time = "2025-02-19T22:15:01.647Z" }, +] + [[package]] name = "ecdsa" version = "0.19.2" @@ -419,6 +434,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/07/cb/5f001272b6faeb23c1c9e0acc04d48eaaf5c862c17709d20e3469c6e0139/jmespath-0.10.0-py2.py3-none-any.whl", hash = "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f", size = 24489, upload-time = "2020-05-12T22:03:45.643Z" }, ] +[[package]] +name = "jwt" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7f/20/21254c9e601e6c29445d1e8854c2a81bdb554e07a82fb1f9846137a6965c/jwt-1.4.0.tar.gz", hash = "sha256:f6f789128ac247142c79ee10f3dba6e366ec4e77c9920d18c1592e28aa0a7952", size = 24911, upload-time = "2025-06-23T13:28:38.289Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/80/34e3fae850adb0b7b8b9b1cf02b2d975fcb68e0e8eb7d56d6b4fc23f7433/jwt-1.4.0-py3-none-any.whl", hash = "sha256:7560a7f1de4f90de94ac645ee0303ac60c95b9e08e058fb69f6c330f71d71b11", size = 18248, upload-time = "2025-06-23T13:28:37.012Z" }, +] + [[package]] name = "mako" version = "1.3.12" @@ -608,6 +635,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, +] + [[package]] name = "python-jose" version = "3.5.0"