Initial commit
This commit is contained in:
BIN
app/__pycache__/main.cpython-310.pyc
Normal file
BIN
app/__pycache__/main.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/settings.cpython-310.pyc
Normal file
BIN
app/__pycache__/settings.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/api/__pycache__/db.cpython-310.pyc
Normal file
BIN
app/api/__pycache__/db.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/api/__pycache__/login.cpython-310.pyc
Normal file
BIN
app/api/__pycache__/login.cpython-310.pyc
Normal file
Binary file not shown.
BIN
app/api/__pycache__/submit_record.cpython-310.pyc
Normal file
BIN
app/api/__pycache__/submit_record.cpython-310.pyc
Normal file
Binary file not shown.
24
app/api/db.py
Normal file
24
app/api/db.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from sqlalchemy import create_engine, MetaData
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from app.settings import DATABASE_URL
|
||||||
|
|
||||||
|
# 创建SQLAlchemy引擎
|
||||||
|
engine = create_engine(DATABASE_URL)
|
||||||
|
|
||||||
|
# 创建元数据对象
|
||||||
|
metadata = MetaData()
|
||||||
|
|
||||||
|
# 创建会话工厂
|
||||||
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||||
|
|
||||||
|
# 创建基类
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
# 依赖项:获取数据库会话
|
||||||
|
def get_db():
|
||||||
|
db = SessionLocal()
|
||||||
|
try:
|
||||||
|
yield db
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
31
app/api/login.py
Normal file
31
app/api/login.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import text
|
||||||
|
from app.api.db import get_db
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from app.settings import WHITELIST_TABLE, WHITELIST_COLUMN
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
# 请求模型
|
||||||
|
class EmailRequest(BaseModel):
|
||||||
|
email: str
|
||||||
|
|
||||||
|
# 检查邮箱是否在白名单中
|
||||||
|
@router.post("/check-email")
|
||||||
|
async def check_email_in_whitelist(request: EmailRequest, db: Session = Depends(get_db)):
|
||||||
|
try:
|
||||||
|
# 构建查询语句
|
||||||
|
query = text(f"SELECT COUNT(*) FROM {WHITELIST_TABLE} WHERE {WHITELIST_COLUMN} = :email")
|
||||||
|
|
||||||
|
# 执行查询
|
||||||
|
result = db.execute(query, {"email": request.email})
|
||||||
|
count = result.scalar()
|
||||||
|
|
||||||
|
if count > 0:
|
||||||
|
return {"status": "success", "message": "继续操作"}
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=403, detail="邮箱不在白名单中,请联系管理员")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=f"服务器错误:{str(e)}")
|
||||||
43
app/api/submit_record.py
Normal file
43
app/api/submit_record.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import text
|
||||||
|
from app.api.db import get_db
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from app.settings import SUBMIT_RECORD_TABLE
|
||||||
|
from datetime import datetime
|
||||||
|
import pytz
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
class SubmitRecordRequest(BaseModel):
|
||||||
|
user_email: str
|
||||||
|
operation_type: str
|
||||||
|
storage_path: str
|
||||||
|
|
||||||
|
@router.post("/submit-record")
|
||||||
|
async def submit_record(request: SubmitRecordRequest, db: Session = Depends(get_db)):
|
||||||
|
try:
|
||||||
|
if request.operation_type not in ['upload', 'delete']:
|
||||||
|
raise HTTPException(status_code=400, detail="操作类型必须是 'upload' 或 'delete'")
|
||||||
|
|
||||||
|
china_tz = pytz.timezone('Asia/Shanghai')
|
||||||
|
operation_time = datetime.now(china_tz)
|
||||||
|
|
||||||
|
query = text(f"""
|
||||||
|
INSERT INTO {SUBMIT_RECORD_TABLE} (user_email, operation_time, operation_type, storage_path)
|
||||||
|
VALUES (:user_email, :operation_time, :operation_type, :storage_path)
|
||||||
|
""")
|
||||||
|
|
||||||
|
db.execute(query, {
|
||||||
|
"user_email": request.user_email,
|
||||||
|
"operation_time": operation_time,
|
||||||
|
"operation_type": request.operation_type,
|
||||||
|
"storage_path": request.storage_path
|
||||||
|
})
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return {"status": "success", "message": "操作记录已保存"}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.rollback()
|
||||||
|
raise HTTPException(status_code=500, detail=f"服务器错误:{str(e)}")
|
||||||
7
app/base_packages.txt
Normal file
7
app/base_packages.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
name: backend_env
|
||||||
|
channels:
|
||||||
|
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
|
||||||
|
- defaults
|
||||||
|
dependencies:
|
||||||
|
- python=3.10
|
||||||
|
prefix: D:\anaconda3\envs\backend_env
|
||||||
28
app/main.py
Normal file
28
app/main.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from app.api.login import router as login_router
|
||||||
|
from app.api.submit_record import router as submit_record_router
|
||||||
|
from app.api.db import Base, engine
|
||||||
|
from app.settings import API_V1_STR
|
||||||
|
|
||||||
|
# 创建数据库表
|
||||||
|
Base.metadata.create_all(bind=engine)
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title="PBMDB API",
|
||||||
|
description="微生物数据库后端API",
|
||||||
|
version="1.0.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 配置CORS
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"], # 在生产环境中应该设置具体的前端域名
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# 包含路由
|
||||||
|
app.include_router(login_router, prefix=API_V1_STR, tags=["login"])
|
||||||
|
app.include_router(submit_record_router, prefix=API_V1_STR, tags=["submit_record"])
|
||||||
28
app/requirements.txt
Normal file
28
app/requirements.txt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
annotated-doc==0.0.4
|
||||||
|
annotated-types==0.7.0
|
||||||
|
anyio==4.12.0
|
||||||
|
async-timeout==5.0.1
|
||||||
|
asyncpg==0.31.0
|
||||||
|
click==8.3.1
|
||||||
|
colorama==0.4.6
|
||||||
|
databases==0.9.0
|
||||||
|
exceptiongroup==1.3.1
|
||||||
|
fastapi==0.125.0
|
||||||
|
greenlet==3.3.0
|
||||||
|
h11==0.16.0
|
||||||
|
httptools==0.7.1
|
||||||
|
idna==3.11
|
||||||
|
psycopg2==2.9.11
|
||||||
|
psycopg2-binary==2.9.11
|
||||||
|
pydantic==2.12.5
|
||||||
|
pydantic_core==2.41.5
|
||||||
|
python-dotenv==1.2.1
|
||||||
|
pytz==2025.2
|
||||||
|
PyYAML==6.0.3
|
||||||
|
SQLAlchemy==2.0.45
|
||||||
|
starlette==0.50.0
|
||||||
|
typing-inspection==0.4.2
|
||||||
|
typing_extensions==4.15.0
|
||||||
|
uvicorn==0.38.0
|
||||||
|
watchfiles==1.1.1
|
||||||
|
websockets==15.0.1
|
||||||
12
app/settings.py
Normal file
12
app/settings.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# 数据库配置
|
||||||
|
DATABASE_URL = 'postgresql://ABM_DB_user:4FynWQfy0AEotP1dgyimrGF7PSDJh1nDYnDwg4hN@122.205.95.244:5433/ABM_DB'
|
||||||
|
|
||||||
|
# API配置
|
||||||
|
API_V1_STR = "/api/v1"
|
||||||
|
|
||||||
|
# 白名单验证相关配置
|
||||||
|
WHITELIST_TABLE = "submit_user"
|
||||||
|
WHITELIST_COLUMN = "user_email"
|
||||||
|
|
||||||
|
# 操作记录相关配置
|
||||||
|
SUBMIT_RECORD_TABLE = "submit_record"
|
||||||
49
environment.yml
Normal file
49
environment.yml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: backend_env
|
||||||
|
channels:
|
||||||
|
- defaults
|
||||||
|
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
|
||||||
|
dependencies:
|
||||||
|
- bzip2=1.0.8=h2bbff1b_6
|
||||||
|
- ca-certificates=2025.12.2=haa95532_0
|
||||||
|
- expat=2.7.3=h885b0b7_4
|
||||||
|
- libexpat=2.7.3=h885b0b7_4
|
||||||
|
- libffi=3.4.4=hd77b12b_1
|
||||||
|
- libzlib=1.3.1=h02ab6af_0
|
||||||
|
- openssl=3.0.18=h543e019_0
|
||||||
|
- pip=25.3=pyhc872135_0
|
||||||
|
- python=3.10.19=h981015d_0
|
||||||
|
- setuptools=80.9.0=py310haa95532_0
|
||||||
|
- sqlite=3.51.0=hda9a48d_0
|
||||||
|
- tk=8.6.15=hf199647_0
|
||||||
|
- tzdata=2025b=h04d1e81_0
|
||||||
|
- ucrt=10.0.22621.0=haa95532_0
|
||||||
|
- vc=14.3=h2df5915_10
|
||||||
|
- vc14_runtime=14.44.35208=h4927774_10
|
||||||
|
- vs2015_runtime=14.44.35208=ha6b5a95_10
|
||||||
|
- wheel=0.45.1=py310haa95532_0
|
||||||
|
- xz=5.6.4=h4754444_1
|
||||||
|
- zlib=1.3.1=h02ab6af_0
|
||||||
|
- pip:
|
||||||
|
- annotated-doc==0.0.4
|
||||||
|
- annotated-types==0.7.0
|
||||||
|
- anyio==4.12.0
|
||||||
|
- click==8.3.1
|
||||||
|
- colorama==0.4.6
|
||||||
|
- exceptiongroup==1.3.1
|
||||||
|
- fastapi==0.125.0
|
||||||
|
- greenlet==3.3.0
|
||||||
|
- h11==0.16.0
|
||||||
|
- httptools==0.7.1
|
||||||
|
- idna==3.11
|
||||||
|
- pydantic==2.12.5
|
||||||
|
- pydantic-core==2.41.5
|
||||||
|
- python-dotenv==1.2.1
|
||||||
|
- pyyaml==6.0.3
|
||||||
|
- sqlalchemy==2.0.45
|
||||||
|
- starlette==0.50.0
|
||||||
|
- typing-extensions==4.15.0
|
||||||
|
- typing-inspection==0.4.2
|
||||||
|
- uvicorn==0.38.0
|
||||||
|
- watchfiles==1.1.1
|
||||||
|
- websockets==15.0.1
|
||||||
|
prefix: D:\anaconda3\envs\backend_env
|
||||||
9
start_server.py
Normal file
9
start_server.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import uvicorn
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uvicorn.run(
|
||||||
|
"app.main:app",
|
||||||
|
host="0.0.0.0",
|
||||||
|
port=8000,
|
||||||
|
reload=True
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user