rb-commons 0.1.16__tar.gz → 0.1.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {rb_commons-0.1.16 → rb_commons-0.1.18}/PKG-INFO +1 -1
  2. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/configs/injections.py +1 -1
  3. rb_commons-0.1.18/rb_commons/http/exceptions.py +41 -0
  4. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/orm/managers.py +39 -8
  5. rb_commons-0.1.18/rb_commons/permissions/__init__.py +0 -0
  6. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/permissions/role_permissions.py +3 -2
  7. rb_commons-0.1.18/rb_commons/schemes/__init__.py +0 -0
  8. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons.egg-info/PKG-INFO +1 -1
  9. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons.egg-info/SOURCES.txt +2 -0
  10. {rb_commons-0.1.16 → rb_commons-0.1.18}/setup.py +1 -1
  11. rb_commons-0.1.16/rb_commons/permissions/__init__.py +0 -1
  12. {rb_commons-0.1.16 → rb_commons-0.1.18}/README.md +0 -0
  13. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/__init__.py +0 -0
  14. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/configs/__init__.py +0 -0
  15. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/configs/config.py +0 -0
  16. {rb_commons-0.1.16/rb_commons/orm → rb_commons-0.1.18/rb_commons/http}/__init__.py +0 -0
  17. {rb_commons-0.1.16/rb_commons/schemes → rb_commons-0.1.18/rb_commons/orm}/__init__.py +0 -0
  18. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/orm/exceptions.py +0 -0
  19. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons/schemes/jwt.py +0 -0
  20. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons.egg-info/dependency_links.txt +0 -0
  21. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons.egg-info/requires.txt +0 -0
  22. {rb_commons-0.1.16 → rb_commons-0.1.18}/rb_commons.egg-info/top_level.txt +0 -0
  23. {rb_commons-0.1.16 → rb_commons-0.1.18}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rb-commons
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Commons of project and simplified orm based on sqlalchemy.
5
5
  Home-page: https://github.com/RoboSell-organization/rb-commons
6
6
  Author: Abdulvoris
@@ -1,6 +1,6 @@
1
1
  from typing import Annotated
2
2
 
3
- from rb_commons.permissions import IsAdmin, IsCustomer
3
+ from rb_commons.permissions.role_permissions import IsAdmin, IsCustomer
4
4
  from rb_commons.schemes.jwt import Claims
5
5
  from fastapi import Request, Depends
6
6
 
@@ -0,0 +1,41 @@
1
+ from fastapi import HTTPException, status
2
+
3
+
4
+ class CustomHTTPException(HTTPException):
5
+ def __init__(self, message: str, status: int, code: str = None, additional_info: dict = None):
6
+ super().__init__(status_code=status, detail=message)
7
+
8
+ self.code = code
9
+ self.message = message
10
+ self.status = status
11
+ self.additional_info = additional_info
12
+
13
+
14
+ class NotAuthorizedException(CustomHTTPException):
15
+ def __init__(self, message: str = "You are not authorized", status: int = 401, code: str = None,
16
+ additional_info: dict = None):
17
+ super().__init__(message=message, status=status, code=code, additional_info=additional_info)
18
+
19
+
20
+ class ForbiddenException(CustomHTTPException):
21
+ def __init__(self, message: str = "Permission denied", status: int = 403, code: str = None,
22
+ additional_info: dict = None):
23
+ super().__init__(message=message, status=status, code=code, additional_info=additional_info)
24
+
25
+
26
+ class BadRequestException(CustomHTTPException):
27
+ def __init__(self, message: str = "Bad request", status: int = 400, code: str = None,
28
+ additional_info: dict = None):
29
+ super().__init__(message=message, status=status, code=code, additional_info=additional_info)
30
+
31
+
32
+ class NotFoundException(CustomHTTPException):
33
+ def __init__(self, message: str = "Not found", status: int = 404, code: str = None,
34
+ additional_info: dict = None):
35
+ super().__init__(message=message, status=status, code=code, additional_info=additional_info)
36
+
37
+
38
+ class InternalException(CustomHTTPException):
39
+ def __init__(self, message: str = "Internal exception", status: int = 500, code: str = None,
40
+ additional_info: dict = None):
41
+ super().__init__(message=message, status=status, code=code, additional_info=additional_info)
@@ -1,8 +1,11 @@
1
- from typing import TypeVar, Type, Generic, Optional, List, Dict
1
+ import uuid
2
+ from typing import TypeVar, Type, Generic, Optional, List, Dict, Literal, Union
2
3
  from sqlalchemy import select, delete, update
3
4
  from sqlalchemy.exc import IntegrityError, SQLAlchemyError, NoResultFound
4
5
  from sqlalchemy.ext.asyncio import AsyncSession
5
6
  from sqlalchemy.orm import declarative_base
7
+
8
+ from rb_commons.http.exceptions import NotFoundException
6
9
  from rb_commons.orm.exceptions import DatabaseException, InternalException
7
10
 
8
11
  ModelType = TypeVar('ModelType', bound=declarative_base())
@@ -12,27 +15,55 @@ class BaseManager(Generic[ModelType]):
12
15
 
13
16
  def __init__(self, session: AsyncSession) -> None:
14
17
  self.session = session
18
+ self.data = None
19
+ self.filters = {}
15
20
 
16
- async def get(self, **kwargs) -> Optional[ModelType]:
21
+ async def get(self, pk: Union[str, int, uuid.UUID]) -> Optional[ModelType]:
17
22
  """
18
23
  get object based on conditions
19
24
  """
20
- query = select(self.model).filter_by(**kwargs)
25
+ query = select(self.model).filter_by(id=pk)
21
26
  result = await self.session.execute(query)
22
- return result.scalar_one_or_none()
27
+ instance = result.scalar_one_or_none()
28
+
29
+ if instance is None:
30
+ raise NotFoundException(
31
+ message="Object does not exist",
32
+ status=404,
33
+ code="0001",
34
+ )
35
+
36
+ return instance
23
37
 
24
- async def filter(self, **kwargs) -> List[ModelType]:
38
+ async def filter(self, **kwargs) -> 'BaseManager[ModelType]':
25
39
  """
26
40
  Filter objects based on conditions
27
41
  """
28
- query = select(self.model).filter_by(**kwargs)
42
+ self.filters.update(kwargs)
43
+ return self
44
+
45
+ async def all(self) -> List[ModelType]:
46
+ """Return all filtered results."""
47
+ query = select(self.model).filter_by(**self.filters)
29
48
  result = await self.session.execute(query)
30
49
  return list(result.scalars().all())
31
50
 
51
+ async def first(self) -> Optional[ModelType]:
52
+ """Return the first matching object, or None."""
53
+ query = select(self.model).filter_by(**self.filters)
54
+ result = await self.session.execute(query)
55
+ return result.scalars().first()
56
+
57
+ async def count(self) -> int:
58
+ """Return the count of matching records."""
59
+ query = select(self.model).filter_by(**self.filters)
60
+ result = await self.session.execute(query)
61
+ return len(result.scalars().all())
62
+
32
63
  async def create(self, **kwargs) -> ModelType:
33
64
  """
34
65
  Create a new object
35
- """
66
+ """
36
67
  obj = self.model(**kwargs)
37
68
 
38
69
  try:
@@ -52,7 +83,7 @@ class BaseManager(Generic[ModelType]):
52
83
  raise InternalException(f"Unexpected error during creation: {str(e)}") from e
53
84
 
54
85
 
55
- async def delete(self, id: Optional[int] = None, **filters) -> bool | None:
86
+ async def delete(self, id: Optional[int] = None, **filters):
56
87
  """
57
88
  Delete object(s) with flexible filtering options
58
89
 
File without changes
@@ -1,13 +1,14 @@
1
- from fastapi import Depends, HTTPException
1
+ from fastapi import Depends
2
2
 
3
3
  from rb_commons.configs.injections import get_claims
4
+ from rb_commons.http.exceptions import ForbiddenException
4
5
  from rb_commons.schemes.jwt import Claims, UserRole
5
6
 
6
7
 
7
8
  class BasePermission:
8
9
  def __call__(self, claims: Claims = Depends(get_claims)):
9
10
  if not self.has_permission(claims):
10
- raise HTTPException(status_code=403, detail="Permission Denied")
11
+ raise ForbiddenException(message=f"Access denied", status=401, code="0000")
11
12
 
12
13
  def has_permission(self, claims: Claims) -> bool:
13
14
  return False
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rb-commons
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Commons of project and simplified orm based on sqlalchemy.
5
5
  Home-page: https://github.com/RoboSell-organization/rb-commons
6
6
  Author: Abdulvoris
@@ -9,6 +9,8 @@ rb_commons.egg-info/top_level.txt
9
9
  rb_commons/configs/__init__.py
10
10
  rb_commons/configs/config.py
11
11
  rb_commons/configs/injections.py
12
+ rb_commons/http/__init__.py
13
+ rb_commons/http/exceptions.py
12
14
  rb_commons/orm/__init__.py
13
15
  rb_commons/orm/exceptions.py
14
16
  rb_commons/orm/managers.py
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="rb-commons",
8
- version="0.1.16",
8
+ version="0.1.18",
9
9
  author="Abdulvoris",
10
10
  author_email="erkinovabdulvoris101@gmail.com",
11
11
  description="Commons of project and simplified orm based on sqlalchemy.",
@@ -1 +0,0 @@
1
- from role_permissions import *
File without changes
File without changes