Skip to content

Commit 71d0d8e

Browse files
authored
Merge pull request #84 from seamusic-official/SM-68
ENHANCEMENT SM-68: add MAO & S3MAOImplementation
2 parents 62e9b5f + 950e198 commit 71d0d8e

File tree

3 files changed

+93
-2
lines changed
  • src
    • app
      • auth/users/interfaces/ma
      • music/albums/interfaces/ma
    • domain/auth/users/interfaces/ma

3 files changed

+93
-2
lines changed
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from dataclasses import dataclass
2+
from types import TracebackType
3+
from typing import Self
4+
5+
from src.domain.auth.users.interfaces.ma.mao import MAO
6+
from src.infrastructure.loggers import app as logger
7+
from src.infrastructure.s3 import S3SessionMixin, unique_filename, get_file_stream
8+
9+
10+
@dataclass
11+
class S3MAOImplementation(MAO, S3SessionMixin):
12+
async def update_profile_picture(self, data: bytes, user_id: int) -> str:
13+
logger.info("update_profile_picture MAO request")
14+
cover_url = await self.update(
15+
path="/users/",
16+
filename=unique_filename(str(user_id)),
17+
file_stream=get_file_stream(data=data),
18+
)
19+
return cover_url
20+
21+
async def __aenter__(self) -> Self:
22+
return self
23+
24+
async def __aexit__(
25+
self,
26+
exc_type: type[Exception] | None = None,
27+
exc_val: Exception | None = None,
28+
exc_tb: TracebackType | None = None,
29+
) -> None:
30+
pass
31+
32+
33+
def get_s3_mao_implementation() -> S3MAOImplementation:
34+
"""
35+
:return S3MAOImplementation: an instance of S3 interface session
36+
"""
37+
return S3MAOImplementation()

src/app/music/albums/interfaces/ma/mao.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
from dataclasses import dataclass
12
from types import TracebackType
23
from typing import Self
34

45
from src.domain.music.albums.interfaces.ma.mao import MAO
56
from src.infrastructure.loggers import app as logger
6-
from src.infrastructure.s3 import Session, unique_filename, get_file_stream
7+
from src.infrastructure.s3 import S3SessionMixin, unique_filename, get_file_stream
78

89

9-
class S3MAOImplementation(MAO, Session):
10+
@dataclass
11+
class S3MAOImplementation(MAO, S3SessionMixin):
1012
async def update_cover(self, data: bytes, album_id: int) -> str:
1113
logger.info("update_cover MAO request")
1214
cover_url = await self.update(
@@ -29,4 +31,7 @@ async def __aexit__(
2931

3032

3133
def get_s3_mao_implementation() -> S3MAOImplementation:
34+
"""
35+
:return S3MAOImplementation: an instance of S3 interface session
36+
"""
3237
return S3MAOImplementation()
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from abc import abstractmethod
2+
from dataclasses import dataclass
3+
from types import TracebackType
4+
from typing import Self
5+
6+
from src.domain.auth.users.interfaces.base import BaseInterface
7+
8+
9+
@dataclass
10+
class MAO(BaseInterface):
11+
"""
12+
Media Access Object (MAO) is an abstract class created
13+
to define and describe necessary functions for files acess.
14+
15+
It's used in services' layer to manage files.
16+
17+
As an abstraction, MAO cannot be used directly - that will
18+
cause `NotImplementedError` and crash the application. So,
19+
to provide the files access, a MAO implementation is required.
20+
21+
MAO implementation is a MAO's subclass designed in a unique way
22+
for an exact type of media storage. It can only be used for
23+
files operations with data in that type of storage. The implementation
24+
must be provided to the service's layer via factory to avoid using
25+
globals.
26+
"""
27+
28+
@abstractmethod
29+
async def update_profile_picture(self, data: bytes, user_id: int) -> str:
30+
"""
31+
Changes user's profile picture
32+
33+
:param user_id: user's numeric identificator
34+
:param data: file data in bytes format
35+
:return: cover's URL
36+
:raise NotImplementedError: when called directly by abstract class instance
37+
"""
38+
raise NotImplementedError
39+
40+
async def __aenter__(self) -> Self:
41+
return self
42+
43+
async def __aexit__(
44+
self,
45+
exc_type: type[Exception] | None = None,
46+
exc_val: Exception | None = None,
47+
exc_tb: TracebackType | None = None,
48+
) -> None:
49+
pass

0 commit comments

Comments
 (0)