重构现代化 FastAPI 后端项目框架
This commit is contained in:
0
app/__init__.py
Normal file
0
app/__init__.py
Normal file
0
app/algorithms/__init__.py
Normal file
0
app/algorithms/__init__.py
Normal 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
0
app/api/__init__.py
Normal file
0
app/api/v1/__init__.py
Normal file
0
app/api/v1/__init__.py
Normal file
0
app/api/v1/endpoints/__init__.py
Normal file
0
app/api/v1/endpoints/__init__.py
Normal file
0
app/api/v1/endpoints/auth.py
Normal file
0
app/api/v1/endpoints/auth.py
Normal file
0
app/api/v1/endpoints/extension.py
Normal file
0
app/api/v1/endpoints/extension.py
Normal file
0
app/api/v1/endpoints/network_elements.py
Normal file
0
app/api/v1/endpoints/network_elements.py
Normal file
0
app/api/v1/endpoints/project.py
Normal file
0
app/api/v1/endpoints/project.py
Normal file
0
app/api/v1/endpoints/scada.py
Normal file
0
app/api/v1/endpoints/scada.py
Normal file
0
app/api/v1/endpoints/simulation.py
Normal file
0
app/api/v1/endpoints/simulation.py
Normal file
0
app/api/v1/endpoints/snapshots.py
Normal file
0
app/api/v1/endpoints/snapshots.py
Normal file
20
app/api/v1/router.py
Normal file
20
app/api/v1/router.py
Normal 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
0
app/audit/__init__.py
Normal file
0
app/auth/__init__.py
Normal file
0
app/auth/__init__.py
Normal file
21
app/auth/dependencies.py
Normal file
21
app/auth/dependencies.py
Normal 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
0
app/core/__init__.py
Normal file
3
app/core/audit.py
Normal file
3
app/core/audit.py
Normal 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
30
app/core/config.py
Normal 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
9
app/core/encryption.py
Normal 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
23
app/core/security.py
Normal 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
0
app/crypto/__init__.py
Normal file
0
app/domain/__init__.py
Normal file
0
app/domain/__init__.py
Normal file
0
app/domain/models/__init__.py
Normal file
0
app/domain/models/__init__.py
Normal file
0
app/domain/schemas/__init__.py
Normal file
0
app/domain/schemas/__init__.py
Normal file
0
app/infra/__init__.py
Normal file
0
app/infra/__init__.py
Normal file
0
app/infra/audit/__init__.py
Normal file
0
app/infra/audit/__init__.py
Normal file
0
app/infra/cache/__init__.py
vendored
Normal file
0
app/infra/cache/__init__.py
vendored
Normal file
0
app/infra/db/__init__.py
Normal file
0
app/infra/db/__init__.py
Normal file
0
app/infra/db/influxdb/__init__.py
Normal file
0
app/infra/db/influxdb/__init__.py
Normal 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
|
||||||
@@ -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__)
|
||||||
@@ -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__)
|
||||||
0
app/infra/repositories/__init__.py
Normal file
0
app/infra/repositories/__init__.py
Normal 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
0
app/native/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user