Skip to content

Commit

Permalink
fixed public api routes and async sqlite
Browse files Browse the repository at this point in the history
  • Loading branch information
Nneji123 committed Jan 7, 2024
1 parent a601755 commit e1fb676
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 83 deletions.
23 changes: 11 additions & 12 deletions api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,25 @@

@asynccontextmanager
async def lifespan(app: FastAPI):
db = next(get_db()) # Fetching the database session
create_db_and_tables()
async for db in get_db(): # Iterating over the asynchronous generator
await create_db_and_tables()

try:
create_town_and_people(db)
yield
except IntegrityError as e:
# Perform any cleanup or teardown operations if needed
yield
try:
await create_town_and_people(db)
yield
except IntegrityError as e:
# Perform any cleanup or teardown operations if needed
yield


def create_app(settings: Settings):
app = FastAPI(
# title=settings.PROJECT_NAME,
# version=settings.VERSION,
title=settings.PROJECT_NAME,
version=settings.VERSION,
docs_url="/docs",
# description=settings.DESCRIPTION,
description=settings.DESCRIPTION,
lifespan=lifespan,
)

app.include_router(town_router)
app.include_router(people_router)

Expand Down
18 changes: 18 additions & 0 deletions api/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import uvicorn
from pathlib import Path
import sys

# Get the absolute path of the directory containing this script
current_file = Path(__file__).resolve()
parent_directory = current_file.parent
project_directory = parent_directory.parent

sys.path.insert(0, str(project_directory))

from api.app import create_app
from api.config import settings

api = create_app(settings)

if __name__ == "__main__":
uvicorn.run("asgi:api", host="0.0.0.0", port=8090, reload=True)
22 changes: 13 additions & 9 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,29 @@


class Settings(BaseSettings):
PROJECT_NAME: str = f"SQLModel API - {os.getenv('ENV', 'development').capitalize()}"
DESCRIPTION: str = "A FastAPI + SQLModel production-ready API"
PROJECT_NAME: str = f"Webscraper API - {os.getenv('ENV', 'development').capitalize()}"
DESCRIPTION: str = "A Google Maps Webscraper API Built with FastAPI and SQLModel"
ENV: Literal["development", "staging", "production"] = "development"
VERSION: str = "0.1"
SECRET_KEY: str = secrets.token_urlsafe(32)
DATABASE_URI: str = "sqlite:///./database.db"
API_USERNAME: str = "svc_test"
API_PASSWORD: str = "superstrongpassword"
DATABASE_URI: str = os.getenv("DATABASE_URI", "sqlite+aiosqlite:///./database.db")


class Config:
case_sensitive = True


settings = Settings()


class TestSettings(Settings):
class Config:
case_sensitive = True



def load_env():
from dotenv import load_dotenv
env_path = "../.env"
load_dotenv(env_path)


load_env()
settings = Settings()
test_settings = TestSettings()
107 changes: 62 additions & 45 deletions api/database.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
from sqlmodel import Session, SQLModel, create_engine
from sqlmodel.ext.asyncio import session
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker

from sqlalchemy.orm import sessionmaker
from api.public.people.crud import create_person
from api.public.towns.crud import create_town
from api.public.people.models import PersonCreate
from api.public.towns.models import TownCreate
from api.config import settings

connect_args = {"check_same_thread": False}
engine = create_engine(settings.DATABASE_URI, echo=True, connect_args=connect_args)
async_engine = create_async_engine(settings.DATABASE_URI)

# Create an asynchronous sessionmaker
async_session = sessionmaker(
bind=async_engine,
class_=AsyncSession,
expire_on_commit=False
)

# def create_db_and_tables():
# SQLModel.metadata.create_all(engine)
async def get_db() -> AsyncSession:
async with async_session() as session:
yield session

async def create_db_and_tables():
async with async_engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all)


# def get_db():
Expand All @@ -19,50 +35,9 @@



# def create_town_and_people(db: Session):
# # Create towns
# town_data = [
# {"name": "Town A", "population": 10000, "country": "Country A"},
# {"name": "Town B", "population": 15000, "country": "Country B"},
# # Add more towns as needed
# ]

# created_towns = []
# for town_info in town_data:
# town = TownCreate(**town_info)
# created_town = create_town(db, town)
# created_towns.append(created_town)

# # Create people
# people_data = [
# {"name": "Alice", "age": 30, "town_id": created_towns[0].id},
# {"name": "Bob", "age": 25, "town_id": created_towns[1].id},
# # Assign people to towns created above, adjust town_id as needed
# ]

# created_people = []
# for person_info in people_data:
# person = PersonCreate(**person_info)
# created_person = create_person(db, person)
# created_people.append(created_person)

# return created_towns, created_people

async def connect_to_db():
await database.connect()

async def close_db_connection():
await database.disconnect()

def create_db_and_tables():
engine = create_engine(settings.DATABASE_URI, echo=True, connect_args={"check_same_thread": False})
SQLModel.metadata.create_all(engine)

async def get_db() -> Session:
async with database.transaction():
yield Session()

async def create_town_and_people(db: Session):
# Create towns
town_data = [
{"name": "Town A", "population": 10000, "country": "Country A"},
{"name": "Town B", "population": 15000, "country": "Country B"},
Expand All @@ -75,6 +50,7 @@ async def create_town_and_people(db: Session):
created_town = await create_town(db, town)
created_towns.append(created_town)

# Create people
people_data = [
{"name": "Alice", "age": 30, "town_id": created_towns[0].id},
{"name": "Bob", "age": 25, "town_id": created_towns[1].id},
Expand All @@ -88,3 +64,44 @@ async def create_town_and_people(db: Session):
created_people.append(created_person)

return created_towns, created_people

# async def connect_to_db():
# await database.connect()

# async def close_db_connection():
# await database.disconnect()

# def create_db_and_tables():
# engine = create_engine(settings.DATABASE_URI, echo=True, connect_args={"check_same_thread": False})
# SQLModel.metadata.create_all(engine)

# async def get_db() -> Session:
# async with database.transaction():
# yield Session()

# async def create_town_and_people(db: Session):
# town_data = [
# {"name": "Town A", "population": 10000, "country": "Country A"},
# {"name": "Town B", "population": 15000, "country": "Country B"},
# # Add more towns as needed
# ]

# created_towns = []
# for town_info in town_data:
# town = TownCreate(**town_info)
# created_town = await create_town(db, town)
# created_towns.append(created_town)

# people_data = [
# {"name": "Alice", "age": 30, "town_id": created_towns[0].id},
# {"name": "Bob", "age": 25, "town_id": created_towns[1].id},
# # Assign people to towns created above, adjust town_id as needed
# ]

# created_people = []
# for person_info in people_data:
# person = PersonCreate(**person_info)
# created_person = await create_person(db, person)
# created_people.append(created_person)

# return created_towns, created_people
10 changes: 6 additions & 4 deletions api/public/people/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ async def create_person(db: Session, person: PersonCreate) -> Person:

async def get_person(db: Session, person_id: int) -> Optional[Person]:
query = select(Person).where(Person.id == person_id)
return await db.exec(query).first()
result = await db.execute(query)
return result.scalars().all()

async def get_people(db: Session, skip: int = 0, limit: int = 10) -> List[Person]:
query = select(Person).offset(skip).limit(limit)
return await db.exec(query).all()
result = await db.execute(query)
return result.scalars().all()


async def update_person(db: Session, person: Person, updated_person: PersonUpdate) -> Person:
Expand All @@ -30,7 +32,7 @@ async def update_person(db: Session, person: Person, updated_person: PersonUpdat


async def delete_person(db: Session, person_id: int) -> Person:
person = await db.exec(select(Person).where(Person.id == person_id)).first()
person = await db.execute(select(Person).where(Person.id == person_id)).first()
db.delete(person)
await db.commit()
return person
return person.scalars().all()
9 changes: 5 additions & 4 deletions api/public/towns/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async def get_town(db: Session, town_id: int) -> Optional[Town]:
:return: An object of the town class
"""
query = select(Town).where(Town.id == town_id)
return await db.exec(query).first()
return await db.execute(query).first()

async def get_towns(db: Session, skip: int = 0, limit: int = 10) -> List[Town]:
"""
Expand All @@ -39,7 +39,8 @@ async def get_towns(db: Session, skip: int = 0, limit: int = 10) -> List[Town]:
:return: A list of town objects
"""
query = select(Town).offset(skip).limit(limit)
return await db.exec(query).all()
result = await db.execute(query)
return result.scalars().all()


async def update_town(db: Session, town: Town, updated_town: TownUpdate) -> Town:
Expand Down Expand Up @@ -67,7 +68,7 @@ async def delete_town(db: Session, town_id: int) -> Town:
:param town_id: int: Specify which town to delete
:return: The deleted town
"""
town = db.exec(select(Town).where(Town.id == town_id)).first()
town = db.execute(select(Town).where(Town.id == town_id)).first()
db.delete(town)
await db.commit()
return town
return town.scalars().all()
2 changes: 2 additions & 0 deletions requirements.txt → api/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
aiosqlite==0.19.0
alembic==1.13.1
annotated-types==0.6.0
anyio==4.2.0
Expand Down Expand Up @@ -27,6 +28,7 @@ pipreqs==0.4.13
platformdirs==4.1.0
pyasn1==0.5.1
pydantic==2.5.3
pydantic-settings==2.1.0
pydantic_core==2.14.6
python-dotenv==1.0.0
python-jose==3.3.0
Expand Down
File renamed without changes.
9 changes: 0 additions & 9 deletions asgi.py

This file was deleted.

0 comments on commit e1fb676

Please sign in to comment.