rb-commons 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

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.
rb_commons/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,30 @@
1
+ from pydantic_settings import BaseSettings
2
+
3
+ class CommonConfigs(BaseSettings):
4
+ service_name: str
5
+ service_port: int
6
+ service_id: str
7
+ service_hostname: str = '127.0.0.1'
8
+ service_host: str
9
+
10
+ consul_host: str = '127.0.0.1'
11
+ consul_port: int = 8888
12
+
13
+ # db
14
+ POSTGRES_HOST: str
15
+ POSTGRES_USER: str
16
+ POSTGRES_PORT: int
17
+ POSTGRES_PASSWORD: str
18
+ POSTGRES_DB: str
19
+ DB_ALEMBIC_URL: str
20
+
21
+ @property
22
+ def database_url(self):
23
+ return f"postgresql+asyncpg://{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_DB}"
24
+
25
+ class Config:
26
+ env_file = ".env"
27
+ env_file_encoding = "utf-8"
28
+
29
+
30
+ configs = CommonConfigs()
File without changes
@@ -0,0 +1,11 @@
1
+ class DatabaseException(Exception):
2
+ def __init__(self, text: str, user_id: int | None = None , original_exception=None):
3
+ self.user_id = user_id
4
+ self.text = text
5
+ self.original_exception = original_exception
6
+
7
+ class InternalException(Exception):
8
+ def __init__(self, text: str, user_id: int | None = None, telegram_id: int | None = None, original_exception=None):
9
+ self.user_id = user_id
10
+ self.text = text
11
+ self.original_exception = original_exception
@@ -0,0 +1,178 @@
1
+ from typing import TypeVar, Type, Generic, Optional, List, Dict
2
+ from sqlalchemy import select, delete, update
3
+ from sqlalchemy.exc import IntegrityError, SQLAlchemyError, NoResultFound
4
+ from sqlalchemy.ext.asyncio import AsyncSession
5
+ from sqlalchemy.orm import declarative_base
6
+ from rb_commons.orm.exceptions import DatabaseException, InternalException
7
+
8
+ ModelType = TypeVar('ModelType', bound=declarative_base())
9
+
10
+ class BaseManager(Generic[ModelType]):
11
+ model: Type[ModelType]
12
+
13
+ def __init__(self, session: AsyncSession) -> None:
14
+ self.session = session
15
+
16
+ async def get(self, **kwargs) -> Optional[ModelType]:
17
+ """
18
+ get object based on conditions
19
+ """
20
+ query = select(self.model).filter_by(**kwargs)
21
+ result = await self.session.execute(query)
22
+ return result.scalar_one_or_none()
23
+
24
+ async def filter(self, **kwargs) -> List[ModelType]:
25
+ """
26
+ Filter objects based on conditions
27
+ """
28
+ query = select(self.model).filter_by(**kwargs)
29
+ result = await self.session.execute(query)
30
+ return list(result.scalars().all())
31
+
32
+ async def create(self, **kwargs) -> ModelType:
33
+ """
34
+ Create a new object
35
+ """
36
+ obj = self.model(**kwargs)
37
+
38
+ try:
39
+ self.session.add(obj)
40
+ await self.session.flush()
41
+ await self.session.commit()
42
+ await self.session.refresh(obj)
43
+ return obj
44
+ except IntegrityError as e:
45
+ await self.session.rollback()
46
+ raise DatabaseException(f"Constraint violation: {str(e)}") from e
47
+ except SQLAlchemyError as e:
48
+ await self.session.rollback()
49
+ raise DatabaseException(f"Database error occurred: {str(e)}") from e
50
+ except Exception as e:
51
+ await self.session.rollback()
52
+ raise InternalException(f"Unexpected error during creation: {str(e)}") from e
53
+
54
+
55
+ async def delete(self, id: Optional[int] = None, **filters) -> bool | None:
56
+ """
57
+ Delete object(s) with flexible filtering options
58
+
59
+ :param id: Specific ID to delete
60
+ :param filters: Additional filter conditions
61
+ :return: Number of deleted records or None
62
+ """
63
+ try:
64
+ if id is not None:
65
+ filters['id'] = id
66
+
67
+ delete_stmt = delete(self.model).filter_by(**filters)
68
+ result = await self.session.execute(delete_stmt)
69
+ await self.session.commit()
70
+ return result.rowcount() > 0
71
+ except NoResultFound:
72
+ return False
73
+ except SQLAlchemyError as e:
74
+ await self.session.rollback()
75
+ raise DatabaseException(f"Delete operation failed: {str(e)}") from e
76
+
77
+ async def bulk_delete(self, **filters) -> int:
78
+ """
79
+ Bulk delete with flexible filtering
80
+
81
+ :param filters: Conditions for bulk deletion
82
+ :return: Number of deleted records
83
+ """
84
+ try:
85
+ delete_stmt = delete(self.model).filter_by(**filters)
86
+ result = await self.session.execute(delete_stmt)
87
+ await self.session.commit()
88
+ return result.rowcount()
89
+ except SQLAlchemyError as e:
90
+ await self.session.rollback()
91
+ raise DatabaseException(f"Bulk delete failed: {str(e)}") from e
92
+
93
+ async def update_by_filters(self, filters: Dict, **update_fields) -> Optional[ModelType]:
94
+ """
95
+ Update object(s) with flexible filtering options
96
+
97
+ :param filters: Conditions for selecting records to update
98
+ :param update_fields: Fields and values to update
99
+ :return: Number of updated records
100
+ """
101
+ if not update_fields:
102
+ raise InternalException("No fields provided for update")
103
+
104
+ try:
105
+ update_stmt = update(self.model).filter_by(**filters).values(**update_fields)
106
+ await self.session.execute(update_stmt)
107
+ await self.session.commit()
108
+ updated_instance = await self.get(**filters)
109
+ return updated_instance
110
+ except IntegrityError as e:
111
+ await self.session.rollback()
112
+ raise InternalException(f"Constraint violation: {str(e)}") from e
113
+ except SQLAlchemyError as e:
114
+ await self.session.rollback()
115
+ raise DatabaseException(f"Update operation failed: {str(e)}") from e
116
+
117
+ async def update(self, instance: ModelType, **update_fields) -> Optional[ModelType]:
118
+ """
119
+ Update an existing database instance with new fields
120
+
121
+ :param instance: The database model instance to update
122
+ :param update_fields: Keyword arguments of fields to update
123
+ :return: The updated instance
124
+
125
+ :raises ValueError: If no update fields are provided
126
+ :raises RuntimeError: For database-related errors
127
+ """
128
+ # Validate update fields
129
+ if not update_fields:
130
+ raise InternalException("No fields provided for update")
131
+
132
+ try:
133
+ # Apply updates directly to the instance
134
+ for key, value in update_fields.items():
135
+ setattr(instance, key, value)
136
+
137
+ self.session.add(instance)
138
+ await self.session.commit()
139
+ await self.session.refresh(instance)
140
+
141
+ return instance
142
+
143
+ except IntegrityError as e:
144
+ await self.session.rollback()
145
+ raise InternalException(f"Constraint violation: {str(e)}") from e
146
+
147
+ except SQLAlchemyError as e:
148
+ await self.session.rollback()
149
+ raise DatabaseException(f"Update operation failed: {str(e)}") from e
150
+
151
+ async def save(self, instance: ModelType) -> Optional[ModelType]:
152
+ """
153
+ Save instance
154
+
155
+ :param instance: The database model instance to save
156
+ :return: The saved instance
157
+
158
+ :raises ValueError: If no update fields are provided
159
+ :raises RuntimeError: For database-related errors
160
+ """
161
+ try:
162
+ self.session.add(instance)
163
+ await self.session.commit()
164
+ await self.session.refresh(instance)
165
+ return instance
166
+
167
+ except IntegrityError as e:
168
+ await self.session.rollback()
169
+ raise InternalException(f"Constraint violation: {str(e)}") from e
170
+
171
+ except SQLAlchemyError as e:
172
+ await self.session.rollback()
173
+ raise DatabaseException(f"Update operation failed: {str(e)}") from e
174
+
175
+
176
+ async def is_exists(self, **kwargs) -> bool:
177
+ return await self.get(**kwargs) is not None
178
+
@@ -1,35 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rb-commons
3
- Version: 0.1.0
4
- Summary: Orm commons for sqlalchemy based projects
3
+ Version: 0.1.1
4
+ Summary: Commons of project and simplified orm based on sqlalchemy.
5
5
  Home-page: https://github.com/Abdulvoris101/rb-commons
6
6
  Author: Abdulvoris
7
7
  Author-email: erkinovabdulvoris101@gmail.com
8
8
  Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
9
10
  Classifier: Operating System :: OS Independent
10
11
  Requires-Python: >=3.11
11
12
  Description-Content-Type: text/markdown
12
- Requires-Dist: annotated-types~=0.7.0
13
- Requires-Dist: anyio~=4.7.0
14
- Requires-Dist: click~=8.1.8
15
- Requires-Dist: colorama~=0.4.6
16
- Requires-Dist: fastapi~=0.115.6
17
- Requires-Dist: greenlet~=3.1.1
18
- Requires-Dist: h11~=0.14.0
19
- Requires-Dist: httptools~=0.6.4
20
- Requires-Dist: idna~=3.10
21
- Requires-Dist: pydantic~=2.10.4
22
- Requires-Dist: pydantic-settings~=2.7.1
23
- Requires-Dist: pydantic_core~=2.27.2
24
- Requires-Dist: python-dotenv~=1.0.1
25
- Requires-Dist: PyYAML~=6.0.2
26
- Requires-Dist: sniffio~=1.3.1
27
- Requires-Dist: SQLAlchemy~=2.0.36
28
- Requires-Dist: starlette~=0.41.3
29
- Requires-Dist: typing_extensions~=4.12.2
30
- Requires-Dist: uvicorn~=0.34.0
31
- Requires-Dist: watchfiles~=1.0.3
32
- Requires-Dist: websockets~=14.1
13
+ Requires-Dist: annotated-types==0.7.0
14
+ Requires-Dist: greenlet==3.1.1
15
+ Requires-Dist: pydantic==2.10.4
16
+ Requires-Dist: PyJWT==2.10.1
17
+ Requires-Dist: python-dotenv==1.0.1
18
+ Requires-Dist: SQLAlchemy==2.0.36
33
19
 
34
20
  # RB-Commons
35
21
 
@@ -0,0 +1,10 @@
1
+ rb_commons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ rb_commons/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ rb_commons/configs/config.py,sha256=8Z2_om4yHAQI7PYX5qzVNR78DMAYsgbKfoa5skGBWlk,746
4
+ rb_commons/orm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ rb_commons/orm/exceptions.py,sha256=1aMctiEwrPjyehoXVX1l6ML5ZOhmDkmBISzlTD5ey1Y,509
6
+ rb_commons/orm/managers.py,sha256=VopUw29sCXrPTriBALR9qwkG5yCu6BDHRgR7cCygNiE,6726
7
+ rb_commons-0.1.1.dist-info/METADATA,sha256=84zZkWX-fJFyuUuy2Q7h--H_RBRDytEwwMDXjggwRt4,6276
8
+ rb_commons-0.1.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
9
+ rb_commons-0.1.1.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
10
+ rb_commons-0.1.1.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ rb_commons
@@ -1,4 +0,0 @@
1
- rb_commons-0.1.0.dist-info/METADATA,sha256=Sk7kcuRLGSWvp0FHU6UkpKYi_2At2g8Tgd-MxGqJ-hI,6703
2
- rb_commons-0.1.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
3
- rb_commons-0.1.0.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
4
- rb_commons-0.1.0.dist-info/RECORD,,
@@ -1 +0,0 @@
1
-