Skip to main content

A tool for managing dependencies in a modular python project by tracking which dependencies are needed by which sub-modules

Project description

Import Tracker

Import Tracker is a Python package offering a number of capabilities related to tracking and managing optional dependencies in Python projects. Specifically, this project enables developers to:

  • Track the dependencies of a python project to map each module within the project to the set of dependencies it relies on. This can be useful for debugging of dependencies in large projects.

  • Enable lazy import errors in a python projects to prevent code from crashing when uninstalled imports are imported, but not utilized. This can be helpful in large projects, especially those which incorporate lots of hierarchical wild imports, as importing the top level package of such projects can often bring a lot of heavy dependencies into sys.modules.

  • Programmatically determine the install_requires and extras_require arguments to setuptools.setup where the extras sets are determined by a set of modules that should be optional.

Running Import Tracker

To run import_tracker against a project, simply invoke the module's main:

python3 -m import_tracker --name <my_module>

The main supports the following additional arguments:

  • --package: Allows --name to be a relative import (see importlib.import_module)
  • --recursive: Recurse into sub-modules within the given module to produce the full mapping for the given module
  • --num_jobs: When --recurse is given, run the recursive jobs concurrently with the given number of workers (0 implies serial execution)
  • --indent: Indent the output json for pretty printing
  • --log_level: Set the level of logging (up to debug4) to debug unexpected behavior
  • --submodules: List of sub-modules to recurse on (only used when --recursive set)
  • --side_effect_modules: Modules with known import-time side effect which should always be allowed to import
  • --track_import_stack: Store the stack trace of imports belonging to the tracked module
    • NOTE: This is very slow and should be used only when performing specific debugging tasks!

Integrating import_tracker into a projects

When using import_tracker to implement optional dependencies in a project, there are two steps to take:

  1. Enable lazy_import_errors for the set of modules that should be managed as optional
  2. Use setup_tools.parse_requirements in setup.py to determine the install_requires and extras_require arguments

In the following examples, we'll use a fictitious project with the following structure:

my_module/
├── __init__.py
├── utils.py
└── widgets
    ├── __init__.py
    ├── widget1.py
    └── widget2.py

Enabling lazy_import_errors

The import_tracker.lazy_import_errors function can be invoked directly to enable lazy import errors globally, or used as a context manager to enable them only for a selcted set of modules.

To globally enable lazy import errors, my_module/__init__.py would look like the following:

# Globally enable lazy import errors
from import_tracker import lazy_import_errors
lazy_import_errors()

from . import utils, widgets

Alternately, applying lazy import error semantics only to the widgets would look like the following:

from import_tracker import lazy_import_errors

# Require all downstream imports from utils to exist
from . import utils

# Enable lazy import errors for widgets
with lazy_import_errors():
    from . import widgets

When using lazy import errors, there are two ways to customize the error message that is raised when a failed import is used:

    1. The get_extras_modules argument takes a function which returns a Set[str] of the module names that are tracked as extras. If the import error is triggered within a module that is managed as an extras set, the error message is updated to include instructions on which extras set needs to be installed.
  1. The make_error_message argument allows the caller to specify a fully custom error message generation function.

Using setup_tools.parse_requirements

To take advantage of the automatic dependency parsing when building a package, the setup.py would look like the following:

import import_tracker
import os
import setuptools

# Determine the path to the requirements.txt for the project
requirements_file = os.path.join(os.path.dirname(__file__), "requirements.txt")

# Parse the requirement sets
install_requires, extras_require = import_tracker.setup_tools.parse_requirements(
    requirements_file=requirements_file,
    library_name="my_module",
    extras_modules=[
        "my_module.widgets.widget1",
        "my_module.widgets.widget2",
    ],
)

# Perform the standard setup call
setuptools.setup(
    name="my_module",
    author="me",
    version="1.2.3",
    license="MIT",
    install_requires=install_requires,
    extras_require=extras_require,
    packages=setuptools.find_packages(),
)

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

import_tracker-2.2.0-py310-none-any.whl (23.5 kB view details)

Uploaded Python 3.10

import_tracker-2.2.0-py39-none-any.whl (23.5 kB view details)

Uploaded Python 3.9

import_tracker-2.2.0-py38-none-any.whl (23.5 kB view details)

Uploaded Python 3.8

import_tracker-2.2.0-py37-none-any.whl (23.5 kB view details)

Uploaded Python 3.7

File details

Details for the file import_tracker-2.2.0-py310-none-any.whl.

File metadata

File hashes

Hashes for import_tracker-2.2.0-py310-none-any.whl
Algorithm Hash digest
SHA256 d43eaf28bd38d26cb010a0186ac316417bb47eb8a5f471bfb8175b4901e2de66
MD5 d14e75d140207df8126ae7e633372a92
BLAKE2b-256 d5ca8b437c580cb13a1896b12c9109b7ac970301b6975283dfd86be95d1e2abb

See more details on using hashes here.

File details

Details for the file import_tracker-2.2.0-py39-none-any.whl.

File metadata

  • Download URL: import_tracker-2.2.0-py39-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3.9
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.13

File hashes

Hashes for import_tracker-2.2.0-py39-none-any.whl
Algorithm Hash digest
SHA256 86a419d5274fc480c72c1a7b2a26959ea8469a2fc6f44e021463f43c90cf75ec
MD5 5f439d01cd4cb699a72183699e5994e8
BLAKE2b-256 2a0eeb9600ff74f90b24e022813d3a30c166888f76ee898ec755a299a8bb629a

See more details on using hashes here.

File details

Details for the file import_tracker-2.2.0-py38-none-any.whl.

File metadata

  • Download URL: import_tracker-2.2.0-py38-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.8.13

File hashes

Hashes for import_tracker-2.2.0-py38-none-any.whl
Algorithm Hash digest
SHA256 5bbe00641e78a932352d024f499665337045220a583208de9ebfc2e7ebf9cfe6
MD5 7202b9bf11f9d27114a23059631ca834
BLAKE2b-256 54536c84a35dcfb90216956d6e0572b437696e558ab46798862fcb2810c7d493

See more details on using hashes here.

File details

Details for the file import_tracker-2.2.0-py37-none-any.whl.

File metadata

  • Download URL: import_tracker-2.2.0-py37-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3.7
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.7.13

File hashes

Hashes for import_tracker-2.2.0-py37-none-any.whl
Algorithm Hash digest
SHA256 62b34d8295dc2278c175915480baa0dcc3ee8811c592ce34ae07c970b23d568a
MD5 a7abddcddcda92e721b9230ffba88699
BLAKE2b-256 307f7f28e9f1a880fec59fc0840499af504e95398b8f3299f7b6bfa2fb6cebf8

See more details on using hashes here.

Supported by

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