Skip to main content

Run multiple Python package versions together without dependency conflicts

Project description

Depfix — install and import any Python package version

PyPI Python 3.11+ Sponsor agent0ai

No more Python dependency pain!

The win What it means
🧩 No dependency conflicts Every package keeps the dependency versions it needs.
🔀 Multiple versions together Import two versions of the same package in one Python process.
⚡ Install at runtime Packages are downloaded when your code first needs them, then cached.
🧹 No dependency files No requirements.txt or dependency list in pyproject.toml is required.
🐍 Normal Python imports Select a version, then keep writing ordinary import package.
🌱 Start with one line No environment redesign or separate installation workflow.
🚀 Production ready Built-in CLI and Python APIs let you preinstall or vendor packages for predictable deployments.
import depfix

with depfix.using("requests==2.31.0"):
    import requests as requests_old

with depfix.using("requests==2.32.3"):
    import requests as requests_new

assert requests_old is not requests_new

That is the idea: put the version next to the import and let Depfix handle the rest.

No requirements.txt needed. No dependency list in pyproject.toml. No virtual-environment juggling because two packages want different versions of the same dependency. Depfix downloads packages when they are first used, keeps them cached, and makes sure each package continues using the dependencies it was installed with.

Your imports become the source of truth. Dependency conflicts stop being a project-wide problem.

Your imports are the package manager

Install Depfix once:

python -m pip install depfix

Then choose whichever import style fits your code.

Set a default version

Use default() when the rest of the file or application should import selected versions normally. You can select one or several packages together:

import depfix

depfix.default(
    "requests==2.32.3",
    "PyYAML==6.0.2",
)

import requests
import yaml

response = requests.get("https://raw.githubusercontent.com/pypa/pip/main/.pre-commit-config.yaml")
workflow = yaml.safe_load(response.text)

There is no separate install step. The first default() call prepares the requested packages, and later runs reuse the cache.

Use a version temporarily

Use using() when one part of your program needs a specific version:

import depfix

with depfix.using("openai==0.7.0"):
    import openai as openai_0_7

with depfix.using("openai==0.28.1"):
    import openai as openai_0_28

The imported objects keep working after the block ends:

with depfix.using("requests==2.31.0"):
    import requests as legacy_requests

response = legacy_requests.get("https://example.com")

using() also works as a function decorator:

import depfix


@depfix.using("requests==2.31.0")
def fetch_with_legacy_requests(url: str):
    import requests

    return requests.get(url)

The selected version is active every time the function runs. Async functions work too.

Import a package directly

Use import_module() when you want the module returned immediately:

import depfix

requests = depfix.import_module("requests==2.32.3")

This is especially convenient for dynamic code:

version = "2.32.3"
requests = depfix.import_module(f"requests=={version}")

Most packages expose one obvious import. If a package exposes several and you already know which ones you need, select each with module=:

import depfix

setuptools = depfix.import_module(
    "setuptools==75.0.0",
    module="setuptools",
)

pkg_resources = depfix.import_module(
    "setuptools==75.0.0",
    module="pkg_resources",
)

Use load_package() when you want to inspect package metadata or discover its available module names before importing:

package = depfix.load_package("setuptools==75.0.0")

print(package.name, package.version)
print(package.module_names)
print(package.dependencies)

Dependency conflicts just work

Imagine two packages that cannot be installed together conventionally:

awscli==1.32.0  needs botocore==1.34.0
boto3==1.36.0   needs botocore>=1.36,<1.37

With Depfix, import both:

import depfix

with depfix.using("awscli==1.32.0", "boto3==1.36.0"):
    import awscli.clidriver
    import boto3

Each package receives the Botocore version it needs. You do not have to pin the shared dependency, split the application, or create another environment. See the runnable AWS CLI and Boto3 example.

More than PyPI

The same APIs accept version ranges and common Python package sources:

requests = depfix.import_module("requests>=2.31,<3")
requests_with_socks = depfix.import_module("pypi:requests[socks]~=2.32")
sdk = depfix.import_module("git:https://github.com/acme/sdk.git@v2.4.0")
local_package = depfix.import_module("file:../my-local-package")
helpers = depfix.import_module("file:./helpers.py")

module = depfix.import_module("url:https://packages.example/acme_sdk-2.4.0-py3-none-any.whl#sha256=<digest>")

Standard PEP 508 direct references work as well.

Start simple, lock it later

For local development, just run your Python file. Depfix installs and caches packages as the code reaches them. It does not create project files.

When you want a repeatable deployment, Depfix can scan the same imports and prepare everything in advance:

depfix export . -o .depfix/imports.lock
depfix install .depfix/imports.lock --frozen
python application.py

This is optional. You can start with one import and add deployment controls only when you need them. Offline bundles, containers, and generated IDE aliases are also available.

Good to know

  • Importing depfix alone does nothing expensive. Installation starts only when you call a loading function.
  • Package preparation is shown on stderr, so you can see what is happening. Set DEPFIX_LOG_LEVEL=WARNING for quiet mode.
  • Depfix supports pure-Python and native wheel packages on CPython 3.11–3.13. Automatic mode isolates pure dependency graphs and loads native graphs through guarded, conventional Python imports.
  • A native package can own one compatible public import version per process. Reusing it is idempotent; requesting an incompatible second owner raises a clear error instead of silently returning the wrong version.
  • using() works as scoped syntax sugar for the first compatible native version. That version remains loaded as the process owner after the scope exits; use a worker when you need to switch or overlap native versions.
  • Unsafe package classifications and strict in-process native loading are denied by default. Trusted callers can opt in per request with allow_unsafe=True or process-wide with depfix.configure(allow_unsafe=True).
  • Depfix isolates pure dependency versions; it is not a sandbox for untrusted code.

Documentation

Created by Agent Zero

Depfix is an open-source project by agent0ai, creator of Agent Zero, Space Agent, and DOX.

License

Depfix is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

depfix-0.3.0.tar.gz (128.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

depfix-0.3.0-py3-none-any.whl (99.8 kB view details)

Uploaded Python 3

File details

Details for the file depfix-0.3.0.tar.gz.

File metadata

  • Download URL: depfix-0.3.0.tar.gz
  • Upload date:
  • Size: 128.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for depfix-0.3.0.tar.gz
Algorithm Hash digest
SHA256 15419d58dcb677d82a350bb5c4cf791b3742f91dcbdb5c87de58bc0b6ec10116
MD5 8c5c6c387e11db944c3829845012ee24
BLAKE2b-256 12a780bada7aa521409e3bed332ea531d82c99d23471e5a3cb33e7ed31f37413

See more details on using hashes here.

Provenance

The following attestation bundles were made for depfix-0.3.0.tar.gz:

Publisher: publish-pypi.yml on agent0ai/depfix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file depfix-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: depfix-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 99.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for depfix-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 002bb3c08a77ef1adef0af2005bb05d2d69b80a806268538b2a5e1cbbebb1179
MD5 563239aa9d1314adbb6665cbd11fecd5
BLAKE2b-256 33f9a487b38b772345a3981a6053970161b4f8605d6bb2732c4977c40dc361ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for depfix-0.3.0-py3-none-any.whl:

Publisher: publish-pypi.yml on agent0ai/depfix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page