diff --git a/.gitignore b/.gitignore index 0ba7b27d..db7faedb 100644 --- a/.gitignore +++ b/.gitignore @@ -161,3 +161,6 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +#Custom stuff +zt_backend/notebook.toml \ No newline at end of file diff --git a/zt_backend/main.py b/zt_backend/main.py index 2a12d9d2..098c8f04 100644 --- a/zt_backend/main.py +++ b/zt_backend/main.py @@ -1,8 +1,12 @@ from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware +from typing import OrderedDict +from zt_backend.models.notebook import Notebook, CodeCell import router +import toml import os +import uuid app = FastAPI() @@ -24,6 +28,20 @@ expose_headers=["*"] ) +@app.on_event("startup") +def open_project(): + if not os.path.exists('notebook.toml'): + codeCell = CodeCell( + id=str(uuid.uuid4()), + code='#code here or else', + components=[], + output='', + cellType='code' + ) + zt_notebook = Notebook(cells=OrderedDict([(codeCell.id, codeCell)])) + with open('notebook.toml', "w") as project_file: + toml.dump(zt_notebook.model_dump(), project_file) + if run_mode=='app': app.mount(route_prefix, StaticFiles(directory="dist_app"), name="assets") else: diff --git a/zt_backend/requirements.txt b/zt_backend/requirements.txt index 81a49306..34f5f2ac 100644 --- a/zt_backend/requirements.txt +++ b/zt_backend/requirements.txt @@ -1,3 +1,4 @@ fastapi uvicorn -pydantic \ No newline at end of file +pydantic +toml \ No newline at end of file diff --git a/zt_backend/router.py b/zt_backend/router.py index d8c11a1b..07dd046d 100644 --- a/zt_backend/router.py +++ b/zt_backend/router.py @@ -1,10 +1,10 @@ -from fastapi import APIRouter, Request +from fastapi import APIRouter from fastapi.responses import FileResponse -from zt_backend.models import request -from zt_backend.models import notebook +from zt_backend.models import request, notebook, response from runner.execute_code import execute_request import os import uuid +import toml router = APIRouter() @@ -20,15 +20,43 @@ def health(): return('UP') @router.post("/api/runcode") -async def runcode(request: request.Request): - return execute_request(request) +def runcode(request: request.Request): + globalStateUpdate(run_request=request) + response = execute_request(request) + globalStateUpdate(run_response=response) + return response @router.post("/api/create_cell") def create_cell(): - return notebook.CodeCell( + createdCell = notebook.CodeCell( id=str(uuid.uuid4()), code='#code here or else', components=[], output='', cellType='code' - ) \ No newline at end of file + ) + globalStateUpdate(newCell=createdCell) + return createdCell + +@router.get("/api/notebook") +def get_notebook(): + return get_notebook() + +def get_notebook(): + with open('notebook.toml', "r") as project_file: + notebook_data = toml.load(project_file) + return notebook.Notebook(**notebook_data) + +def globalStateUpdate(newCell: notebook.CodeCell=None, run_request: request.Request=None, run_response: response.Response=None): + zt_notebook = get_notebook() + if newCell is not None: + zt_notebook.cells[newCell.id] = newCell + if run_request is not None: + for requestCell in run_request.cells: + zt_notebook.cells[requestCell.id].code = requestCell.code + if run_response is not None: + for responseCell in run_response.cells: + zt_notebook.cells[responseCell.id].components = responseCell.components + zt_notebook.cells[responseCell.id].output = responseCell.output + with open('notebook.toml', "w") as project_file: + toml.dump(zt_notebook.model_dump(), project_file) diff --git a/zt_frontend/src/App.vue b/zt_frontend/src/App.vue index c5b1e761..42d40ea6 100644 --- a/zt_frontend/src/App.vue +++ b/zt_frontend/src/App.vue @@ -40,24 +40,22 @@ export default { }, async created() { - const response = await axios.post(import.meta.env.VITE_BACKEND_URL + 'api/create_cell'); - const startCell: CodeCell = response.data - this.notebook.cells = {} - this.notebook.cells[startCell.id] = startCell + const response = await axios.get(import.meta.env.VITE_BACKEND_URL + 'api/notebook') + this.notebook = response.data }, methods: { async runCode() { - const cellRequests: CodeRequest[] = []; + const cellRequests: CodeRequest[] = [] const requestComponents: ZTComponent[] = [] for (let key in this.notebook.cells){ - const cellRequest: CodeRequest = {id: key, code: this.notebook.cells[key].code}; + const cellRequest: CodeRequest = {id: key, code: this.notebook.cells[key].code} requestComponents.push.apply(requestComponents, this.notebook.cells[key].components) - cellRequests.push(cellRequest); + cellRequests.push(cellRequest) } - const request: Request = { cells: cellRequests, components: requestComponents }; - const axiosResponse = await axios.post(import.meta.env.VITE_BACKEND_URL + 'api/runcode', request); - const response: Response = axiosResponse.data; + const request: Request = { cells: cellRequests, components: requestComponents } + const axiosResponse = await axios.post(import.meta.env.VITE_BACKEND_URL + 'api/runcode', request) + const response: Response = axiosResponse.data for (const cellResponse of response.cells){ this.notebook.cells[cellResponse.id].components = cellResponse.components this.notebook.cells[cellResponse.id].output = cellResponse.output