Mike Slinn

A Python Virtual Environment For Every Project

Published 2021-04-09. Last modified 2024-02-14.
Time to read: 6 minutes.

This page is part of the posts collection, categorized under Bash, Python.

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 11 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.11, the following command is required:

Shell
$ 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.

Shell
$ yes | sudo apt install python3-pip

You could install both of the above packages together, of course:

Shell
$ yes | sudo apt install python3.11-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.

Shell
$ python3 -m venv ~/venv/default

Re-running this command at a later date will update the version of Python in an existing venv. Each time you run this command, all pip packages are removed.

At this point, the virtual environment just contained executable images for Python.

Shell
$ 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/ 

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.

Shell
$ 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:

~/.bash_aliases
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.

Shell
(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:

Shell
$ 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:

  1. Create a venv in .venv
  2. Install specified library dependencies
  3. Run the program using the venv dependencies
  4. 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:

Shell
$ 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:

Shell
$ 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:

Shell
$ 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.

Shell
$ deactivate

Here is a fragment of a script that detects if a venv is active, and disables it if so:

Bash script fragment
# 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:

  1. Install Poetry, preferably system-wide. I used apt to install the poetry package.
    Shell
    $ yes | sudo apt install python3-poetry
  2. Configure Poetry to manage the libraries within the venv. The poetry config help message is shown below.
  3. Use Poetry to install the library dependencies.
  4. 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:

Shell
$ 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.

Shell
$ 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:

Shell
$ 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.

Shell
$ 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/c/work/my_project/, poetry.toml will contain:

/mnt/c/work/my_project/poetry.toml
[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:

/mnt/c/work/my_project/.venv/pyvenv.cfg
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.

Shell
$ poetry run python my_program

If the first line of a script is the shebang for running Python, like this:

scripts/setup shebang
#!/usr/bin/env python3

... then we do not need to specify python or python3 on the command line.

Shell
$ 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:

Shell
$ 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:

Shell
$ 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:

Shell
$ 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.


* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.