Skip to content

Commit e91be7c

Browse files
committed
WIP
1 parent 8b9d76c commit e91be7c

File tree

12 files changed

+111
-42
lines changed

12 files changed

+111
-42
lines changed

src/bss_web_file_server/main.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"""Main module for the FastAPI application."""
22

3+
from typing import Annotated
4+
35
from fastapi import FastAPI
46

57
from .routers import health, member, video
6-
from .services.member import create_member_base_path
7-
from .services.video import create_video_base_path
8+
from .services.member import MemberService
9+
from .services.video import VideoService
810

911
app = FastAPI()
1012

@@ -14,7 +16,10 @@
1416

1517

1618
@app.on_event("startup")
17-
async def startup_event():
19+
async def startup_event(
20+
member_service=MemberService(),
21+
video_service=VideoService(),
22+
):
1823
"""Create the base paths for the video and member folders on startup."""
19-
create_video_base_path()
20-
create_member_base_path()
24+
video_service.create_base_path()
25+
member_service.create_base_path()
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
"""Health check endpoints."""
22

33
from fastapi import APIRouter
4+
from fastapi.responses import PlainTextResponse
45

56
router = APIRouter(tags=["Health"])
67

78

8-
@router.get("/health", response_model=str)
9+
@router.get("/health", response_class=PlainTextResponse)
910
async def health():
1011
return "UP"
1112

1213

13-
@router.get("/ping", response_model=str)
14+
@router.get("/ping", response_class=PlainTextResponse)
1415
async def ping():
1516
return "PONG"

src/bss_web_file_server/routers/member.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,64 @@
33
import re
44
from uuid import UUID
55

6-
from fastapi import APIRouter, Response, UploadFile, status
6+
from fastapi import APIRouter, Depends, Response, UploadFile, status
77

88
from ..models.member import Member
9-
from ..services.member import (
10-
create_folder_structure,
11-
create_profile_picture,
12-
to_id_path,
13-
update_symlink,
14-
)
9+
from ..services.member import MemberService
1510

1611
router = APIRouter(tags=["Member"], prefix="/api/v1/member")
1712

1813

1914
@router.post("", response_model=Member)
20-
def create_member_folder(member: Member):
15+
def create_member_folder(
16+
member: Member,
17+
service: MemberService = Depends(MemberService),
18+
):
2119
"""
2220
Create a folder structure for a member and return the member object.
2321
:param member: Member object
22+
:param service: MemberService
2423
:return: 200 and the original member object
2524
"""
26-
create_folder_structure(member)
25+
service.create_folder_structure(member)
2726
return member
2827

2928

3029
@router.put("", response_model=Member)
31-
def update_member_folder(member: Member):
30+
def update_member_folder(
31+
member: Member,
32+
service: MemberService = Depends(MemberService),
33+
):
3234
"""
3335
Update the folder structure for a member and return the member object.
3436
If the member does not exist, return a 404.
3537
:param member: Member object
38+
:param service: MemberService
3639
:return: 200 and the original member object
3740
"""
38-
if not to_id_path(member.id).exists():
41+
if not service.to_id_path(member.id).exists():
3942
return Response(status_code=status.HTTP_404_NOT_FOUND)
40-
update_symlink(member)
43+
service.update_symlink(member)
4144
return member
4245

4346

4447
@router.post("/{member_id}/profilePicture", response_model=UUID)
45-
async def upload_member_picture(member_id: UUID, file: UploadFile):
48+
async def upload_member_picture(
49+
member_id: UUID,
50+
file: UploadFile,
51+
service: MemberService = Depends(MemberService),
52+
):
4653
"""
4754
Upload a picture for a member to convert
4855
and store the profile picture in different formats
4956
If the member does not exist, return a 404.
5057
If the file is not an image, return a 500.
5158
:param member_id: the id of the member
5259
:param file: the image file
60+
:param service: MemberService
5361
:return: 200 and the original member_id
5462
"""
55-
if not to_id_path(member_id).exists():
63+
if not service.to_id_path(member_id).exists():
5664
return Response(status_code=status.HTTP_404_NOT_FOUND)
5765
# pylint: disable=duplicate-code
5866
if file.content_type is not None and not re.match("image/.+", file.content_type):
@@ -62,5 +70,5 @@ async def upload_member_picture(member_id: UUID, file: UploadFile):
6270
)
6371
# pylint: enable=duplicate-code
6472
file_content = await file.read()
65-
create_profile_picture(file_content, member_id)
73+
service.create_profile_picture(file_content, member_id)
6674
return member_id

src/bss_web_file_server/routers/video.py

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,64 @@
33
import re
44
from uuid import UUID
55

6-
from fastapi import APIRouter, Response, UploadFile, status
6+
from fastapi import APIRouter, Depends, Response, UploadFile, status
77

8-
from ..services.video import (
9-
Video,
10-
create_folder_structure,
11-
create_thumbnails,
12-
to_id_path,
13-
update_symlinks,
14-
)
8+
from ..models.video import Video
9+
from ..services.video import VideoService
1510

1611
router = APIRouter(tags=["Video"], prefix="/api/v1/video")
1712

1813

1914
@router.post("", response_model=Video)
20-
def create_video_folder(video: Video):
15+
def create_video_folder(
16+
video: Video,
17+
service: VideoService = Depends(VideoService),
18+
):
2119
"""
2220
Create a folder structure for a video and return the video object.
2321
:param video: Video object
22+
:param service: VideoService
2423
:return: 200 and the original video object
2524
"""
26-
create_folder_structure(video)
25+
service.create_folder_structure(video)
2726
return video
2827

2928

3029
@router.put("", response_model=Video)
31-
def update_video_folder(video: Video):
30+
def update_video_folder(
31+
video: Video,
32+
service: VideoService = Depends(VideoService),
33+
):
3234
"""
3335
Update the folder structure for a video and return the video object.
3436
If the video does not exist, return a 404.
3537
:param video: Video object
38+
:param service: VideoService
3639
:return: 200 and the original video object
3740
"""
38-
if not to_id_path(video.id).exists():
41+
if not service.to_id_path(video.id).exists():
3942
return Response(status_code=status.HTTP_404_NOT_FOUND)
40-
update_symlinks(video)
43+
service.update_symlinks(video)
4144
return video
4245

4346

4447
@router.post("/{video_id}/thumbnail", response_model=UUID)
45-
async def upload_video_poster(video_id: UUID, file: UploadFile):
48+
async def upload_video_poster(
49+
video_id: UUID,
50+
file: UploadFile,
51+
service: VideoService = Depends(VideoService),
52+
):
4653
"""
4754
Upload a picture for a video thumbnail to convert
4855
and store the thumbnail in different formats
4956
If the video does not exist, return a 404.
5057
If the file is not an image, return a 500.
5158
:param video_id: the id of the video
5259
:param file: the image file
60+
:param service: VideoService
5361
:return: 200 and the original video_id
5462
"""
55-
if not to_id_path(video_id).exists():
63+
if not service.to_id_path(video_id).exists():
5664
return Response(status_code=status.HTTP_404_NOT_FOUND)
5765
# pylint: disable=duplicate-code
5866
if file.content_type is not None and not re.match("image/.+", file.content_type):
@@ -62,5 +70,5 @@ async def upload_video_poster(video_id: UUID, file: UploadFile):
6270
)
6371
# pylint: enable=duplicate-code
6472
file_content = await file.read()
65-
create_thumbnails(file_content, video_id)
73+
service.create_thumbnails(file_content, video_id)
6674
return video_id

src/bss_web_file_server/services/member.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def update_symlink(self, member: Member):
6767
)
6868

6969
# pylint: disable=duplicate-code
70-
def create_member_base_path(self):
70+
def create_base_path(self):
7171
"""
7272
This method will create the parent folder for all id and url folders.
7373
"""

src/bss_web_file_server/services/video.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""This module contains all video related service logic."""
22

33
from pathlib import Path
4+
from typing import Annotated
45
from uuid import UUID
56

67
from ..models.video import Video
@@ -69,7 +70,7 @@ def update_symlinks(self, video: Video):
6970
)
7071

7172
# pylint: disable=duplicate-code
72-
def create_video_base_path(self):
73+
def create_base_path(self):
7374
"""This method will create the parent folder for all id and url folders."""
7475
if not self.id_paths_base.exists():
7576
self.id_paths_base.mkdir(parents=True, exist_ok=True)

tests/bss_web_file_server/routers/__init__.py

Whitespace-only changes.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from fastapi import FastAPI
2+
from fastapi.testclient import TestClient
3+
4+
from bss_web_file_server.routers import health
5+
6+
app = FastAPI()
7+
8+
app.include_router(health.router)
9+
10+
client = TestClient(app)
11+
12+
13+
def test_health():
14+
response = client.get("/health")
15+
assert response.status_code == 200
16+
assert response.text == "UP"
17+
18+
19+
def test_ping():
20+
response = client.get("/ping")
21+
assert response.status_code == 200
22+
assert response.text == "PONG"
Loading
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from pathlib import Path
2+
3+
from bss_web_file_server.services.image import ImgFormat, create_images
4+
5+
6+
def test_create_iamges(tmp_path):
7+
img_file = Path(__file__).parent.joinpath("mountains.jpg").read_bytes()
8+
image_sizes = [
9+
ImgFormat(300, 300, "large"),
10+
ImgFormat(200, 200, "medium"),
11+
ImgFormat(100, 100, "small"),
12+
]
13+
14+
create_images(img_file, tmp_path, image_sizes)
15+
16+
assert Path(tmp_path, "large.avif").exists()
17+
assert Path(tmp_path, "large.webp").exists()
18+
assert Path(tmp_path, "large.jpeg").exists()
19+
assert Path(tmp_path, "medium.avif").exists()
20+
assert Path(tmp_path, "medium.webp").exists()
21+
assert Path(tmp_path, "medium.jpeg").exists()
22+
assert Path(tmp_path, "small.avif").exists()
23+
assert Path(tmp_path, "small.webp").exists()
24+
assert Path(tmp_path, "small.jpeg").exists()

tests/bss_web_file_server/services/test_member.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def member_service(tmp_path):
2121
:return: member service
2222
"""
2323
service = MemberService(base_path=str(tmp_path))
24-
service.create_member_base_path()
24+
service.create_base_path()
2525
assert service.id_paths_base.exists()
2626
assert service.url_paths_base.exists()
2727
return service

tests/bss_web_file_server/services/test_video.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def video_service(tmp_path):
2121
:return: video service
2222
"""
2323
service = VideoService(base_path=str(tmp_path))
24-
service.create_video_base_path()
24+
service.create_base_path()
2525
assert service.id_paths_base.exists()
2626
assert service.url_paths_base.exists()
2727
return service

0 commit comments

Comments
 (0)