Published 2021-04-09.
Last modified 2024-06-10.
Time to read: 6 minutes.
Python virtual environments are cheap to make and use – unless you are unfortunate enough to program in native Windows. I have adopted the habit of making a Python virtual environment (venv) for each significant Python project, plus a default venv for trivial Python work.
Why Virtualize Python?
It is better to use virtualized user- and project-specific Python instances, instead of working with a system-wide installation of Python. This allows you to install and upgrade Python packages without using supervisor privileges. Also, virtualized instances allows you to work on many different independent Python projects at the same time, without package version collisions.
Docker
is over-sold.
It adds unnecessary complexity to software projects.
Instead of virtualizing the entire software environment,
as docker
attempts to do,
virtualizing the Python programming environment as described in this article,
Ruby rbenv
,
or node.js nvm
are much easier and more productive approaches.
I think docker
has been pushed hard in the media because it is a gateway technology to
PaSS.
This is a trend that PaSS vendors like AWS and Azure want to encourage, but
customers are pushing back.
Python’s venv Virtualization Module
Venv
is a tool to create isolated virtual Python environments.
It has been included with Python since Python v3.3,
which was released 12 years ago.
PEP 405 specifies Python’s
venv
virtualization module.
Deprecated Virtualization Modules
Python 3.6 was released 7 years ago.
It deprecated the other virtualization modules,
pyenv
and
virtualenv
.
Instead, use venv
, as described in this article.
Extra Installation Steps for Ubuntu
Venv
was included with Python on Ubuntu until Ubuntu 23.04
It virtualizes all the common Python executables.
Debian changed pip
’s behavior
as a result of
PEP 668 – Marking Python base environments as “externally managed”.
This affects Ubuntu because it is downstream.
Starting with Ubuntu 23.04, you need to install venv
by typing:
$ yes | sudo apt install python3.xx-venv
... where xx
is the minor version number of Python that is installed.
For Python 3.12, provided with Ubuntu 24.04 (Noble Numbat), the following incantation is required:
$ yes | sudo apt install python3.12-venv
For Python 3.11, provided with Ubuntu 23.10 (Mantic Minotaur), the following incantation is required:
$ yes | sudo apt install python3.11-venv
Some software projects use meta-packages to specify version-agnostic dependencies. Perhaps Python on Ubuntu will do so in the future.
In order to virtualize pip
, venv
needs to invoke ensurepip
,
which is not installed by default on Ubuntu.
On Ubuntu systems, the ensurepip
command is provided by a package called python3-pip
.
$ yes | sudo apt install python3-pip
You could install both of the above packages together, of course:
$ yes | sudo apt install python3.12-venv python3-pip
Manually Creating a VEnv
The following demonstrates how to create a new virtual python environment in the ~/venv/default/
directory.
Intermediate directories, such as venv
in this example, will be created as required.
$ python3 -m venv ~/venv/default
At this point, the virtual environment just contained executable images for Python.
$ ls ~/venv/default/** /home/mslinn/venv/default/lib64@ /home/mslinn/venv/default/pyvenv.cfg /home/mslinn/venv/default/bin: Activate.ps1 activate activate.csh activate.fish pip* pip3* pip3.10* python@ python3@ python3.10@ /home/mslinn/venv/default/include: /home/mslinn/venv/default/lib: python3.10/
Upgrading Python
Re-installing the venv
at a later date will update the version of Python in the venv
.
You will also need to install the appropriate python3-venv
package when upgrading Python.
Each time you (re)install a virtual environment, all pip
packages are removed.
To prevent the loss of your installed pip
packages,
use pip freeze
before upgrading Ubuntu,
so the pip packages are memorialized in requirements.txt
.
After upgrading Python, run pip install
to re-install the pip
packages.
The following incantation runs pip freeze
on every directory under ~/venv
,
and creates a file called requirements.txt
in each venv
directory:
$ find ~/venv -maxdepth 1 -mindepth 1 -type d -print0 |
while IFS= read -r -d '' DIR; do
source "$DIR/bin/activate"
pip freeze > "$DIR/requirements.txt"
done
The above incantation should be performed for each of your Python venvs before you upgrade Ubuntu, because sometimes Python venvs do not work after an upgrade. The next step should fix Python venvs that broke during an Ubuntu upgrade.
Here is an example showing the commands that must be typed to upgrade Python from v3.11 to v3.12, which you will have to do when upgrading from Ubuntu 23.10 to Ubuntu 24.04. Scroll the code window to see all the commands:
$ yes | sudo apt install python3.12-venv Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: python3.12-venv 0 upgraded, 1 newly installed, 0 to remove and 4 not upgraded. Need to get 5676 B of archives. After this operation, 28.7 kB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu noble/universe amd64 python3.12-venv amd64 3.12.3-1 [5676 B] Fetched 5676 B in 0s (31.1 kB/s) Selecting previously unselected package python3.12-venv. (Reading database ... 444385 files and directories currently installed.) Preparing to unpack .../python3.12-venv_3.12.3-1_amd64.deb ... Unpacking python3.12-venv (3.12.3-1) ... Setting up python3.12-venv (3.12.3-1) ... Scanning processes...
No services need to be restarted.
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
$ find ~/venv -maxdepth 1 -type d -print0 | while IFS= read -r -d '' DIR; do python3 -m venv "$DIR" source "$DIR/bin/activate" pip install -r "$DIR/requirements.txt" done
VEnvs are Nearly Free
The cost of a venv is virtually free for all OSes except native Windows. This is because on all OSes except native Windows, the executable images are linked by default, so they do not require much storage space.
The ls
command below shows that the python
program in the default
venv
is linked to /usr/bin/python3.10
.
$ ls -go ~/venv/default/bin/python lrwxrwxrwx 1 18 Apr 9 06:01 /home/mslinn/venv/default/bin/python -> python3*
Create a VEnv for Every Python Project
My projects are stored under the directory pointed to by $work
.
My standard procedure when making a Python project called $work/blah
is to also create a venv for it at within the project, at $work/blah/.venv/
.
I add an entry to .gitignore
that merely consists of a line that says .venv/
.
A bash alias could be defined called blah
that makes the project directory current and activates the venv:
alias blah="cd $work/blah; source ./venv/bin/activate"
Now you could type blah
at a shell prompt,
and you would be working on that project.
Boom!
Deactivate a VEnv
Stop using venvs with deactivate
.
Notice that the prompt changes.
(aw) $ deactivate $
Directory-Locked Python Virtualization
After setting up a Python virtual environment,
a quick examination of the pip
script
shows that it is hard-coded to the directory that it was made for:
$ head -n 1 ~/venv/aw/bin/pip #!/home/mslinn/venv/aw/bin/python
For virtualized environments, such as Docker, this means that a Python virtual environment created without Docker can only be used within a Docker image if the path to it is the same from within the Docker image as when it was created.
Poetry and Python Virtual Environments
Python venvs are a good way to isolate Python programs from each other, so their dependencies do not clash.
The two best-known package managers for Python are
PIP
and Poetry.
PIP
is bundled with Python, while Poetry needs to be explicitly installed.
Python venvs use links to provide virtualized Python commands.
Inside each venv
, you will find links to programs like python
, pip
and library dependencies for every project that installs dependencies while the venv
is active.
Poetry can:
- Create a venv in
.venv
- Install specified library dependencies
- Run the program using the venv dependencies
- Publish the Python package.
Installing Poetry
If you are not careful, installing Poetry could be a
chicken-and-egg race condition.
You do not want Poetry to be a dependency of the venv
that it manages,
because it is designed to manage the libraries within the venv
.
Poetry has a custom installer that creates a dedicated virtual environment for itself, and operates independently from other Python-related mechanisms. This isolated environment prevents unintentional upgrades or removals of dependencies, allowing Poetry to manage its own dependencies properly.
While it is possible to install Poetry using PIP within a venv, it is better to install Poetry system-wide. The Setup section below discusses how to do that.
PIP dependencies are often specified in a file called requirements.txt
.
This file ensures that a Python project uses the correct versions of dependencies
by listing all the packages and their versions.
Poetry uses a file called poetry.lock
for the same purpose.
In addition to the names and versions of the dependencies, poetry.lock
also specifies the hashes of the dependant source files.
Poetry Help Messages
The top-level help message for Poetry is:
$ poetry --help Description: Lists commands.
Usage: list [options] [--] [<namespace>]
Arguments: namespace The namespace name
Options: -h, --help Display help for the given command. When no command is given display help for the list command. -q, --quiet Do not output any message. -V, --version Display this application version. --ansi Force ANSI output. --no-ansi Disable ANSI output. -n, --no-interaction Do not ask any interactive question. --no-plugins Disables plugins. --no-cache Disables Poetry source caches. -C, --directory=DIRECTORY The working directory for the Poetry command (defaults to the current working directory). -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug.
Help: The list command lists all commands:
poetry list
You can also display the commands for a specific namespace:
poetry list test
The Poetry commands are:
$ poetry list Poetry (version 1.7.1)
Usage: command [options] [arguments]
Options: -h, --help Display help for the given command. When no command is given display help for the list command. -q, --quiet Do not output any message. -V, --version Display this application version. --ansi Force ANSI output. --no-ansi Disable ANSI output. -n, --no-interaction Do not ask any interactive question. --no-plugins Disables plugins. --no-cache Disables Poetry source caches. -C, --directory=DIRECTORY The working directory for the Poetry command (defaults to the current working directory). -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug.
Available commands: about Shows information about Poetry. add Adds a new dependency to pyproject.toml. build Builds a package, as a tarball and a wheel by default. check Validates the content of the pyproject.toml file and its consistency with the poetry.lock file. config Manages configuration settings. export Exports the lock file to alternative formats. help Displays help for a command. init Creates a basic pyproject.toml file in the current directory. install Installs the project dependencies. list Lists commands. lock Locks the project dependencies. new Creates a new Python project at <path>. publish Publishes a package to a remote repository. remove Removes a package from the project dependencies. run Runs a command in the appropriate environment. search Searches for packages on remote repositories. shell Spawns a shell within the virtual environment. show Shows information about packages. update Update the dependencies as according to the pyproject.toml file. version Shows the version of the project or bumps it when a valid bump rule is provided.
cache cache clear Clears a Poetry cache by name. cache list List Poetry's caches.
debug debug info Shows debug information. debug resolve Debugs dependency resolution.
env env info Displays information about the current environment. env list Lists all virtualenvs associated with the current project. env remove Remove virtual environments associated with the project. env use Activates or creates a new virtualenv for the current project.
self self add Add additional packages to Poetry's runtime environment. self install Install locked packages (incl. addons) required by this Poetry installation. self lock Lock the Poetry installation's system requirements. self remove Remove additional packages from Poetry's runtime environment. self show Show packages from Poetry's runtime environment. self show plugins Shows information about the currently installed plugins. self update Updates Poetry to the latest version.
source source add Add source configuration for project. source remove Remove source configured for the project. source show Show information about sources configured for the project.
Detecting a Venv
Active virtual environments suppress Poetry’s behavior.
For example:
$ poetry shell Virtual environment already activated: /home/mslinn/venv/default
If you want to use Poetry on a project, deactivate any active virtual environment before attempting to work on the project.
$ deactivate
Here is a fragment of a script that detects if a venv is active, and disables it if so:
# Disable any activated virtual environment VENV="$( dirname "$( which virtualenv)" )" if [ -d "$VENV" ]; then source "$VENV/activate" && deactivate; fi
Setup
The optimal process for setting up Poetry for use in a project is:
-
Install Poetry, preferably system-wide.
I used
apt
to install thepoetry
package.
Shell$ yes | sudo apt install python3-poetry
-
Configure Poetry to manage the libraries within the
venv
. Thepoetry config
help message is shown below. - Use Poetry to install the library dependencies.
- Use Poetry to run the program using the dependencies in the venv, and/or to spawn a command-line subshell that provides access to the dependencies managed by Poetry.
The help information for the poetry config
command is:
$ poetry config --help Description: Manages configuration settings.
Usage: config [options] [--] [<key> [<value>...]]
Arguments: key Setting key. value Setting value.
Options: --list List configuration settings. --unset Unset configuration setting. --local Set/Get from the project's local configuration. -h, --help Display help for the given command. When no command is given display help for the list command. -q, --quiet Do not output any message. -V, --version Display this application version. --ansi Force ANSI output. --no-ansi Disable ANSI output. -n, --no-interaction Do not ask any interactive question. --no-plugins Disables plugins. --no-cache Disables Poetry source caches. -C, --directory=DIRECTORY The working directory for the Poetry command (defaults to the current working directory). -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug.
Help: This command allows you to edit the poetry config settings and repositories.
To add a repository:
poetry config repositories.foo https://bar.com/simple/
To remove a repository (repo is a short alias for repositories):
poetry config --unset repo.foo
Initializing the Poetry .venv
Imagine you have a Python project stored in $my_project
.
$ cd $my_project
poetry install
The poetry install
subcommand installs dependencies specified in poetry.lock
,
within the venv.
The help information for the poetry install
command is:
$ poetry install --help Description: Installs the project dependencies.
Usage: install [options]
Options: --without=WITHOUT The dependency groups to ignore. (multiple values allowed) --with=WITH The optional dependency groups to include. (multiple values allowed) --only=ONLY The only dependency groups to include. (multiple values allowed) --no-dev Do not install the development dependencies. (Deprecated) --sync Synchronize the environment with the locked packages and the specified groups. --no-root Do not install the root package (the current project). --no-directory Do not install any directory path dependencies; useful to install dependencies without source code, e.g. for caching of Docker layers) --dry-run Output the operations but do not execute anything (implicitly enables --verbose). --remove-untracked Removes packages not present in the lock file. (Deprecated) -E, --extras=EXTRAS Extra sets of dependencies to install. (multiple values allowed) --all-extras Install all extra dependencies. --only-root Exclude all dependencies. --compile Compile Python source files to bytecode. (This option has no effect if modern-installation is disabled because the old installer always compiles.) -h, --help Display help for the given command. When no command is given display help for the list command. -q, --quiet Do not output any message. -V, --version Display this application version. --ansi Force ANSI output. --no-ansi Disable ANSI output. -n, --no-interaction Do not ask any interactive question. --no-plugins Disables plugins. --no-cache Disables Poetry source caches. -C, --directory=DIRECTORY The working directory for the Poetry command (defaults to the current working directory). -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug.
Help: The install command reads the poetry.lock file from the current directory, processes it, and downloads and installs all the libraries and dependencies outlined in that file. If the file does not exist it will look for pyproject.toml and do the same.
poetry install
By default, the above command will also install the current project. To install only the dependencies and not including the current project, run the command with the --no-root option like below:
poetry install --no-root
Here is an example of using poetry install
.
$ poetry install --with local Creating virtualenv private-gpt in /mnt/f/work/my_project/.venv
Created Files
The first time that Poetry does something, e.g. when the poetry install
or
poetry shell
subcommands are run,
Poetry creates a file in the project directory called poetry.toml
.
As an example, if your Python project is stored in /mnt/
,
poetry.toml
will contain:
[virtualenvs] create = true in-project = true path = "/mnt/c/work/my_project/.venv"
A file called .venv/pyvenv.cfg
is also created, which looks like this:
home = /usr/bin implementation = CPython version_info = 3.11.6.final.0 virtualenv = 20.24.1+ds include-system-site-packages = false base-prefix = /usr base-exec-prefix = /usr base-executable = /usr/bin/python3 prompt = my_project-py3.11
poetry run
The poetry run
subcommand runs Python programs and scripts with the virtual environment managed by Poetry.
$ poetry run python my_program
If the first line of a script is the shebang for running Python, like this:
#!/usr/bin/env python3
... then we do not need to specify python
or python3
on the command line.
$ poetry run my_script_containg_shebang
poetry shell
You could spawn a subshell
that provides access to the dependencies managed by Poetry with the poetry shell
subcommand:
$ poetry shell Creating virtualenv my_project in /mnt/f/work/evelyn/my_project/.venv Spawning shell within /mnt/f/work/my_project/.venv . /mnt/f/work/my_project/.venv/bin/activate . /mnt/f/work/my_project/.venv/bin/activate
To deactivate the virtual environment, and exit this new shell,
type CTRL-D or exit
.
poetry show --tree
You can view all the dependencies for a Poetry project like this:
$ poetry show --tree black 22.12.0 The uncompromising code formatter. ├── click >=8.0.0 │ └── colorama * ├── mypy-extensions >=0.4.3 ├── pathspec >=0.9.0 └── platformdirs >=2 boto3 1.34.2 The AWS SDK for Python ├── botocore >=1.34.2,<1.35.0 │ ├── jmespath >=0.7.1,<2.0.0 │ ├── python-dateutil >=2.1,<3.0.0 │ │ └── six >=1.5 │ └── urllib3 >=1.25.4,<2.1 ├── jmespath >=0.7.1,<2.0.0 └── s3transfer >=0.9.0,<0.10.0 └── botocore >=1.33.2,<2.0a.0 ├── jmespath >=0.7.1,<2.0.0 ├── python-dateutil >=2.1,<3.0.0 │ └── six >=1.5 └── urllib3 >=1.25.4,<2.1 chromadb 0.4.20 Chroma. ├── bcrypt >=4.0.1 ├── chroma-hnswlib 0.7.3 │ └── numpy * ├── fastapi >=0.95.2 │ ├── anyio >=3.7.1,<4.0.0 │ │ ├── idna >=2.8 │ │ └── sniffio >=1.1 │ ├── email-validator >=2.0.0 │ │ ├── dnspython >=2.0.0 │ │ └── idna >=2.0.0 (circular dependency aborted here) │ ├── httpx >=0.23.0 │ │ ├── anyio * (circular dependency aborted here) │ │ ├── certifi * │ │ ├── h2 >=3,<5 │ │ │ ├── hpack >=4.0,<5 │ │ │ └── hyperframe >=6.0,<7 │ │ ├── httpcore ==1.* │ │ │ ├── certifi * (circular dependency aborted here) │ │ │ └── h11 >=0.13,<0.15 │ │ ├── idna * (circular dependency aborted here) │ │ └── sniffio * (circular dependency aborted here) │ ├── itsdangerous >=1.1.0 │ ├── jinja2 >=2.11.2 │ │ └── markupsafe >=2.0 │ ├── orjson >=3.2.1 │ ├── pydantic >=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0 │ │ ├── annotated-types >=0.4.0 │ │ ├── pydantic-core 2.14.5 │ │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ │ └── typing-extensions >=4.6.1 (circular dependency aborted here) │ ├── pydantic-extra-types >=2.0.0 │ │ └── pydantic >=2.0.3 (circular dependency aborted here) │ ├── pydantic-settings >=2.0.0 │ │ ├── pydantic >=2.3.0 (circular dependency aborted here) │ │ └── python-dotenv >=0.21.0 │ ├── python-multipart >=0.0.5 │ ├── pyyaml >=5.3.1 │ ├── starlette >=0.27.0,<0.28.0 │ │ └── anyio >=3.4.0,<5 (circular dependency aborted here) │ ├── typing-extensions >=4.5.0 (circular dependency aborted here) │ ├── ujson >=4.0.1,<4.0.2 || >4.0.2,<4.1.0 || >4.1.0,<4.2.0 || >4.2.0,<4.3.0 || >4.3.0,<5.0.0 || >5.0.0,<5.1.0 || >5.1.0 │ └── uvicorn >=0.12.0 │ ├── click >=7.0 │ │ └── colorama * │ ├── colorama >=0.4 (circular dependency aborted here) │ ├── h11 >=0.8 (circular dependency aborted here) │ ├── httptools >=0.5.0 │ ├── python-dotenv >=0.13 (circular dependency aborted here) │ ├── pyyaml >=5.1 (circular dependency aborted here) │ ├── uvloop >=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1 │ ├── watchfiles >=0.13 │ │ └── anyio >=3.0.0 (circular dependency aborted here) │ └── websockets >=10.4 ├── grpcio >=1.58.0 ├── importlib-resources * ├── kubernetes >=28.1.0 │ ├── certifi >=14.05.14 │ ├── google-auth >=1.0.1 │ │ ├── cachetools >=2.0.0,<6.0 │ │ ├── pyasn1-modules >=0.2.1 │ │ │ └── pyasn1 >=0.4.6,<0.6.0 │ │ └── rsa >=3.1.4,<5 │ │ └── pyasn1 >=0.1.3 (circular dependency aborted here) │ ├── oauthlib >=3.2.2 │ ├── python-dateutil >=2.5.3 │ │ └── six >=1.5 │ ├── pyyaml >=5.4.1 │ ├── requests * │ │ ├── certifi >=2017.4.17 (circular dependency aborted here) │ │ ├── charset-normalizer >=2,<4 │ │ ├── idna >=2.5,<4 │ │ └── urllib3 >=1.21.1,<3 │ ├── requests-oauthlib * │ │ ├── oauthlib >=3.0.0 (circular dependency aborted here) │ │ └── requests >=2.0.0 (circular dependency aborted here) │ ├── six >=1.9.0 (circular dependency aborted here) │ ├── urllib3 >=1.24.2,<2.0 (circular dependency aborted here) │ └── websocket-client >=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0 ├── mmh3 >=4.0.1 ├── numpy >=1.22.5 ├── onnxruntime >=1.14.1 │ ├── coloredlogs * │ │ └── humanfriendly >=9.1 │ │ └── pyreadline3 * │ ├── flatbuffers * │ ├── numpy >=1.21.6 │ ├── packaging * │ ├── protobuf * │ └── sympy * │ └── mpmath >=0.19 ├── opentelemetry-api >=1.2.0 │ ├── deprecated >=1.2.6 │ │ └── wrapt >=1.10,<2 │ └── importlib-metadata >=6.0,<7.0 │ └── zipp >=0.5 ├── opentelemetry-exporter-otlp-proto-grpc >=1.2.0 │ ├── backoff >=1.10.0,<3.0.0 │ ├── deprecated >=1.2.6 │ │ └── wrapt >=1.10,<2 │ ├── googleapis-common-protos >=1.52,<2.0 │ │ └── protobuf >=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0 │ ├── grpcio >=1.0.0,<2.0.0 │ ├── opentelemetry-api >=1.15,<2.0 │ │ ├── deprecated >=1.2.6 (circular dependency aborted here) │ │ └── importlib-metadata >=6.0,<7.0 │ │ └── zipp >=0.5 │ ├── opentelemetry-exporter-otlp-proto-common 1.21.0 │ │ ├── backoff >=1.10.0,<3.0.0 (circular dependency aborted here) │ │ └── opentelemetry-proto 1.21.0 │ │ └── protobuf >=3.19,<5.0 (circular dependency aborted here) │ ├── opentelemetry-proto 1.21.0 (circular dependency aborted here) │ └── opentelemetry-sdk >=1.21.0,<1.22.0 │ ├── opentelemetry-api 1.21.0 (circular dependency aborted here) │ ├── opentelemetry-semantic-conventions 0.42b0 │ └── typing-extensions >=3.7.4 ├── opentelemetry-instrumentation-fastapi >=0.41b0 │ ├── opentelemetry-api >=1.12,<2.0 │ │ ├── deprecated >=1.2.6 │ │ │ └── wrapt >=1.10,<2 │ │ └── importlib-metadata >=6.0,<7.0 │ │ └── zipp >=0.5 │ ├── opentelemetry-instrumentation 0.42b0 │ │ ├── opentelemetry-api >=1.4,<2.0 (circular dependency aborted here) │ │ ├── setuptools >=16.0 │ │ └── wrapt >=1.0.0,<2.0.0 (circular dependency aborted here) │ ├── opentelemetry-instrumentation-asgi 0.42b0 │ │ ├── asgiref >=3.0,<4.0 │ │ ├── opentelemetry-api >=1.12,<2.0 (circular dependency aborted here) │ │ ├── opentelemetry-instrumentation 0.42b0 (circular dependency aborted here) │ │ ├── opentelemetry-semantic-conventions 0.42b0 │ │ └── opentelemetry-util-http 0.42b0 │ ├── opentelemetry-semantic-conventions 0.42b0 (circular dependency aborted here) │ └── opentelemetry-util-http 0.42b0 (circular dependency aborted here) ├── opentelemetry-sdk >=1.2.0 │ ├── opentelemetry-api 1.21.0 │ │ ├── deprecated >=1.2.6 │ │ │ └── wrapt >=1.10,<2 │ │ └── importlib-metadata >=6.0,<7.0 │ │ └── zipp >=0.5 │ ├── opentelemetry-semantic-conventions 0.42b0 │ └── typing-extensions >=3.7.4 ├── overrides >=7.3.1 ├── posthog >=2.4.0 │ ├── backoff >=1.10.0 │ ├── monotonic >=1.5 │ ├── python-dateutil >2.1 │ │ └── six >=1.5 │ ├── requests >=2.7,<3.0 │ │ ├── certifi >=2017.4.17 │ │ ├── charset-normalizer >=2,<4 │ │ ├── idna >=2.5,<4 │ │ └── urllib3 >=1.21.1,<3 │ └── six >=1.5 (circular dependency aborted here) ├── pulsar-client >=3.1.0 │ └── certifi * ├── pydantic >=1.9 │ ├── annotated-types >=0.4.0 │ ├── pydantic-core 2.14.5 │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ └── typing-extensions >=4.6.1 (circular dependency aborted here) ├── pypika >=0.48.9 ├── pyyaml >=6.0.0 ├── requests >=2.28 │ ├── certifi >=2017.4.17 │ ├── charset-normalizer >=2,<4 │ ├── idna >=2.5,<4 │ └── urllib3 >=1.21.1,<3 ├── tenacity >=8.2.3 ├── tokenizers >=0.13.2 │ └── huggingface-hub >=0.16.4,<1.0 │ ├── filelock * │ ├── fsspec >=2023.5.0 │ │ ├── aiohttp <4.0.0a0 || >4.0.0a0,<4.0.0a1 || >4.0.0a1 │ │ │ ├── aiosignal >=1.1.2 │ │ │ │ └── frozenlist >=1.1.0 │ │ │ ├── attrs >=17.3.0 │ │ │ ├── frozenlist >=1.1.1 (circular dependency aborted here) │ │ │ ├── multidict >=4.5,<7.0 │ │ │ └── yarl >=1.0,<2.0 │ │ │ ├── idna >=2.0 │ │ │ └── multidict >=4.0 (circular dependency aborted here) │ │ └── requests * │ │ ├── certifi >=2017.4.17 │ │ ├── charset-normalizer >=2,<4 │ │ ├── idna >=2.5,<4 (circular dependency aborted here) │ │ └── urllib3 >=1.21.1,<3 │ ├── packaging >=20.9 │ ├── pyyaml >=5.1 │ ├── requests * (circular dependency aborted here) │ ├── tqdm >=4.42.1 │ │ └── colorama * │ └── typing-extensions >=3.7.4.3 ├── tqdm >=4.65.0 │ └── colorama * ├── typer >=0.9.0 │ ├── click >=7.1.1,<9.0.0 │ │ └── colorama * │ ├── colorama >=0.4.3,<0.5.0 (circular dependency aborted here) │ ├── rich >=10.11.0,<14.0.0 │ │ ├── markdown-it-py >=2.2.0 │ │ │ └── mdurl >=0.1,<1.0 │ │ └── pygments >=2.13.0,<3.0.0 │ ├── shellingham >=1.3.0,<2.0.0 │ └── typing-extensions >=3.7.4.3 ├── typing-extensions >=4.5.0 └── uvicorn >=0.18.3 ├── click >=7.0 │ └── colorama * ├── colorama >=0.4 (circular dependency aborted here) ├── h11 >=0.8 ├── httptools >=0.5.0 ├── python-dotenv >=0.13 ├── pyyaml >=5.1 ├── uvloop >=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1 ├── watchfiles >=0.13 │ └── anyio >=3.0.0 │ ├── idna >=2.8 │ └── sniffio >=1.1 └── websockets >=10.4 fastapi 0.103.2 FastAPI framework, high performance, easy to learn, fast to code, ready for production ├── anyio >=3.7.1,<4.0.0 │ ├── idna >=2.8 │ └── sniffio >=1.1 ├── email-validator >=2.0.0 │ ├── dnspython >=2.0.0 │ └── idna >=2.0.0 ├── httpx >=0.23.0 │ ├── anyio * │ │ ├── idna >=2.8 │ │ └── sniffio >=1.1 │ ├── certifi * │ ├── h2 >=3,<5 │ │ ├── hpack >=4.0,<5 │ │ └── hyperframe >=6.0,<7 │ ├── httpcore ==1.* │ │ ├── certifi * (circular dependency aborted here) │ │ └── h11 >=0.13,<0.15 │ ├── idna * (circular dependency aborted here) │ └── sniffio * (circular dependency aborted here) ├── itsdangerous >=1.1.0 ├── jinja2 >=2.11.2 │ └── markupsafe >=2.0 ├── orjson >=3.2.1 ├── pydantic >=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0 │ ├── annotated-types >=0.4.0 │ ├── pydantic-core 2.14.5 │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ └── typing-extensions >=4.6.1 (circular dependency aborted here) ├── pydantic-extra-types >=2.0.0 │ └── pydantic >=2.0.3 │ ├── annotated-types >=0.4.0 │ ├── pydantic-core 2.14.5 │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ └── typing-extensions >=4.6.1 (circular dependency aborted here) ├── pydantic-settings >=2.0.0 │ ├── pydantic >=2.3.0 │ │ ├── annotated-types >=0.4.0 │ │ ├── pydantic-core 2.14.5 │ │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ │ └── typing-extensions >=4.6.1 (circular dependency aborted here) │ └── python-dotenv >=0.21.0 ├── python-multipart >=0.0.5 ├── pyyaml >=5.3.1 ├── starlette >=0.27.0,<0.28.0 │ └── anyio >=3.4.0,<5 │ ├── idna >=2.8 │ └── sniffio >=1.1 ├── typing-extensions >=4.5.0 ├── ujson >=4.0.1,<4.0.2 || >4.0.2,<4.1.0 || >4.1.0,<4.2.0 || >4.2.0,<4.3.0 || >4.3.0,<5.0.0 || >5.0.0,<5.1.0 || >5.1.0 └── uvicorn >=0.12.0 ├── click >=7.0 │ └── colorama * ├── colorama >=0.4 (circular dependency aborted here) ├── h11 >=0.8 ├── httptools >=0.5.0 ├── python-dotenv >=0.13 ├── pyyaml >=5.1 ├── uvloop >=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1 ├── watchfiles >=0.13 │ └── anyio >=3.0.0 │ ├── idna >=2.8 │ └── sniffio >=1.1 └── websockets >=10.4 injector 0.21.0 Injector - Python dependency injection framework, inspired by Guice llama-index 0.9.3 Interface between LLMs and your data ├── aiohttp >=3.8.6,<4.0.0 │ ├── aiosignal >=1.1.2 │ │ └── frozenlist >=1.1.0 │ ├── attrs >=17.3.0 │ ├── frozenlist >=1.1.1 (circular dependency aborted here) │ ├── multidict >=4.5,<7.0 │ └── yarl >=1.0,<2.0 │ ├── idna >=2.0 │ └── multidict >=4.0 (circular dependency aborted here) ├── aiostream >=0.5.2,<0.6.0 │ └── typing-extensions * ├── beautifulsoup4 >=4.12.2,<5.0.0 │ └── soupsieve >1.2 ├── dataclasses-json >=0.5.7,<0.6.0 │ ├── marshmallow >=3.18.0,<4.0.0 │ │ └── packaging >=17.0 │ └── typing-inspect >=0.4.0,<1 │ ├── mypy-extensions >=0.3.0 │ └── typing-extensions >=3.7.4 ├── deprecated >=1.2.9.3 │ └── wrapt >=1.10,<2 ├── fsspec >=2023.5.0 │ ├── aiohttp <4.0.0a0 || >4.0.0a0,<4.0.0a1 || >4.0.0a1 │ │ ├── aiosignal >=1.1.2 │ │ │ └── frozenlist >=1.1.0 │ │ ├── attrs >=17.3.0 │ │ ├── frozenlist >=1.1.1 (circular dependency aborted here) │ │ ├── multidict >=4.5,<7.0 │ │ └── yarl >=1.0,<2.0 │ │ ├── idna >=2.0 │ │ └── multidict >=4.0 (circular dependency aborted here) │ └── requests * │ ├── certifi >=2017.4.17 │ ├── charset-normalizer >=2,<4 │ ├── idna >=2.5,<4 (circular dependency aborted here) │ └── urllib3 >=1.21.1,<3 ├── httpx * │ ├── anyio * │ │ ├── idna >=2.8 │ │ └── sniffio >=1.1 │ ├── certifi * │ ├── h2 >=3,<5 │ │ ├── hpack >=4.0,<5 │ │ └── hyperframe >=6.0,<7 │ ├── httpcore ==1.* │ │ ├── certifi * (circular dependency aborted here) │ │ └── h11 >=0.13,<0.15 │ ├── idna * (circular dependency aborted here) │ └── sniffio * (circular dependency aborted here) ├── nest-asyncio >=1.5.8,<2.0.0 ├── nltk >=3.8.1,<4.0.0 │ ├── click * │ │ └── colorama * │ ├── joblib * │ ├── regex >=2021.8.3 │ └── tqdm * │ └── colorama * (circular dependency aborted here) ├── numpy * ├── openai >=1.1.0 │ ├── anyio >=3.5.0,<5 │ │ ├── idna >=2.8 │ │ └── sniffio >=1.1 │ ├── distro >=1.7.0,<2 │ ├── httpx >=0.23.0,<1 │ │ ├── anyio * (circular dependency aborted here) │ │ ├── certifi * │ │ ├── h2 >=3,<5 │ │ │ ├── hpack >=4.0,<5 │ │ │ └── hyperframe >=6.0,<7 │ │ ├── httpcore ==1.* │ │ │ ├── certifi * (circular dependency aborted here) │ │ │ └── h11 >=0.13,<0.15 │ │ ├── idna * (circular dependency aborted here) │ │ └── sniffio * (circular dependency aborted here) │ ├── pydantic >=1.9.0,<3 │ │ ├── annotated-types >=0.4.0 │ │ ├── pydantic-core 2.14.5 │ │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ │ └── typing-extensions >=4.6.1 (circular dependency aborted here) │ ├── sniffio * (circular dependency aborted here) │ ├── tqdm >4 │ │ └── colorama * │ └── typing-extensions >=4.5,<5 (circular dependency aborted here) ├── optimum >=1.13.2,<2.0.0 │ ├── coloredlogs * │ │ └── humanfriendly >=9.1 │ │ └── pyreadline3 * │ ├── datasets * │ │ ├── aiohttp * │ │ │ ├── aiosignal >=1.1.2 │ │ │ │ └── frozenlist >=1.1.0 │ │ │ ├── attrs >=17.3.0 │ │ │ ├── frozenlist >=1.1.1 (circular dependency aborted here) │ │ │ ├── multidict >=4.5,<7.0 │ │ │ └── yarl >=1.0,<2.0 │ │ │ ├── idna >=2.0 │ │ │ └── multidict >=4.0 (circular dependency aborted here) │ │ ├── dill >=0.3.0,<0.3.8 │ │ ├── fsspec >=2021.11.1 │ │ │ ├── aiohttp <4.0.0a0 || >4.0.0a0,<4.0.0a1 || >4.0.0a1 (circular dependency aborted here) │ │ │ └── requests * │ │ │ ├── certifi >=2017.4.17 │ │ │ ├── charset-normalizer >=2,<4 │ │ │ ├── idna >=2.5,<4 (circular dependency aborted here) │ │ │ └── urllib3 >=1.21.1,<3 │ │ ├── huggingface-hub >=0.14.0,<1.0.0 │ │ │ ├── filelock * │ │ │ ├── fsspec >=2023.5.0 (circular dependency aborted here) │ │ │ ├── packaging >=20.9 │ │ │ ├── pyyaml >=5.1 │ │ │ ├── requests * (circular dependency aborted here) │ │ │ ├── tqdm >=4.42.1 │ │ │ │ └── colorama * │ │ │ └── typing-extensions >=3.7.4.3 │ │ ├── multiprocess * │ │ │ └── dill >=0.3.7 (circular dependency aborted here) │ │ ├── numpy >=1.17 │ │ ├── packaging * (circular dependency aborted here) │ │ ├── pandas * │ │ │ ├── numpy >=1.23.2,<2 (circular dependency aborted here) │ │ │ ├── python-dateutil >=2.8.2 │ │ │ │ └── six >=1.5 │ │ │ ├── pytz >=2020.1 │ │ │ └── tzdata >=2022.1 │ │ ├── pyarrow >=8.0.0 │ │ │ └── numpy >=1.16.6 (circular dependency aborted here) │ │ ├── pyyaml >=5.1 (circular dependency aborted here) │ │ ├── requests >=2.19.0 (circular dependency aborted here) │ │ ├── tqdm >=4.62.1 (circular dependency aborted here) │ │ └── xxhash * │ ├── datasets >=1.2.1 (circular dependency aborted here) │ ├── evaluate * │ │ ├── datasets >=2.0.0 (circular dependency aborted here) │ │ ├── dill * (circular dependency aborted here) │ │ ├── fsspec >=2021.05.0 (circular dependency aborted here) │ │ ├── huggingface-hub >=0.7.0 (circular dependency aborted here) │ │ ├── multiprocess * (circular dependency aborted here) │ │ ├── numpy >=1.17 (circular dependency aborted here) │ │ ├── packaging * (circular dependency aborted here) │ │ ├── pandas * (circular dependency aborted here) │ │ ├── requests >=2.19.0 (circular dependency aborted here) │ │ ├── responses <0.19 │ │ │ ├── requests >=2.0,<3.0 (circular dependency aborted here) │ │ │ └── urllib3 >=1.25.10 (circular dependency aborted here) │ │ ├── tqdm >=4.62.1 (circular dependency aborted here) │ │ └── xxhash * (circular dependency aborted here) │ ├── huggingface-hub >=0.8.0 (circular dependency aborted here) │ ├── numpy * (circular dependency aborted here) │ ├── onnx * │ │ ├── numpy * (circular dependency aborted here) │ │ └── protobuf >=3.20.2 │ ├── onnxruntime >=1.11.0 │ │ ├── coloredlogs * (circular dependency aborted here) │ │ ├── flatbuffers * │ │ ├── numpy >=1.21.6 (circular dependency aborted here) │ │ ├── packaging * (circular dependency aborted here) │ │ ├── protobuf * (circular dependency aborted here) │ │ └── sympy * │ │ └── mpmath >=0.19 │ ├── packaging * (circular dependency aborted here) │ ├── protobuf >=3.20.1 (circular dependency aborted here) │ ├── sympy * (circular dependency aborted here) │ ├── torch >=1.9 │ │ ├── filelock * (circular dependency aborted here) │ │ ├── fsspec * (circular dependency aborted here) │ │ ├── jinja2 * │ │ │ └── markupsafe >=2.0 │ │ ├── networkx * │ │ ├── nvidia-cublas-cu12 12.1.3.1 │ │ ├── nvidia-cuda-cupti-cu12 12.1.105 │ │ ├── nvidia-cuda-nvrtc-cu12 12.1.105 │ │ ├── nvidia-cuda-runtime-cu12 12.1.105 │ │ ├── nvidia-cudnn-cu12 8.9.2.26 │ │ │ └── nvidia-cublas-cu12 * (circular dependency aborted here) │ │ ├── nvidia-cufft-cu12 11.0.2.54 │ │ ├── nvidia-curand-cu12 10.3.2.106 │ │ ├── nvidia-cusolver-cu12 11.4.5.107 │ │ │ ├── nvidia-cublas-cu12 * (circular dependency aborted here) │ │ │ ├── nvidia-cusparse-cu12 * │ │ │ │ └── nvidia-nvjitlink-cu12 * │ │ │ └── nvidia-nvjitlink-cu12 * (circular dependency aborted here) │ │ ├── nvidia-cusparse-cu12 12.1.0.106 (circular dependency aborted here) │ │ ├── nvidia-nccl-cu12 2.18.1 │ │ ├── nvidia-nvtx-cu12 12.1.105 │ │ ├── sympy * (circular dependency aborted here) │ │ ├── triton 2.1.0 │ │ │ └── filelock * (circular dependency aborted here) │ │ └── typing-extensions * (circular dependency aborted here) │ └── transformers >=4.26.0 │ ├── accelerate >=0.21.0 │ │ ├── huggingface-hub * (circular dependency aborted here) │ │ ├── numpy >=1.17 (circular dependency aborted here) │ │ ├── packaging >=20.0 (circular dependency aborted here) │ │ ├── psutil * │ │ ├── pyyaml * (circular dependency aborted here) │ │ ├── safetensors >=0.3.1 │ │ └── torch >=1.10.0 (circular dependency aborted here) │ ├── filelock * (circular dependency aborted here) │ ├── huggingface-hub >=0.19.3,<1.0 (circular dependency aborted here) │ ├── numpy >=1.17 (circular dependency aborted here) │ ├── packaging >=20.0 (circular dependency aborted here) │ ├── protobuf * (circular dependency aborted here) │ ├── pyyaml >=5.1 (circular dependency aborted here) │ ├── regex !=2019.12.17 │ ├── requests * (circular dependency aborted here) │ ├── safetensors >=0.3.1 (circular dependency aborted here) │ ├── sentencepiece >=0.1.91,<0.1.92 || >0.1.92 │ ├── tokenizers >=0.14,<0.19 │ │ └── huggingface-hub >=0.16.4,<1.0 (circular dependency aborted here) │ ├── torch >=1.10,<1.12.0 || >1.12.0 (circular dependency aborted here) │ └── tqdm >=4.27 (circular dependency aborted here) ├── pandas * │ ├── numpy >=1.23.2,<2 │ ├── python-dateutil >=2.8.2 │ │ └── six >=1.5 │ ├── pytz >=2020.1 │ └── tzdata >=2022.1 ├── sentencepiece >=0.1.99,<0.2.0 ├── sqlalchemy >=1.4.49 │ ├── greenlet !=0.4.17 │ └── typing-extensions >=4.2.0 ├── tenacity >=8.2.0,<9.0.0 ├── tiktoken >=0.3.3 │ ├── regex >=2022.1.18 │ └── requests >=2.26.0 │ ├── certifi >=2017.4.17 │ ├── charset-normalizer >=2,<4 │ ├── idna >=2.5,<4 │ └── urllib3 >=1.21.1,<3 ├── transformers >=4.34.0,<5.0.0 │ ├── accelerate >=0.21.0 │ │ ├── huggingface-hub * │ │ │ ├── filelock * │ │ │ ├── fsspec >=2023.5.0 │ │ │ │ ├── aiohttp <4.0.0a0 || >4.0.0a0,<4.0.0a1 || >4.0.0a1 │ │ │ │ │ ├── aiosignal >=1.1.2 │ │ │ │ │ │ └── frozenlist >=1.1.0 │ │ │ │ │ ├── attrs >=17.3.0 │ │ │ │ │ ├── frozenlist >=1.1.1 (circular dependency aborted here) │ │ │ │ │ ├── multidict >=4.5,<7.0 │ │ │ │ │ └── yarl >=1.0,<2.0 │ │ │ │ │ ├── idna >=2.0 │ │ │ │ │ └── multidict >=4.0 (circular dependency aborted here) │ │ │ │ └── requests * │ │ │ │ ├── certifi >=2017.4.17 │ │ │ │ ├── charset-normalizer >=2,<4 │ │ │ │ ├── idna >=2.5,<4 (circular dependency aborted here) │ │ │ │ └── urllib3 >=1.21.1,<3 │ │ │ ├── packaging >=20.9 │ │ │ ├── pyyaml >=5.1 │ │ │ ├── requests * (circular dependency aborted here) │ │ │ ├── tqdm >=4.42.1 │ │ │ │ └── colorama * │ │ │ └── typing-extensions >=3.7.4.3 │ │ ├── numpy >=1.17 │ │ ├── packaging >=20.0 (circular dependency aborted here) │ │ ├── psutil * │ │ ├── pyyaml * (circular dependency aborted here) │ │ ├── safetensors >=0.3.1 │ │ └── torch >=1.10.0 │ │ ├── filelock * (circular dependency aborted here) │ │ ├── fsspec * (circular dependency aborted here) │ │ ├── jinja2 * │ │ │ └── markupsafe >=2.0 │ │ ├── networkx * │ │ ├── nvidia-cublas-cu12 12.1.3.1 │ │ ├── nvidia-cuda-cupti-cu12 12.1.105 │ │ ├── nvidia-cuda-nvrtc-cu12 12.1.105 │ │ ├── nvidia-cuda-runtime-cu12 12.1.105 │ │ ├── nvidia-cudnn-cu12 8.9.2.26 │ │ │ └── nvidia-cublas-cu12 * (circular dependency aborted here) │ │ ├── nvidia-cufft-cu12 11.0.2.54 │ │ ├── nvidia-curand-cu12 10.3.2.106 │ │ ├── nvidia-cusolver-cu12 11.4.5.107 │ │ │ ├── nvidia-cublas-cu12 * (circular dependency aborted here) │ │ │ ├── nvidia-cusparse-cu12 * │ │ │ │ └── nvidia-nvjitlink-cu12 * │ │ │ └── nvidia-nvjitlink-cu12 * (circular dependency aborted here) │ │ ├── nvidia-cusparse-cu12 12.1.0.106 (circular dependency aborted here) │ │ ├── nvidia-nccl-cu12 2.18.1 │ │ ├── nvidia-nvtx-cu12 12.1.105 │ │ ├── sympy * │ │ │ └── mpmath >=0.19 │ │ ├── triton 2.1.0 │ │ │ └── filelock * (circular dependency aborted here) │ │ └── typing-extensions * (circular dependency aborted here) │ ├── filelock * (circular dependency aborted here) │ ├── huggingface-hub >=0.19.3,<1.0 (circular dependency aborted here) │ ├── numpy >=1.17 (circular dependency aborted here) │ ├── packaging >=20.0 (circular dependency aborted here) │ ├── protobuf * │ ├── pyyaml >=5.1 (circular dependency aborted here) │ ├── regex !=2019.12.17 │ ├── requests * (circular dependency aborted here) │ ├── safetensors >=0.3.1 (circular dependency aborted here) │ ├── sentencepiece >=0.1.91,<0.1.92 || >0.1.92 │ ├── tokenizers >=0.14,<0.19 │ │ └── huggingface-hub >=0.16.4,<1.0 (circular dependency aborted here) │ ├── torch >=1.10,<1.12.0 || >1.12.0 (circular dependency aborted here) │ └── tqdm >=4.27 (circular dependency aborted here) ├── typing-extensions >=4.5.0 ├── typing-inspect >=0.8.0 │ ├── mypy-extensions >=0.3.0 │ └── typing-extensions >=3.7.4 └── urllib3 <2 mypy 1.7.1 Optional static typing for Python ├── mypy-extensions >=1.0.0 └── typing-extensions >=4.1.0 pre-commit 2.21.0 A framework for managing and maintaining multi-language pre-commit hooks. ├── cfgv >=2.0.0 ├── identify >=1.0.0 ├── nodeenv >=0.11.1 │ └── setuptools * ├── pyyaml >=5.1 └── virtualenv >=20.10.0 ├── distlib >=0.3.7,<1 ├── filelock >=3.12.2,<4 └── platformdirs >=3.9.1,<5 pypdf 3.17.2 A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files pytest 7.4.3 pytest: simple powerful testing with Python ├── colorama * ├── iniconfig * ├── packaging * └── pluggy >=0.12,<2.0 pytest-asyncio 0.21.1 Pytest support for asyncio └── pytest >=7.0.0 ├── colorama * ├── iniconfig * ├── packaging * └── pluggy >=0.12,<2.0 pytest-cov 3.0.0 Pytest plugin for measuring coverage. ├── coverage >=5.2.1 └── pytest >=4.6 ├── colorama * ├── iniconfig * ├── packaging * └── pluggy >=0.12,<2.0 python-multipart 0.0.6 A streaming multipart parser for Python pyyaml 6.0.1 YAML parser and emitter for Python qdrant-client 1.7.0 Client library for the Qdrant vector search engine ├── grpcio >=1.41.0 ├── grpcio-tools >=1.41.0 │ ├── grpcio >=1.60.0 │ ├── protobuf >=4.21.6,<5.0dev │ └── setuptools * ├── httpx >=0.14.0 │ ├── anyio * │ │ ├── idna >=2.8 │ │ └── sniffio >=1.1 │ ├── certifi * │ ├── h2 >=3,<5 │ │ ├── hpack >=4.0,<5 │ │ └── hyperframe >=6.0,<7 │ ├── httpcore ==1.* │ │ ├── certifi * (circular dependency aborted here) │ │ └── h11 >=0.13,<0.15 │ ├── idna * (circular dependency aborted here) │ └── sniffio * (circular dependency aborted here) ├── numpy >=1.21 ├── portalocker >=2.7.0,<3.0.0 │ └── pywin32 >=226 ├── pydantic >=1.10.8 │ ├── annotated-types >=0.4.0 │ ├── pydantic-core 2.14.5 │ │ └── typing-extensions >=4.6.0,<4.7.0 || >4.7.0 │ └── typing-extensions >=4.6.1 (circular dependency aborted here) └── urllib3 >=1.26.14,<2.0.0 ruff 0.1.8 An extremely fast Python linter and code formatter, written in Rust. types-pyyaml 6.0.12.12 Typing stubs for PyYAML watchdog 3.0.0 Filesystem events monitoring
poetry update
You can update all the dependencies for a Poetry project like this:
$ poetry update
For Further Reading
Python Best Practices for a New Project in 2021. This article is already becoming dated. YMMV.
Summary
- Demonstrated how to make an alias for working with Python virtual environments (venvs) that are coupled with Python projects.
- Deactivating the current venv was demonstrated using the
deactivate
command, provided with every venv. - Locked directories mean that Python virtual environments should normally only be created in the same environment they are intended to be used.