panther 4.2.3__tar.gz → 4.2.5__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 (81) hide show
  1. {panther-4.2.3 → panther-4.2.5}/PKG-INFO +1 -1
  2. {panther-4.2.3 → panther-4.2.5}/panther/__init__.py +1 -1
  3. {panther-4.2.3 → panther-4.2.5}/panther/cli/utils.py +1 -1
  4. {panther-4.2.3 → panther-4.2.5}/panther/db/connections.py +1 -1
  5. {panther-4.2.3 → panther-4.2.5}/panther/db/queries/mongodb_queries.py +2 -0
  6. {panther-4.2.3 → panther-4.2.5}/panther/db/queries/pantherdb_queries.py +2 -0
  7. {panther-4.2.3 → panther-4.2.5}/panther/db/queries/queries.py +27 -1
  8. {panther-4.2.3 → panther-4.2.5}/panther/logging.py +0 -5
  9. {panther-4.2.3 → panther-4.2.5}/panther/utils.py +14 -0
  10. {panther-4.2.3 → panther-4.2.5}/panther/websocket.py +6 -0
  11. {panther-4.2.3 → panther-4.2.5}/panther.egg-info/PKG-INFO +1 -1
  12. {panther-4.2.3 → panther-4.2.5}/LICENSE +0 -0
  13. {panther-4.2.3 → panther-4.2.5}/README.md +0 -0
  14. {panther-4.2.3 → panther-4.2.5}/panther/_load_configs.py +0 -0
  15. {panther-4.2.3 → panther-4.2.5}/panther/_utils.py +0 -0
  16. {panther-4.2.3 → panther-4.2.5}/panther/app.py +0 -0
  17. {panther-4.2.3 → panther-4.2.5}/panther/authentications.py +0 -0
  18. {panther-4.2.3 → panther-4.2.5}/panther/background_tasks.py +0 -0
  19. {panther-4.2.3 → panther-4.2.5}/panther/base_request.py +0 -0
  20. {panther-4.2.3 → panther-4.2.5}/panther/base_websocket.py +0 -0
  21. {panther-4.2.3 → panther-4.2.5}/panther/caching.py +0 -0
  22. {panther-4.2.3 → panther-4.2.5}/panther/cli/__init__.py +0 -0
  23. {panther-4.2.3 → panther-4.2.5}/panther/cli/create_command.py +0 -0
  24. {panther-4.2.3 → panther-4.2.5}/panther/cli/main.py +0 -0
  25. {panther-4.2.3 → panther-4.2.5}/panther/cli/monitor_command.py +0 -0
  26. {panther-4.2.3 → panther-4.2.5}/panther/cli/run_command.py +0 -0
  27. {panther-4.2.3 → panther-4.2.5}/panther/cli/template.py +0 -0
  28. {panther-4.2.3 → panther-4.2.5}/panther/configs.py +0 -0
  29. {panther-4.2.3 → panther-4.2.5}/panther/db/__init__.py +0 -0
  30. {panther-4.2.3 → panther-4.2.5}/panther/db/cursor.py +0 -0
  31. {panther-4.2.3 → panther-4.2.5}/panther/db/models.py +0 -0
  32. {panther-4.2.3 → panther-4.2.5}/panther/db/queries/__init__.py +0 -0
  33. {panther-4.2.3 → panther-4.2.5}/panther/db/queries/base_queries.py +0 -0
  34. {panther-4.2.3 → panther-4.2.5}/panther/db/utils.py +0 -0
  35. {panther-4.2.3 → panther-4.2.5}/panther/events.py +0 -0
  36. {panther-4.2.3 → panther-4.2.5}/panther/exceptions.py +0 -0
  37. {panther-4.2.3 → panther-4.2.5}/panther/file_handler.py +0 -0
  38. {panther-4.2.3 → panther-4.2.5}/panther/generics.py +0 -0
  39. {panther-4.2.3 → panther-4.2.5}/panther/main.py +0 -0
  40. {panther-4.2.3 → panther-4.2.5}/panther/middlewares/__init__.py +0 -0
  41. {panther-4.2.3 → panther-4.2.5}/panther/middlewares/base.py +0 -0
  42. {panther-4.2.3 → panther-4.2.5}/panther/monitoring.py +0 -0
  43. {panther-4.2.3 → panther-4.2.5}/panther/pagination.py +0 -0
  44. {panther-4.2.3 → panther-4.2.5}/panther/panel/__init__.py +0 -0
  45. {panther-4.2.3 → panther-4.2.5}/panther/panel/apis.py +0 -0
  46. {panther-4.2.3 → panther-4.2.5}/panther/panel/urls.py +0 -0
  47. {panther-4.2.3 → panther-4.2.5}/panther/panel/utils.py +0 -0
  48. {panther-4.2.3 → panther-4.2.5}/panther/permissions.py +0 -0
  49. {panther-4.2.3 → panther-4.2.5}/panther/request.py +0 -0
  50. {panther-4.2.3 → panther-4.2.5}/panther/response.py +0 -0
  51. {panther-4.2.3 → panther-4.2.5}/panther/routings.py +0 -0
  52. {panther-4.2.3 → panther-4.2.5}/panther/serializer.py +0 -0
  53. {panther-4.2.3 → panther-4.2.5}/panther/status.py +0 -0
  54. {panther-4.2.3 → panther-4.2.5}/panther/test.py +0 -0
  55. {panther-4.2.3 → panther-4.2.5}/panther/throttling.py +0 -0
  56. {panther-4.2.3 → panther-4.2.5}/panther.egg-info/SOURCES.txt +0 -0
  57. {panther-4.2.3 → panther-4.2.5}/panther.egg-info/dependency_links.txt +0 -0
  58. {panther-4.2.3 → panther-4.2.5}/panther.egg-info/entry_points.txt +0 -0
  59. {panther-4.2.3 → panther-4.2.5}/panther.egg-info/requires.txt +0 -0
  60. {panther-4.2.3 → panther-4.2.5}/panther.egg-info/top_level.txt +0 -0
  61. {panther-4.2.3 → panther-4.2.5}/pyproject.toml +0 -0
  62. {panther-4.2.3 → panther-4.2.5}/setup.cfg +0 -0
  63. {panther-4.2.3 → panther-4.2.5}/setup.py +0 -0
  64. {panther-4.2.3 → panther-4.2.5}/tests/test_authentication.py +0 -0
  65. {panther-4.2.3 → panther-4.2.5}/tests/test_background_tasks.py +0 -0
  66. {panther-4.2.3 → panther-4.2.5}/tests/test_caching.py +0 -0
  67. {panther-4.2.3 → panther-4.2.5}/tests/test_cli.py +0 -0
  68. {panther-4.2.3 → panther-4.2.5}/tests/test_database.py +0 -0
  69. {panther-4.2.3 → panther-4.2.5}/tests/test_events.py +0 -0
  70. {panther-4.2.3 → panther-4.2.5}/tests/test_generics.py +0 -0
  71. {panther-4.2.3 → panther-4.2.5}/tests/test_multipart.py +0 -0
  72. {panther-4.2.3 → panther-4.2.5}/tests/test_panel_apis.py +0 -0
  73. {panther-4.2.3 → panther-4.2.5}/tests/test_request.py +0 -0
  74. {panther-4.2.3 → panther-4.2.5}/tests/test_response.py +0 -0
  75. {panther-4.2.3 → panther-4.2.5}/tests/test_routing.py +0 -0
  76. {panther-4.2.3 → panther-4.2.5}/tests/test_run.py +0 -0
  77. {panther-4.2.3 → panther-4.2.5}/tests/test_serializer.py +0 -0
  78. {panther-4.2.3 → panther-4.2.5}/tests/test_status.py +0 -0
  79. {panther-4.2.3 → panther-4.2.5}/tests/test_throttling.py +0 -0
  80. {panther-4.2.3 → panther-4.2.5}/tests/test_utils.py +0 -0
  81. {panther-4.2.3 → panther-4.2.5}/tests/test_websockets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panther
3
- Version: 4.2.3
3
+ Version: 4.2.5
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
@@ -1,6 +1,6 @@
1
1
  from panther.main import Panther # noqa: F401
2
2
 
3
- __version__ = '4.2.3'
3
+ __version__ = '4.2.5'
4
4
 
5
5
 
6
6
  def version():
@@ -142,7 +142,7 @@ def print_info(config: Config):
142
142
  if config.HAS_WS:
143
143
  try:
144
144
  import gunicorn
145
- gunicorn_msg = f'{h} * You have WS so make sure to run gunicorn with --preload{h}\n'
145
+ gunicorn_msg = f'{h} * You have WS, so make sure to run gunicorn with --preload{h}\n'
146
146
  except ImportError:
147
147
  pass
148
148
 
@@ -75,7 +75,7 @@ class MongoDBConnection(BaseDatabaseConnection):
75
75
 
76
76
  class PantherDBConnection(BaseDatabaseConnection):
77
77
  def init(self, path: str | None = None, encryption: bool = False):
78
- params = {'db_name': str(path), 'return_dict': True, 'return_cursor': True}
78
+ params = {'db_name': path, 'return_dict': True, 'return_cursor': True}
79
79
  if encryption:
80
80
  try:
81
81
  import cryptography
@@ -114,6 +114,8 @@ class BaseMongoDBQuery(BaseQuery):
114
114
  else:
115
115
  update_query['$set'] = update_query.get('$set', {})
116
116
  update_query['$set'][field] = value
117
+ if isinstance(value, dict):
118
+ value = type(getattr(self, field))(**value)
117
119
  setattr(self, field, value)
118
120
 
119
121
  await db.session[self.__class__.__name__].update_one({'_id': self._id}, update_query)
@@ -96,6 +96,8 @@ class BasePantherDBQuery(BaseQuery):
96
96
  self._validate_data(data=kwargs, is_updating=True)
97
97
 
98
98
  for field, value in document.items():
99
+ if isinstance(value, dict):
100
+ value = type(getattr(self, field))(**value)
99
101
  setattr(self, field, value)
100
102
  db.session.collection(self.__class__.__name__).update_one({'_id': self._id}, **document)
101
103
 
@@ -2,6 +2,7 @@ import sys
2
2
  from typing import Sequence, Iterable
3
3
 
4
4
  from pantherdb import Cursor as PantherDBCursor
5
+ from pydantic import BaseModel
5
6
 
6
7
  from panther.configs import QueryObservable
7
8
  from panther.db.cursor import Cursor
@@ -364,6 +365,26 @@ class Query(BaseQuery):
364
365
 
365
366
  raise NotFoundAPIError(detail=f'{cls.__name__} Does Not Exist')
366
367
 
368
+ @classmethod
369
+ async def exists(cls, _filter: dict | None = None, /, **kwargs) -> bool:
370
+ """
371
+ Check if document exists in collection or not
372
+
373
+ Example:
374
+ -------
375
+ >>> from app.models import User
376
+
377
+ >>> await User.exists(age=18, name='Ali')
378
+ or
379
+ >>> await User.exists({'age': 18, 'name': 'Ali'})
380
+ or
381
+ >>> await User.exists({'age': 18}, name='Ali')
382
+ """
383
+ if await cls.count(_filter, **kwargs) > 0:
384
+ return True
385
+ else:
386
+ return False
387
+
367
388
  async def save(self) -> None:
368
389
  """
369
390
  Save the document
@@ -382,7 +403,12 @@ class Query(BaseQuery):
382
403
  >>> user = User(name='Ali')
383
404
  >>> await user.save()
384
405
  """
385
- document = {field: getattr(self, field) for field in self.model_fields_set if field != 'request'}
406
+ document = {
407
+ field: getattr(self, field).model_dump()
408
+ if issubclass(type(getattr(self, field)), BaseModel)
409
+ else getattr(self, field)
410
+ for field in self.model_fields_set if field != 'request'
411
+ }
386
412
 
387
413
  if self.id:
388
414
  await self.update(document)
@@ -64,10 +64,5 @@ LOGGING = {
64
64
  'handlers': ['default', 'query_file'],
65
65
  'level': 'DEBUG',
66
66
  },
67
- 'uvicorn.error': {
68
- 'handlers': ['default'],
69
- 'level': 'INFO',
70
- 'propagate': False,
71
- },
72
67
  }
73
68
  }
@@ -50,6 +50,20 @@ def generate_secret_key() -> str:
50
50
 
51
51
 
52
52
  def round_datetime(dt: datetime, delta: timedelta):
53
+ """
54
+ Example:
55
+ >>> round_datetime(datetime(2024, 7, 15, 13, 22, 11, 562159), timedelta(days=2))
56
+ datetime.datetime(2024, 7, 16, 0, 0)
57
+
58
+ >>> round_datetime(datetime(2024, 7, 16, 13, 22, 11, 562159), timedelta(days=2))
59
+ datetime.datetime(2024, 7, 16, 0, 0)
60
+
61
+ >>> round_datetime(datetime(2024, 7, 17, 13, 22, 11, 562159), timedelta(days=2))
62
+ datetime.datetime(2024, 7, 18, 0, 0)
63
+
64
+ >>> round_datetime(datetime(2024, 7, 18, 13, 22, 11, 562159), timedelta(days=2))
65
+ datetime.datetime(2024, 7, 18, 0, 0)
66
+ """
53
67
  return datetime.min + round((dt - datetime.min) / delta) * delta
54
68
 
55
69
 
@@ -27,6 +27,12 @@ class GenericWebsocket(Websocket):
27
27
  """
28
28
  return await super().send(data=data)
29
29
 
30
+ async def close(self, code: int = status.WS_1000_NORMAL_CLOSURE, reason: str = ''):
31
+ """
32
+ Called whenever server or client, wants to close the connection
33
+ """
34
+ return await super().close(code=code, reason=reason)
35
+
30
36
 
31
37
  async def send_message_to_websocket(connection_id: str, data: any):
32
38
  await config.WEBSOCKET_CONNECTIONS.publish(connection_id=connection_id, action='send', data=data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panther
3
- Version: 4.2.3
3
+ Version: 4.2.5
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
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes