From 3b50678d0a3fce1e4c5ffc6531cd5b50e3cc01dd Mon Sep 17 00:00:00 2001 From: linuskmr Date: Wed, 22 Dec 2021 12:10:08 +0100 Subject: [PATCH] Add database engine and session creation --- backend/src/database.py | 29 +++++++++++++++++++++++++++++ backend/src/main.py | 17 ++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 backend/src/database.py diff --git a/backend/src/database.py b/backend/src/database.py new file mode 100644 index 0000000..c008a22 --- /dev/null +++ b/backend/src/database.py @@ -0,0 +1,29 @@ +from sqlmodel import SQLModel, create_engine, Session + +db_name = "database.db" +db_connection_url = f"sqlite:///{db_name}" + +# Disable check_same_thread. Default is True, but FastAPI may use different threads for handling one request due to a +# paused async function may resume in another thread. We will make sure that sessions do not get shared between +# requests by injecting the session as dependency. +connect_args = {"check_same_thread": False} + +# Connect to database +engine = create_engine(db_connection_url, echo=True, connect_args=connect_args) + + +def create_db_and_tables(): + """Creates database and tables if they do not exist yet.""" + + SQLModel.metadata.create_all(engine) + + +def get_session(): + """Yields a database session. This method is used to inject a session into request handling functions. + + Example: + async def my_route(*, session: Session = Depends(get_session), hero: HeroCreate) + """ + + with Session(engine) as session: + yield session diff --git a/backend/src/main.py b/backend/src/main.py index f59cb38..b583481 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -4,6 +4,7 @@ import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from src import database from src.routes.projects import router as project_router from src.routes.tags import router as tag_router from src.routes.records import router as record_router @@ -15,10 +16,11 @@ Welcome to the Juggl API. This API allows you to retrieve your timetracking data. """ + app = FastAPI( title="Juggl API", description=description, - contact={ # Contact information. See https://fastapi.tiangolo.com/tutorial/metadata/ + contact={ # Optional contact information. See https://fastapi.tiangolo.com/tutorial/metadata/ "name": "Juggl Management", "url": "https://juggl.giller.dev/contact", "email": "help@juggl.giller.dev", @@ -27,6 +29,7 @@ app = FastAPI( ) """The main FastAPI instance""" + # Enable CORS to allow requests from other domains/origins. # See https://en.wikipedia.org/wiki/Cross-origin_resource_sharing app.add_middleware( @@ -39,6 +42,14 @@ app.add_middleware( allow_headers=["*"], ) + +@app.on_event("startup") +def on_startup(): + """Code executed on HTTP server startup. Until now only creating databases and tables.""" + + database.create_db_and_tables() + + # Add subroutes app.include_router(project_router) app.include_router(tag_router) @@ -57,11 +68,11 @@ def parse_args() -> argparse.Namespace: """Parses command line arguments on application startup.""" parser = argparse.ArgumentParser( - description="Juggl Backend v2", + description="Juggl Backend API v2. Start a server listening on port.", formatter_class=argparse.ArgumentDefaultsHelpFormatter # show default values ) parser.add_argument("--dev", default=False, action=argparse.BooleanOptionalAction, - help="Start a dev server with auto-reloading") + help="Enable auto-reloading on file-save") parser.add_argument("--port", type=int, default=8192, help="Port on which the API should run") return parser.parse_args()