From 288a40952ee2eb986d91a1d0680dc0d96a56efe3 Mon Sep 17 00:00:00 2001 From: Sami Abuzakuk Date: Sun, 12 Oct 2025 10:22:07 +0200 Subject: [PATCH] Add backend support for settings --- backend/backend.py | 74 ++++++++++++++++++++++++++++++++++++++++-- backend/model.py | 9 +++++ backend/run_scripts.py | 30 ++++++++++++++++- 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/backend/backend.py b/backend/backend.py index 99d5089..fab8e8d 100644 --- a/backend/backend.py +++ b/backend/backend.py @@ -3,8 +3,8 @@ from fastapi import FastAPI from fastapi.exceptions import HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel -from model import Log, SessionLocal, Script -from run_scripts import run_scripts +from model import Log, SessionLocal, Script, Settings +from run_scripts import run_scripts, update_requirements, update_environment import uvicorn app = FastAPI() @@ -52,6 +52,76 @@ def hello(): return {"message": "Welcome to the Project Monitor API"} +# Define Pydantic models for Settings +class SettingsBase(BaseModel): + requirements: str + environment: str + user: str + + +class SettingsUpdate(SettingsBase): + pass + + +class SettingsResponse(SettingsBase): + id: int + + model_config = {"from_attributes": True} + + +# Settings API Endpoints +@app.get("/settings", response_model=list[SettingsResponse]) +def read_settings(): + db = SessionLocal() + settings = db.query(Settings).all() + db.close() + return settings + + +@app.post("/settings", response_model=SettingsResponse) +def create_setting(settings: SettingsBase): + db = SessionLocal() + new_setting = Settings(**settings.model_dump()) + db.add(new_setting) + db.commit() + db.refresh(new_setting) + db.close() + + return new_setting + + +@app.get("/settings/{settings_id}", response_model=SettingsResponse) +def read_setting(settings_id: int): + db = SessionLocal() + setting = db.query(Settings).filter(Settings.id == settings_id).first() + db.close() + if not setting: + raise HTTPException(status_code=404, detail="Setting not found") + return setting + + +@app.put("/settings/{settings_id}", response_model=SettingsResponse) +def update_setting(settings_id: int, settings: SettingsUpdate): + db = SessionLocal() + existing_setting = db.query(Settings).filter(Settings.id == settings_id).first() + if not existing_setting: + raise HTTPException(status_code=404, detail="Setting not found") + + if existing_setting.requirements != settings.requirements: + existing_setting.requirements = settings.requirements + update_requirements(settings) + + if existing_setting.environment != settings.environment: + existing_setting.environment = settings.environment + update_environment(settings) + + db.commit() + db.refresh(existing_setting) + db.close() + + return existing_setting + + @app.get("/script", response_model=list[ScriptResponse]) def read_scripts(): db = SessionLocal() diff --git a/backend/model.py b/backend/model.py index 1670be3..803cf8b 100644 --- a/backend/model.py +++ b/backend/model.py @@ -43,5 +43,14 @@ class Log(Base): script_id = Column(Integer, ForeignKey("scripts.id"), nullable=False) +class Settings(Base): + __tablename__ = "user_settings" + + id = Column(Integer, primary_key=True, index=True) + requirements = Column(String, nullable=False) + environment = Column(String, nullable=False) + user = Column(String, nullable=False) + + # Create the database tables Base.metadata.create_all(bind=engine) diff --git a/backend/run_scripts.py b/backend/run_scripts.py index 18ec2b3..6c25630 100644 --- a/backend/run_scripts.py +++ b/backend/run_scripts.py @@ -34,14 +34,42 @@ def run_scripts(script_ids: list[int] | None = None): def dump_script_to_file(script, filename): with open(filename, "w") as file: + file.write("from dotenv import load_dotenv\nload_dotenv()\n") file.write(script.script_content) def execute_script(filename) -> subprocess.CompletedProcess: - result = subprocess.run(["python", filename], capture_output=True, text=True) + result = subprocess.run( + ["exec_folder/venv/bin/python", filename], capture_output=True, text=True + ) return result +def update_requirements(settings): + if settings is None: + raise ValueError("No default settings found") + + # create requirements.txt + with open("exec_folder/requirements.txt", "w") as file: + file.write("dotenv\n") + file.write(settings.requirements) + + # install requirements + subprocess.run( + ["exec_folder/venv/bin/pip", "install", "-r", "exec_folder/requirements.txt"], + check=True, + ) + + +def update_environment(settings): + if settings is None: + raise ValueError("No default settings found") + + # create .env file + with open("exec_folder/.env", "w") as file: + file.write(settings.environment) + + def delete_script(filename): try: os.remove(filename)