-
Notifications
You must be signed in to change notification settings - Fork 332
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 request: Support application-factory pattern for Python apps #1106
Comments
Flask supports factory thru the magic name "create_app" or "make_app": https://flask.palletsprojects.com/en/2.3.x/patterns/appfactories/ Personally, I would much prefer factories having zero arguments and then there is a "factory" boolean in the configuration, similar to uvicorn. (I find gunicorn's solution too obscure and flask's too complicated). |
Thank you for filing this; we definitely want to support the application factory pattern. I especially appreciate your linking to gunicorn / uvicorn / Flask docs here. We'll need to have a discussion to decide on the best pattern, but consider this officially on our backlog :) |
@callahad Does this issue need work. would be happy to contribute to it. I have a approach which I tested on my local. Not sure , This is 100% correct or not. Here it is.
For, this need to make change in python related validation object like in and now in the nxt_python_set_target, we can set target, if factory option is there. If support for arguments for application factory need to be given, that can also be achieved with some additional changes |
I think what's missing is the why this is needed? and how does it relate to "app"? if you specify "factory" do you need to specify "app"? |
If you are asking about why the separate "factory" option is needed. So my point is that "callable" by its name suggests that it is some callable which have interface as per wsgi or asgi standard. So, if "factory" as a different option is introduced that would mean it is some callable, if called would return callable supporting wsgi or asgi standard. There can be other way of doing this like, if factory option is passed as true, then the callable should be considered as which factory which when called should return wsgi or asgi supporting callable So, if we go by first way- then below is more explanation so , both the below given config can be said to correct
If we go by the second way then , both the below given config can be said to correct
|
any point or suggestion on it |
OK, thanks, (it didn't help I mixed callable and app up...). But, yes, you wouldn't specify callable & factory (unless you specify factory as true..) So I take it "factory" is some Python terminology? I probably need to go read up on it sometime... |
"Factory" is just software terminology. An "application factory" as input to a server runner is supported in a bunch of python server runners, as already described in the issue description. I am not sure about its prevalence in other languages since I don't have experience developing applications in those. As for the discussion about format, I would personally prefer "callable" to be the path to both factory and app, and a "factory" boolean specifying if it is a factory or not. (The solution called "the second way" above.) |
Heh, not something I've come across in over 25 years in the world of C... ah, it's an OOP thing, well that explains everything... |
If a Java design patterns textbook shows up on your doorstep, it wasn't me 🥸 |
@gourav-kandoria If you have a patch, would you mind opening a pull request? Even if it's unpolished, having something concrete is a great starting point.
That's probably my biggest question at the moment. Honestly, my next step that I just haven't gotten around to yet is to survey how other WSGI/ASGI servers handle this pattern. If someone wants to do that research and write up a quick summary, I'd really appreciate it. I guess I'd at least look at gunicorn, uWSGI, and mod_wsgi on the WSGI side, and uvicorn, hypercorn, and daphne on the ASGI side? |
(Admittedly, I'm just cribbing from memory on the WSGI side and riffing off the Starlette docs for ASGI. If there are other popular servers not represented, do let me know) |
I could use a door stop! |
|
|
So, it seems:
I find myself agreeing with @bunny-therapist's sensibilities:
"Explicit is better than implicit," right? |
Concretely: Let's add an optional "hello": {
"module": "hello",
"callable": "create_app",
"factory": true
} To align with common usage, we may want to consider supporting |
This adds support for 'Application Factories' to the Python language module. This essentially allows you to run some code _before_ the main application is loaded. This is similar to the '--factory' setting in Uvicorn. It can be configured like "python-app": { "type": "python", "path": "/srv/www", "module": "create_app", "factory": true } The factory setting defaults to false. Closes: nginx#1106 [ Commit subject, message and some minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
This adds support for 'Application Factories' to the Python language module. This essentially allows you to run some code _before_ the main application is loaded. This is similar to the '--factory' setting in Uvicorn. It can be configured like "python-app": { "type": "python", "path": "/srv/www", "module": "create_app", "factory": true } The factory setting defaults to false. Closes: nginx#1106 [ Commit subject, message and some minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Amusingly, uWSGI does seem to support factories in the gunicorn style (appending |
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]> python: Support application factories Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable 4. When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable 4. When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable 4. When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable or When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable or When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable or When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
Adds support for the app factory pattern to the Python language module. A factory is a callable that returns a WSGI or ASGI application object. Unit does not support passing arguments to factories. Setting the `factory` option to `true` instructs Unit to treat the configured `callable` as a factory. For example: "my-app": { "type": "python", "path": "/srv/www/", "module": "hello", "callable": "create_app", "factory": true } This is similar to other WSGI / ASGI servers. E.g., $ uvicorn --factory hello:create_app $ gunicorn 'hello:create_app()' The factory setting defaults to false. Closes: nginx#1106 Link: <nginx#1336 (comment)> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <[email protected]>
…fig" Add the following tests cases: 1. When "factory" key is used inside the "targets" option. 2. When "factory" key is used at the root level of python application config. 3. When factory returns invalid callable or When factory is invalid callable Closes: nginx#1106 Link: <nginx#1336> Signed-off-by: Andrew Clayton <[email protected]>
"Application factory" means that the "app" object in your python code that you are passing to unit is not the app itself, but a callable that needs to be called to create the app, i.e.
the_actual_app = app()
.Uvicorn supports this with the
--factory
option: https://www.uvicorn.org/settings/Gunicorn also supports this by specifying the app with parentheses: "app()": https://flask.palletsprojects.com/en/3.0.x/deploying/gunicorn/#running
It would be nice if unit supported this for Python apps (WSGI and ASGI). I looked in the documentation but could not find anything about this, and I could not get it to work, so I assume it is currently not supported by unit.
The text was updated successfully, but these errors were encountered: