panther 1.3.1__tar.gz → 1.4.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 (46) hide show
  1. {panther-1.3.1 → panther-1.4.0}/PKG-INFO +8 -14
  2. {panther-1.3.1 → panther-1.4.0}/README.md +7 -13
  3. {panther-1.3.1 → panther-1.4.0}/panther/__init__.py +1 -1
  4. {panther-1.3.1 → panther-1.4.0}/panther/authentications.py +5 -4
  5. {panther-1.3.1 → panther-1.4.0}/panther/cli/template.py +2 -0
  6. {panther-1.3.1 → panther-1.4.0}/panther/configs.py +3 -1
  7. {panther-1.3.1 → panther-1.4.0}/panther/db/queries/mongodb_queries.py +1 -13
  8. {panther-1.3.1 → panther-1.4.0}/panther/db/queries/pantherdb_queries.py +2 -3
  9. {panther-1.3.1 → panther-1.4.0}/panther/db/queries/queries.py +15 -1
  10. {panther-1.3.1 → panther-1.4.0}/panther/db/utils.py +4 -4
  11. {panther-1.3.1 → panther-1.4.0}/panther/logger.py +17 -17
  12. {panther-1.3.1 → panther-1.4.0}/panther/main.py +1 -0
  13. {panther-1.3.1 → panther-1.4.0}/panther/middlewares/monitoring.py +3 -3
  14. {panther-1.3.1 → panther-1.4.0}/panther.egg-info/PKG-INFO +8 -14
  15. {panther-1.3.1 → panther-1.4.0}/panther.egg-info/requires.txt +1 -1
  16. {panther-1.3.1 → panther-1.4.0}/setup.py +1 -1
  17. {panther-1.3.1 → panther-1.4.0}/LICENSE +0 -0
  18. {panther-1.3.1 → panther-1.4.0}/panther/_utils.py +0 -0
  19. {panther-1.3.1 → panther-1.4.0}/panther/app.py +0 -0
  20. {panther-1.3.1 → panther-1.4.0}/panther/caching.py +0 -0
  21. {panther-1.3.1 → panther-1.4.0}/panther/cli/__init__.py +0 -0
  22. {panther-1.3.1 → panther-1.4.0}/panther/cli/create_command.py +0 -0
  23. {panther-1.3.1 → panther-1.4.0}/panther/cli/main.py +0 -0
  24. {panther-1.3.1 → panther-1.4.0}/panther/cli/monitor_command.py +0 -0
  25. {panther-1.3.1 → panther-1.4.0}/panther/cli/run_command.py +0 -0
  26. {panther-1.3.1 → panther-1.4.0}/panther/cli/utils.py +0 -0
  27. {panther-1.3.1 → panther-1.4.0}/panther/db/__init__.py +0 -0
  28. {panther-1.3.1 → panther-1.4.0}/panther/db/connection.py +0 -0
  29. {panther-1.3.1 → panther-1.4.0}/panther/db/models.py +0 -0
  30. {panther-1.3.1 → panther-1.4.0}/panther/db/queries/__init__.py +0 -0
  31. {panther-1.3.1 → panther-1.4.0}/panther/exceptions.py +0 -0
  32. {panther-1.3.1 → panther-1.4.0}/panther/middlewares/__init__.py +0 -0
  33. {panther-1.3.1 → panther-1.4.0}/panther/middlewares/base.py +0 -0
  34. {panther-1.3.1 → panther-1.4.0}/panther/middlewares/db.py +0 -0
  35. {panther-1.3.1 → panther-1.4.0}/panther/middlewares/redis.py +0 -0
  36. {panther-1.3.1 → panther-1.4.0}/panther/request.py +0 -0
  37. {panther-1.3.1 → panther-1.4.0}/panther/response.py +0 -0
  38. {panther-1.3.1 → panther-1.4.0}/panther/routings.py +0 -0
  39. {panther-1.3.1 → panther-1.4.0}/panther/status.py +0 -0
  40. {panther-1.3.1 → panther-1.4.0}/panther/utils.py +0 -0
  41. {panther-1.3.1 → panther-1.4.0}/panther.egg-info/SOURCES.txt +0 -0
  42. {panther-1.3.1 → panther-1.4.0}/panther.egg-info/dependency_links.txt +0 -0
  43. {panther-1.3.1 → panther-1.4.0}/panther.egg-info/entry_points.txt +0 -0
  44. {panther-1.3.1 → panther-1.4.0}/panther.egg-info/top_level.txt +0 -0
  45. {panther-1.3.1 → panther-1.4.0}/pyproject.toml +0 -0
  46. {panther-1.3.1 → panther-1.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panther
3
- Version: 1.3.1
3
+ Version: 1.4.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
@@ -93,14 +93,10 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
93
93
  ```
94
94
 
95
95
  - #### Run Project
96
- Panther needs Uvicorn as ASGI (Asynchronous Server Gateway Interface)
97
- ```console
98
- $ pip install uvicorn[standard]
99
- ```
100
- Then
101
- ```console
102
- $ panther run
103
- ```
96
+ Panther Uses [Uvicorn](https://github.com/encode/uvicorn) as ASGI (Asynchronous Server Gateway Interface)
97
+ ```console
98
+ $ panther run
99
+ ```
104
100
 
105
101
  - #### Monitoring Requests
106
102
 
@@ -109,7 +105,7 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
109
105
  ```
110
106
 
111
107
  - #### Python Shell
112
-
108
+ Panther Uses [bpython](https://bpython-interpreter.org) for shell
113
109
  ```console
114
110
  $ panther shell
115
111
  ```
@@ -154,7 +150,7 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
154
150
  **app/apis.py**:
155
151
 
156
152
  ```python
157
- from datetime import timedelta, datetime
153
+ from datetime import datetime
158
154
 
159
155
  from panther.app import API
160
156
  from panther.configs import config
@@ -168,15 +164,13 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
168
164
  return {'detail': 'Hello World'}
169
165
 
170
166
 
171
- @API(cache=True, cache_exp_time=timedelta(minutes=2))
167
+ @API(cache=True)
172
168
  async def info(request: Request):
173
169
  data = {
174
170
  'version': version(),
175
171
  'datetime_now': datetime.now().isoformat(),
176
172
  'user_agent': request.headers.user_agent,
177
- 'middlewares': config['middlewares'],
178
173
  'db_engine': config['db_engine'],
179
- 'urls': config['urls'],
180
174
  }
181
175
  return Response(data=data, status_code=status.HTTP_202_ACCEPTED)
182
176
  ```
@@ -77,14 +77,10 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
77
77
  ```
78
78
 
79
79
  - #### Run Project
80
- Panther needs Uvicorn as ASGI (Asynchronous Server Gateway Interface)
81
- ```console
82
- $ pip install uvicorn[standard]
83
- ```
84
- Then
85
- ```console
86
- $ panther run
87
- ```
80
+ Panther Uses [Uvicorn](https://github.com/encode/uvicorn) as ASGI (Asynchronous Server Gateway Interface)
81
+ ```console
82
+ $ panther run
83
+ ```
88
84
 
89
85
  - #### Monitoring Requests
90
86
 
@@ -93,7 +89,7 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
93
89
  ```
94
90
 
95
91
  - #### Python Shell
96
-
92
+ Panther Uses [bpython](https://bpython-interpreter.org) for shell
97
93
  ```console
98
94
  $ panther shell
99
95
  ```
@@ -138,7 +134,7 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
138
134
  **app/apis.py**:
139
135
 
140
136
  ```python
141
- from datetime import timedelta, datetime
137
+ from datetime import datetime
142
138
 
143
139
  from panther.app import API
144
140
  from panther.configs import config
@@ -152,15 +148,13 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
152
148
  return {'detail': 'Hello World'}
153
149
 
154
150
 
155
- @API(cache=True, cache_exp_time=timedelta(minutes=2))
151
+ @API(cache=True)
156
152
  async def info(request: Request):
157
153
  data = {
158
154
  'version': version(),
159
155
  'datetime_now': datetime.now().isoformat(),
160
156
  'user_agent': request.headers.user_agent,
161
- 'middlewares': config['middlewares'],
162
157
  'db_engine': config['db_engine'],
163
- 'urls': config['urls'],
164
158
  }
165
159
  return Response(data=data, status_code=status.HTTP_202_ACCEPTED)
166
160
  ```
@@ -1,6 +1,6 @@
1
1
  from .main import Panther
2
2
 
3
- __version__ = '1.3.1'
3
+ __version__ = '1.4.0'
4
4
 
5
5
 
6
6
  def version():
@@ -49,10 +49,11 @@ class JWTAuthentication:
49
49
  if user_id := payload.get('user_id') is None:
50
50
  raise AuthenticationException
51
51
  user_model = config['user_model'] or cls.model
52
- user = user_model.get_one(id=user_id)
53
- if user is None:
54
- raise AuthenticationException
55
- return user
52
+
53
+ if user := user_model.get_one(id=user_id):
54
+ return user
55
+
56
+ raise AuthenticationException
56
57
 
57
58
  @staticmethod
58
59
  def encode_jwt(user_id: int) -> str:
@@ -65,6 +65,8 @@ USER_MODEL = 'panther.db.models.User'
65
65
 
66
66
  MONITORING = True
67
67
 
68
+ LOG_QUERIES = True
69
+
68
70
  URLs = 'core/urls.py'
69
71
  """ % datetime.now().date().isoformat()
70
72
 
@@ -15,6 +15,7 @@ class JWTConfig:
15
15
  class Config(TypedDict):
16
16
  base_dir: Path
17
17
  monitoring: bool
18
+ log_queries: bool
18
19
  urls: dict
19
20
  middlewares: list
20
21
  reversed_middlewares: list
@@ -28,7 +29,8 @@ class Config(TypedDict):
28
29
 
29
30
  config: Config = {
30
31
  'base_dir': Path(),
31
- 'monitoring': True,
32
+ 'monitoring': False,
33
+ 'log_queries': False,
32
34
  'secret_key': None,
33
35
  'urls': {},
34
36
  'middlewares': [],
@@ -3,7 +3,7 @@ from typing import TypeVar
3
3
  import bson
4
4
 
5
5
  from panther.db.connection import db # NOQA: F401
6
- from panther.db.utils import clean_object_id_in_dicts, merge_dicts, query_logger
6
+ from panther.db.utils import clean_object_id_in_dicts, merge_dicts, log_query
7
7
 
8
8
  # TODO: Not sure about this bounding
9
9
  T = TypeVar('T', bound='BaseMongoDBQuery')
@@ -12,7 +12,6 @@ T = TypeVar('T', bound='BaseMongoDBQuery')
12
12
  class BaseMongoDBQuery:
13
13
 
14
14
  @classmethod
15
- @query_logger
16
15
  def get_one(cls: type[T], _data: dict = None, /, **kwargs) -> T:
17
16
  clean_object_id_in_dicts(_data, kwargs)
18
17
  _query = merge_dicts(_data, kwargs)
@@ -20,14 +19,12 @@ class BaseMongoDBQuery:
20
19
  return cls(**obj) if obj else None
21
20
 
22
21
  @classmethod
23
- @query_logger
24
22
  def count(cls, _data: dict = None, /, **kwargs) -> int:
25
23
  clean_object_id_in_dicts(_data, kwargs)
26
24
  _query = merge_dicts(_data, kwargs)
27
25
  return eval(f'db.session.{cls.__name__}.count_documents(_query)')
28
26
 
29
27
  @classmethod
30
- @query_logger
31
28
  def list(cls, _data: dict = None, /, **kwargs):
32
29
  clean_object_id_in_dicts(_data, kwargs)
33
30
  _query = merge_dicts(_data, kwargs)
@@ -35,32 +32,27 @@ class BaseMongoDBQuery:
35
32
  return [cls(**obj) for obj in result]
36
33
 
37
34
  @classmethod
38
- @query_logger
39
35
  def create(cls, _data: dict = None, **kwargs) -> bson.objectid.ObjectId:
40
36
  _query = merge_dicts(_data, kwargs)
41
37
  return eval(f'db.session.{cls.__name__}.insert_one(_query)').inserted_id
42
38
 
43
- @query_logger
44
39
  def delete(self) -> bool:
45
40
  _filter = {'_id': self._id}
46
41
  result = eval(f'db.session.{self.__class__.__name__}.delete_one(_filter)')
47
42
  return bool(result.deleted_count)
48
43
 
49
44
  @classmethod
50
- @query_logger
51
45
  def delete_one(cls, **kwargs) -> bool:
52
46
  clean_object_id_in_dicts(kwargs)
53
47
  result = eval(f'db.session.{cls.__name__}.delete_one(kwargs)')
54
48
  return bool(result.deleted_count)
55
49
 
56
50
  @classmethod
57
- @query_logger
58
51
  def delete_many(cls, **kwargs) -> int:
59
52
  clean_object_id_in_dicts(kwargs)
60
53
  result = eval(f'db.session.{cls.__name__}.delete_many(kwargs)')
61
54
  return result.deleted_count
62
55
 
63
- @query_logger
64
56
  def update(self, _data: dict = None, **kwargs) -> dict:
65
57
  for field, value in (_data or kwargs).items():
66
58
  if hasattr(self, field):
@@ -70,7 +62,6 @@ class BaseMongoDBQuery:
70
62
  return eval(f'db.session.{self.__class__.__name__}.update_one(_filter, _update)')
71
63
 
72
64
  @classmethod
73
- @query_logger
74
65
  def update_one(cls, _filter, _data: dict = None, /, **kwargs) -> dict:
75
66
  clean_object_id_in_dicts(_filter)
76
67
 
@@ -81,19 +72,16 @@ class BaseMongoDBQuery:
81
72
  return eval(f'db.session.{cls.__name__}.update_one(_filter, _data | _update)')
82
73
 
83
74
  @classmethod
84
- @query_logger
85
75
  def update_many(cls, _filter, **kwargs) -> dict:
86
76
  _update = {'$set': kwargs}
87
77
  return eval(f'db.session.{cls.__name__}.update_many(_filter, _update)')
88
78
 
89
79
  @classmethod
90
- @query_logger
91
80
  def increment(cls, _filter, **kwargs):
92
81
  _update = {'$inc': kwargs}
93
82
  return eval(f'db.session.{cls.__name__}.update_many({_filter}, {_update})')
94
83
 
95
84
  @classmethod
96
- @query_logger
97
85
  def get_or_create(cls, **kwargs) -> tuple[bool, any]:
98
86
  obj = cls.get_one(**kwargs)
99
87
  if obj:
@@ -1,9 +1,8 @@
1
- import operator
2
- from functools import reduce
3
1
  from typing import Self
4
2
  from pydantic import ValidationError
5
3
 
6
4
  from panther.db.connection import db
5
+ from panther.db.utils import merge_dicts
7
6
  from panther.exceptions import DBException
8
7
 
9
8
 
@@ -32,7 +31,7 @@ class BasePantherDBQuery:
32
31
  @classmethod
33
32
  def _merge(cls, *args) -> dict:
34
33
  # TODO: Convert "id" to "_id"
35
- return reduce(operator.ior, filter(None, args), {})
34
+ return merge_dicts(*args)
36
35
 
37
36
  # # # # # Find # # # # #
38
37
  @classmethod
@@ -1,8 +1,9 @@
1
1
  from typing import Self
2
2
 
3
+ from panther.configs import config
4
+ from panther.db.utils import log_query
3
5
  from panther.db.queries.mongodb_queries import BaseMongoDBQuery
4
6
  from panther.db.queries.pantherdb_queries import BasePantherDBQuery
5
- from panther.configs import config
6
7
 
7
8
  if config['db_engine'] == 'pantherdb':
8
9
  BaseQuery = BasePantherDBQuery
@@ -18,6 +19,7 @@ class Query(BaseQuery):
18
19
 
19
20
  # # # # # Find # # # # #
20
21
  @classmethod
22
+ @log_query
21
23
  def find_one(cls, _data: dict = None, /, **kwargs) -> Self | None:
22
24
  """
23
25
  example:
@@ -27,6 +29,7 @@ class Query(BaseQuery):
27
29
  return super().find_one(_data, **kwargs)
28
30
 
29
31
  @classmethod
32
+ @log_query
30
33
  def find(cls, _data: dict = None, /, **kwargs) -> list[Self]:
31
34
  """
32
35
  example:
@@ -37,6 +40,7 @@ class Query(BaseQuery):
37
40
 
38
41
  # # # # # Insert # # # # #
39
42
  @classmethod
43
+ @log_query
40
44
  def insert_one(cls, _data: dict = None, /, **kwargs) -> Self:
41
45
  """
42
46
  example:
@@ -46,10 +50,12 @@ class Query(BaseQuery):
46
50
  return super().insert_one(_data, **kwargs)
47
51
 
48
52
  @classmethod
53
+ @log_query
49
54
  def insert_many(cls, _data: dict = None, **kwargs):
50
55
  return super().insert_many(_data, **kwargs)
51
56
 
52
57
  # # # # # Delete # # # # #
58
+ @log_query
53
59
  def delete(self) -> None:
54
60
  """
55
61
  example:
@@ -60,6 +66,7 @@ class Query(BaseQuery):
60
66
  return super().delete()
61
67
 
62
68
  @classmethod
69
+ @log_query
63
70
  def delete_one(cls, **kwargs) -> bool:
64
71
  """
65
72
  example:
@@ -69,6 +76,7 @@ class Query(BaseQuery):
69
76
  return super().delete_one(**kwargs)
70
77
 
71
78
  @classmethod
79
+ @log_query
72
80
  def delete_many(cls, **kwargs) -> int:
73
81
  """
74
82
  example:
@@ -78,6 +86,7 @@ class Query(BaseQuery):
78
86
  return super().delete_many(**kwargs)
79
87
 
80
88
  # # # # # Update # # # # #
89
+ @log_query
81
90
  def update(self, **kwargs) -> None:
82
91
  """
83
92
  example:
@@ -88,6 +97,7 @@ class Query(BaseQuery):
88
97
  return super().update(**kwargs)
89
98
 
90
99
  @classmethod
100
+ @log_query
91
101
  def update_one(cls, _filter, _data: dict = None, /, **kwargs) -> bool:
92
102
  """
93
103
  example:
@@ -98,6 +108,7 @@ class Query(BaseQuery):
98
108
  return super().update_one(_filter, _data, **kwargs)
99
109
 
100
110
  @classmethod
111
+ @log_query
101
112
  def update_many(cls, _filter, **kwargs) -> int:
102
113
  """
103
114
  example:
@@ -108,6 +119,7 @@ class Query(BaseQuery):
108
119
 
109
120
  # # # # # Other # # # # #
110
121
  @classmethod
122
+ @log_query
111
123
  def first(cls, _data: dict = None, /, **kwargs) -> Self | None:
112
124
  """
113
125
  It works same as find_one()
@@ -118,6 +130,7 @@ class Query(BaseQuery):
118
130
  return super().first(_data, **kwargs)
119
131
 
120
132
  @classmethod
133
+ @log_query
121
134
  def last(cls, _data: dict = None, /, **kwargs) -> Self | None:
122
135
  """
123
136
  example:
@@ -127,6 +140,7 @@ class Query(BaseQuery):
127
140
  return super().last(_data, **kwargs)
128
141
 
129
142
  @classmethod
143
+ @log_query
130
144
  def count(cls, _data: dict = None, /, **kwargs) -> int:
131
145
  """
132
146
  example:
@@ -4,18 +4,18 @@ from functools import reduce
4
4
  from time import perf_counter
5
5
 
6
6
  from panther.configs import config
7
- from panther.logger import logger
7
+ from panther.logger import query_logger
8
8
 
9
9
 
10
- def query_logger(func):
10
+ def log_query(func):
11
11
  def log(*args, **kwargs):
12
- if config['monitoring'] is False:
12
+ if config['log_queries'] is False:
13
13
  return func(*args, **kwargs)
14
14
  start = perf_counter()
15
15
  response = func(*args, **kwargs)
16
16
  end = perf_counter()
17
17
  class_name = args[0].__name__ if hasattr(args[0], '__name__') else args[0].__class__.__name__
18
- logger.info(f'\033[1mQuery -->\033[0m {class_name}.{func.__name__}() --> {(end - start) * 1_000:.2} ms')
18
+ query_logger.info(f'\033[1mQuery -->\033[0m {class_name}.{func.__name__}() --> {(end - start) * 1_000:.2} ms')
19
19
  return response
20
20
  return log
21
21
 
@@ -1,14 +1,6 @@
1
1
  import os
2
2
  import logging
3
3
  from pydantic import BaseModel
4
- from panther.cli.utils import error
5
-
6
- try:
7
- import uvicorn
8
- del uvicorn
9
- except ImportError:
10
- error('No module named "uvicorn"\n\nHint: Try to install with "pip install uvicorn[standard]"')
11
- exit()
12
4
 
13
5
  from logging.config import dictConfig
14
6
  from panther.configs import config
@@ -26,6 +18,7 @@ class LogConfig(BaseModel):
26
18
  DEFAULT_LOG_FORMAT: str = '%(levelprefix)s | %(asctime)s | %(message)s'
27
19
  FILE_LOG_FORMAT: str = '%(asctime)s | %(message)s'
28
20
  LOG_LEVEL: str = 'DEBUG'
21
+ MAX_FILE_SIZE: int = 1024 * 1024 * 100 # 100 MB
29
22
 
30
23
  version = 1
31
24
  disable_existing_loggers = False
@@ -47,15 +40,21 @@ class LogConfig(BaseModel):
47
40
  'formatter': 'file_formatter',
48
41
  'filename': LOGS_DIR / 'monitoring.log',
49
42
  'class': 'logging.handlers.RotatingFileHandler',
50
- 'maxBytes': 1024 * 1024 * 100, # 100 MB,
43
+ 'maxBytes': MAX_FILE_SIZE, # 100 MB,
44
+ 'backupCount': 3,
45
+ },
46
+ 'query_file': {
47
+ 'formatter': 'file_formatter',
48
+ 'filename': LOGS_DIR / 'query.log',
49
+ 'class': 'logging.handlers.RotatingFileHandler',
50
+ 'maxBytes': MAX_FILE_SIZE, # 100 MB,
51
51
  'backupCount': 3,
52
52
  },
53
53
  'file': {
54
54
  'formatter': 'file_formatter',
55
- # TODO: Don't know but base_dir.name will return '.' here :\
56
- 'filename': LOGS_DIR / f'{config["base_dir"].name}.log',
55
+ 'filename': LOGS_DIR / f'main.log',
57
56
  'class': 'logging.handlers.RotatingFileHandler',
58
- 'maxBytes': 1024 * 1024 * 100, # 100 MB,
57
+ 'maxBytes': MAX_FILE_SIZE, # 100 MB,
59
58
  'backupCount': 3,
60
59
  },
61
60
  'default': {
@@ -73,13 +72,14 @@ class LogConfig(BaseModel):
73
72
  'handlers': ['monitoring_file'],
74
73
  'level': LOG_LEVEL,
75
74
  },
75
+ 'query': {
76
+ 'handlers': ['default', 'query_file'],
77
+ 'level': LOG_LEVEL,
78
+ },
76
79
  }
77
80
 
78
81
 
79
82
  dictConfig(LogConfig().dict())
80
83
  logger = logging.getLogger('panther')
81
- monitoring = logging.getLogger('monitoring')
82
-
83
- """
84
- [debug, info, warning, error, critical]
85
- """
84
+ query_logger = logging.getLogger('query')
85
+ monitoring_logger = logging.getLogger('monitoring')
@@ -117,6 +117,7 @@ class Panther:
117
117
 
118
118
  # Put Variables In "config"
119
119
  config['monitoring'] = self.settings.get('MONITORING', config['monitoring'])
120
+ config['log_queries'] = self.settings.get('LOG_QUERIES', config['log_queries'])
120
121
  config['default_cache_exp'] = self.settings.get('DEFAULT_CACHE_EXP', config['default_cache_exp'])
121
122
  config['secret_key'] = self._get_secret_key()
122
123
 
@@ -1,8 +1,8 @@
1
1
  from time import perf_counter
2
2
 
3
- from panther.logger import monitoring
4
- from panther.middlewares.base import BaseMiddleware
5
3
  from panther.request import Request
4
+ from panther.logger import monitoring_logger
5
+ from panther.middlewares.base import BaseMiddleware
6
6
 
7
7
 
8
8
  class Middleware(BaseMiddleware):
@@ -21,4 +21,4 @@ class Middleware(BaseMiddleware):
21
21
  but we should put in middlewares chain later ...
22
22
  """
23
23
  response_time = (perf_counter() - self.start_time) * 1_000
24
- monitoring.info(f'{self.log} | {response_time: .3} ms | {status_code}')
24
+ monitoring_logger.info(f'{self.log} | {response_time: .3} ms | {status_code}')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: panther
3
- Version: 1.3.1
3
+ Version: 1.4.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
@@ -93,14 +93,10 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
93
93
  ```
94
94
 
95
95
  - #### Run Project
96
- Panther needs Uvicorn as ASGI (Asynchronous Server Gateway Interface)
97
- ```console
98
- $ pip install uvicorn[standard]
99
- ```
100
- Then
101
- ```console
102
- $ panther run
103
- ```
96
+ Panther Uses [Uvicorn](https://github.com/encode/uvicorn) as ASGI (Asynchronous Server Gateway Interface)
97
+ ```console
98
+ $ panther run
99
+ ```
104
100
 
105
101
  - #### Monitoring Requests
106
102
 
@@ -109,7 +105,7 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
109
105
  ```
110
106
 
111
107
  - #### Python Shell
112
-
108
+ Panther Uses [bpython](https://bpython-interpreter.org) for shell
113
109
  ```console
114
110
  $ panther shell
115
111
  ```
@@ -154,7 +150,7 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
154
150
  **app/apis.py**:
155
151
 
156
152
  ```python
157
- from datetime import timedelta, datetime
153
+ from datetime import datetime
158
154
 
159
155
  from panther.app import API
160
156
  from panther.configs import config
@@ -168,15 +164,13 @@ with [https://github.com/nakabonne/ali](https://github.com/nakabonne/ali) and he
168
164
  return {'detail': 'Hello World'}
169
165
 
170
166
 
171
- @API(cache=True, cache_exp_time=timedelta(minutes=2))
167
+ @API(cache=True)
172
168
  async def info(request: Request):
173
169
  data = {
174
170
  'version': version(),
175
171
  'datetime_now': datetime.now().isoformat(),
176
172
  'user_agent': request.headers.user_agent,
177
- 'middlewares': config['middlewares'],
178
173
  'db_engine': config['db_engine'],
179
- 'urls': config['urls'],
180
174
  }
181
175
  return Response(data=data, status_code=status.HTTP_202_ACCEPTED)
182
176
  ```
@@ -1,6 +1,6 @@
1
1
  pantherdb>=1.2.0
2
2
  pydantic>=1.10.5
3
- watchfiles>=0.18.1
3
+ uvicorn==0.20.0
4
4
  bpython>=0.24
5
5
  bson>=0.5.10
6
6
  redis>=4.0.2
@@ -45,7 +45,7 @@ setup(
45
45
  install_requires=[
46
46
  'pantherdb>=1.2.0',
47
47
  'pydantic>=1.10.5',
48
- 'watchfiles>=0.18.1',
48
+ 'uvicorn==0.20.0',
49
49
  'bpython>=0.24',
50
50
  'bson>=0.5.10',
51
51
  'redis>=4.0.2',
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