diff --git a/travian/backend/src/__init__.py b/travian/backend/src/__init__.py index dcfc21ff..c6d29bd2 100644 --- a/travian/backend/src/__init__.py +++ b/travian/backend/src/__init__.py @@ -1,4 +1,5 @@ -from fastapi import FastAPI, Depends +from fastapi import FastAPI, Depends, Response +from fastapi.responses import RedirectResponse from src.api.v1.village import village_router from src.api.v1.auth import auth_router from src.core.auth import get_current_user @@ -7,7 +8,7 @@ def create_app() -> FastAPI: - root_app = FastAPI() + root_app = FastAPI(title="Travian API",version="0.1") root_app.add_middleware( CORSMiddleware, @@ -31,8 +32,8 @@ def create_app() -> FastAPI: tags=["village"], ) - @root_app.get("/") + @root_app.get("/", response_class=RedirectResponse) async def root(): - return {"message": "Hello World"} + return "/docs" # Redirect to the OpenAPI docs return root_app diff --git a/travian/backend/src/api/v1/village.py b/travian/backend/src/api/v1/village.py index 72550f83..c72cc24a 100644 --- a/travian/backend/src/api/v1/village.py +++ b/travian/backend/src/api/v1/village.py @@ -12,13 +12,17 @@ village_router = village = APIRouter() -@village.post("/") -def insert_village( - village: NewVillage, session=Depends(get_db), current_user=Depends(get_current_user) -): - create_village(session, current_user.id, village) - return {"dd": village} - +@village.post("/create_village", response_model=NewVillage) +def new_village(session=Depends(get_db), current_user=Depends(get_current_user)): + new_village_data = { + "name": 'URSULA', + "owner_id": current_user.id, + "position_id": 2, + "population": 25000 + } + new_village = NewVillage(**new_village_data) + village_created = create_village(session, current_user.id, new_village) + return village_created """ @village.get("/{village_id}") diff --git a/travian/backend/src/core/config.py b/travian/backend/src/core/config.py index 153f526f..a433bf9a 100644 --- a/travian/backend/src/core/config.py +++ b/travian/backend/src/core/config.py @@ -1,4 +1,7 @@ import os +from dotenv import load_dotenv +load_dotenv(dotenv_path="local.env") +print("123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789") # FastAPI AUTH_TOKEN_ALGO = "HS256" diff --git a/travian/backend/src/db/conn.py b/travian/backend/src/db/conn.py index 970caccc..4afd5dab 100644 --- a/travian/backend/src/db/conn.py +++ b/travian/backend/src/db/conn.py @@ -1,18 +1,10 @@ import psycopg2 from psycopg2.extras import DictCursor, DictRow - class Database: """PostgreSQL Database class.""" - def __init__( - self, - host, - username, - password, - port, - dbname, - ): + def __init__(self, host, username, password, port, dbname): self.host = host self.username = username self.password = password @@ -32,19 +24,25 @@ def connect(self) -> None: port=self.port, dbname=self.dbname, ) - except psycopg2.DatabaseError as psycopg2_err: - raise psycopg2_err + except psycopg2.DatabaseError as e: + raise e finally: print("Connection opened successfully.") - def select_rows(self, query: str) -> list[tuple]: - """Run a SQL query to select rows from table.""" + def execute_query(self, query: str, parameters=None, fetch=False): + """Execute a SQL query optionally fetching results.""" self.connect() with self.conn.cursor() as cur: - cur.execute(query) - records = cur.fetchall() - cur.close() - return records + cur.execute(query, parameters) + self.conn.commit() + if fetch: + result = cur.fetchone() + return result[0] if result else None + return f"{cur.rowcount} rows affected." + + def select_rows(self, query: str) -> list[tuple]: + """Run a SQL query to select rows from table.""" + return self.execute_query(query, fetch=True) def select_rows_dict_cursor(self, query: str, parameters=None) -> list[DictRow]: """Run SELECT query and return dictionaries.""" @@ -52,23 +50,16 @@ def select_rows_dict_cursor(self, query: str, parameters=None) -> list[DictRow]: with self.conn.cursor(cursor_factory=DictCursor) as cur: cur.execute(query, parameters) records = cur.fetchall() - cur.close() return records def select_first_record(self, query: str, parameters=None) -> DictRow: - """Run SELECT query and return dictionaries.""" + """Run SELECT query and return the first record as a dictionary.""" self.connect() - cur = self.conn.cursor(cursor_factory=DictCursor) - cur.execute(query, parameters) - record = cur.fetchone() - cur.close() - return record - - def update_rows(self, query: str, parameters=None) -> str: - """Run a SQL query to update rows in table.""" - self.connect() - with self.conn.cursor() as cur: + with self.conn.cursor(cursor_factory=DictCursor) as cur: cur.execute(query, parameters) - self.conn.commit() - cur.close() - return f"{cur.rowcount} rows affected." + return cur.fetchone() + + def update_rows(self, query: str, parameters=None, fetch=False) -> str: + """Run a SQL query to update rows in table, optionally fetching a result.""" + return self.execute_query(query, parameters, fetch) + diff --git a/travian/backend/src/db/schemas/user.py b/travian/backend/src/db/schemas/user.py index 44a8e496..224858af 100644 --- a/travian/backend/src/db/schemas/user.py +++ b/travian/backend/src/db/schemas/user.py @@ -22,5 +22,5 @@ class UserAuth(BaseModel): class UserJWTToken(BaseModel): """current authenticated User data stored in the JWT Web Token""" - id: int + id: str ##UUID email: str diff --git a/travian/backend/src/db/schemas/villages.py b/travian/backend/src/db/schemas/villages.py index 169fcd60..67a873a1 100644 --- a/travian/backend/src/db/schemas/villages.py +++ b/travian/backend/src/db/schemas/villages.py @@ -1,29 +1,28 @@ # pylint: disable=no-name-in-module, too-few-public-methods from turtle import position +from typing import Optional + from pydantic import BaseModel +class NewVillageResponse(BaseModel): + name: str + owner_id: int + position_id: int + population: int + class Village(BaseModel): - village_id: int name: str owner_id: int - location_id: int + position_id: int + population: int + +class NewVillage(Village): + village_id: Optional[int] + class UserVillages(BaseModel): villages: list[Village] - - -class NewVillage(BaseModel): - name: str - population: int - position_id: int - - -class VillageInfo(BaseModel): - name: str - population: int - owner_id: int - location_id: int diff --git a/travian/backend/src/db/services/village.py b/travian/backend/src/db/services/village.py index 2b30f4e5..81bf0cf7 100644 --- a/travian/backend/src/db/services/village.py +++ b/travian/backend/src/db/services/village.py @@ -33,10 +33,14 @@ def get_user_villages(session: Database, user_id: int) -> village_schemas.UserVi return village_schemas.UserVillages(villages=user_villages) -def create_village(session: Database, id: str, new_village: village_schemas.Village): +def create_village( + session: Database, id: str, new_village: village_schemas.Village +) -> int: + # SQL statement with the RETURNING clause to get the newly generated id sql = """ - INSERT INTO villages (name, population, owner_id, position_id) + INSERT INTO transactions.villages (name, population, owner_id, position_id) VALUES (%s, %s, %s, %s) + RETURNING id """ params = ( new_village.name, @@ -44,8 +48,15 @@ def create_village(session: Database, id: str, new_village: village_schemas.Vill id, new_village.position_id, ) - session.update_rows(sql, params) - return "True" + # Execute the SQL and fetch the id of the newly inserted row + new_village_id = session.update_rows(sql, params, fetch=True) + return village_schemas.Village( + village_id=new_village_id, + name=new_village.name, + owner_id=id, + position_id=new_village.position_id, + population=new_village.population, + ) def get_village_infos(