panther 4.3.0__py3-none-any.whl → 4.3.2__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.
- panther/__init__.py +1 -1
- panther/_load_configs.py +12 -1
- panther/_utils.py +9 -9
- panther/db/queries/base_queries.py +1 -1
- panther/main.py +8 -11
- panther/serializer.py +1 -1
- {panther-4.3.0.dist-info → panther-4.3.2.dist-info}/METADATA +5 -4
- {panther-4.3.0.dist-info → panther-4.3.2.dist-info}/RECORD +12 -12
- {panther-4.3.0.dist-info → panther-4.3.2.dist-info}/WHEEL +1 -1
- {panther-4.3.0.dist-info → panther-4.3.2.dist-info}/LICENSE +0 -0
- {panther-4.3.0.dist-info → panther-4.3.2.dist-info}/entry_points.txt +0 -0
- {panther-4.3.0.dist-info → panther-4.3.2.dist-info}/top_level.txt +0 -0
panther/__init__.py
CHANGED
panther/_load_configs.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import logging
|
2
2
|
import sys
|
3
|
+
import types
|
3
4
|
from importlib import import_module
|
4
5
|
from multiprocessing import Manager
|
5
6
|
|
6
|
-
from panther._utils import import_class
|
7
|
+
from panther._utils import import_class, check_function_type_endpoint, check_class_type_endpoint
|
7
8
|
from panther.background_tasks import background_tasks
|
8
9
|
from panther.base_websocket import WebsocketConnections
|
9
10
|
from panther.cli.utils import import_error
|
@@ -36,6 +37,7 @@ __all__ = (
|
|
36
37
|
'load_authentication_class',
|
37
38
|
'load_urls',
|
38
39
|
'load_websocket_connections',
|
40
|
+
'check_endpoints_inheritance',
|
39
41
|
)
|
40
42
|
|
41
43
|
logger = logging.getLogger('panther')
|
@@ -265,5 +267,14 @@ def load_websocket_connections():
|
|
265
267
|
config.WEBSOCKET_CONNECTIONS = WebsocketConnections(pubsub_connection=pubsub_connection)
|
266
268
|
|
267
269
|
|
270
|
+
def check_endpoints_inheritance():
|
271
|
+
"""Should be after `load_urls()`"""
|
272
|
+
for _, endpoint in config.FLAT_URLS.items():
|
273
|
+
if isinstance(endpoint, types.FunctionType):
|
274
|
+
check_function_type_endpoint(endpoint=endpoint)
|
275
|
+
else:
|
276
|
+
check_class_type_endpoint(endpoint=endpoint)
|
277
|
+
|
278
|
+
|
268
279
|
def _exception_handler(field: str, error: str | Exception) -> PantherError:
|
269
280
|
return PantherError(f"Invalid '{field}': {error}")
|
panther/_utils.py
CHANGED
@@ -4,12 +4,13 @@ import logging
|
|
4
4
|
import re
|
5
5
|
import subprocess
|
6
6
|
import types
|
7
|
-
from typing import Any, Generator, Iterator, AsyncGenerator
|
8
7
|
from collections.abc import Callable
|
9
8
|
from traceback import TracebackException
|
9
|
+
from typing import Any, Generator, Iterator, AsyncGenerator
|
10
10
|
|
11
11
|
from panther.exceptions import PantherError
|
12
12
|
from panther.file_handler import File
|
13
|
+
from panther.websocket import GenericWebsocket
|
13
14
|
|
14
15
|
logger = logging.getLogger('panther')
|
15
16
|
|
@@ -99,19 +100,18 @@ def reformat_code(base_dir):
|
|
99
100
|
def check_function_type_endpoint(endpoint: types.FunctionType) -> Callable:
|
100
101
|
# Function Doesn't Have @API Decorator
|
101
102
|
if not hasattr(endpoint, '__wrapped__'):
|
102
|
-
|
103
|
-
|
104
|
-
return endpoint
|
103
|
+
raise PantherError(
|
104
|
+
f'You may have forgotten to use `@API()` on the `{endpoint.__module__}.{endpoint.__name__}()`')
|
105
105
|
|
106
106
|
|
107
107
|
def check_class_type_endpoint(endpoint: Callable) -> Callable:
|
108
108
|
from panther.app import GenericAPI
|
109
109
|
|
110
|
-
if not issubclass(endpoint, GenericAPI):
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
if not issubclass(endpoint, (GenericAPI, GenericWebsocket)):
|
111
|
+
raise PantherError(
|
112
|
+
f'You may have forgotten to inherit from `panther.app.GenericAPI` or `panther.app.GenericWebsocket` '
|
113
|
+
f'on the `{endpoint.__module__}.{endpoint.__name__}()`'
|
114
|
+
)
|
115
115
|
|
116
116
|
|
117
117
|
def async_next(iterator: Iterator):
|
@@ -28,7 +28,7 @@ class BaseQuery:
|
|
28
28
|
def _clean_error_message(cls, validation_error: ValidationError, is_updating: bool = False) -> str:
|
29
29
|
error = ', '.join(
|
30
30
|
'{field}="{error}"'.format(
|
31
|
-
field='.'.join(loc for loc in e['loc']),
|
31
|
+
field='.'.join(str(loc) for loc in e['loc']),
|
32
32
|
error=e['msg']
|
33
33
|
)
|
34
34
|
for e in validation_error.errors()
|
panther/main.py
CHANGED
@@ -67,6 +67,8 @@ class Panther:
|
|
67
67
|
load_urls(self._configs_module, urls=self._urls)
|
68
68
|
load_websocket_connections()
|
69
69
|
|
70
|
+
check_endpoints_inheritance()
|
71
|
+
|
70
72
|
async def __call__(self, scope: dict, receive: Callable, send: Callable) -> None:
|
71
73
|
if scope['type'] == 'lifespan':
|
72
74
|
message = await receive()
|
@@ -160,19 +162,10 @@ class Panther:
|
|
160
162
|
await request.read_body()
|
161
163
|
|
162
164
|
# Find Endpoint
|
163
|
-
|
164
|
-
if
|
165
|
+
endpoint, found_path = find_endpoint(path=request.path)
|
166
|
+
if endpoint is None:
|
165
167
|
return await self._raise(send, monitoring=monitoring, status_code=status.HTTP_404_NOT_FOUND)
|
166
168
|
|
167
|
-
# Check Endpoint Type
|
168
|
-
try:
|
169
|
-
if isinstance(_endpoint, types.FunctionType):
|
170
|
-
endpoint = check_function_type_endpoint(endpoint=_endpoint)
|
171
|
-
else:
|
172
|
-
endpoint = check_class_type_endpoint(endpoint=_endpoint)
|
173
|
-
except TypeError:
|
174
|
-
return await self._raise(send, monitoring=monitoring, status_code=status.HTTP_501_NOT_IMPLEMENTED)
|
175
|
-
|
176
169
|
# Collect Path Variables
|
177
170
|
request.collect_path_variables(found_path=found_path)
|
178
171
|
|
@@ -186,6 +179,10 @@ class Panther:
|
|
186
179
|
f'Make sure to return the `request` at the end of `{middleware.__class__.__name__}.before()`')
|
187
180
|
return await self._raise(send, monitoring=monitoring)
|
188
181
|
|
182
|
+
# Prepare the method
|
183
|
+
if not isinstance(endpoint, types.FunctionType):
|
184
|
+
endpoint = endpoint().call_method
|
185
|
+
|
189
186
|
# Call Endpoint
|
190
187
|
response = await endpoint(request=request)
|
191
188
|
|
panther/serializer.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: panther
|
3
|
-
Version: 4.3.
|
4
|
-
Summary: Fast &
|
3
|
+
Version: 4.3.2
|
4
|
+
Summary: Fast & Friendly, Web Framework For Building Async APIs
|
5
5
|
Home-page: https://github.com/alirn76/panther
|
6
6
|
Author: Ali RajabNezhad
|
7
7
|
Author-email: alirn76@yahoo.com
|
@@ -10,16 +10,17 @@ Classifier: Operating System :: OS Independent
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
13
14
|
Requires-Python: >=3.10
|
14
15
|
Description-Content-Type: text/markdown
|
15
16
|
License-File: LICENSE
|
16
|
-
Requires-Dist: httptools~=0.6.1
|
17
17
|
Requires-Dist: pantherdb~=2.1.0
|
18
|
-
Requires-Dist: pydantic~=2.
|
18
|
+
Requires-Dist: pydantic~=2.8.2
|
19
19
|
Requires-Dist: rich~=13.7.1
|
20
20
|
Requires-Dist: uvicorn~=0.27.1
|
21
21
|
Requires-Dist: pytz~=2024.1
|
22
22
|
Requires-Dist: Jinja2~=3.1
|
23
|
+
Requires-Dist: httptools~=0.6.1
|
23
24
|
Provides-Extra: full
|
24
25
|
Requires-Dist: redis==5.0.1; extra == "full"
|
25
26
|
Requires-Dist: motor~=3.5.0; extra == "full"
|
@@ -1,6 +1,6 @@
|
|
1
|
-
panther/__init__.py,sha256=
|
2
|
-
panther/_load_configs.py,sha256=
|
3
|
-
panther/_utils.py,sha256=
|
1
|
+
panther/__init__.py,sha256=iuzw5A_s3YRldLNyqlVibCbLNLiQRYeD3EIDBqDOldY,110
|
2
|
+
panther/_load_configs.py,sha256=NZEwp3s7Mq_gU6w5FFN-3JfJImjZtf4_q-qengDQ6Y0,9875
|
3
|
+
panther/_utils.py,sha256=R1tsUde1zA5iJtk-ZvWe8hp6JaNhKgNoH2rxpdiQDMc,4449
|
4
4
|
panther/app.py,sha256=e2eb4sXIaBje5vpcm4pbvvEO_sj83pLfBHCIZJFFX38,8222
|
5
5
|
panther/authentications.py,sha256=gf7BVyQ8vXKhiumJAtD0aAK7uIHWx_snbOKYAKrYuVw,5677
|
6
6
|
panther/background_tasks.py,sha256=HBYubDIiO_673cl_5fqCUP9zzimzRgRkDSkag9Msnbs,7656
|
@@ -13,14 +13,14 @@ panther/exceptions.py,sha256=7rHdJIES2__kqOStIqbHl3Uxask2lzKgLQlkZvvDwFA,1591
|
|
13
13
|
panther/file_handler.py,sha256=I94tpbtTVniBnnUMkFr3Eis6kPDt8sLzS5u8TzFrR5I,1323
|
14
14
|
panther/generics.py,sha256=D2ia7M4ML15kMZiuCIMpL7ZfQhMmKpqE4wCmuRE-q4Y,7233
|
15
15
|
panther/logging.py,sha256=SGgF9faQM1QmbmMPVc6m1DY-TbV329kTD8BuzGLx3I0,2073
|
16
|
-
panther/main.py,sha256=
|
16
|
+
panther/main.py,sha256=SnDN_aqpg5qG7jqwrb9JEiBs9bSmUUDursGuXs3FJbQ,9159
|
17
17
|
panther/monitoring.py,sha256=y1F3c8FJlnmooM-m1nSyOTa9eWq0v1nHnmw9zz-4Kls,1314
|
18
18
|
panther/pagination.py,sha256=ANJrEF0q1nVAfD33I4nZfUUxFcETzJb01gIhbZX3HEw,1639
|
19
19
|
panther/permissions.py,sha256=9-J5vzvEKa_PITwEVQbZZv8PG2FOu05YBlD5yMrKcfc,348
|
20
20
|
panther/request.py,sha256=F9ZiAWSse7_6moAzqdoFInUN4zTKlzijh9AdU9w3Jfw,1673
|
21
21
|
panther/response.py,sha256=uQ41lmBhdFUu3mmkftmbiZEvVgGoenEbt7zVwIDodbk,8851
|
22
22
|
panther/routings.py,sha256=1eqbjubLnUUEQRlz8mIF464ImvCMjyasiekHBtxEQoQ,6218
|
23
|
-
panther/serializer.py,sha256=
|
23
|
+
panther/serializer.py,sha256=5O5dypP9ys0qTKrjwaXONmOqCfDHoXY1q5ajsirFjM8,9083
|
24
24
|
panther/status.py,sha256=Gc_PnYrHfInTsZpGbqiCfDB-py1C7Rh8KMdb6Lq9Exs,3346
|
25
25
|
panther/test.py,sha256=RsQtP5IURLWR__BihOjruWoX3NscmGDqDqj1CfAb3bI,7037
|
26
26
|
panther/throttling.py,sha256=mVa_mGv6w_Ad7LLtV4eG5QpDwwNsk4QjFFi0mIHQBnE,231
|
@@ -39,7 +39,7 @@ panther/db/cursor.py,sha256=jJ6bhz_Zljt3-AoeVdi563e2q3MSDJPP33WVbQk-goE,1287
|
|
39
39
|
panther/db/models.py,sha256=GRbKXJiwnxQJ_SjuPfXPzA5miH_djZNTPPyqiRp5DI8,2561
|
40
40
|
panther/db/utils.py,sha256=ZZa3TMkuRtssl5ZRItFLonyxvMFsTq4fmTD4BblhLDA,1589
|
41
41
|
panther/db/queries/__init__.py,sha256=uF4gvBjLBJ-Yl3WLqoZEVNtHCVhFRKW3_Vi44pJxDNI,45
|
42
|
-
panther/db/queries/base_queries.py,sha256=
|
42
|
+
panther/db/queries/base_queries.py,sha256=nUhkkfkZT7Fi3NE395b59IJMet0yCS-S1QXfCugh-p8,3769
|
43
43
|
panther/db/queries/mongodb_queries.py,sha256=VLRrUc6kO6YinzEa3mnxzOPv2YyAEh7KjPS4WwzCcRM,5707
|
44
44
|
panther/db/queries/pantherdb_queries.py,sha256=c9K3EHvOTZFN-1ZH8LUiK1BSXpEjPR8vaqPt5FuC05U,4581
|
45
45
|
panther/db/queries/queries.py,sha256=9VY8CMmn0wIbuQVHJO7U5xeym-53saYmFkRIL3sensc,12420
|
@@ -49,9 +49,9 @@ panther/panel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
49
|
panther/panel/apis.py,sha256=COsbwKZyTgyHvHYbpDfusifAH9ojMS3z1KhZCt9M-Ms,2428
|
50
50
|
panther/panel/urls.py,sha256=JiV-H4dWE-m_bfaTTVxzOxTvJmOWhyLOvcbM7xU3Bn4,240
|
51
51
|
panther/panel/utils.py,sha256=0Rv79oR5IEqalqwpRKQHMn1p5duVY5mxMqDKiA5mWx4,437
|
52
|
-
panther-4.3.
|
53
|
-
panther-4.3.
|
54
|
-
panther-4.3.
|
55
|
-
panther-4.3.
|
56
|
-
panther-4.3.
|
57
|
-
panther-4.3.
|
52
|
+
panther-4.3.2.dist-info/LICENSE,sha256=2aF1hL2aC0zRPjzUkSxJUzZbn2_uLoOkn7DHjzZni-I,1524
|
53
|
+
panther-4.3.2.dist-info/METADATA,sha256=NQJXMcJ6Kd8GR6edWAT-JyFJjGrEAq3LgV8Bx93tuGw,6587
|
54
|
+
panther-4.3.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
55
|
+
panther-4.3.2.dist-info/entry_points.txt,sha256=6GPxYFGuzVfNB4YpHFJvYex6iWah5_tLnirAHwj2Qsg,51
|
56
|
+
panther-4.3.2.dist-info/top_level.txt,sha256=VbBs02JGXTIoHMzsX-eLOk2MCbBZzQbLhWiYpI7xI2g,8
|
57
|
+
panther-4.3.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|