Project Delivery

Guide to Creating and Distributing Python Packages via Version Control using Poetry

Feeling overwhelmed by Python package management and distribution? This guide empowers you to take control! Leverage version control and Poetry to streamline your development workflow. Master best practices for building, distributing, and publishing your packages, ensuring efficient collaboration and effortless delivery.

Introduction

This guide serves Python developers who wish to refine their package management and distribution practices using version control. The primary intention is to streamline the process of package creation, management, and distribution, ensuring efficiency and consistency across development cycles. Developers often face obstacles such as managing dependencies, versioning, and ensuring package integrity across environments. By leveraging version control systems and tools like Poetry, these challenges can be mitigated.

The guide outlines steps to set up a project, manage dependencies, and automate package distribution, effectively overcoming common hurdles. By following the practices detailed below, developers can achieve package distribution, enhance collaboration, and maintain high-quality software delivery.

Creating Your Package

1. Initial Repository Setup

  • Create a New Repository: Begin by initializing a new repository for your Python package:
git init <repository-name>
view raw 1 hosted with ❤ by GitHub

2. Local Development Environment

  • Setting Up Your Local Directory:
mkdir private-package && cd private-package
view raw 2 hosted with ❤ by GitHub

     This step creates a dedicated directory for your package and moves you into it.

  • Initialize Your Project with Poetry:
poetry init
view raw 3 hosted with ❤ by GitHub

     Poetry is a tool used for Python dependency management and packaging.

3. .gitignore Configuration

  • Setting Up .gitignore: A properly configured `.gitignore` file is crucial for Python projects. Here’s an example that you can use as a starting point:
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
# Django stuff
*.log
local_settings.py
src/db.sqlite3
db.sqlite3-journal
# Flask stuff
instance/
.webassets-cache
# Scrapy stuff
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# pipenv
Pipfile.lock
# poetry
poetry.lock
# pytest
.cache
.pytest_cache/
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# virtualenv
venv/
ENV/
env/
bin/
Scripts/
pyvenv.cfg
*.pyc
# Spacemacs
.spacemacs
.spacemacs.env
# VS Code
.vscode/
# IntelliJ
.idea/
# Jupyter
.ipynb_checkpoints
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# AWS CLI
.aws/
# dotenv environment variables file
.env
.env.*
# Database files
*.sqlite3
*.sqlite3-journal
*.db
# Coverage reports
htmlcov/
.coverage
.coverage.*
*.cover
*.py,cover
.hypothesis/
.coverage-*
# Others
node_modules/
view raw 4 hosted with ❤ by GitHub

4. Structuring Your Source Code

  • Create the Source Directory:
mkdir src && cd src
view raw 5 hosted with ❤ by GitHub

Your project structure should now include the `src` directory, along with other initial files created by poetry like `README.md`, `poetry.lock`, and `pyproject.toml`.

This is the default structure for Poetry – which is a clean structure and conforms with PEP 423.

5. Package Configuration with Poetry

  • Edit pyproject.toml: Specify which modules to include in your package by updating your `pyproject.toml` file:
[tool.poetry]
...
packages = [{include = "<your_module>", from = "src"}]
view raw 6 hosted with ❤ by GitHub
  • Ensure Compatibility Across Python Versions: Your `pyproject.toml` should also specify the Python versions your package supports:
[tool.poetry.dependencies]
python = "^3.9"
view raw 7 hosted with ❤ by GitHub

6. Development, Testing, and Building

     Run this command within the src directory. to test building your package.

poetry build
view raw 8 hosted with ❤ by GitHub

During package development, the build process compiles and packages your code into distributable formats. When you run poetry build, Poetry compiles source files, incorporates dependencies specified in pyproject.toml, and generates a wheel and/or source archive. This ensures the package is isolated from local environments, making it reproducible across different systems. Testing the build verifies that the package can be installed and functions as expected in a clean environment.

7. Distributing Your Package

  • Push and Tag Your Changes:Once your changes are ready, push them to the repository and create a version tag.
  • Package Installation:
poetry add git+https://github.com/<username>/<repo-name>.git#<tag>
view raw 9 hosted with ❤ by GitHub

This command allows users to install your package.


If your repository is private, users will need proper credentials to access and install the package. For package installation from a private GitHub repository, the command slightly alters to include authentication details:

poetry add git+https://<token>:x-oauth-basic@github.com/<username>/<repo-name>.git#<tag>
view raw 10 hosted with ❤ by GitHub

Here, <token> should be replaced with a personal access token (PAT) that grants read access to the repository. This method securely allows Poetry to clone the repository and install the package. Users with read credentials can seamlessly install the package using their access tokens, ensuring both distribution control and privacy.

8. Publishing to PyPI for Widespread Public Consumption

To make your package available to a broader audience via the Python Package Index (PyPI), follow these steps:

  • Prepare Your Package: Ensure your pyproject.toml includes all necessary information: project name, version, author, and other metadata. Verify your package is properly structured and all dependencies are correctly listed.
  • Create Accounts: If you haven't already, create accounts on PyPI and TestPyPI, a separate instance of the package index for testing and experimentation.
  • Build Your Package: Run poetry build to generate the distribution archives. This command produces a .tar.gz file and possibly wheel files in the dist directory.
  • Test Your Package: (Optional) Before publishing to PyPI, you might want to upload your package to TestPyPI to ensure it installs and works correctly. Use poetry publish --repository testpypi -u <username> -p <password> to upload it.
  • Publish to PyPI: Once you're ready to publish, use the command poetry publish -u <username> -p <password>. This command uploads your package to PyPI, making it available for anyone to install via pip install <package-name>.

Remember to update your package version in pyproject.toml for subsequent releases. Always test your package thoroughly to maintain quality and reliability for end users.

Conclusion

This guide aims to equip Python developers with the necessary knowledge and tools to manage and distribute Python packages effectively using version control. From initial setup to leveraging Poetry for dependency management and package configuration, the guide outlines a comprehensive approach to streamline the development process. Addressing common obstacles such as dependency management, version control, and package distribution, it provides practical solutions and best practices. The guide also extends into advanced topics like distributing private packages and publishing to PyPI for broader public consumption, ensuring developers have the resources to manage both private and public packages efficiently. By adhering to the practices outlined, developers can achieve streamlined package distribution, enhance collaboration among team members, and ensure consistent, high-quality software delivery across various environments.