Skip to content

Commit

Permalink
Merge pull request #35 from robert-cronin/feature/implement-data-model
Browse files Browse the repository at this point in the history
Implement and verify data model, test system refactor / general organization improvements.
  • Loading branch information
fearnworks authored Sep 6, 2024
2 parents 83c985e + 3b07111 commit 12be86f
Show file tree
Hide file tree
Showing 57 changed files with 2,560 additions and 381 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,6 @@ server.pid

# Huggingface
models_cache/

# Embedding models
**/models--**
5 changes: 5 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ vars:
sh: echo ${ROOT_DIR}/.env

tasks:
default:
desc: List all the tasks
cmds:
- task --list

echo-project-root:
desc: Echo the project root directory. Helps ensure environment is set up and tasks will run.
cmds:
Expand Down
83 changes: 83 additions & 0 deletions modules/odr_api/odr_api/api/endpoints/content_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from odr_core.crud import content_event as content_event_crud
from odr_core.schemas.content import ContentEvent, ContentEventCreate, ContentEventUpdate
from odr_core.database import get_db
from odr_api.api.auth.auth_provider import AuthProvider
from odr_core.models.content import ContentStatus

router = APIRouter(tags=["content_events"])


@router.post("/content/{content_id}/events/", response_model=ContentEvent)
def create_content_event(
content_id: int,
event: ContentEventCreate,
db: Session = Depends(get_db),
current_user=Depends(AuthProvider())
):
event.content_id = content_id
event.set_by = current_user.id
return content_event_crud.create_content_event(db=db, event=event)


@router.get("/content/{content_id}/events/{event_id}", response_model=ContentEvent)
def read_content_event(
content_id: int,
event_id: int,
db: Session = Depends(get_db)
):
db_event = content_event_crud.get_content_event(db, event_id=event_id)
if db_event is None or db_event.content_id != content_id:
raise HTTPException(status_code=404, detail="Content event not found")
return db_event


@router.get("/content/{content_id}/events/", response_model=List[ContentEvent])
def read_content_events(
content_id: int,
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db)
):
events = content_event_crud.get_content_events(db, content_id=content_id, skip=skip, limit=limit)
return events


@router.put("/content/{content_id}/events/{event_id}", response_model=ContentEvent)
def update_content_event(
content_id: int,
event_id: int,
event: ContentEventUpdate,
db: Session = Depends(get_db),
current_user=Depends(AuthProvider())
):
db_event = content_event_crud.update_content_event(db, event_id=event_id, event=event)
if db_event is None or db_event.content_id != content_id:
raise HTTPException(status_code=404, detail="Content event not found")
return db_event


@router.delete("/content/{content_id}/events/{event_id}", response_model=bool)
def delete_content_event(
content_id: int,
event_id: int,
db: Session = Depends(get_db),
current_user=Depends(AuthProvider())
):
success = content_event_crud.delete_content_event(db, event_id=event_id)
if not success:
raise HTTPException(status_code=404, detail="Content event not found")
return success


@router.get("/content/{content_id}/status", response_model=ContentStatus)
def get_content_status(
content_id: int,
db: Session = Depends(get_db)
):
status = content_event_crud.get_latest_content_status(db, content_id=content_id)
if status is None:
raise HTTPException(status_code=404, detail="Content not found or no status events")
return status
23 changes: 21 additions & 2 deletions modules/odr_core/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
# aidriver_stores Taskfile
version: '3'
version: "3"
tasks:
default:
desc: List all the tasks
cmds:
- task --list

install:
desc: Install the package in editable mode
dir: modules/odr_core
cmds:
- pip install -e .

test:
desc: Run tests for the core module
deps: [install]
dir: modules/odr_core
cmds:
- python -m pytest tests

coverage:
desc: Run tests with coverage report
deps: [install]
dir: modules/odr_core
cmds:
- echo "Core module testing not implemented yet"
- python -m pytest --cov=odr_core --cov-report=term-missing --cov-report=xml tests

test-db:
desc: Run tests for the database manager
Expand Down
4 changes: 4 additions & 0 deletions modules/odr_core/odr_core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class Settings(BaseSettings):
# Models
MODEL_CACHE_DIR: str

# Embedding
CONTENT_EMBEDDING_DIMENSION: int = 512
ANNOTATION_EMBEDDING_DIMENSION: int = 384

class Config:
env_file = ".env"

Expand Down
8 changes: 8 additions & 0 deletions modules/odr_core/odr_core/crud/annotation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
create_annotation_rating,
get_annotation_rating,
get_annotation_ratings_by_annotation,
get_annotation_ratings,
update_annotation_rating,
delete_annotation_rating,
)
from odr_core.crud.annotation.annotation_report import (
create_annotation_report,
get_annotation_report,
get_annotation_reports,
update_annotation_report,
delete_annotation_report,
)
13 changes: 7 additions & 6 deletions modules/odr_core/odr_core/crud/annotation/annotation_rating.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ def create_annotation_rating(
) -> AnnotationRating:
db_annotation_rating = AnnotationRating(
annotation_id=annotation_rating.annotation_id,
rated_by_id=(
annotation_rating.rated_by_id
if annotation_rating.rated_by_id
else current_user.id
),
rated_by_id=annotation_rating.rated_by_id,
rating=annotation_rating.rating,
reason=annotation_rating.reason,
created_at=datetime.now(timezone.utc),
Expand Down Expand Up @@ -44,11 +40,16 @@ def get_annotation_ratings_by_annotation(
)


def get_annotation_ratings(
db: Session, skip: int = 0, limit: int = 100
) -> List[AnnotationRating]:
return db.query(AnnotationRating).offset(skip).limit(limit).all()


def update_annotation_rating(
db: Session,
rating_id: int,
annotation_rating_update: AnnotationRatingUpdate,
current_user: User,
) -> Optional[AnnotationRating]:
db_annotation_rating = (
db.query(AnnotationRating).filter(AnnotationRating.id == rating_id).first()
Expand Down
39 changes: 39 additions & 0 deletions modules/odr_core/odr_core/crud/annotation/annotation_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from sqlalchemy.orm import Session
from odr_core.models.annotation import AnnotationReport
from odr_core.schemas.annotation import AnnotationReportCreate, AnnotationReportUpdate


def create_annotation_report(db: Session, report: AnnotationReportCreate) -> AnnotationReport:
db_report = AnnotationReport(**report.model_dump())
db.add(db_report)
db.commit()
db.refresh(db_report)
return db_report


def get_annotation_report(db: Session, report_id: int) -> AnnotationReport | None:
return db.query(AnnotationReport).filter(AnnotationReport.id == report_id).first()


def get_annotation_reports(db: Session, annotation_id: int, skip: int = 0, limit: int = 100):
return db.query(AnnotationReport).filter(AnnotationReport.annotation_id == annotation_id).offset(skip).limit(limit).all()


def update_annotation_report(db: Session, report_id: int, report: AnnotationReportUpdate) -> AnnotationReport | None:
db_report = db.query(AnnotationReport).filter(AnnotationReport.id == report_id).first()
if db_report:
update_data = report.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(db_report, key, value)
db.commit()
db.refresh(db_report)
return db_report


def delete_annotation_report(db: Session, report_id: int) -> bool:
db_report = db.query(AnnotationReport).filter(AnnotationReport.id == report_id).first()
if db_report:
db.delete(db_report)
db.commit()
return True
return False
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ def update_annotation_source(
db: Session,
annotation_source_id: int,
annotation_source_update: AnnotationSourceUpdate,
current_user: User,
) -> Optional[AnnotationSource]:
db_annotation_source = (
db.query(AnnotationSource)
Expand Down
41 changes: 40 additions & 1 deletion modules/odr_core/odr_core/crud/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
ContentType,
ContentStatus,
ContentSourceType,
ContentAuthor
)
from odr_core.schemas.content import (
ContentCreate,
ContentUpdate,
ContentSourceCreate,
ContentSourceUpdate,
ContentAuthorCreate,
ContentAuthorUpdate,
httpurl_to_str,
)
from typing import List, Optional
from sqlalchemy import Enum as SQLAlchemyEnum
from loguru import logger
from datetime import datetime, timezone
from sqlalchemy.exc import IntegrityError
Expand Down Expand Up @@ -76,6 +78,7 @@ def create_content(db: Session, content: ContentCreate, from_user_id: int):
db_content = Content(
name=content.name,
type=ContentType(content.type.value),
url=content.url,
hash=content.hash,
phash=content.phash,
width=content.width,
Expand Down Expand Up @@ -173,6 +176,42 @@ def delete_content(db: Session, content_id: int) -> bool:
return False


def create_content_author(db: Session, content_author: ContentAuthorCreate) -> ContentAuthor:
db_content_author = ContentAuthor(**content_author.model_dump())
db.add(db_content_author)
db.commit()
db.refresh(db_content_author)
return db_content_author


def get_content_author(db: Session, content_author_id: int) -> Optional[ContentAuthor]:
return db.query(ContentAuthor).filter(ContentAuthor.id == content_author_id).first()


def get_content_authors(db: Session, content_id: int, skip: int = 0, limit: int = 100) -> List[ContentAuthor]:
return db.query(ContentAuthor).filter(ContentAuthor.content_id == content_id).offset(skip).limit(limit).all()


def update_content_author(db: Session, content_author_id: int, content_author: ContentAuthorUpdate) -> Optional[ContentAuthor]:
db_content_author = get_content_author(db, content_author_id)
if db_content_author:
update_data = content_author.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(db_content_author, key, value)
db.commit()
db.refresh(db_content_author)
return db_content_author


def delete_content_author(db: Session, content_author_id: int) -> bool:
db_content_author = get_content_author(db, content_author_id)
if db_content_author:
db.delete(db_content_author)
db.commit()
return True
return False


# Additional helper functions


Expand Down
46 changes: 46 additions & 0 deletions modules/odr_core/odr_core/crud/content_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from sqlalchemy.orm import Session
from odr_core.models.content import ContentEvents, ContentStatus
from odr_core.schemas.content import ContentEventCreate, ContentEventUpdate
from typing import List, Optional


def create_content_event(db: Session, event: ContentEventCreate) -> ContentEvents:
db_event = ContentEvents(**event.model_dump())
db.add(db_event)
db.commit()
db.refresh(db_event)
return db_event


def get_content_event(db: Session, event_id: int) -> Optional[ContentEvents]:
return db.query(ContentEvents).filter(ContentEvents.id == event_id).first()


def get_content_events(db: Session, content_id: int, skip: int = 0, limit: int = 100) -> List[ContentEvents]:
return db.query(ContentEvents).filter(ContentEvents.content_id == content_id).offset(skip).limit(limit).all()


def update_content_event(db: Session, event_id: int, event: ContentEventUpdate) -> Optional[ContentEvents]:
db_event = get_content_event(db, event_id)
if db_event:
update_data = event.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(db_event, key, value)
db.commit()
db.refresh(db_event)
return db_event


def delete_content_event(db: Session, event_id: int) -> bool:
db_event = get_content_event(db, event_id)
if db_event:
db.delete(db_event)
db.commit()
return True
return False


def get_latest_content_status(db: Session, content_id: int) -> Optional[ContentStatus]:
latest_event = db.query(ContentEvents).filter(ContentEvents.content_id
== content_id).order_by(ContentEvents.created_at.desc()).first()
return latest_event.status if latest_event else None
40 changes: 40 additions & 0 deletions modules/odr_core/odr_core/crud/content_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from sqlalchemy.orm import Session
from odr_core.models.content import ContentReport
from odr_core.schemas.content_report import ContentReportCreate, ContentReportUpdate
from typing import List, Optional


def create_content_report(db: Session, report: ContentReportCreate) -> ContentReport:
db_report = ContentReport(**report.model_dump())
db.add(db_report)
db.commit()
db.refresh(db_report)
return db_report


def get_content_report(db: Session, report_id: int) -> Optional[ContentReport]:
return db.query(ContentReport).filter(ContentReport.id == report_id).first()


def get_content_reports(db: Session, skip: int = 0, limit: int = 100) -> List[ContentReport]:
return db.query(ContentReport).offset(skip).limit(limit).all()


def update_content_report(db: Session, report_id: int, report: ContentReportUpdate) -> Optional[ContentReport]:
db_report = db.query(ContentReport).filter(ContentReport.id == report_id).first()
if db_report:
update_data = report.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(db_report, key, value)
db.commit()
db.refresh(db_report)
return db_report


def delete_content_report(db: Session, report_id: int) -> bool:
db_report = db.query(ContentReport).filter(ContentReport.id == report_id).first()
if db_report:
db.delete(db_report)
db.commit()
return True
return False
Loading

0 comments on commit 12be86f

Please sign in to comment.