uvx flask
This is a neat little trick that I couldn't find documented online. I am working on a small, single-file flask application and looking to keep my workflow as simple as possible. To that end, I am using uvx (shorthand for uv run) to manage my dependencies in an implicit virtualenv:
# /// script
# dependencies = [
# "Flask"
# ]
# ///
This new file format allows me to skip requirements.txt and pyproject.toml, which may not seem like much but keeps my entire software application in one file.
To run the flask devserver, I added the following code:
if __name__ == "__main__":
app.run(debug=True, port=PORT)
And run with uvx app.py.
While this is great for development, I wanted to use gunicorn for production, which presented a challenge: gunicorn is its own command line tool and expects an wsgi application. Typically, running gunicorn for flask looks like:
$ gunicorn --bind 0.0.0.0:PORT --workers N app:app
Naively, I tried:
$ uvx gunicorn --bind 0.0.0.0:PORT --workers N app:app
but with this invocation, uvx only installs gunicorn into the virtualenv, and ignores dependencies in app.py. Browsing the docs, I found uvx --with-requirements <reqs...>, which supports requirements.txt - but moving requirements out of the single file defeats the beauty of my single file application!
On a hunch, I wondered if uvx --with-requirements <reqs...> could read the requirements from the script itself (via the inline metadata), while running a separate tool, as in uvx --with-requirements <script.py> <tool cli> .... This worked! It's possible to define my requirements just once, and run a different tool with uvx, leading to a true single file application experience:
$ uvx --with-requirements app.py gunicorn --bind 0.0.0.0:PORT --workers N app:app
This approach also works with the flask cli, meaning that app.run() can be removed. Tada 🎊
$ uvx --with-requirements app.py flask run --port PORT
tl;dr
uvx is a nifty tool for creating true single file applications (dependencies and all), extending to software served by other tools (e.g. flask web applications). The value of a single file application is subtle: easy to share with others, easy to ship, easy to work with an ai agent.
To run a tool on a script with the script's dependencies:
$ uvx --with-requirements <script.py> <tool cli>