diff --git a/docs/docs/configs.md b/docs/docs/configs.md
index 7961a051..f4b5562b 100644
--- a/docs/docs/configs.md
+++ b/docs/docs/configs.md
@@ -100,3 +100,15 @@ It should be dotted address of your `shutdown` function
this function can be `sync` or `async`
_Example:_ `URLS = 'core.configs.shutdown'`
+
+---
+### [AUTO_REFORMAT](https://pantherpy.github.io/auto_reformat)
+> Type: `bool` (Default: `False`)
+
+It will reformat your code on every reload (on every change if you run the project with `--reload`)
+
+You may want to write your custom `ruff.toml` in root of your project.
+
+Reference: [https://docs.astral.sh/ruff/formatter/](https://docs.astral.sh/ruff/formatter/)
+
+_Example:_ `AUTO_REFORMAT = True`
diff --git a/docs/docs/release_notes.md b/docs/docs/release_notes.md
index 0be78389..d7f0dcd1 100644
--- a/docs/docs/release_notes.md
+++ b/docs/docs/release_notes.md
@@ -1,3 +1,6 @@
+### 3.3.0
+- Add Auto Reformat Code
+
### 3.2.4
- Add all() query
- Add tests for `pantherdb`, `load_configs()`, `status.py`, `Panel`, `multipart`, `request headers`
@@ -5,9 +8,6 @@
- Check `uvloop` installation on `Panther init`
- Minor Improvement
-### 3.2.1
-- Minor Improvement
-
### 3.2.1
- Move `Startup` to `__call__`
diff --git a/example/app/apis.py b/example/app/apis.py
index c9c6b896..0884dc41 100644
--- a/example/app/apis.py
+++ b/example/app/apis.py
@@ -5,24 +5,23 @@
from app.models import User
from app.serializers import (
FileSerializer,
+ ImageSerializer,
UserInputSerializer,
UserOutputSerializer,
UserUpdateSerializer,
- ImageSerializer,
)
from core.permissions import UserPermission
from panther import status
from panther.app import API, GenericAPI
from panther.authentications import JWTAuthentication
-from panther.background_tasks import background_tasks, BackgroundTask
+from panther.background_tasks import BackgroundTask, background_tasks
from panther.db.connection import redis
from panther.request import Request
from panther.response import HTMLResponse, Response
from panther.throttling import Throttling
from panther.websocket import close_websocket_connection, send_message_to_websocket
-
logger = logging.getLogger('panther')
@@ -173,10 +172,9 @@ async def run_background_tasks_api():
async def hello(name: str):
time.sleep(5)
print(f'Done {name}')
+
task = (
- BackgroundTask(hello, 'ali1')
- .interval(2)
- .every_seconds(2)
+ BackgroundTask(hello, 'ali1').interval(2).every_seconds(2)
# .on_time(datetime.time(hour=19, minute=18, second=10))
)
background_tasks.add_task(task)
diff --git a/example/app/urls.py b/example/app/urls.py
index 90ffe69a..e4987447 100644
--- a/example/app/urls.py
+++ b/example/app/urls.py
@@ -9,6 +9,7 @@
async def test(*args, **kwargs):
return Response(data={'detail': 'this is for test'})
+
urls = {
'none-class/': ReturnNone,
'none/': return_none,
diff --git a/example/core/configs.py b/example/core/configs.py
index 534ae912..51dcc6a2 100644
--- a/example/core/configs.py
+++ b/example/core/configs.py
@@ -57,12 +57,14 @@
async def startup():
- print('inside startup function')
+ print('Starting Up')
async def shutdown():
- print('inside shutdown function')
+ print('Shutting Down')
STARTUP = 'core.configs.startup'
SHUTDOWN = 'core.configs.shutdown'
+
+AUTO_REFORMAT = True
diff --git a/example/single_file_example.py b/example/single_file_example.py
index a658e2f0..d9228883 100644
--- a/example/single_file_example.py
+++ b/example/single_file_example.py
@@ -6,17 +6,18 @@
async def hello_world_api():
return {'detail': 'Hello World'}
+
url_routing = {
'/': hello_world_api,
}
def startup():
- print("Its startup")
+ print('Its startup')
def shutdown():
- print("Its shutdown")
+ print('Its shutdown')
app = Panther(__name__, configs=__name__, urls=url_routing, startup=startup, shutdown=shutdown)
diff --git a/panther/__init__.py b/panther/__init__.py
index d3b1f361..459cee86 100644
--- a/panther/__init__.py
+++ b/panther/__init__.py
@@ -1,6 +1,6 @@
from panther.main import Panther # noqa: F401
-__version__ = '3.2.5'
+__version__ = '3.3.0'
def version():
diff --git a/panther/_load_configs.py b/panther/_load_configs.py
index 6364454b..06a8d0c7 100644
--- a/panther/_load_configs.py
+++ b/panther/_load_configs.py
@@ -28,6 +28,7 @@
'load_jwt_config',
'load_startup',
'load_shutdown',
+ 'load_auto_reformat',
'collect_all_models',
'load_urls',
'load_panel_urls',
@@ -133,6 +134,10 @@ def load_shutdown(configs: dict, /) -> Callable:
return configs.get('SHUTDOWN') and import_class(configs['SHUTDOWN'])
+def load_auto_reformat(configs: dict, /) -> bool:
+ return configs.get('AUTO_REFORMAT', config['auto_reformat'])
+
+
def collect_all_models() -> list[dict]:
"""Collecting all models for panel APIs"""
from panther.db.models import Model
diff --git a/panther/configs.py b/panther/configs.py
index dbd4dd59..46c1d439 100644
--- a/panther/configs.py
+++ b/panther/configs.py
@@ -49,6 +49,7 @@ class Config(TypedDict):
has_ws: bool
startup: Callable
shutdown: Callable
+ auto_reformat: bool
config: Config = {
@@ -72,4 +73,5 @@ class Config(TypedDict):
'has_ws': False,
'startup': None,
'shutdown': None,
+ 'auto_reformat': False,
}
diff --git a/panther/main.py b/panther/main.py
index 9194a439..b632f57b 100644
--- a/panther/main.py
+++ b/panther/main.py
@@ -1,6 +1,7 @@
import asyncio
import contextlib
import logging
+import subprocess
import sys
import types
from collections.abc import Callable
@@ -44,6 +45,9 @@ def __init__(self, name: str, configs=None, urls: dict | None = None, startup: C
logger.error(clean_traceback_message(e))
sys.exit()
+ # Reformat Code
+ self.reformat_code()
+
# Monitoring
self.monitoring = Monitoring(is_active=config['monitoring'])
@@ -77,6 +81,7 @@ def load_configs(self) -> None:
config['jwt_config'] = load_jwt_config(self._configs_module)
config['startup'] = load_startup(self._configs_module)
config['shutdown'] = load_shutdown(self._configs_module)
+ config['auto_reformat'] = load_auto_reformat(self._configs_module)
config['models'] = collect_all_models()
# Initialize Background Tasks
@@ -113,6 +118,12 @@ def _create_ws_connections_instance(self):
else:
self.ws_redis_connection = None
+ @classmethod
+ def reformat_code(cls):
+ if config['auto_reformat']:
+ subprocess.run(['ruff', 'format', config['base_dir']])
+ subprocess.run(['ruff', 'check', '--select', 'I', '--fix', config['base_dir']])
+
async def __call__(self, scope: dict, receive: Callable, send: Callable) -> None:
"""
1.