Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Allow custom folder locations (and thoughts on how to solve it by refactoring a lot of how py4web handles apps) #947

Open
laundmo opened this issue Dec 3, 2024 · 0 comments

Comments

@laundmo
Copy link
Contributor

laundmo commented Dec 3, 2024

static

In _scaffold and a few other example apps, the static folder is defined in settings.py like this:

STATIC_FOLDER = required_folder(APP_FOLDER, "static")

This setting is never used anywhere, and is completely skipped by the fact Reloader.import_app has a static path of <appname>/static/<path>, hardcoded here:

py4web/py4web/core.py

Lines 1445 to 1450 in e9f28a5

static_folder = os.path.join(path, "static")
if os.path.exists(static_folder):
app_name = path.split(os.path.sep)[-1]
prefix = "" if app_name == "_default" else f"/{app_name}"
path = prefix + r"/static/<re((_\d+(\.\d+){2}/)?)><fp.path()>"

templates

Theres no settings.py setting for templates yet. The template path is hardcoded by a combination of the Template.on_success method:

py4web/py4web/core.py

Lines 619 to 624 in e9f28a5

app_folder = os.path.join(os.environ["PY4WEB_APPS_FOLDER"], request.app_name)
path = self.path or os.path.join(app_folder, "templates")
filename = os.path.join(path, self.filename)
if not os.path.exists(filename):
generic_filename = os.path.join(path, "generic.html")
if os.path.exists(generic_filename):

And the fact instances of Template are created based on a str in action.uses:
if isinstance(fixture, str):

This means using the normal way of adding templates, by using a str as an argument to action.uses, it's impossible to set the Template.path attribute. To change the Template base path, a user would have to explicitly create Template instances for each individual controller.

issues

Currently, py4web only seems to separate multiple apps by their routes in Reloader. Any global values py4web exposes are either utilizing thread locals scoped to the request, or are potentially shared between all apps. This means a simple global variable which the user can overwrite would change this variable for every app.

solution

One possible solution, which I quite like, would be a App class which owns app-specific configuration. For new apps, this would be instantiated in common.py and passed the relevant information like static path, template path, and possibly other per-app config.

py4web could store instances of App by app_name, where each App instance stores its own routes, error handlers, and possibly other related data (ICECUPE? a bottle application object?).

action could then be a method or property of App. For easier migration, users could set action = myapp.action in common.py and import this instead of py4web.action in controllers.

The App object could also define methods for Reloader to use, like App.unload() which removes this instances routes and maybe even unloads the modules, and App.load() which implements some of what Reloader.import_app() currently does, like registering the static route (this is one way the static path could be read from the App instance)
Doing reloading like this could allow for easily implementing a pre_unload callback, for apps to do their own clean-up before they're reloaded.

To maintain backwards compatibility without any user interaction, py4web could define action using a (subclass) of App containing the current default logic, then expose the normal action with action = default_app.action.

A App class like this with an instance per App, would also allow easily defining other utilities like global Template helpers which are currently made more difficult by the fact theres no way to store per-app data.

@laundmo laundmo changed the title Feature: Allow custom static files folder location Feature: Allow custom static folder location Dec 3, 2024
@laundmo laundmo changed the title Feature: Allow custom static folder location Feature: Allow custom folder locations Dec 3, 2024
@laundmo laundmo changed the title Feature: Allow custom folder locations Feature: Allow custom folder locations (and thoughts on how to solve it by refactoring a lot of how py4web handles apps) Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant