various bugs fixing

This commit is contained in:
GotthardG
2024-12-06 14:53:27 +01:00
parent 996fc66d76
commit 29a9d16bc3
10 changed files with 123 additions and 87 deletions

View File

@ -1,6 +1,6 @@
import logging
from sqlalchemy.orm import Session, joinedload
from app.models import Shipment
from .models import Shipment
def get_shipments(db: Session):
logging.info("Fetching all shipments from the database.")

View File

@ -3,7 +3,7 @@ from sqlalchemy.orm import Session
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from app import models
from . import models
import os
# Get username and password from environment variables
@ -31,12 +31,12 @@ def get_db():
def init_db():
# Import models inside function to avoid circular dependency
from app import models
from . import models
Base.metadata.create_all(bind=engine)
def load_sample_data(session: Session):
# Import models inside function to avoid circular dependency
from app.data import contacts, return_addresses, dewars, proposals, shipments, pucks, samples, dewar_types, serial_numbers, slots, sample_events
from .data import contacts, return_addresses, dewars, proposals, shipments, pucks, samples, dewar_types, serial_numbers, slots, sample_events
# If any data already exists, skip seeding
if session.query(models.ContactPerson).first():

View File

@ -1,5 +1,5 @@
# app/dependencies.py
from app.database import SessionLocal # Import SessionLocal from database.py
from .database import SessionLocal # Import SessionLocal from database.py
def get_db():
db = SessionLocal()

View File

@ -1,4 +1,4 @@
from app.database import init_db
from .database import init_db
def initialize_database():

View File

@ -1,58 +0,0 @@
# app/main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app import ssl_heidi
from pathlib import Path
from app.routers import address, contact, proposal, dewar, shipment, puck, spreadsheet, logistics, auth, sample
from app.database import Base, engine, SessionLocal, load_sample_data
app = FastAPI()
# Generate SSL Key and Certificate if not exist
Path("ssl").mkdir(parents=True, exist_ok=True)
if not Path("ssl/cert.pem").exists() or not Path("ssl/key.pem").exists():
ssl_heidi.generate_self_signed_cert("ssl/cert.pem", "ssl/key.pem")
# Apply CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Enable CORS for all origins
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.on_event("startup")
def on_startup():
# Drop and recreate database schema
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
db = SessionLocal()
try:
load_sample_data(db)
finally:
db.close()
# Include routers with correct configuration
app.include_router(auth.router, prefix="/auth", tags=["auth"])
app.include_router(contact.router, prefix="/contacts", tags=["contacts"])
app.include_router(address.router, prefix="/addresses", tags=["addresses"])
app.include_router(proposal.router, prefix="/proposals", tags=["proposals"])
app.include_router(dewar.router, prefix="/dewars", tags=["dewars"])
app.include_router(shipment.router, prefix="/shipments", tags=["shipments"])
app.include_router(puck.router, prefix="/pucks", tags=["pucks"])
app.include_router(spreadsheet.router, tags=["spreadsheet"])
app.include_router(logistics.router, prefix="/logistics", tags=["logistics"])
app.include_router(sample.router, prefix="/samples", tags=["samples"])
if __name__ == "__main__":
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(certfile="ssl/cert.pem", keyfile="ssl/key.pem")
uvicorn.run(app, host="127.0.0.1", port=8000, log_level="debug", ssl_context=ssl_context)

View File

@ -1,6 +1,6 @@
from sqlalchemy import Column, Integer, String, Date, ForeignKey, JSON, Interval, DateTime, Boolean
from sqlalchemy.orm import relationship
from app.database import Base
from .database import Base
from datetime import datetime, timedelta
import uuid

View File

@ -191,84 +191,84 @@ class SpreadsheetModel(BaseModel):
raise ValueError(f" '{v}' is not valid. Value must be one of {allowed}.")
return v
@field_validator('spacegroupnumber', mode="before")
@classmethod
def spacegroupnumber_allowed(cls, v):
if v is not None:
try:
v = int(v)
if not (1 <= v <= 230):
raise ValueError(f" '{v}' is not valid. Value must be an integer between 1 and 230.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be an integer between 1 and 230.") from e
return v
@field_validator('spacegroupnumber', mode="before")
@classmethod
def spacegroupnumber_allowed(cls, v):
if v is not None:
try:
v = int(v)
if not (1 <= v <= 230):
raise ValueError(f" '{v}' is not valid. Value must be an integer between 1 and 230.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be an integer between 1 and 230.") from e
return v
@field_validator('cellparameters', mode="before")
@classmethod
def cellparameters_format(cls, v):
if v:
values = [float(i) for i in v.split(",")]
if len(values) != 6 or any(val <= 0 for val in values):
raise ValueError(f" '{v}' is not valid. Value must be a set of six positive floats or integers.")
return v
@field_validator('cellparameters', mode="before")
@classmethod
def cellparameters_format(cls, v):
if v:
values = [float(i) for i in v.split(",")]
if len(values) != 6 or any(val <= 0 for val in values):
raise ValueError(f" '{v}' is not valid. Value must be a set of six positive floats or integers.")
return v
@field_validator('rescutkey', 'rescutvalue', mode="before")
@classmethod
def rescutkey_value_pair(cls, values):
rescutkey = values.get('rescutkey')
rescutvalue = values.get('rescutvalue')
if rescutkey and rescutvalue:
if rescutkey not in {"is", "cchalf"}:
raise ValueError("Rescutkey must be either 'is' or 'cchalf'")
if not isinstance(rescutvalue, float) or rescutvalue <= 0:
raise ValueError("Rescutvalue must be a positive float if rescutkey is provided")
return values
@field_validator('rescutkey', 'rescutvalue', mode="before")
@classmethod
def rescutkey_value_pair(cls, values):
rescutkey = values.get('rescutkey')
rescutvalue = values.get('rescutvalue')
if rescutkey and rescutvalue:
if rescutkey not in {"is", "cchalf"}:
raise ValueError("Rescutkey must be either 'is' or 'cchalf'")
if not isinstance(rescutvalue, float) or rescutvalue <= 0:
raise ValueError("Rescutvalue must be a positive float if rescutkey is provided")
return values
@field_validator('trustedhigh', mode="before")
@classmethod
def trustedhigh_allowed(cls, v):
if v is not None:
try:
v = float(v)
if not (0 <= v <= 2.0):
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 2.0.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 2.0.") from e
return v
@field_validator('trustedhigh', mode="before")
@classmethod
def trustedhigh_allowed(cls, v):
if v is not None:
try:
v = float(v)
if not (0 <= v <= 2.0):
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 2.0.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 2.0.") from e
return v
@field_validator('chiphiangles', mode="before")
@classmethod
def chiphiangles_allowed(cls, v):
if v is not None:
try:
v = float(v)
if not (0 <= v <= 30):
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 30.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 30.") from e
return v
@field_validator('chiphiangles', mode="before")
@classmethod
def chiphiangles_allowed(cls, v):
if v is not None:
try:
v = float(v)
if not (0 <= v <= 30):
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 30.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be a float between 0 and 30.") from e
return v
@field_validator('dose', mode="before")
@classmethod
def dose_positive(cls, v):
if v is not None:
try:
v = float(v)
if v <= 0:
raise ValueError(f" '{v}' is not valid. Value must be a positive float.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be a positive float.") from e
return v
@field_validator('dose', mode="before")
@classmethod
def dose_positive(cls, v):
if v is not None:
try:
v = float(v)
if v <= 0:
raise ValueError(f" '{v}' is not valid. Value must be a positive float.")
except (ValueError, TypeError) as e:
raise ValueError(f" '{v}' is not valid. Value must be a positive float.") from e
return v
class TELLModel(SpreadsheetModel):
input_order: int
samplemountcount: int = 0
samplestatus: str = "not present"
puckaddress: str = "---"
username: str
puck_number: int
prefix: Optional[str]
folder: Optional[str]
class TELLModel(SpreadsheetModel):
input_order: int
samplemountcount: int = 0
samplestatus: str = "not present"
puckaddress: str = "---"
username: str
puck_number: int
prefix: Optional[str]
folder: Optional[str]
class SpreadsheetResponse(BaseModel):
data: List[SpreadsheetModel] # Validated data rows as SpreadsheetModel instances