Skip to content

Allow factory kwargs #2445

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

SaravananSathyanandhaQC
Copy link

@SaravananSathyanandhaQC SaravananSathyanandhaQC commented Aug 20, 2024

Summary

Addresses #2377 and #1644

This PR allows passing factory_kwargs to all workers when using uvicorn.run. This is more flexible than using environment variables because it means you can

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

@lekeeith
Copy link

in my test,i can not get worker_kwargs as what i expect.
i have tow py file, run.py and a.py.
run.py as flow

from pathlib import Path
import uvicorn
import a
app = a.app
print("-------- queue  ----------")
if __name__ == '__main__':
    max_workers = 4
    uvicorn.run(f"{Path(a.__file__).stem}:app", host='0.0.0.0', port=8000, reload=True,
        worker_kwargs={"shared_queue": [1, 2, 3, 4]})

a.py as follow

from fastapi import FastAPI
app = FastAPI()

@app.get("/city/{city_id}")
def get_city(city_id: str):
    return {"city_id": city_id, "app": dir(app)}

curl

result

{
  "city_id": "123",
  "app": [
    "__call__",
    "__class__",
    "__delattr__",
    "__dict__",
    "__dir__",
    "__doc__",
    "__eq__",
    "__format__",
    "__ge__",
    "__getattribute__",
    "__gt__",
    "__hash__",
    "__init__",
    "__init_subclass__",
    "__le__",
    "__lt__",
    "__module__",
    "__ne__",
    "__new__",
    "__reduce__",
    "__reduce_ex__",
    "__repr__",
    "__setattr__",
    "__sizeof__",
    "__str__",
    "__subclasshook__",
    "__weakref__",
    "add_api_route",
    "add_api_websocket_route",
    "add_event_handler",
    "add_exception_handler",
    "add_middleware",
    "add_route",
    "add_websocket_route",
    "api_route",
    "build_middleware_stack",
    "contact",
    "debug",
    "delete",
    "dependency_overrides",
    "description",
    "docs_url",
    "exception_handler",
    "exception_handlers",
    "extra",
    "get",
    "head",
    "host",
    "include_router",
    "license_info",
    "middleware",
    "middleware_stack",
    "mount",
    "on_event",
    "openapi",
    "openapi_schema",
    "openapi_tags",
    "openapi_url",
    "openapi_version",
    "options",
    "patch",
    "post",
    "put",
    "redoc_url",
    "root_path",
    "root_path_in_servers",
    "route",
    "router",
    "routes",
    "separate_input_output_schemas",
    "servers",
    "setup",
    "state",
    "summary",
    "swagger_ui_init_oauth",
    "swagger_ui_oauth2_redirect_url",
    "swagger_ui_parameters",
    "terms_of_service",
    "title",
    "trace",
    "url_path_for",
    "user_middleware",
    "version",
    "webhooks",
    "websocket",
    "websocket_route"
  ]
}

in my opinion,i can get shared_queue in app but not.
i use what you changed code.

@SaravananSathyanandhaQC
Copy link
Author

The option only applies when you use the factory option (maybe I should call it factory_kwargs), since then you have a function to return the app, and that function can get kwargs passed. If you use a single app like this then it will not work, it doesn't try to add attributes to the app itself (though that could be an alternate solution too).

If you made your a.py look like the following:

from fastapi import FastAPI

def app_creator(shared_queue = None):
    app = FastAPI()

    @app.get("/city/{city_id}")
    def get_city(city_id: str):
        return {"city_id": city_id, "shared_queue": shared_queue}

    return app

you should see the shared_queue passed.

If you actually intend to use this as a shared queue between workers that has items added/removed (as the variable name suggests at least) you should use a shared memory list or a SyncManager list

@hchargois-ipsos
Copy link

I agree naming the parameter factory_kwargs would be better.

I was going to make that PR myself when I saw it already existed. This feature is a must for being able to use uvicorn.run programmatically without having to resort to workarounds like environment variables to simply pass configuration values to the app.

So, bumping here, hoping this gets merged soon.

@SaravananSathyanandhaQC
Copy link
Author

SaravananSathyanandhaQC commented Jun 5, 2025

I've updated it to factory_kwargs and added those type hints. I continue to work around this with env vars, but this PR would make my code a lot cleaner.

@SaravananSathyanandhaQC SaravananSathyanandhaQC changed the title Allow worker kwargs Allow factory kwargs Jun 6, 2025
@guillaume-mueller
Copy link

Merging this would be a must.

I looked at the changes and find them very clean and straightforward.

Can't wait to use this missing feature.

@MatteoCampinoti94
Copy link

Great work! Simple and clean and it will hopefully get added to the CLI interface as well (only string values ofc, but better than nothing).

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

Successfully merging this pull request may close these issues.

5 participants