Skip to content

Commit 3783a37

Browse files
committed
Create bookimage endpoint
1 parent efebf24 commit 3783a37

File tree

7 files changed

+77
-16
lines changed

7 files changed

+77
-16
lines changed

book/models.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class Book(UUIDMixin, BaseModel): #type: ignore
2626
edition = Column(String)
2727
available = Column(Boolean, default=True)
2828
release_date = Column(DATE)
29-
created = Column(DateTime, default=datetime.now)
30-
updated = Column(DateTime, server_default=func.now())
29+
created = Column(DateTime, default=datetime.now) # TODO created_at
30+
updated = Column(DateTime, server_default=func.now()) # TODO on_update updated_at
3131
description = Column(String)
3232
language = Column(String)
3333
pages = Column(Integer)

image/endpoints.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
from email.mime import image
21
from fastapi import APIRouter, Depends, BackgroundTasks
2+
from sqlalchemy.ext.asyncio import AsyncSession
33

4-
from utils import write_file
5-
from image.schemas import BookImageCreate
4+
from core.db import get_session
5+
from image.schemas import BookImageCreate, BookImageRetrieve
6+
from image import services as image_services
67

78

89
router = APIRouter()
910

1011

11-
@router.post('/create')
12+
@router.post('/create', response_model=BookImageRetrieve)
1213
async def create_image(
1314
background_tasks: BackgroundTasks,
14-
form: BookImageCreate = Depends(BookImageCreate.as_form)
15+
form: BookImageCreate = Depends(BookImageCreate.as_form),
16+
session: AsyncSession = Depends(get_session)
1517
):
16-
17-
# background_tasks.add_task(write_file, file)
18-
return form.file.filename
18+
image = await image_services.insert_image(
19+
session=session,
20+
background_tasks=background_tasks,
21+
form=form
22+
)
23+
return image

image/models.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
class ImageMixin:
1818
title = Column(String(length=255))
1919
available = Column(Boolean, default=True)
20-
created = Column(DateTime, default=datetime.now)
20+
created = Column(DateTime, default=datetime.now) # TODO created_at
2121
image_path = Column(String)
2222

2323

24-
2524
class BookImage(UUIDMixin, ImageMixin, BaseModel): # type: ignore
2625
__tablename__ = 'book_image'
2726

image/schemas.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from datetime import datetime
2+
13
from fastapi import UploadFile, Form
2-
from pydantic import BaseModel, UUID4, constr
4+
from pydantic import BaseModel, UUID4, constr, validator
35

46

57
class BookImageCreate(BaseModel):
@@ -16,4 +18,18 @@ def as_form(
1618
available: bool = Form(...),
1719
file: UploadFile = Form(...)
1820
):
19-
return cls(book_id=book_id, title=title, available=available, file=file)
21+
return cls(book_id=book_id, title=title, available=available, file=file)
22+
23+
24+
class BookImageRetrieve(BaseModel):
25+
id: UUID4
26+
book_id: UUID4
27+
title: str
28+
available: bool
29+
created: datetime
30+
31+
class Config:
32+
orm_mode = True
33+
json_encoders = {
34+
datetime: lambda v: v.strftime("%Y-%m-%d %H:%M:%S")
35+
}

image/services.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from fastapi import Depends, BackgroundTasks
2+
from sqlalchemy import insert
3+
from sqlalchemy.ext.asyncio import AsyncSession
4+
5+
from image.schemas import BookImageCreate
6+
from image.models import BookImage
7+
from utils import write_file
8+
9+
10+
async def insert_image(
11+
session: AsyncSession,
12+
background_tasks: BackgroundTasks,
13+
form: BookImageCreate = Depends(BookImageCreate.as_form)
14+
):
15+
file = form.file
16+
filepath = f"media/{file.filename}"
17+
form_data = form.dict()
18+
form_data['book_id'] = form_data['book_id'].hex
19+
form_data['image_path'] = filepath
20+
del form_data['file']
21+
statement = insert(BookImage).values(form_data).returning(
22+
BookImage.id,
23+
BookImage.book_id,
24+
BookImage.title,
25+
BookImage.available,
26+
BookImage.created
27+
)
28+
result = await session.execute(statement)
29+
await session.commit()
30+
image = result.one()
31+
background_tasks.add_task(write_file, filepath, file)
32+
return image

main.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
import os
2+
from pathlib import Path
3+
14
from fastapi import FastAPI
25
from fastapi_pagination import add_pagination
36

47
from routes import routes
58
from core.db import database
9+
from config import BASE_DIR
610

711

812
app = FastAPI(title='Library API')
913
app.include_router(routes)
1014

15+
MEDIA = BASE_DIR.joinpath('media')
16+
17+
if not os.path.isdir(MEDIA):
18+
Path.mkdir(MEDIA)
19+
1120
add_pagination(app)
1221

1322

utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ def extract_objects(objects: tuple):
1212
yield object_tuple[0]
1313

1414

15-
def write_file(file: UploadFile = File(...)):
16-
with open(f'{file.filename}', 'wb') as buffer:
15+
def write_file(filepath, file: UploadFile = File(...)):
16+
with open(filepath, 'wb') as buffer:
1717
shutil.copyfileobj(file.file, buffer)

0 commit comments

Comments
 (0)