Python advice requested:

I need to include a small test program, written in Python, in a repository containing other software not in Python. The program will have multiple source files and use dependencies from PyPI, but does not need to be installed anywhere. The expected usage is to just run it directly from the directory where it lives.

Is there a suitable tool to use to run it which will create a temporary virtual environment, install the dependencies, run the program, and then clean that stuff up?

#Python

Thanks for all the replies! It appears that 'uv', with its support for PEP 723, will be the way to go here.

Confirmed: uv meets my needs. Here's a tiny example:

https://forge.km6g.us/kpfleming/muart-failsafe/src/branch/stm32-firmware/prototest/prototest.py

This uses PEP 723 inline metadata and 'uv run', and includes two dependencies and three local modules. It also has a shebang line so that the user can just run `./prototest.py`, and the only requirement is that they have a suitably-recent version of 'uv' installed and available.

muart-failsafe/prototest/prototest.py at stm32-firmware

muart-failsafe - Failsafe hardware for use with the MUART project

KM6G Software Forge

@kevin I'm not sure if you'll get the automatic cleanup, at least not by default, but other than that: this sounds like a task for any of
- pipenv, using `pipenv run <file.py>`
- pdm in its non-installable project mode, also using `pdm run <file.py>`
- uv, probably (I don't actually know if it can do this but it tries to do everything so I'd imagine it can)

#Python

@diazona @kevin not sure about pipenv, but I *don't think* PDM would create a venv and install deps with just `pdm run`.

I would definitely recommend `uv run --script program.py` (which will do all that) as well as writing the dependencies directly in program.py, see https://packaging.python.org/en/latest/specifications/inline-script-metadata/#example.

Inline script metadata - Python Packaging User Guide

@pawamoy @kevin I thought about recommending pip-run, which does the same thing, but the OP mentioned it being multiple source files which I think rules that out.

#Python

@diazona @kevin yeah I'm not sure how `uv run --script` will behave either with multiple modules :) Try and let us know @kevin 😄

You've got conflicting requirements here @kevin.

By depending on third-party libraries, you do need an install step, which installs your Python program along with its dependencies, as a coherent whole.

So I think you can't also have "the program doesn't need to be installed anywhere"; yeah, it does, otherwise it's just a file sitting on the disk. It needs to be installed before the recipient can use it as a program.

You did this too, @kevin: you *manually* did the job of an installer (getting the search path right, installing dependency modules, ensuring other dependencies are set up).

The recipient of your repository can't reliably be expected to have that; all they've got is your files, somewhere arbitrary on their filesystem. You need to arrange that reliable environment, with an build-and-install step. Typically you configure that with the Package Metadata file, 'pyproject.toml'.

@bignose @kevin I’m reading it as Kevin saying it’s not a requirement to create an *installable* version of the tool for third parties to use.
Running scripts | uv

A guide to using uv to run Python scripts, including support for inline dependency metadata, reproducible scripts, and more.

@aoristdual Interesting! When I first heard about this it was always referred to as 'single file scripts' so I wonder if it will work with local modules.

@kevin @aoristdual Yeah, you just need to make sure you list all the PyPI dependencies of local modules in the main file you run.

For example, this deploy calls "uv run generate_metadata.py"
https://github.com/python-docs-translations/dashboard/blob/a6586fb364c837ce38cc5df6b992569db93bd763/.github/workflows/update.yml#L59

Here's its inline script metadata:
https://github.com/python-docs-translations/dashboard/blob/a6586fb364c837ce38cc5df6b992569db93bd763/generate_metadata.py#L1-L12

Which includes things like potodo, needed for another local import.
#Python #uv

dashboard/.github/workflows/update.yml at a6586fb364c837ce38cc5df6b992569db93bd763 · python-docs-translations/dashboard

List of translation projects of the Python documentation - python-docs-translations/dashboard

GitHub
@kevin uv can run scripts with in-line dependencies:
https://docs.astral.sh/uv/guides/scripts/
Running scripts | uv

A guide to using uv to run Python scripts, including support for inline dependency metadata, reproducible scripts, and more.

@kevin Have you looked at Pipx ? https://github.com/pypa/pipx
GitHub - pypa/pipx: Install and Run Python Applications in Isolated Environments

Install and Run Python Applications in Isolated Environments - pypa/pipx

GitHub
@technikhil Yes, I use it regularly! It's just not a good fit for this situation.

@kevin maybe you could look at mise-en-place https://mise.jdx.dev/ it helps with automating such tasks as well as automating everything needed for a repository.

We use it to setup venvs if they don'T exist, update dependencies, in one project we even use it to call on tofu to build Infrastructure for testing.

Home | mise-en-place

mise-en-place documentation

mise-en-place
Running scripts | uv

A guide to using uv to run Python scripts, including support for inline dependency metadata, reproducible scripts, and more.

@kevin uv can do that (not sure about removal , the rest it can do)