Skip to main content

Python package to automatically package and build a folder, fetching all relevant dependencies.

Project description

python-package-folder

Tests Coverage

Easily build and publish any target folder in a repository, including subfolders of a monorepo.
Together with sysappend, this library makes relative imports, flexible import management, and package publishing a breeze.

Documentation

Use Cases

1) Publishing a Subfolder from src/ in a Monorepo

If you have a monorepo structure with multiple packages in src/:

project/
├── src/
│   ├── core_package/
│   │   ├── __init__.py
│   │   ├── core.py
│   │   └── README.md
│   ├── api_package/
│   │   ├── __init__.py
│   │   ├── api.py
│   │   └── README.md
│   └── utils_package/
│       ├── __init__.py
│       ├── utils.py
│       └── README.md
├── shared/
│   └── common.py
└── pyproject.toml

You can build and publish any subfolder from src/ as a standalone package:

# Navigate to the subfolder you want to publish
cd src/api_package

# Build and publish to TestPyPI with version 1.2.0
python-package-folder --publish testpypi --version 1.2.0

# Or publish to PyPI with automatic version resolution via conventional commits
python-package-folder --publish pypi

# Or publish to PyPI with a custom package name
python-package-folder --publish pypi --version 1.2.0 --package-name "my-api-package"

# Include a specific dependency group from the parent pyproject.toml
python-package-folder --publish pypi --version 1.2.0 --dependency-group "dev"

The tool will automatically:

  1. Detect the project root (where pyproject.toml is located)
  2. Use src/api_package as the source directory
  3. Copy any external dependencies (like shared/common.py) into the package before building
  4. Use the subfolder's README if present, or create a minimal one
  5. Create a temporary pyproject.toml with the subfolder's package name and version
  6. Build and publish the package
  7. Clean up all temporary files and restore the original pyproject.toml

This is especially useful for monorepos where you want to publish individual packages independently while sharing common code.

2) Building Packages with Shared Code

If your project structure looks like this:

project/
├── src/
│   └── my_package/
│       └── main.py
├── shared/
│   ├── utils.py
│   └── helpers.py
└── pyproject.toml

And main.py imports from shared/:

from shared.utils import some_function
from shared.helpers import Helper

This package will automatically:

  1. Detect that shared/ is outside src/
  2. Copy shared/ into src/ before building
  3. Build your package with all dependencies included
  4. Clean up the copied files after build

Features

  • Subfolder Build Support: Build subfolders as separate packages with automatic detection and configuration

    • Automatic subfolder detection: Detects when building a subfolder (not the main src/ directory)
    • Creates any needed file for publishing automatically, cleaning up if not originally in the subfolder after the build/publish process. E.g. copies external dependencies into the source directory before build and cleans them up afterward; temporary __init__.py creation for non-package subfolders; uses subfolder README if present, otherwise creates minimal README
    • Automatic package name derivation from subfolder name
    • Automatic temporary pyproject.toml creation with correct package structure
    • Dependency group selection: specify which dependency group from parent pyproject.toml to include.
  • Smart Import Classification and analysis:

    • Recursively parses all .py files to detect import and from ... import ... statements
    • Handles external dependencies (modules and files that originate from outside the main package directory), and distinguishes standard library imports, 3rd-party packages (from site-packages), local/external/relative/ambiguous imports.
  • Idempotent Operations: Safely handles repeated runs without duplicating files

  • Build Integration: Seamlessly integrates with build tools like uv build, pip build, etc.

  • Version Management:

    • Set static versions for publishing (PEP 440 compliant)
    • Temporarily override dynamic versioning during builds
    • Automatic restoration of dynamic versioning after build
    • Automatic version resolution via conventional commits (Python-native, no Node.js required)
  • Package Publishing:

    • Uses twine to publish the built folder/subfolder
    • Handles publishing to to PyPI, TestPyPI, or Azure Artifacts, with interactive credential prompts, secure storage support

Quick Start

The simplest way to use this package is via the command-line interface

Build/publish a specific subfolder in a repository

Useful for monorepos containing many subfolders that may need publishing as stand-alone packages for external usage.

# First cd to the specific subfolder
cd src/subfolder_to_build_and_publish

# Build and publish any subdirectory of your repo to TestPyPi (https://test.pypi.org/)
# Version can be provided explicitly or resolved automatically via conventional commits
python-package-folder --publish testpypi --version 0.0.2

# Or let the tool determine the next version automatically from conventional commits
python-package-folder --publish testpypi

# Only analyse (no building)
cd src/subfolder_to_build_and_publish
python-package-folder --analyze-only

# Only build
cd src/subfolder_to_build_and_publish
python-package-folder

# Build with automatic dependency management
python-package-folder --build-command "uv build"

You can also target a specific subfolder via commandline, rather than cding there:

# Specify custom project root and source directory
python-package-folder --project-root /path/to/project --src-dir /path/to/src --build-command "pip build"

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

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

python_package_folder-9.0.0.tar.gz (161.8 kB view details)

Uploaded Source

Built Distribution

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

python_package_folder-9.0.0-py3-none-any.whl (66.1 kB view details)

Uploaded Python 3

File details

Details for the file python_package_folder-9.0.0.tar.gz.

File metadata

File hashes

Hashes for python_package_folder-9.0.0.tar.gz
Algorithm Hash digest
SHA256 c7fb7a20ce9f6a4632e40da0107be3b4cef30c62301f689a52953ea576680c72
MD5 f63675b13f99c35c7b55f79e634cf9fe
BLAKE2b-256 1e5c45892deec2f989f1543658a47e04fa5cfdffdaa8f39f6bc7309e569b3cba

See more details on using hashes here.

File details

Details for the file python_package_folder-9.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for python_package_folder-9.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e5fce87084e15fc851b57c549039731138ba830244411e5e49e21ee33c1213d0
MD5 8388a9f47147a64d32e74dddf0ccc5bb
BLAKE2b-256 893e40219fb898708054b7b2db1318fb6ae615caffd4eccffc0024e36f613b5e

See more details on using hashes here.

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