Skip to content

Commit

Permalink
Transformed models into UUID SqlAlchemy models, and fixed internal st…
Browse files Browse the repository at this point in the history
…ream API
  • Loading branch information
CedricCortenraede committed Jun 19, 2024
1 parent bf27083 commit 39e7846
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/api/api/db/seeders/stream_seeder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@listens_for(Stream.__table__, "after_create")
def insert_rows(target: Table, connection, **kw) -> None:
# Load stored countries and tags.
countries = connection.execute(select(Country.iso, Country.name)).fetchall()
countries = connection.execute(select(Country.id, Country.name)).fetchall()
tags = connection.execute(select(StreamTag.id, StreamTag.name)).fetchall()

# Create conversions function to convert name to associated id.
Expand All @@ -23,7 +23,7 @@ def insert_rows(target: Table, connection, **kw) -> None:
df["tag"] = df["tag"].apply(lambda row: tag2id[row.lower()])
df["country"] = df["country"].apply(lambda row: country2id[row.lower()])

df = df.rename(columns={"tag": "tag_id", "country": "country_iso"})
df = df.rename(columns={"tag": "tag_id", "country": "country_id"})

# Insert the rows into the database.
connection.execute(
Expand Down
6 changes: 3 additions & 3 deletions src/api/api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from models.country import Country
from models.animal import Animal
from models.stream import Stream
from litestar.contrib.sqlalchemy.base import UUIDAuditBase


from core import settings
from db.connector import redis_connection, postgres_connection
Expand All @@ -35,8 +37,6 @@


async def init_db(app: Litestar) -> None:
from models.base import Base

# Import models.
import models.country
import models.stream
Expand All @@ -49,7 +49,7 @@ async def init_db(app: Litestar) -> None:
import db.seeders.stream_seeder

async with app.state.db_engine.begin() as connection:
await connection.run_sync(Base.metadata.create_all)
await connection.run_sync(UUIDAuditBase.metadata.create_all)


def create_app() -> Litestar:
Expand Down
5 changes: 2 additions & 3 deletions src/api/api/models/animal.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
mapped_column,
relationship,
)
from models.base import Base
from litestar.contrib.sqlalchemy.base import UUIDAuditBase


class Animal(Base):
class Animal(UUIDAuditBase):
__tablename__ = "animals"

id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String)

streams: Mapped[List["Stream"]] = relationship(
Expand Down
5 changes: 0 additions & 5 deletions src/api/api/models/base.py

This file was deleted.

8 changes: 4 additions & 4 deletions src/api/api/models/country.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
mapped_column,
relationship,
)
from models.base import Base
from litestar.contrib.sqlalchemy.base import UUIDAuditBase


class Country(Base):
class Country(UUIDAuditBase):
__tablename__ = "countries"

iso: Mapped[str] = mapped_column(String(3), primary_key=True)
iso: Mapped[str] = mapped_column(String(3))
name: Mapped[str] = mapped_column(String)

streams: Mapped[List["Stream"]] = relationship(
back_populates="country", cascade="all, delete-orphan"
)

def __repr__(self) -> str:
return f"Country(iso={self.iso!r}, name={self.name!r})"
return f"Country(id={self.id!r}, iso={self.iso!r}, name={self.name!r})"
14 changes: 6 additions & 8 deletions src/api/api/models/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
mapped_column,
relationship,
)
from models.base import Base
from litestar.contrib.sqlalchemy.base import UUIDAuditBase


class StreamTag(Base):
class StreamTag(UUIDAuditBase):
__tablename__ = "tags"

id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String)
model: Mapped[str] = mapped_column(String, nullable=True)

Expand All @@ -20,17 +19,16 @@ class StreamTag(Base):
)

def __repr__(self) -> str:
return f"StreamTag(id={self.id!r}, name={self.name!r})"
return f"StreamTag(id={self.id!r}, name={self.name!r}, model={self.model!r})"


class Stream(Base):
class Stream(UUIDAuditBase):
__tablename__ = "streams"

id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String)
url: Mapped[str] = mapped_column(String)
tag_id: Mapped[int] = mapped_column(ForeignKey("tags.id"))
country_iso: Mapped[str] = mapped_column(ForeignKey("countries.iso"))
country_id: Mapped[str] = mapped_column(ForeignKey("countries.id"))
location: Mapped[str] = mapped_column(String)
latitude: Mapped[float] = mapped_column(Double)
longitude: Mapped[float] = mapped_column(Double)
Expand All @@ -43,4 +41,4 @@ class Stream(Base):
)

def __repr__(self) -> str:
return f"Stream(id={self.id!r}, name={self.name!r}, url={self.url!r}, tag={self.tag_id!r}, country_iso={self.country_iso!r}, location={self.location!r}, latitude={self.latitude!r}, longitude={self.longitude!r})"
return f"Stream(id={self.id!r}, name={self.name!r}, url={self.url!r}, tag={self.tag_id!r}, country_id={self.country_id!r}, location={self.location!r}, latitude={self.latitude!r}, longitude={self.longitude!r})"
4 changes: 2 additions & 2 deletions src/api/api/models/streams_animals.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from models.base import Base
from sqlalchemy import Table, Column, ForeignKey
from sqlalchemy.types import Integer
from litestar.contrib.sqlalchemy.base import UUIDAuditBase

streams_animals = Table(
"streams_animals",
Base.metadata,
UUIDAuditBase.metadata,
Column("stream_id", ForeignKey("streams.id"), primary_key=True),
Column("animal_id", ForeignKey("animals.id"), primary_key=True),
Column("count", Integer, default=0),
Expand Down
33 changes: 25 additions & 8 deletions src/api/api/routers/v1/internal_streams.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from dataclasses import dataclass
from typing import Annotated
from uuid import UUID
from litestar import Controller, get, Request, post, Response, MediaType
from litestar.exceptions import *
from litestar.enums import RequestEncodingType
from litestar.params import Body
from pydantic import BaseModel, TypeAdapter
from sqlalchemy.ext.asyncio import AsyncSession

from sqlalchemy.dialects.postgresql import insert
Expand All @@ -18,12 +20,21 @@
from litestar.di import Provide


class StreamBasic(BaseModel):
model_config = {"from_attributes": True}

id: UUID | None
url: str


class StreamRepository(SQLAlchemyAsyncRepository[Stream]):
model_type = Stream


async def provide_streams_repository(session: AsyncSession) -> StreamRepository:
return StreamRepository(session=session)
async def provide_streams_repository(db_session: AsyncSession) -> StreamRepository:
return StreamRepository(
session=db_session,
)


# TODO: exclude from schemas
Expand All @@ -35,13 +46,19 @@ class internalStreamsController(Controller):
dependencies = {"streams_repository": Provide(provide_streams_repository)}

@get("/streams")
async def get_streams(self, streams_repository: StreamRepository) -> list[Stream]:
return await streams_repository.list()
async def get_streams(self, streams_repository: StreamRepository) -> list[StreamBasic]:
streams = await streams_repository.list()
streams = [StreamBasic(id=stream.id, url=stream.url) for stream in streams]

return streams

@get("/streams/{stream_id:int}")
@get("/streams/{stream_id:uuid}")
async def get_stream(
self, streams_repository: StreamRepository, stream_id: int
self, streams_repository: StreamRepository, stream_id: UUID
) -> Stream:
return await streams_repository.get(
item_id=stream_id, load=[Stream.tag, Stream.country, Stream.animals]
stream = await streams_repository.get(
item_id=stream_id,
load=[Stream.tag, Stream.country, Stream.animals],
)

return stream

0 comments on commit 39e7846

Please sign in to comment.