summaryrefslogtreecommitdiffhomepage
path: root/src/python
diff options
context:
space:
mode:
authorGourav <gouravkandoria1500@gmail.com>2024-06-26 11:14:50 +0530
committerAndrew Clayton <a.clayton@nginx.com>2024-07-02 19:13:14 +0100
commita9aa9e76db2766a681350c09947df848898531f6 (patch)
treeb95692f62e8bce738656740e6fb8fea20fe03b76 /src/python
parentd62a5e2c3749a927e1f5283c1ad2178d665cd399 (diff)
downloadunit-a9aa9e76db2766a681350c09947df848898531f6.tar.gz
unit-a9aa9e76db2766a681350c09947df848898531f6.tar.bz2
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: https://github.com/nginx/unit/issues/1106 Link: <https://github.com/nginx/unit/pull/1336#issuecomment-2179381605> [ Commit message - Dan / Minor code tweaks - Andrew ] Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'src/python')
-rw-r--r--src/python/nxt_python.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c
index 7c059649..aa0f65b1 100644
--- a/src/python/nxt_python.c
+++ b/src/python/nxt_python.c
@@ -403,11 +403,13 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target,
char *callable, *module_name;
PyObject *module, *obj;
nxt_str_t str;
+ nxt_bool_t is_factory = 0;
nxt_conf_value_t *value;
static nxt_str_t module_str = nxt_string("module");
static nxt_str_t callable_str = nxt_string("callable");
static nxt_str_t prefix_str = nxt_string("prefix");
+ static nxt_str_t factory_flag_str = nxt_string("factory");
module = obj = NULL;
@@ -449,7 +451,30 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target,
goto fail;
}
- if (nxt_slow_path(PyCallable_Check(obj) == 0)) {
+ value = nxt_conf_get_object_member(conf, &factory_flag_str, NULL);
+ if (value != NULL) {
+ is_factory = nxt_conf_get_boolean(value);
+ }
+
+ if (is_factory) {
+ if (nxt_slow_path(PyCallable_Check(obj) == 0)) {
+ nxt_alert(task,
+ "factory \"%s\" in module \"%s\" "
+ "can not be called to fetch callable",
+ callable, module_name);
+ goto fail;
+ }
+
+ obj = PyObject_CallObject(obj, NULL);
+ if (nxt_slow_path(PyCallable_Check(obj) == 0)) {
+ nxt_alert(task,
+ "factory \"%s\" in module \"%s\" "
+ "did not return callable object",
+ callable, module_name);
+ goto fail;
+ }
+
+ } else if (nxt_slow_path(PyCallable_Check(obj) == 0)) {
nxt_alert(task, "\"%s\" in module \"%s\" is not a callable object",
callable, module_name);
goto fail;