This commit is contained in:
2021-11-14 10:38:47 +03:00
commit 30835e31fa
43 changed files with 2366 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
from app.views.source import source_router
from app.views.author import author_router
from app.views.author_annotation import author_annotation_router
from app.views.book import book_router
from app.views.book_annotation import book_annotation_router
from app.views.translation import translation_router
from app.views.sequence import sequence_router
from app.views.sequence_info import sequence_info_router
routers = [
source_router,
author_router,
author_annotation_router,
book_router,
book_annotation_router,
translation_router,
sequence_router,
sequence_info_router,
]

View File

@@ -0,0 +1,83 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate
from fastapi_book_server.app.utils.pagination import CustomPage
from app.models import Author as AuthorDB, AuthorAnnotation as AuthorAnnotationDB, Book as BookDB
from app.serializers.author import Author, CreateAuthor, UpdateAuthor, AuthorBook, TranslatedBook
from app.serializers.author_annotation import AuthorAnnotation
from app.services.author import AuthorTGRMSearchService
author_router = APIRouter(
prefix="/api/v1/authors",
tags=["author"],
)
@author_router.get("/", response_model=Page[Author], dependencies=[Depends(Params)])
async def get_authors():
return await paginate(
AuthorDB.objects.prefetch_related("source")
)
@author_router.post("/", response_model=Author)
async def create_author(data: CreateAuthor):
author = await AuthorDB.objects.create(
**data.dict()
)
return await AuthorDB.objects.prefetch_related("source").get(id=author.id)
@author_router.get("/{id}", response_model=Author)
async def get_author(id: int):
author = await AuthorDB.objects.prefetch_related("source").get_or_none(id=id)
if author is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return author
@author_router.put("/{id}", response_model=Author)
async def update_author(id: int, data: UpdateAuthor):
author = await AuthorDB.objects.get_or_none(id=id)
if author is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
author.update_from_dict(data.dict())
return await author.save()
@author_router.get("/{id}/annotation", response_model=AuthorAnnotation)
async def get_author_annotation(id: int):
annotation = await AuthorAnnotationDB.objects.get_or_none(author__id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return annotation
@author_router.get("/{id}/books", response_model=CustomPage[AuthorBook], dependencies=[Depends(Params)])
async def get_author_books(id: int):
return await paginate(
BookDB.objects.filter(author__id=id).order_by('title')
)
@author_router.get("/{id}/translated_books", response_model=CustomPage[TranslatedBook])
async def get_translated_books(id: int):
return await paginate(
BookDB.objects.select_related(["translations", "translations__translator"]).filter(translations__translator__id=id)
)
@author_router.get("/search/{query}", response_model=Page[Author], dependencies=[Depends(Params)])
async def search_authors(query: str):
return await AuthorTGRMSearchService.get(query)

View File

@@ -0,0 +1,49 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate
from app.models import AuthorAnnotation as AuthorAnnotationDB
from app.serializers.author_annotation import AuthorAnnotation, CreateAuthorAnnotation, UpdateAuthorAnnotation
author_annotation_router = APIRouter(
prefix="/api/v1/author_annotations",
tags=["author_annotation"]
)
@author_annotation_router.get("/", response_model=Page[AuthorAnnotation], dependencies=[Depends(Params)])
async def get_author_annotations():
return await paginate(
AuthorAnnotationDB.objects
)
@author_annotation_router.post("/", response_model=AuthorAnnotation)
async def create_author_annotation(data: CreateAuthorAnnotation):
return await AuthorAnnotationDB.objects.create(
**data.dict()
)
@author_annotation_router.get("/{id}", response_model=AuthorAnnotation)
async def get_author_annotation(id: int):
annotation = await AuthorAnnotationDB.objects.get_or_none(id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return annotation
@author_annotation_router.put("/{id}", response_model=AuthorAnnotation)
async def update_author_annotation(id: int, data: UpdateAuthorAnnotation):
annotation = await AuthorAnnotationDB.objects.get_or_none(id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
annotation.update_from_dict(data.dict())
return await annotation.save()

View File

@@ -0,0 +1,81 @@
from typing import Union
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate
from app.utils.pagination import CustomPage
from app.models import Book as BookDB, Author as AuthorDB, AuthorAnnotation as AuthorAnnotationDB
from app.serializers.book import Book, CreateBook, UpdateBook, CreateRemoteBook
from app.services.book import BookTGRMSearchService, BookCreator
book_router = APIRouter(
prefix="/api/v1/books",
tags=["book"],
)
@book_router.get("/", response_model=CustomPage[Book], dependencies=[Depends(Params)])
async def get_books():
return await paginate(
BookDB.objects.select_related("authors")
)
@book_router.post("/", response_model=Book)
async def create_book(data: Union[CreateBook, CreateRemoteBook]):
book = await BookCreator.create(data)
return await BookDB.objects.select_related("authors").get(id=book.id)
@book_router.get("/{id}", response_model=Book)
async def get_book(id: int):
book = await BookDB.objects.select_related("authors").get_or_none(id=id)
if book is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return book
@book_router.put("/{id}", response_model=Book)
async def update_book(id: int, data: UpdateBook):
book = await BookDB.objects.select_related("authors").get_or_none(id=id)
if book is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
for author in list(book.authors):
await book.authors.remove(author)
data_dict = data.dict()
author_ids = data_dict.pop("authors", [])
authors = await AuthorDB.objects.filter(id__in=author_ids).all()
book = await BookDB.objects.create(
**data_dict
)
for author in authors:
await book.authors.add(author)
return book
@book_router.get("/{id}/annotation")
async def get_book_annotation(id: int):
annotation = await AuthorAnnotationDB.objects.get(book__id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return annotation
@book_router.get("/search/{query}", response_model=CustomPage[Book], dependencies=[Depends(Params)])
async def search_books(query: str):
return await BookTGRMSearchService.get(query)

View File

@@ -0,0 +1,49 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate
from app.models import BookAnnotation as BookAnnotationDB
from app.serializers.book_annotation import BookAnnotation, CreateBookAnnotation, UpdateBookAnnotation
book_annotation_router = APIRouter(
prefix="/api/v1/book_annotations",
tags=["book_annotation"]
)
@book_annotation_router.get("/", response_model=Page[BookAnnotation], dependencies=[Depends(Params)])
async def get_book_annotations():
return await paginate(
BookAnnotationDB.objects
)
@book_annotation_router.post("/", response_model=BookAnnotation)
async def create_book_annotation(data: CreateBookAnnotation):
return await BookAnnotationDB.objects.create(
**data.dict()
)
@book_annotation_router.get("/{id}", response_model=BookAnnotation)
async def get_book_annotation(id: int):
annotation = await BookAnnotationDB.objects.get_or_none(id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return annotation
@book_annotation_router.put("/{id}", response_model=BookAnnotation)
async def update_book_annotation(id: int, data: UpdateBookAnnotation):
annotation = await BookAnnotationDB.objects.get_or_none(id=id)
if annotation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
annotation.update_from_dict(data.dict())
return annotation.save()

View File

@@ -0,0 +1,39 @@
from fastapi import APIRouter, Depends
from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate
from app.utils.pagination import CustomPage
from app.models import Sequence as SequenceDB
from app.serializers.sequence import Sequence, CreateSequence
from app.services.sequence import SequenceTGRMSearchService
sequence_router = APIRouter(
prefix="/api/v1/sequences",
tags=["sequence"]
)
@sequence_router.get("/", response_model=CustomPage[Sequence], dependencies=[Depends(Params)])
async def get_sequences():
return await paginate(
SequenceDB.objects
)
@sequence_router.get("/{id}", response_model=Sequence)
async def get_sequence(id: int):
return await SequenceDB.objects.get(id=id)
@sequence_router.post("/", response_model=Sequence)
async def create_sequence(data: CreateSequence):
return await SequenceDB.objects.create(
**data.dict()
)
@sequence_router.get("/search/{query}", response_model=CustomPage[Sequence], dependencies=[Depends(Params)])
async def search_sequences(query: str):
return await SequenceTGRMSearchService.get(query)

View File

@@ -0,0 +1,46 @@
from typing import Union
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate
from app.utils.pagination import CustomPage
from app.models import SequenceInfo as SequenceInfoDB
from app.serializers.sequence_info import SequenceInfo, CreateSequenceInfo, CreateRemoteSequenceInfo
from app.services.sequence_info import SequenceInfoCreator
sequence_info_router = APIRouter(
prefix="/api/v1/sequence_info",
tags=["sequence_info"]
)
@sequence_info_router.get("/", response_model=CustomPage[SequenceInfo], dependencies=[Depends(Params)])
async def get_sequence_infos():
return await paginate(
SequenceInfoDB.objects.prefetch_related(["book", "sequence"])
.select_related(["book__authors", "book__translations", "book__translations__translator"])
)
@sequence_info_router.get("/{id}", response_model=SequenceInfo)
async def get_sequence_info(id: int):
sequence_info = SequenceInfoDB.objects.prefetch_related(["book", "sequence"]) \
.select_related(["book__authors", "book__translations", "book__translations__translator"]) \
.get_or_none(id=id)
if sequence_info is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
return sequence_info
@sequence_info_router.post("/", response_model=SequenceInfo)
async def create_sequence_info(data: Union[CreateSequenceInfo, CreateRemoteSequenceInfo]):
sequence_info = await SequenceInfoCreator.create(data)
return await SequenceInfoDB.objects.prefetch_related(["book", "sequence"]) \
.select_related(["book__authors", "book__translations", "book__translations__translator"]) \
.get(id=sequence_info.id)

View File

@@ -0,0 +1,25 @@
from fastapi import APIRouter, Depends
from fastapi_pagination import Params, Page
from fastapi_pagination.ext.ormar import paginate
from app.models import Source as SourceDB
from app.serializers.source import Source, CreateSource
source_router = APIRouter(
prefix="/api/v1/sources",
tags=["source"],
)
@source_router.get("", response_model=Page[Source], dependencies=[Depends(Params)])
async def get_sources():
return await paginate(SourceDB.objects)
@source_router.post("", response_model=Source)
async def create_source(data: CreateSource):
return await SourceDB.objects.create(
**data.dict()
)

View File

@@ -0,0 +1,43 @@
from typing import Union
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi_pagination import Params
from fastapi_pagination.ext.ormar import paginate
from app.utils.pagination import CustomPage
from app.models import Translation as TranslationDB
from app.serializers.translation import Translation, CreateTranslation, CreateRemoteTranslation
from app.services.translation import TranslationCreator
translation_router = APIRouter(
prefix="/api/v1/translation",
tags=["translation"]
)
@translation_router.get("/", response_model=CustomPage[Translation], dependencies=[Depends(Params)])
async def get_translations():
return await paginate(
TranslationDB.objects.prefetch_related(["book", "translator"])
)
@translation_router.post("/", response_model=Translation)
async def create_translation(data: Union[CreateTranslation, CreateRemoteTranslation]):
translation = await TranslationCreator.create(data)
return await TranslationDB.objects.prefetch_related(["book", "translator"]).get(id=translation.id)
@translation_router.delete("/{id}", response_model=Translation)
async def delete_translation(id: int):
translation = await TranslationDB.objects.prefetch_related(["book", "translator"]).get_or_none(id=id)
if translation is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)
await translation.delete()
return translation