commit a92472fe2b2cffc5bce1833c29142bb73478c060 Author: Ronald Date: Sat Jul 6 21:37:46 2024 +0100 Not much here yet, but it's a start. Adding this to a repository now, so that I can start tracing the history of this. diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6236558 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +fastapi +uvicorn +pymysql +sqlalchemy +pydantic +typing-extensions diff --git a/sql_app/__init__.py b/sql_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sql_app/crud.py b/sql_app/crud.py new file mode 100644 index 0000000..8088efd --- /dev/null +++ b/sql_app/crud.py @@ -0,0 +1,66 @@ +from sqlalchemy.orm import Session + +from . import models, schemas + +def get_hosts(db: Session): + hosts = db.query(models.Host).all() + + return hosts + +def get_host_by_hostname(db: Session, hostname: str): + db_host = db.query(models.Host).filter(models.Host.hostname == hostname).first() + if db_host: + return db_host + return {} + +def get_host_id_for_hostname(db: Session, hostname: str): + try: + db_host_id = db.query(models.Host).filter(models.Host.hostname == hostname).first().id + except AttributeError: + return -1 + return db_host_id + +def create_host(db: Session, host: schemas.HostCreate): + db_host = models.Host( + hostname=host.hostname + ) + + db.add(db_host) + db.commit() + db.refresh(db_host) + + return db_host + +def delete_host(db: Session, host_id: str): + db_host = db.query(models.Host).filter(models.Host.id == host_id).first() + db.delete(db_host) + db.commit() + + return { + "message": "Host successfully deleted" + } + +def delete_host_by_hostname(db: Session, hostname: str): + db_host = db.query(models.Host).filter(models.Host.hostname == hostname).first() + db.delete(db_host) + db.commit() + + return { + "message": "Host successfully deleted" + } + +def get_cpus_by_host_id(db: Session, host_id: int): + return db.query(models.CPU).filter(models.CPU.host_id == host_id) + +def create_cpu(db: Session, cpu: schemas.CPUCreate): + db_cpu = models.CPU( + name=cpu.name, + socket=cpu.socket, + host_id=cpu.host_id + ) + + db.add(db_cpu) + db.commit() + db.refresh(db_cpu) + + return db_cpu diff --git a/sql_app/database.py b/sql_app/database.py new file mode 100644 index 0000000..3218890 --- /dev/null +++ b/sql_app/database.py @@ -0,0 +1,12 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker + +SQLALCHEMY_DATABASE_URL = "mysql+pymysql://" + \ + "/lsm?charset=utf8mb4" + +engine = create_engine(SQLALCHEMY_DATABASE_URL) + +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +Base = declarative_base() diff --git a/sql_app/main.py b/sql_app/main.py new file mode 100644 index 0000000..6319448 --- /dev/null +++ b/sql_app/main.py @@ -0,0 +1,61 @@ +from typing import List + +from fastapi import FastAPI, Depends, HTTPException +from sqlalchemy.orm import Session + +from .database import SessionLocal, engine +from . import models, schemas, crud + +models.Base.metadata.create_all(bind=engine) +app = FastAPI() + +# Dependency +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() + +@app.get("/hosts/", response_model=List[schemas.Host]) +def get_hosts(db: Session = Depends(get_db)): + hosts = crud.get_hosts(db) + + return hosts + +@app.get("/get_host_by_hostname/{hostname}") +def get_host_by_hostname(hostname: str, db: Session = Depends(get_db)): + return crud.get_host_by_hostname(db, hostname=hostname) + +@app.get("/get_host_id_for_hostname/{hostname}") +def get_host_id_for_hostname(hostname: str, db: Session = Depends(get_db)): + return crud.get_host_id_for_hostname(db, hostname=hostname) + +@app.post("/add_host/", response_model=schemas.HostCreate, status_code=201) +def create_host(host: schemas.HostCreate, db: Session = Depends(get_db)): + db_host = crud.get_host_by_hostname(db, hostname=host.hostname) + if db_host: + raise HTTPException(status_code=400, detail="Host already exists") + + return crud.create_host(db=db, host=host) + +@app.delete("/delete_host/{host_id}") +def delete_host(host_id: int, db: Session = Depends(get_db)): + return crud.delete_host(db, host_id=host_id) + +@app.delete("/delete_host_by_hostname/{hostname}") +def delete_host_by_hostname(hostname: str, db: Session = Depends(get_db)): + return crud.delete_host_by_hostname(db, hostname=hostname) + +@app.get("/get_cpus_by_host_id/{host_id}") +def get_cpus_by_host_id(host_id: int, db: Session = Depends(get_db)) -> List[schemas.CPU]: + return crud.get_cpus_by_host_id(db, host_id=host_id) + +@app.post("/add_cpu/", response_model=schemas.CPUCreate, status_code=201) +def create_cpu(cpu: schemas.CPUCreate, db: Session = Depends(get_db)): + db_cpus = crud.get_cpus_by_host_id(db, host_id=cpu.host_id) + for db_cpu in db_cpus: + if cpu.socket == db_cpu.socket: + raise HTTPException(status_code=400, detail="CPU already exists") + + return crud.create_cpu(db, cpu=cpu) diff --git a/sql_app/models.py b/sql_app/models.py new file mode 100644 index 0000000..1cccc93 --- /dev/null +++ b/sql_app/models.py @@ -0,0 +1,37 @@ +from sqlalchemy import Column, Integer, Float, ForeignKey, String +from sqlalchemy.orm import relationship + +from .database import Base + + +class Host(Base): + __tablename__ = "hosts" + + id = Column(Integer, primary_key=True) + hostname = Column(String(255), unique=True, index=True) + + cpus = relationship("CPU", back_populates="host") + memory = relationship("Memory", back_populates="host") + +class CPU(Base): + __tablename__ = "cpus" + + id = Column(Integer, primary_key=True) + socket = Column(Integer, index=True) + name = Column(String(255), index=True) + usage = Column(Float, index=True) + host_id = Column(Integer, ForeignKey("hosts.id")) + + host = relationship("Host", back_populates="cpus") + +class Memory(Base): + __tablename__ = "memory" + + id = Column(Integer, primary_key=True) + type = Column(String(12), index=True) + total = Column(Integer, index=True) + used = Column(Integer, index=True) + usage = Column(Float, index=True) + host_id = Column(Integer, ForeignKey("hosts.id")) + + host = relationship("Host", back_populates="memory") diff --git a/sql_app/schemas.py b/sql_app/schemas.py new file mode 100644 index 0000000..ee4a3f1 --- /dev/null +++ b/sql_app/schemas.py @@ -0,0 +1,45 @@ +from typing import Optional + +from pydantic import BaseModel + +class CPUBase(BaseModel): + name: str + socket: int + +class CPUCreate(CPUBase): + host_id: int + +class CPU(CPUBase): + id: int + usage: Optional[float] + + class Config: + from_attributes = True + +class MemoryBase(BaseModel): + type: str + +class MemoryCreate(MemoryBase): + host_id: int + +class Memory(MemoryBase): + total: int + used: Optional[int] + usage: Optional[float] + + class Config: + from_attributes = True + +class HostBase(BaseModel): + hostname: str + +class HostCreate(HostBase): + pass + +class Host(HostBase): + id: int + cpus: Optional[list['CPU']] + memory: Optional[list['Memory']] + + class Config: + from_attributes = True