panther 1.4.0__tar.gz → 1.5.0__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 (47) hide show
  1. {panther-1.4.0 → panther-1.5.0}/PKG-INFO +2 -2
  2. {panther-1.4.0 → panther-1.5.0}/README.md +1 -1
  3. {panther-1.4.0 → panther-1.5.0}/panther/__init__.py +1 -1
  4. {panther-1.4.0 → panther-1.5.0}/panther/db/connection.py +9 -6
  5. panther-1.5.0/panther/db/queries/mongodb_queries.py +85 -0
  6. {panther-1.4.0 → panther-1.5.0}/panther/db/queries/pantherdb_queries.py +6 -37
  7. {panther-1.4.0 → panther-1.5.0}/panther/db/queries/queries.py +33 -10
  8. {panther-1.4.0 → panther-1.5.0}/panther.egg-info/PKG-INFO +2 -2
  9. {panther-1.4.0 → panther-1.5.0}/panther.egg-info/requires.txt +2 -1
  10. {panther-1.4.0 → panther-1.5.0}/setup.py +2 -1
  11. panther-1.4.0/panther/db/queries/mongodb_queries.py +0 -90
  12. {panther-1.4.0 → panther-1.5.0}/LICENSE +0 -0
  13. {panther-1.4.0 → panther-1.5.0}/panther/_utils.py +0 -0
  14. {panther-1.4.0 → panther-1.5.0}/panther/app.py +0 -0
  15. {panther-1.4.0 → panther-1.5.0}/panther/authentications.py +0 -0
  16. {panther-1.4.0 → panther-1.5.0}/panther/caching.py +0 -0
  17. {panther-1.4.0 → panther-1.5.0}/panther/cli/__init__.py +0 -0
  18. {panther-1.4.0 → panther-1.5.0}/panther/cli/create_command.py +0 -0
  19. {panther-1.4.0 → panther-1.5.0}/panther/cli/main.py +0 -0
  20. {panther-1.4.0 → panther-1.5.0}/panther/cli/monitor_command.py +0 -0
  21. {panther-1.4.0 → panther-1.5.0}/panther/cli/run_command.py +0 -0
  22. {panther-1.4.0 → panther-1.5.0}/panther/cli/template.py +0 -0
  23. {panther-1.4.0 → panther-1.5.0}/panther/cli/utils.py +0 -0
  24. {panther-1.4.0 → panther-1.5.0}/panther/configs.py +0 -0
  25. {panther-1.4.0 → panther-1.5.0}/panther/db/__init__.py +0 -0
  26. {panther-1.4.0 → panther-1.5.0}/panther/db/models.py +0 -0
  27. {panther-1.4.0 → panther-1.5.0}/panther/db/queries/__init__.py +0 -0
  28. {panther-1.4.0 → panther-1.5.0}/panther/db/utils.py +0 -0
  29. {panther-1.4.0 → panther-1.5.0}/panther/exceptions.py +0 -0
  30. {panther-1.4.0 → panther-1.5.0}/panther/logger.py +0 -0
  31. {panther-1.4.0 → panther-1.5.0}/panther/main.py +3 -3
  32. {panther-1.4.0 → panther-1.5.0}/panther/middlewares/__init__.py +0 -0
  33. {panther-1.4.0 → panther-1.5.0}/panther/middlewares/base.py +0 -0
  34. {panther-1.4.0 → panther-1.5.0}/panther/middlewares/db.py +0 -0
  35. {panther-1.4.0 → panther-1.5.0}/panther/middlewares/monitoring.py +0 -0
  36. {panther-1.4.0 → panther-1.5.0}/panther/middlewares/redis.py +0 -0
  37. {panther-1.4.0 → panther-1.5.0}/panther/request.py +0 -0
  38. {panther-1.4.0 → panther-1.5.0}/panther/response.py +0 -0
  39. {panther-1.4.0 → panther-1.5.0}/panther/routings.py +0 -0
  40. {panther-1.4.0 → panther-1.5.0}/panther/status.py +0 -0
  41. {panther-1.4.0 → panther-1.5.0}/panther/utils.py +0 -0
  42. {panther-1.4.0 → panther-1.5.0}/panther.egg-info/SOURCES.txt +0 -0
  43. {panther-1.4.0 → panther-1.5.0}/panther.egg-info/dependency_links.txt +0 -0
  44. {panther-1.4.0 → panther-1.5.0}/panther.egg-info/entry_points.txt +0 -0
  45. {panther-1.4.0 → panther-1.5.0}/panther.egg-info/top_level.txt +0 -0
  46. {panther-1.4.0 → panther-1.5.0}/pyproject.toml +0 -0
  47. {panther-1.4.0 → panther-1.5.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panther
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: Fast & Friendly, Web Framework For Building Async APIs
5
5
  Home-page: https://github.com/alirn76/panther
6
6
  Author: Ali RajabNezhad
@@ -25,7 +25,7 @@ License-File: LICENSE
25
25
  ---
26
26
 
27
27
  ### Features
28
- - Document-oriented Databases ORM ([PantherDB](https://pypi.org/project/pantherdb/), MongoDB)
28
+ - Document-oriented Databases ODM ([PantherDB](https://pypi.org/project/pantherdb/), MongoDB)
29
29
  - Visual API Monitoring (In Terminal)
30
30
  - Cache APIs (In Memory, In Redis)
31
31
  - Built-in Authentication Classes (Customizable)
@@ -9,7 +9,7 @@
9
9
  ---
10
10
 
11
11
  ### Features
12
- - Document-oriented Databases ORM ([PantherDB](https://pypi.org/project/pantherdb/), MongoDB)
12
+ - Document-oriented Databases ODM ([PantherDB](https://pypi.org/project/pantherdb/), MongoDB)
13
13
  - Visual API Monitoring (In Terminal)
14
14
  - Cache APIs (In Memory, In Redis)
15
15
  - Built-in Authentication Classes (Customizable)
@@ -1,6 +1,6 @@
1
1
  from .main import Panther
2
2
 
3
- __version__ = '1.4.0'
3
+ __version__ = '1.5.0'
4
4
 
5
5
 
6
6
  def version():
@@ -1,6 +1,7 @@
1
1
  from redis import Redis
2
2
  from pantherdb import PantherDB
3
3
  from panther.configs import config
4
+ from panther.cli.utils import error
4
5
 
5
6
 
6
7
  class Singleton(object):
@@ -19,9 +20,8 @@ class DBSession(Singleton):
19
20
  if db_url:
20
21
  self._db_name = db_url[:db_url.find(':')]
21
22
  match self._db_name:
22
- # case 'mongodb':
23
- # # TODO: Check pymongo installed or not
24
- # self._create_mongodb_session(db_url)
23
+ case 'mongodb':
24
+ self._create_mongodb_session(db_url)
25
25
  case 'pantherdb':
26
26
  self._create_pantherdb_session(db_url[12:])
27
27
  case _:
@@ -37,8 +37,12 @@ class DBSession(Singleton):
37
37
  return self._db_name
38
38
 
39
39
  def _create_mongodb_session(self, db_url: str) -> None:
40
- from pymongo import MongoClient
41
- from pymongo.database import Database
40
+ try:
41
+ from pymongo import MongoClient
42
+ from pymongo.database import Database
43
+ except ImportError:
44
+ error('No module named "pymongo"\n\nHint: Try to install with "pip install pymongo"')
45
+ raise ImportError(error)
42
46
  self._client: MongoClient = MongoClient(db_url)
43
47
  self._session: Database = self._client.get_database()
44
48
 
@@ -56,7 +60,6 @@ class RedisConnection(Singleton, Redis):
56
60
  is_connected: bool = False
57
61
 
58
62
  def __init__(self, host: str | None = None, port: int | None = None, **kwargs):
59
- # TODO: Check redis installed or not
60
63
  if host and port:
61
64
  super().__init__(host=host, port=port, **kwargs)
62
65
  self.is_connected = True
@@ -0,0 +1,85 @@
1
+ from typing import Self
2
+
3
+ from panther.db.connection import db # NOQA: F401
4
+ from panther.exceptions import DBException
5
+ from panther.db.utils import clean_object_id_in_dicts, merge_dicts
6
+
7
+
8
+ class BaseMongoDBQuery:
9
+
10
+ @classmethod
11
+ def _merge(cls, *args) -> dict:
12
+ clean_object_id_in_dicts(*args)
13
+ # TODO: Convert "id" to "_id"
14
+ return merge_dicts(*args)
15
+
16
+ # # # # # Find # # # # #
17
+ @classmethod
18
+ def find_one(cls, _data: dict = None, /, **kwargs) -> Self | None:
19
+ _query = cls._merge(_data, kwargs)
20
+ if document := eval(f'db.session.{cls.__name__}.find_one(_query)'):
21
+ return cls(**document)
22
+
23
+ @classmethod
24
+ def find(cls, _data: dict = None, /, **kwargs) -> list[Self]:
25
+ _query = cls._merge(_data, kwargs)
26
+ documents = eval(f'db.session.{cls.__name__}.find(_query)')
27
+ return [cls(**document) for document in documents]
28
+
29
+ # # # # # Insert # # # # #
30
+ @classmethod
31
+ def insert_one(cls, _data: dict = None, **kwargs) -> Self:
32
+ document = cls._merge(_data, kwargs)
33
+ document['id'] = eval(f'db.session.{cls.__name__}.insert_one(document)').inserted_id
34
+ return cls(**document)
35
+
36
+ @classmethod
37
+ def insert_many(cls, _data: dict = None, **kwargs) -> Self:
38
+ raise DBException('insert_many() is not supported while using MongoDB.')
39
+
40
+ # # # # # Delete # # # # #
41
+ def delete(self) -> None:
42
+ _filter = {'_id': self._id}
43
+ eval(f'db.session.{self.__class__.__name__}.delete_one(_filter)')
44
+
45
+ @classmethod
46
+ def delete_one(cls, _data: dict = None, /, **kwargs) -> bool:
47
+ _query = cls._merge(_data, kwargs)
48
+ result = eval(f'db.session.{cls.__name__}.delete_one(_query)')
49
+ return bool(result.deleted_count)
50
+
51
+ @classmethod
52
+ def delete_many(cls, _data: dict = None, /, **kwargs) -> int:
53
+ _query = cls._merge(_data, kwargs)
54
+ result = eval(f'db.session.{cls.__name__}.delete_many(_query)')
55
+ return result.deleted_count
56
+
57
+ # # # # # Update # # # # #
58
+ def update(self, **kwargs) -> None:
59
+ for field, value in kwargs.items():
60
+ setattr(self, field, value)
61
+ _filter = {'_id': self._id}
62
+ _update = {'$set': kwargs}
63
+ eval(f'db.session.{self.__class__.__name__}.update_one(_filter, _update)')
64
+
65
+ @classmethod
66
+ def update_one(cls, _filter, _data: dict = None, /, **kwargs) -> bool:
67
+ clean_object_id_in_dicts(_filter)
68
+ _update = {'$set': kwargs | {}}
69
+ if isinstance(_data, dict):
70
+ _data['$set'] = _data.get('$set', {}) | (kwargs or {})
71
+
72
+ result = eval(f'db.session.{cls.__name__}.update_one(_filter, _data | _update)')
73
+ return bool(result.updated_count)
74
+
75
+ @classmethod
76
+ def update_many(cls, _filter, _data: dict = None, /, **kwargs) -> int:
77
+ _update = {'$set': cls._merge(_data, kwargs)}
78
+ result = eval(f'db.session.{cls.__name__}.update_many(_filter, _update)')
79
+ return result.updated_count
80
+
81
+ # # # # # Other # # # # #
82
+ @classmethod
83
+ def count(cls, _data: dict = None, /, **kwargs) -> int:
84
+ _query = cls._merge(_data, kwargs)
85
+ return eval(f'db.session.{cls.__name__}.count_documents(_query)')
@@ -1,5 +1,4 @@
1
1
  from typing import Self
2
- from pydantic import ValidationError
3
2
 
4
3
  from panther.db.connection import db
5
4
  from panther.db.utils import merge_dicts
@@ -8,26 +7,6 @@ from panther.exceptions import DBException
8
7
 
9
8
  class BasePantherDBQuery:
10
9
 
11
- @classmethod
12
- def validate_data(cls, data: dict, is_updating: bool = False) -> Self | None:
13
- """
14
- *. Validate the input of user with its class
15
- *. If is_updating is True & exception happens but the message was empty
16
- Then return nothing (we don't need the obj on update())
17
- & we don't have access to the obj after exception ...
18
- """
19
- try:
20
- obj = cls(**data)
21
- except ValidationError as validation_error:
22
- error = ', '.join(
23
- '{field}="{error}"'.format(field=e['loc'][0], error=e['msg'])
24
- for e in validation_error.errors() if not is_updating or e['type'] != 'value_error.missing')
25
- if error:
26
- message = f'{cls.__name__}({error})'
27
- raise DBException(message)
28
- else:
29
- return obj
30
-
31
10
  @classmethod
32
11
  def _merge(cls, *args) -> dict:
33
12
  # TODO: Convert "id" to "_id"
@@ -36,7 +15,7 @@ class BasePantherDBQuery:
36
15
  # # # # # Find # # # # #
37
16
  @classmethod
38
17
  def find_one(cls, _data: dict = None, /, **kwargs) -> Self | None:
39
- if document := db.session.collection(cls.__name__).first(**cls._merge(_data, kwargs)):
18
+ if document := db.session.collection(cls.__name__).find_one(**cls._merge(_data, kwargs)):
40
19
  return cls(**document)
41
20
 
42
21
  @classmethod
@@ -47,13 +26,12 @@ class BasePantherDBQuery:
47
26
  # # # # # Insert # # # # #
48
27
  @classmethod
49
28
  def insert_one(cls, _data: dict = None, **kwargs) -> Self:
50
- obj = cls.validate_data(kwargs)
51
- obj.id = db.session.collection(cls.__name__).insert_one(**cls._merge(_data, kwargs))['_id']
52
- return obj
29
+ document = db.session.collection(cls.__name__).insert_one(**cls._merge(_data, kwargs))
30
+ return cls(**document)
53
31
 
54
32
  @classmethod
55
33
  def insert_many(cls, _data: dict = None, /, **kwargs):
56
- raise DBException('increment() is not supported while using SlarkDB.')
34
+ raise DBException('insert_many() is not supported while using PantherDB.')
57
35
 
58
36
  # # # # # Delete # # # # #
59
37
  def delete(self) -> None:
@@ -69,7 +47,8 @@ class BasePantherDBQuery:
69
47
 
70
48
  # # # # # Update # # # # #
71
49
  def update(self, **kwargs) -> None:
72
- self.validate_data(kwargs, is_updating=True)
50
+ for field, value in kwargs.items():
51
+ setattr(self, field, value)
73
52
  db.session.collection(self.__class__.__name__).update_one({'_id': self.id}, **kwargs)
74
53
 
75
54
  @classmethod
@@ -81,16 +60,6 @@ class BasePantherDBQuery:
81
60
  return db.session.collection(cls.__name__).update_many(_filter, **cls._merge(_data, kwargs))
82
61
 
83
62
  # # # # # Other # # # # #
84
- @classmethod
85
- def first(cls, _data: dict = None, /, **kwargs) -> Self | None:
86
- if document := db.session.collection(cls.__name__).first(**cls._merge(_data, kwargs)):
87
- return cls(**document)
88
-
89
- @classmethod
90
- def last(cls, _data: dict = None, /, **kwargs) -> Self | None:
91
- if document := db.session.collection(cls.__name__).last(**cls._merge(_data, kwargs)):
92
- return cls(**document)
93
-
94
63
  @classmethod
95
64
  def count(cls, _data: dict = None, /, **kwargs) -> int:
96
65
  return db.session.collection(cls.__name__).count(**cls._merge(_data, kwargs))
@@ -1,9 +1,12 @@
1
1
  from typing import Self
2
2
 
3
+ from pydantic import ValidationError
4
+
3
5
  from panther.configs import config
4
6
  from panther.db.utils import log_query
5
7
  from panther.db.queries.mongodb_queries import BaseMongoDBQuery
6
8
  from panther.db.queries.pantherdb_queries import BasePantherDBQuery
9
+ from panther.exceptions import DBException
7
10
 
8
11
  if config['db_engine'] == 'pantherdb':
9
12
  BaseQuery = BasePantherDBQuery
@@ -17,6 +20,22 @@ __all__ = (
17
20
 
18
21
  class Query(BaseQuery):
19
22
 
23
+ @classmethod
24
+ def validate_data(cls, data: dict, is_updating: bool = False) -> Self | None:
25
+ """
26
+ *. Validate the input of user with its class
27
+ *. If is_updating is True & exception happens but the message was empty
28
+ """
29
+ try:
30
+ cls(**data)
31
+ except ValidationError as validation_error:
32
+ error = ', '.join(
33
+ '{field}="{error}"'.format(field=e['loc'][0], error=e['msg'])
34
+ for e in validation_error.errors() if not is_updating or e['type'] != 'value_error.missing')
35
+ if error:
36
+ message = f'{cls.__name__}({error})'
37
+ raise DBException(message)
38
+
20
39
  # # # # # Find # # # # #
21
40
  @classmethod
22
41
  @log_query
@@ -47,6 +66,7 @@ class Query(BaseQuery):
47
66
  >>> from example.app.models import User
48
67
  >>> User.insert_one(name='Ali', age=24, ...)
49
68
  """
69
+ cls.validate_data(kwargs)
50
70
  return super().insert_one(_data, **kwargs)
51
71
 
52
72
  @classmethod
@@ -94,6 +114,7 @@ class Query(BaseQuery):
94
114
  >>> user = User.find_one(name='Ali')
95
115
  >>> user.update(name='Saba')
96
116
  """
117
+ self.validate_data(kwargs, is_updating=True)
97
118
  return super().update(**kwargs)
98
119
 
99
120
  @classmethod
@@ -120,31 +141,33 @@ class Query(BaseQuery):
120
141
  # # # # # Other # # # # #
121
142
  @classmethod
122
143
  @log_query
123
- def first(cls, _data: dict = None, /, **kwargs) -> Self | None:
144
+ def last(cls, _data: dict = None, /, **kwargs) -> Self | None:
124
145
  """
125
- It works same as find_one()
126
146
  example:
127
147
  >>> from example.app.models import User
128
- >>> User.first(name='Ali')
148
+ >>> user = User.last(name='Ali')
129
149
  """
130
- return super().first(_data, **kwargs)
150
+ return super().last(_data, **kwargs)
131
151
 
132
152
  @classmethod
133
153
  @log_query
134
- def last(cls, _data: dict = None, /, **kwargs) -> Self | None:
154
+ def count(cls, _data: dict = None, /, **kwargs) -> int:
135
155
  """
136
156
  example:
137
157
  >>> from example.app.models import User
138
- >>> User.last(name='Ali')
158
+ >>> User.count(name='Ali')
139
159
  """
140
- return super().last(_data, **kwargs)
160
+ return super().count(_data, **kwargs)
141
161
 
142
162
  @classmethod
143
163
  @log_query
144
- def count(cls, _data: dict = None, /, **kwargs) -> int:
164
+ def find_or_insert(cls, **kwargs) -> tuple[bool, any]:
145
165
  """
146
166
  example:
147
167
  >>> from example.app.models import User
148
- >>> User.count(name='Ali')
168
+ >>> user = User.find_or_insert(name='Ali')
149
169
  """
150
- return super().count(_data, **kwargs)
170
+ if obj := cls.find_one(**kwargs):
171
+ return False, obj
172
+ else:
173
+ return True, cls.insert_one(**kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panther
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: Fast & Friendly, Web Framework For Building Async APIs
5
5
  Home-page: https://github.com/alirn76/panther
6
6
  Author: Ali RajabNezhad
@@ -25,7 +25,7 @@ License-File: LICENSE
25
25
  ---
26
26
 
27
27
  ### Features
28
- - Document-oriented Databases ORM ([PantherDB](https://pypi.org/project/pantherdb/), MongoDB)
28
+ - Document-oriented Databases ODM ([PantherDB](https://pypi.org/project/pantherdb/), MongoDB)
29
29
  - Visual API Monitoring (In Terminal)
30
30
  - Cache APIs (In Memory, In Redis)
31
31
  - Built-in Authentication Classes (Customizable)
@@ -1,6 +1,7 @@
1
1
  pantherdb>=1.2.0
2
2
  pydantic>=1.10.5
3
- uvicorn==0.20.0
3
+ watchfiles>=0.18.1
4
+ uvicorn[standard]
4
5
  bpython>=0.24
5
6
  bson>=0.5.10
6
7
  redis>=4.0.2
@@ -45,7 +45,8 @@ setup(
45
45
  install_requires=[
46
46
  'pantherdb>=1.2.0',
47
47
  'pydantic>=1.10.5',
48
- 'uvicorn==0.20.0',
48
+ 'watchfiles>=0.18.1',
49
+ 'uvicorn[standard]',
49
50
  'bpython>=0.24',
50
51
  'bson>=0.5.10',
51
52
  'redis>=4.0.2',
@@ -1,90 +0,0 @@
1
- from typing import TypeVar
2
-
3
- import bson
4
-
5
- from panther.db.connection import db # NOQA: F401
6
- from panther.db.utils import clean_object_id_in_dicts, merge_dicts, log_query
7
-
8
- # TODO: Not sure about this bounding
9
- T = TypeVar('T', bound='BaseMongoDBQuery')
10
-
11
-
12
- class BaseMongoDBQuery:
13
-
14
- @classmethod
15
- def get_one(cls: type[T], _data: dict = None, /, **kwargs) -> T:
16
- clean_object_id_in_dicts(_data, kwargs)
17
- _query = merge_dicts(_data, kwargs)
18
- obj = eval(f'db.session.{cls.__name__}.find_one(_query)')
19
- return cls(**obj) if obj else None
20
-
21
- @classmethod
22
- def count(cls, _data: dict = None, /, **kwargs) -> int:
23
- clean_object_id_in_dicts(_data, kwargs)
24
- _query = merge_dicts(_data, kwargs)
25
- return eval(f'db.session.{cls.__name__}.count_documents(_query)')
26
-
27
- @classmethod
28
- def list(cls, _data: dict = None, /, **kwargs):
29
- clean_object_id_in_dicts(_data, kwargs)
30
- _query = merge_dicts(_data, kwargs)
31
- result = eval(f'db.session.{cls.__name__}.find(_query)')
32
- return [cls(**obj) for obj in result]
33
-
34
- @classmethod
35
- def create(cls, _data: dict = None, **kwargs) -> bson.objectid.ObjectId:
36
- _query = merge_dicts(_data, kwargs)
37
- return eval(f'db.session.{cls.__name__}.insert_one(_query)').inserted_id
38
-
39
- def delete(self) -> bool:
40
- _filter = {'_id': self._id}
41
- result = eval(f'db.session.{self.__class__.__name__}.delete_one(_filter)')
42
- return bool(result.deleted_count)
43
-
44
- @classmethod
45
- def delete_one(cls, **kwargs) -> bool:
46
- clean_object_id_in_dicts(kwargs)
47
- result = eval(f'db.session.{cls.__name__}.delete_one(kwargs)')
48
- return bool(result.deleted_count)
49
-
50
- @classmethod
51
- def delete_many(cls, **kwargs) -> int:
52
- clean_object_id_in_dicts(kwargs)
53
- result = eval(f'db.session.{cls.__name__}.delete_many(kwargs)')
54
- return result.deleted_count
55
-
56
- def update(self, _data: dict = None, **kwargs) -> dict:
57
- for field, value in (_data or kwargs).items():
58
- if hasattr(self, field):
59
- setattr(self, field, value)
60
- _filter = {'_id': self._id}
61
- _update = {'$set': kwargs}
62
- return eval(f'db.session.{self.__class__.__name__}.update_one(_filter, _update)')
63
-
64
- @classmethod
65
- def update_one(cls, _filter, _data: dict = None, /, **kwargs) -> dict:
66
- clean_object_id_in_dicts(_filter)
67
-
68
- _update = {'$set': kwargs | {}}
69
- if isinstance(_data, dict):
70
- _data['$set'] = _data.get('$set', {}) | (kwargs or {})
71
-
72
- return eval(f'db.session.{cls.__name__}.update_one(_filter, _data | _update)')
73
-
74
- @classmethod
75
- def update_many(cls, _filter, **kwargs) -> dict:
76
- _update = {'$set': kwargs}
77
- return eval(f'db.session.{cls.__name__}.update_many(_filter, _update)')
78
-
79
- @classmethod
80
- def increment(cls, _filter, **kwargs):
81
- _update = {'$inc': kwargs}
82
- return eval(f'db.session.{cls.__name__}.update_many({_filter}, {_update})')
83
-
84
- @classmethod
85
- def get_or_create(cls, **kwargs) -> tuple[bool, any]:
86
- obj = cls.get_one(**kwargs)
87
- if obj:
88
- return False, obj
89
- else:
90
- return True, cls.create(**kwargs)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -4,12 +4,12 @@ from runpy import run_path
4
4
  from pydantic.main import ModelMetaclass
5
5
 
6
6
  from panther import status
7
- from panther.configs import JWTConfig, config
7
+ from panther.request import Request
8
+ from panther.response import Response
8
9
  from panther.exceptions import APIException
10
+ from panther.configs import JWTConfig, config
9
11
  from panther.middlewares.base import BaseMiddleware
10
12
  from panther.middlewares.monitoring import Middleware as MonitoringMiddleware
11
- from panther.request import Request
12
- from panther.response import Response
13
13
  from panther.routings import find_endpoint, check_urls, collect_urls, finalize_urls
14
14
  from panther._utils import http_response, import_class, read_body, collect_path_variables
15
15
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes