sharedkernel 2.1.2__tar.gz → 2.2.1__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 (39) hide show
  1. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/PKG-INFO +6 -1
  2. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/README.md +4 -0
  3. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/setup.py +3 -2
  4. sharedkernel-2.2.1/sharedkernel/database/__init__.py +3 -0
  5. sharedkernel-2.2.1/sharedkernel/database/audit_model.py +17 -0
  6. sharedkernel-2.2.1/sharedkernel/database/mongo_generic_audit_repository.py +72 -0
  7. sharedkernel-2.2.1/sharedkernel/database/mongo_generic_repository.py +122 -0
  8. sharedkernel-2.2.1/sharedkernel/diff_utils.py +65 -0
  9. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/jwt_service.py +14 -8
  10. sharedkernel-2.2.1/sharedkernel/objects/__init__.py +5 -0
  11. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/objects/base_document.py +5 -1
  12. sharedkernel-2.2.1/sharedkernel/objects/user_info.py +13 -0
  13. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel.egg-info/PKG-INFO +6 -1
  14. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel.egg-info/SOURCES.txt +5 -1
  15. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel.egg-info/requires.txt +1 -0
  16. sharedkernel-2.1.2/sharedkernel/database/__init__.py +0 -1
  17. sharedkernel-2.1.2/sharedkernel/database/mongo_generic_repository.py +0 -51
  18. sharedkernel-2.1.2/sharedkernel/objects/__init__.py +0 -4
  19. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/setup.cfg +0 -0
  20. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/common.py +0 -0
  21. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/data_format_converter.py +0 -0
  22. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/date_converter.py +0 -0
  23. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/enum/__init__.py +0 -0
  24. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/enum/error_code.py +0 -0
  25. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/exception/__init__.py +0 -0
  26. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/exception/exception.py +0 -0
  27. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/exception/exception_handlers.py +0 -0
  28. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/normalizer/__init__.py +0 -0
  29. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/normalizer/number_normalizer.py +0 -0
  30. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/normalizer/phone_number_normalizer.py +0 -0
  31. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/normalizer/string_normalizer.py +0 -0
  32. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/objects/json_string_model.py +0 -0
  33. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/objects/jwt_model.py +0 -0
  34. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/objects/result.py +0 -0
  35. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/regex_masking.py +0 -0
  36. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/s3_uploader.py +0 -0
  37. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel/string_extentions.py +0 -0
  38. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel.egg-info/dependency_links.txt +0 -0
  39. {sharedkernel-2.1.2 → sharedkernel-2.2.1}/sharedkernel.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedkernel
3
- Version: 2.1.2
3
+ Version: 2.2.1
4
4
  Summary: sharekernel is a shared package between all python projects
5
5
  Author: Smilinno
6
6
  Description-Content-Type: text/markdown
@@ -18,6 +18,7 @@ Requires-Dist: python-docx
18
18
  Requires-Dist: mammoth
19
19
  Requires-Dist: markdown
20
20
  Requires-Dist: beautifulsoup4
21
+ Requires-Dist: deepdiff
21
22
  Dynamic: author
22
23
  Dynamic: description
23
24
  Dynamic: description-content-type
@@ -28,6 +29,10 @@ Dynamic: summary
28
29
  this is a shared kernel package
29
30
 
30
31
  # Change Log
32
+ ### Version 2.2.1
33
+ - fixbug requirements
34
+ ### Version 2.2.0
35
+ - implement Audit logging
31
36
  ### Version 2.1.2
32
37
  - Update pydantic parse_object with model_validate
33
38
  ### Version 2.1.0
@@ -2,6 +2,10 @@
2
2
  this is a shared kernel package
3
3
 
4
4
  # Change Log
5
+ ### Version 2.2.1
6
+ - fixbug requirements
7
+ ### Version 2.2.0
8
+ - implement Audit logging
5
9
  ### Version 2.1.2
6
10
  - Update pydantic parse_object with model_validate
7
11
  ### Version 2.1.0
@@ -33,10 +33,11 @@ setup(
33
33
  "python-docx",
34
34
  "mammoth",
35
35
  "markdown",
36
- "beautifulsoup4"
36
+ "beautifulsoup4",
37
+ "deepdiff"
37
38
  ],
38
39
  # *strongly* suggested for sharing
39
- version="2.1.2",
40
+ version="2.2.1",
40
41
  description="sharekernel is a shared package between all python projects",
41
42
  long_description=long_description,
42
43
  long_description_content_type="text/markdown",
@@ -0,0 +1,3 @@
1
+ from .mongo_generic_repository import MongoGenericRepository
2
+ from .mongo_generic_audit_repository import MongoGenericAuditRepository
3
+ from .audit_model import AuditLog, AuditOperation
@@ -0,0 +1,17 @@
1
+ from sharedkernel.objects.base_document import BaseDocument
2
+
3
+ from enum import Enum
4
+
5
+ class AuditOperation(str, Enum):
6
+ CREATE = "create"
7
+ UPDATE = "update"
8
+ DELETE = "delete"
9
+
10
+ class AuditLog(BaseDocument):
11
+ user_id: str
12
+ collection_name: str
13
+ document_id: str
14
+ operation: AuditOperation
15
+ original: dict | None = None
16
+ modified: dict
17
+
@@ -0,0 +1,72 @@
1
+ from typing import Generic, TypeVar, List, Type
2
+ from bson import ObjectId
3
+ from pymongo import MongoClient
4
+ from pydantic.v1 import BaseModel
5
+
6
+ from sharedkernel.database.audit_model import AuditLog
7
+
8
+ T = TypeVar("T", bound=BaseModel)
9
+
10
+ AUDIT_COLLECTION_NAME = "audit_log"
11
+
12
+ class MongoGenericAuditRepository():
13
+ def __init__(
14
+ self,
15
+ database: MongoClient,
16
+ audit_collection_name: str | None = None
17
+ ):
18
+ self.database = database
19
+ self.__collection_name = audit_collection_name or AUDIT_COLLECTION_NAME
20
+
21
+ self.collection = self.database[self.__collection_name]
22
+
23
+ def _map_to_model(self, document: dict) -> AuditLog:
24
+ document["id"] = str(document.pop("_id"))
25
+ return AuditLog(**document)
26
+
27
+ def find_one(self, id: str) -> T:
28
+ query = {"_id": ObjectId(id), "is_deleted": False}
29
+ result = self.collection.find_one(query)
30
+ return self._map_to_model(result) if result else None
31
+
32
+ def find(
33
+ self,
34
+ document_id: str | None = None,
35
+ operation: str | None = None,
36
+ collection_name: str | None = None,
37
+ field_name: str | None = None,
38
+ ) -> List[AuditLog]:
39
+
40
+ query = {}
41
+
42
+ if document_id:
43
+ query["document_id"] = document_id
44
+ if operation:
45
+ query["operation"] = operation
46
+ if collection_name:
47
+ query["collection_name"] = collection_name
48
+
49
+ if field_name:
50
+ query["$or"] = [
51
+ {f"original.{field_name}": {"$exists": True}},
52
+ {f"modified.{field_name}": {"$exists": True}},
53
+ ]
54
+
55
+ results = self.collection.find(query)
56
+ return [self._map_to_model(bot) for bot in results]
57
+
58
+ def insert_one(self, data: AuditLog) -> str:
59
+ delattr(data, "id")
60
+ result = self.collection.insert_one(data.model_dump())
61
+ return str(result.inserted_id)
62
+
63
+ def insert_many(self, data: List[AuditLog]) -> List[str]:
64
+ data_list = [delattr(d.model_dump(), "id") for d in data]
65
+ result = self.collection.insert_many(data_list)
66
+ return [str(id_) for id_ in result.inserted_ids]
67
+
68
+ def delete_one(self, id: str) -> int:
69
+ query = {"_id": ObjectId(id)}
70
+ result = self.collection.delete_one(query)
71
+ return result.deleted_count
72
+
@@ -0,0 +1,122 @@
1
+ from bson import ObjectId
2
+ from typing import Generic, TypeVar, List, Type
3
+ from pydantic.v1 import BaseModel
4
+ from pymongo import MongoClient, ReturnDocument
5
+ from contextlib import suppress
6
+
7
+ from sharedkernel.objects.user_info import current_user_info
8
+ from sharedkernel.string_extentions import camel_to_snake
9
+ from sharedkernel.objects.base_document import BaseAuditDocument
10
+ from sharedkernel.database.mongo_generic_audit_repository import MongoGenericAuditRepository
11
+ from sharedkernel.database.audit_model import (
12
+ AuditLog,
13
+ AuditOperation
14
+ )
15
+ from sharedkernel.diff_utils import generate_clean_diff
16
+
17
+ T = TypeVar("T", bound=BaseModel)
18
+
19
+ class MongoGenericRepository(Generic[T]):
20
+ def __init__(self, database: MongoClient, model: Type[T], audit_collection_name: str | None = None):
21
+ self.database = database
22
+ self.__collection_name = camel_to_snake(model.__name__)
23
+ self.collection = self.database[self.__collection_name]
24
+ self.model = model
25
+ self.audit_collection = MongoGenericAuditRepository(
26
+ database=database,
27
+ audit_collection_name=audit_collection_name
28
+ )
29
+
30
+ def _map_to_model(self, document: dict) -> T:
31
+ document["id"] = str(document.pop("_id"))
32
+ return self.model.model_validate(document)
33
+
34
+ def find_one(self, id: str) -> T:
35
+ query = {"_id": ObjectId(id), "is_deleted": False}
36
+ result = self.collection.find_one(query)
37
+ return self._map_to_model(result) if result else None
38
+
39
+ def insert_one(self, data: T) -> str:
40
+ delattr(data, "id")
41
+ result = self.collection.insert_one(data.model_dump())
42
+
43
+ # For Audit log
44
+ with suppress(Exception):
45
+ if isinstance(data, BaseAuditDocument):
46
+ document = AuditLog(
47
+ user_id=current_user_info.get().nameid,
48
+ collection_name=self.__collection_name,
49
+ document_id=str(result.inserted_id),
50
+ operation=AuditOperation.CREATE,
51
+ original=None,
52
+ modified=data.model_dump(),
53
+ )
54
+ self.audit_collection.insert_one(document)
55
+
56
+ return str(result.inserted_id)
57
+
58
+ def insert_many(self, data: List[T]) -> List[str]:
59
+ data_list = [delattr(d.model_dump(), "id") for d in data]
60
+ result = self.collection.insert_many(data_list)
61
+
62
+ # For Audit log
63
+ with suppress(Exception):
64
+ if len(result.inserted_ids) > 0:
65
+ if isinstance(data[0], BaseAuditDocument):
66
+ documents = []
67
+ for i, d in enumerate(data):
68
+ document = AuditLog(
69
+ user_id=current_user_info.get().nameid,
70
+ collection_name=self.__collection_name,
71
+ document_id=str(result.inserted_ids[i]),
72
+ operation=AuditOperation.CREATE,
73
+ original=None,
74
+ modified=d.model_dump(),
75
+ )
76
+ documents.append(document)
77
+
78
+ self.audit_collection.insert_many(documents)
79
+
80
+ return [str(id_) for id_ in result.inserted_ids]
81
+
82
+ def update_one(self, id: str, data: T) -> int:
83
+ delattr(data, "id")
84
+
85
+ query = {"_id": ObjectId(id)}
86
+ before_dict = self.collection.find_one_and_update(
87
+ query,
88
+ {"$set": data.model_dump()},
89
+ return_document=ReturnDocument.BEFORE
90
+ )
91
+
92
+ before_model = self.model(**before_dict)
93
+
94
+ # For Audit log
95
+ with suppress(Exception):
96
+ diff_data = generate_clean_diff(before_model, data)
97
+ old_data, new_data = diff_data["original"], diff_data["modified"]
98
+
99
+ if isinstance(data, BaseAuditDocument) and new_data:
100
+ document = AuditLog(
101
+ user_id=current_user_info.get().nameid,
102
+ collection_name=self.__collection_name,
103
+ document_id=id,
104
+ operation=AuditOperation.UPDATE,
105
+ original=old_data,
106
+ modified=new_data,
107
+ )
108
+
109
+ self.audit_collection.insert_one(document)
110
+
111
+ return 1
112
+
113
+ def delete_one(self, id: str) -> int:
114
+ query = {"_id": ObjectId(id)}
115
+ result = self.collection.delete_one(query)
116
+ return result.deleted_count
117
+
118
+ def get_all(self, page_number=1, page_size=10) -> List[T]:
119
+ skip_count = (page_number - 1) * page_size
120
+ query = {"is_deleted": False}
121
+ result = self.collection.find(query).skip(skip_count).limit(page_size)
122
+ return [self._map_to_model(doc) for doc in result]
@@ -0,0 +1,65 @@
1
+ from deepdiff import DeepDiff
2
+ from pydantic.v1 import BaseModel
3
+
4
+ EXCLUDE_FIELDS = {"created_on", "updated_on"}
5
+
6
+ def generate_clean_diff(before: BaseModel, after: BaseModel, exclude_fields: set = EXCLUDE_FIELDS):
7
+ before_dict = before.model_dump()
8
+ after_dict = after.model_dump()
9
+ try:
10
+ clean_before = {k: v for k, v in before_dict.items() if k not in exclude_fields}
11
+ clean_after = {k: v for k, v in after_dict.items() if k not in exclude_fields}
12
+
13
+ diff = DeepDiff(clean_before, clean_after, ignore_order=True)
14
+ original = {}
15
+ modified = {}
16
+
17
+ for change_type in ["values_changed", "type_changes"]:
18
+ changes = diff.get(change_type, {})
19
+ for path, change in changes.items():
20
+ keys = path.strip("root").strip("[").strip("]").replace("][", ".").replace("'", "").split(".")
21
+ _apply_nested_keys(original, keys, change["old_value"])
22
+ _apply_nested_keys(modified, keys, change["new_value"])
23
+
24
+ return {"original": original, "modified": modified}
25
+
26
+ except Exception as e:
27
+ return {"original": {}, "modified": {}, "error": str(e)}
28
+
29
+ def _apply_nested_keys(base: dict, keys: list, value):
30
+ current = base
31
+ for i, key in enumerate(keys):
32
+ is_last = i == len(keys) - 1
33
+ next_key = keys[i + 1] if not is_last else None
34
+
35
+ # Determine if current key is an index (for lists)
36
+ is_index = key.isdigit()
37
+ key = int(key) if is_index else key
38
+
39
+ # Ensure current is list if key is int
40
+ if is_index and not isinstance(current, list):
41
+ # Convert current to list if it isn't already
42
+ raise TypeError(f"Expected list at {keys[:i]}, got {type(current).__name__}")
43
+
44
+ # Handle last key
45
+ if is_last:
46
+ if isinstance(current, list):
47
+ # Ensure list is big enough
48
+ while len(current) <= key:
49
+ current.append(None)
50
+ current[key] = value
51
+ else:
52
+ current[key] = value
53
+ return
54
+
55
+ # Prepare next container (dict or list)
56
+ if isinstance(current, list):
57
+ while len(current) <= key:
58
+ current.append(None)
59
+ if current[key] is None:
60
+ current[key] = {} if (next_key and not next_key.isdigit()) else []
61
+ current = current[key]
62
+ else:
63
+ if key not in current:
64
+ current[key] = {} if (next_key and not next_key.isdigit()) else []
65
+ current = current[key]
@@ -2,10 +2,9 @@ import jwt
2
2
  import time
3
3
  from fastapi import Request
4
4
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
5
-
6
5
  from sharedkernel.exception.exception import UnAuthorizedException
7
6
  from sharedkernel.objects import JwtModel
8
-
7
+ from sharedkernel.objects.user_info import current_user_info, UserInfo
9
8
 
10
9
  class JWTBearer(HTTPBearer):
11
10
 
@@ -18,21 +17,28 @@ class JWTBearer(HTTPBearer):
18
17
  credentials: HTTPAuthorizationCredentials = await super(
19
18
  JWTBearer, self
20
19
  ).__call__(request)
21
-
22
20
  decoded_token = self.verify(credentials.credentials)
23
21
  request.state.decoded_token = decoded_token
24
22
 
23
+ nameid = decoded_token.get("nameid") or decoded_token.get("id")
24
+
25
+ user_info = UserInfo(
26
+ nameid=nameid, email=decoded_token.get("email"), unique_name=decoded_token.get("unique_name")
27
+ )
28
+
29
+ current_user_info.set(user_info)
30
+
25
31
  except:
26
32
  raise UnAuthorizedException()
27
33
 
28
34
 
29
35
  def verify(self, token: str) -> dict:
30
36
  decoded_token = jwt.decode(
31
- jwt= token.replace("Bearer","").strip(),
32
- key= self.jwt_config.secret_key,
33
- algorithms= self.jwt_config.algorithms,
34
- audience= self.jwt_config.audience,
35
- issuer= self.jwt_config.issuer
37
+ jwt= token.replace("Bearer","").strip(),
38
+ key= self.jwt_config.secret_key,
39
+ algorithms= self.jwt_config.algorithms,
40
+ audience= self.jwt_config.audience,
41
+ issuer= self.jwt_config.issuer
36
42
  )
37
43
 
38
44
  if decoded_token["exp"] < time.time():
@@ -0,0 +1,5 @@
1
+ from .base_document import BaseDocument, BaseAuditDocument
2
+ from .jwt_model import JwtModel
3
+ from .result import Result
4
+ from .json_string_model import JsonStringModel
5
+ from .user_info import UserInfo
@@ -6,4 +6,8 @@ class BaseDocument(BaseModel):
6
6
  id: str | None = None
7
7
  is_deleted: bool | None = False
8
8
  created_on: datetime = Field(default_factory=datetime.now)
9
- updated_on: datetime = Field(default_factory=datetime.now)
9
+ updated_on: datetime = Field(default_factory=datetime.now)
10
+
11
+
12
+ class BaseAuditDocument(BaseDocument):
13
+ pass
@@ -0,0 +1,13 @@
1
+ from pydantic import BaseModel
2
+
3
+ from contextvars import ContextVar
4
+
5
+ class UserInfo(BaseModel):
6
+ nameid: str
7
+ unique_name: str | None = None
8
+ email: str | None = None
9
+ role: str | None = None
10
+
11
+
12
+ current_user_info: ContextVar[UserInfo] = ContextVar("current_user_info")
13
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedkernel
3
- Version: 2.1.2
3
+ Version: 2.2.1
4
4
  Summary: sharekernel is a shared package between all python projects
5
5
  Author: Smilinno
6
6
  Description-Content-Type: text/markdown
@@ -18,6 +18,7 @@ Requires-Dist: python-docx
18
18
  Requires-Dist: mammoth
19
19
  Requires-Dist: markdown
20
20
  Requires-Dist: beautifulsoup4
21
+ Requires-Dist: deepdiff
21
22
  Dynamic: author
22
23
  Dynamic: description
23
24
  Dynamic: description-content-type
@@ -28,6 +29,10 @@ Dynamic: summary
28
29
  this is a shared kernel package
29
30
 
30
31
  # Change Log
32
+ ### Version 2.2.1
33
+ - fixbug requirements
34
+ ### Version 2.2.0
35
+ - implement Audit logging
31
36
  ### Version 2.1.2
32
37
  - Update pydantic parse_object with model_validate
33
38
  ### Version 2.1.0
@@ -3,6 +3,7 @@ setup.py
3
3
  sharedkernel/common.py
4
4
  sharedkernel/data_format_converter.py
5
5
  sharedkernel/date_converter.py
6
+ sharedkernel/diff_utils.py
6
7
  sharedkernel/jwt_service.py
7
8
  sharedkernel/regex_masking.py
8
9
  sharedkernel/s3_uploader.py
@@ -13,6 +14,8 @@ sharedkernel.egg-info/dependency_links.txt
13
14
  sharedkernel.egg-info/requires.txt
14
15
  sharedkernel.egg-info/top_level.txt
15
16
  sharedkernel/database/__init__.py
17
+ sharedkernel/database/audit_model.py
18
+ sharedkernel/database/mongo_generic_audit_repository.py
16
19
  sharedkernel/database/mongo_generic_repository.py
17
20
  sharedkernel/enum/__init__.py
18
21
  sharedkernel/enum/error_code.py
@@ -27,4 +30,5 @@ sharedkernel/objects/__init__.py
27
30
  sharedkernel/objects/base_document.py
28
31
  sharedkernel/objects/json_string_model.py
29
32
  sharedkernel/objects/jwt_model.py
30
- sharedkernel/objects/result.py
33
+ sharedkernel/objects/result.py
34
+ sharedkernel/objects/user_info.py
@@ -12,3 +12,4 @@ python-docx
12
12
  mammoth
13
13
  markdown
14
14
  beautifulsoup4
15
+ deepdiff
@@ -1 +0,0 @@
1
- # from .mongo_repository_base import MongoRepositoryBase
@@ -1,51 +0,0 @@
1
- from pymongo import MongoClient
2
- from bson import ObjectId
3
- from typing import Generic, TypeVar, List, Type
4
- from pydantic.v1 import BaseModel
5
- from sharedkernel.string_extentions import camel_to_snake
6
-
7
- T = TypeVar("T", bound=BaseModel)
8
-
9
-
10
- class MongoGenericRepository(Generic[T]):
11
- def __init__(self, database: MongoClient, model: Type[T]):
12
- self.database = database
13
- self.__collection_name = camel_to_snake(model.__name__)
14
- self.collection = self.database[self.__collection_name]
15
- self.model = model
16
-
17
- def _map_to_model(self, document: dict) -> T:
18
- document["id"] = str(document.pop("_id"))
19
- return self.model.model_validate(document)
20
-
21
- def find_one(self, id: str) -> T:
22
- query = {"_id": ObjectId(id), "is_deleted": False}
23
- result = self.collection.find_one(query)
24
- return self._map_to_model(result) if result else None
25
-
26
- def insert_one(self, data: T) -> str:
27
- delattr(data, "id")
28
- result = self.collection.insert_one(data.dict())
29
- return str(result.inserted_id)
30
-
31
- def insert_many(self, data: List[T]) -> List[str]:
32
- data_list = [delattr(d.dict(), "id") for d in data]
33
- result = self.collection.insert_many(data_list)
34
- return [str(id_) for id_ in result.inserted_ids]
35
-
36
- def update_one(self, id: str, data: T) -> int:
37
- delattr(data, "id")
38
- query = {"_id": ObjectId(id)}
39
- result = self.collection.update_one(query, {"$set": data.dict()})
40
- return result.modified_count
41
-
42
- def delete_one(self, id: str) -> int:
43
- query = {"_id": ObjectId(id)}
44
- result = self.collection.delete_one(query)
45
- return result.deleted_count
46
-
47
- def get_all(self, page_number=1, page_size=10) -> List[T]:
48
- skip_count = (page_number - 1) * page_size
49
- query = {"is_deleted": False}
50
- result = self.collection.find(query).skip(skip_count).limit(page_size)
51
- return [self._map_to_model(doc) for doc in result]
@@ -1,4 +0,0 @@
1
- from .base_document import BaseDocument
2
- from .jwt_model import JwtModel
3
- from .result import Result
4
- from .json_string_model import JsonStringModel
File without changes