Skip to content

Commit

Permalink
Added API endpoint to link detected animals to a stream
Browse files Browse the repository at this point in the history
  • Loading branch information
CedricCortenraede committed Jun 20, 2024
1 parent 47d10a3 commit 65ddec7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 102 deletions.
7 changes: 2 additions & 5 deletions src/api/api/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from litestar import Router

from routers.v1 import streams, word_cloud
from routers.v1 import internal, internal_streams
from routers.v1 import internal_streams, streams, word_cloud


def create_router() -> Router:
Expand All @@ -15,7 +13,6 @@ def create_router_private() -> Router:
return Router(
path="v1",
route_handlers=[
internal.internalController,
internal_streams.internalStreamsController,
internal_streams.streamsController,
],
)
81 changes: 0 additions & 81 deletions src/api/api/routers/v1/internal.py

This file was deleted.

102 changes: 86 additions & 16 deletions src/api/api/routers/v1/internal_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
from typing import Annotated
from uuid import UUID

from litestar import Controller, MediaType, Request, Response, get, post
from litestar import Controller, get, post
from litestar.contrib.sqlalchemy.repository import SQLAlchemyAsyncRepository
from litestar.datastructures import State
from litestar.di import Provide
from litestar.enums import RequestEncodingType
from litestar.exceptions import *
from litestar.params import Body
from models.animal import Animal
from models.stream import Stream
from models.streams_animals import streams_animals
from pydantic import BaseModel, TypeAdapter
from sqlalchemy import select
from sqlalchemy.dialects.postgresql import insert
from models.stream_animal import StreamAnimal
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession


Expand All @@ -35,15 +30,35 @@ class StreamRepository(SQLAlchemyAsyncRepository[Stream]):
model_type = Stream


class AnimalRepository(SQLAlchemyAsyncRepository[Animal]):
model_type = Animal


class StreamAnimalRepository(SQLAlchemyAsyncRepository[StreamAnimal]):
model_type = StreamAnimal


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


# TODO: exclude from schemas
# Controller for internal endpoints
class internalStreamsController(Controller):
async def provide_animals_repository(db_session: AsyncSession) -> AnimalRepository:
return AnimalRepository(
session=db_session,
)


async def provide_stream_animals_repository(
db_session: AsyncSession,
) -> StreamAnimalRepository:
return StreamAnimalRepository(
session=db_session,
)


class streamsController(Controller):
path = "/internal-streams"
tags = ["internal-streams"]

Expand All @@ -64,24 +79,79 @@ async def get_stream(
) -> Stream:
stream = await streams_repository.get(
item_id=stream_id,
load=[Stream.tag, Stream.country, Stream.animals],
load=[Stream.tag, Stream.country, Stream.stream_animals],
)

# TODO: Only return relevant data.

return stream

@post("/streams/{stream_id:uuid}/animals")
@post(
"/streams/{stream_id:uuid}/animals",
dependencies={
"animals_repository": Provide(provide_animals_repository),
"stream_animals_repository": Provide(provide_stream_animals_repository),
},
)
async def store_stream_animals(
self,
streams_repository: StreamRepository,
animals_repository: AnimalRepository,
stream_animals_repository: StreamAnimalRepository,
stream_id: UUID,
data: Annotated[list[StreamAnimalItem], Body()],
) -> Stream:
stream = await streams_repository.get(
item_id=stream_id,
load=[Stream.tag, Stream.country, Stream.animals],
load=[
Stream.tag,
Stream.country,
Stream.stream_animals,
],
)

for animal in data:
pass
for item in data:
animal_name, animal_count = item.animal, item.count

# Check if animal already exists in database.
animal = await animals_repository.get_one_or_none(
name=animal_name,
)

# Check if animal is already linked to stream, if animal already exists.
if animal is not None:
stream_animal = await stream_animals_repository.get_one_or_none(
stream_id=stream.id, animal_id=animal.id
)

# If linked, update the count of the link. Then continue with next row.
if stream_animal is not None:
stream_animal.count += animal_count
await stream_animals_repository.update(stream_animal)

continue

# Else create animal in database and link it to stream.
if animal is None:
# Create animal object in database.
animal = Animal(
name=animal_name,
)
# TODO: Create API call for extra information about animal.

await animals_repository.add(animal)
await animals_repository.session.commit()

# Create link between stream and animal.
await stream_animals_repository.add(
StreamAnimal(
stream_id=stream.id, animal_id=animal.id, count=animal_count
)
)

# Save changes to the Stream Animal table.
await stream_animals_repository.session.commit()

# TODO: Refresh the data, and make use of returning only relevant data like GET-method.

return stream

0 comments on commit 65ddec7

Please sign in to comment.