asyncron/asyncron/apps.py
Oracle 386fc21f29 Fixed long time issues
A failed attempt to reload gunicorn on html change (so now it's just a draft)
Fixed incompatibility with reload = False
Now we catch the lock getting error instead of just raising it!
2025-08-17 02:59:38 +02:00

144 lines
4.3 KiB
Python

from django.apps import AppConfig
from django.conf import settings
from django.apps import apps
import os, pathlib, importlib, types
import re
import tomllib
class AsyncronConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'asyncron'
label = 'asyncron'
def ready( self ):
try: names = settings.ASYNCRON['IMPORT_PER_APP']
except (KeyError, AttributeError): pass
else: self.import_per_app( names )
#if settings.DEBUG:
# os.environ['PYTHONASYNCIODEBUG'] = "1"
#self.watch_templates_for_reload() Does not Work Rn.
self.load_model_auxilaries()
self.load_extensions()
#Init the asyncron worker for this process
from .workers import AsyncronWorker
#The worker should not start working until they know we're responding to requests.
AsyncronWorker.init()
def import_per_app( self, names ):
for app in apps.get_app_configs():
app_dir = pathlib.Path(app.path)
if app_dir.parent != settings.BASE_DIR: continue
for name in names:
import_file = app_dir / f"{name}.py"
if not import_file.exists() or not import_file.is_file(): continue
#print( f"Loading {app.name}.{name}:", import_file )
loader = importlib.machinery.SourceFileLoader( f"{app.name}.{name}", str(import_file) )
loader.exec_module( types.ModuleType(loader.name) )
def watch_templates_for_reload( self ):
from .gunicorn import post_fork
if not hasattr(post_fork, 'worker'): return
if not post_fork.worker.reloader: return
if not any( tconf.get('APP_DIRS', False) for tconf in settings.TEMPLATES ): return
for app in apps.get_app_configs():
app_templates_dir = pathlib.Path(app.path) / "templates"
if not app_templates_dir.exists(): continue
for dirpath, dirnames, filenames in app_templates_dir.walk():
print("D:", dirpath, dirnames, filenames )
post_fork.worker.reloader.add_extra_file( dirpath )
def load_model_auxilaries( self ):
"""
Loads auxilary (passive) data from the models.toml file of each app.
Data is either a keyword argument of a field, or an allowed Meta class value.
There should be no database defining values set the toml file:
- ModelName.Meta.verbose_name -> Allowed
- ModelName.Meta.unique_together -> Bad Idea / Undefined Behaviour
- ModelName.help_text.a_field_name -> Allowed (string)
- ModelName.null.a_field_name -> Bad Idea / Undefined Behaviour
"""
from .base.models import BaseModel
for app in apps.get_app_configs():
app_dir = pathlib.Path(app.path)
toml_file = app_dir / "models.toml"
if not toml_file.exists(): continue
with open(toml_file, 'rb') as f:
model_auxilaries = tomllib.load(f)
for model in app.get_models():
if not issubclass( model, BaseModel ): continue
if model.__name__ not in model_auxilaries: continue
aux = model_auxilaries[model.__name__]
if 'Meta' in aux:
for k, v in aux.pop('Meta').items():
setattr(model._meta, k, v)
for field_kwarg, field_nv in aux.items():
for field_name, field_kwarg_value in field_nv.items():
if not hasattr(model, field_name): continue
field = getattr(model, field_name).field
if not getattr(field, field_kwarg, None): #Set only as default or empty replacements
setattr(field, field_kwarg, field_kwarg_value)
def load_extensions( self ):
from .base.models import BaseModel
from .extender import Extender
from .gunicorn import post_fork #To add them to auto-reload watch
for app in apps.get_app_configs():
app_dir = pathlib.Path(app.path)
for model in app.get_models():
if not issubclass( model, BaseModel ): continue
ext_dir = app_dir / "extensions" / model.__name__
if not ext_dir.exists(): continue
extender = None
for import_file in ext_dir.iterdir():
if not import_file.is_file(): continue
if import_file.suffixes[-1] != ".py": continue
#So the imported module can attach it's method to the extender created last
if extender is None: extender = Extender( model )
loader = importlib.machinery.SourceFileLoader( f"{app.name}.extensions.{model.__name__}.{import_file.stem}", str(import_file) )
loader.exec_module( types.ModuleType(loader.name) )
if hasattr( post_fork, "worker" ):
try: post_fork.worker.reloader.add_extra_file( str(import_file) )
except: pass
if extender:
extender.attach( model )
Extender.stop_capturing()
#