重构现代化 FastAPI 后端项目框架

This commit is contained in:
2026-01-21 16:50:57 +08:00
parent 9e06e68a15
commit c56f2fd1db
352 changed files with 176 additions and 70 deletions

0
app/__init__.py Normal file
View File

View File

View File

@@ -1,6 +1,6 @@
import os import os
from tjnetwork import * from tjnetwork import *
from api.project import copy_project from app.native.api.project import copy_project
from run_simulation import run_simulation_ex, from_clock_to_seconds_2 from run_simulation import run_simulation_ex, from_clock_to_seconds_2
from math import sqrt, pi from math import sqrt, pi
from epanet.epanet import Output from epanet.epanet import Output
@@ -13,16 +13,16 @@ from psycopg import sql
import pandas as pd import pandas as pd
import csv import csv
import chardet import chardet
import simulation import app.services.simulation as simulation
import geopandas as gpd import geopandas as gpd
from sqlalchemy import create_engine from sqlalchemy import create_engine
import ast import ast
import sensitivity import sensitivity
import project_info import app.services.project_info as project_info
import api_ex.kmeans_sensor import app.algorithms.api_ex.kmeans_sensor
import api_ex.Fdataclean import app.algorithms.api_ex.Fdataclean
import api_ex.Pdataclean import app.algorithms.api_ex.Pdataclean
from api.postgresql_info import get_pgconn_string from app.native.api.postgresql_info import get_pgconn_string
############################################################ ############################################################

0
app/api/__init__.py Normal file
View File

0
app/api/v1/__init__.py Normal file
View File

View File

View File

View File

View File

View File

View File

View File

View File

20
app/api/v1/router.py Normal file
View File

@@ -0,0 +1,20 @@
from fastapi import APIRouter
from app.api.v1.endpoints import (
auth,
project,
network_elements,
simulation,
scada,
extension,
snapshots
)
api_router = APIRouter()
api_router.include_router(auth.router, prefix="/auth", tags=["auth"])
api_router.include_router(project.router, prefix="/projects", tags=["projects"])
api_router.include_router(network_elements.router, prefix="/elements", tags=["network-elements"])
api_router.include_router(simulation.router, prefix="/simulation", tags=["simulation"])
api_router.include_router(scada.router, prefix="/scada", tags=["scada"])
api_router.include_router(extension.router, prefix="/extension", tags=["extension"])
api_router.include_router(snapshots.router, prefix="/snapshots", tags=["snapshots"])

0
app/audit/__init__.py Normal file
View File

0
app/auth/__init__.py Normal file
View File

21
app/auth/dependencies.py Normal file
View File

@@ -0,0 +1,21 @@
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from app.core.config import settings
from jose import jwt, JWTError
oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}/login/access-token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
except JWTError:
raise credentials_exception
return username

0
app/core/__init__.py Normal file
View File

3
app/core/audit.py Normal file
View File

@@ -0,0 +1,3 @@
# Placeholder for audit logic
async def log_audit_event(event_type: str, user_id: str, details: dict):
pass

30
app/core/config.py Normal file
View File

@@ -0,0 +1,30 @@
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
PROJECT_NAME: str = "TJWater Server"
API_V1_STR: str = "/api/v1"
SECRET_KEY: str = "your-secret-key-here" # Change in production
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
# Database Config (PostgreSQL)
DB_NAME: str = "tjwater"
DB_HOST: str = "localhost"
DB_PORT: str = "5432"
DB_USER: str = "postgres"
DB_PASSWORD: str = "password"
# InfluxDB
INFLUXDB_URL: str = "http://localhost:8086"
INFLUXDB_TOKEN: str = "token"
INFLUXDB_ORG: str = "org"
INFLUXDB_BUCKET: str = "bucket"
@property
def SQLALCHEMY_DATABASE_URI(self) -> str:
return f"postgresql://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
class Config:
env_file = ".env"
settings = Settings()

9
app/core/encryption.py Normal file
View File

@@ -0,0 +1,9 @@
# Placeholder for encryption logic
class Encryptor:
def encrypt(self, data: str) -> str:
return data # Implement actual encryption
def decrypt(self, data: str) -> str:
return data # Implement actual decryption
encryptor = Encryptor()

23
app/core/security.py Normal file
View File

@@ -0,0 +1,23 @@
from datetime import datetime, timedelta
from typing import Optional, Union, Any
from jose import jwt
from passlib.context import CryptContext
from app.core.config import settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def create_access_token(subject: Union[str, Any], expires_delta: Optional[timedelta] = None) -> str:
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
return encoded_jwt
def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password: str) -> str:
return pwd_context.hash(password)

0
app/crypto/__init__.py Normal file
View File

0
app/domain/__init__.py Normal file
View File

View File

View File

0
app/infra/__init__.py Normal file
View File

View File

0
app/infra/cache/__init__.py vendored Normal file
View File

0
app/infra/db/__init__.py Normal file
View File

View File

View File

@@ -17,19 +17,19 @@ import get_realValue
import get_data import get_data
import psycopg import psycopg
import time import time
import simulation import app.services.simulation as simulation
from tjnetwork import * from tjnetwork import *
import schedule import schedule
import threading import threading
import globals import app.services.globals as globals
import csv import csv
import pandas as pd import pandas as pd
import openpyxl import openpyxl
import pytz import pytz
import influxdb_info import app.infra.db.influxdb.info as influxdb_info
import project_info import app.services.project_info as project_info
import time_api import app.services.time_api as time_api
from api.postgresql_info import get_pgconn_string from app.native.api.postgresql_info import get_pgconn_string
# influxdb数据库连接信息 # influxdb数据库连接信息
url = influxdb_info.url url = influxdb_info.url

View File

@@ -3,7 +3,7 @@ from contextlib import asynccontextmanager
from typing import AsyncGenerator, Dict, Optional from typing import AsyncGenerator, Dict, Optional
import psycopg_pool import psycopg_pool
from psycopg.rows import dict_row from psycopg.rows import dict_row
import api.postgresql_info as postgresql_info import app.native.api.postgresql_info as postgresql_info
# Configure logging # Configure logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -3,7 +3,7 @@ from contextlib import asynccontextmanager
from typing import AsyncGenerator, Dict, Optional from typing import AsyncGenerator, Dict, Optional
import psycopg_pool import psycopg_pool
from psycopg.rows import dict_row from psycopg.rows import dict_row
import timescaledb.timescaledb_info as timescaledb_info import app.infra.db.timescaledb.timescaledb_info as timescaledb_info
# Configure logging # Configure logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

View File

@@ -40,18 +40,18 @@ import msgpack
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
# 第三方/自定义模块 # 第三方/自定义模块
import influxdb_api import app.infra.db.influxdb.api as influxdb_api
import timescaledb import app.infra.db.timescaledb as timescaledb
import postgresql import app.infra.db.postgresql as postgresql
import py_linq import py_linq
import time_api import app.services.time_api as time_api
import simulation import app.services.simulation as simulation
import globals import app.services.globals as globals
import project_info import app.services.project_info as project_info
from timescaledb.database import db as tsdb from app.infra.db.timescaledb.database import db as tsdb
from postgresql.database import db as pgdb from app.infra.db.postgresql.database import db as pgdb
from online_Analysis import * from app.algorithms.online_Analysis import *
from tjnetwork import * from app.services.tjnetwork import *
JUNCTION = 0 JUNCTION = 0

0
app/native/__init__.py Normal file
View File

Some files were not shown because too many files have changed in this diff Show More