Poetry Repositories
This section provides comprehensive documentation for using CloudRepo with Poetry, the modern Python packaging and dependency management tool.
Introduction to Poetry
What is Poetry?
Poetry has emerged as the modern standard for Python dependency management and packaging, offering a more streamlined and deterministic approach compared to traditional tools like pip and setuptools. Poetry combines the best features of package managers from other ecosystems (like npm, cargo, and bundler) while addressing many of the pain points that Python developers have historically faced.
Key advantages of Poetry include:
Deterministic dependencies: Poetry uses a lock file (
poetry.lock
) to ensure everyone on your team gets the exact same dependenciesSimplified project management: One tool handles dependency resolution, virtual environment management, building, and publishing
Modern standards: Built on PEP 517/518, using
pyproject.toml
instead of multiple configuration filesBetter dependency resolution: Sophisticated solver that handles complex dependency graphs more reliably
Intuitive workflow: Commands that feel natural and consistent across different operations
Why Use Poetry with CloudRepo?
CloudRepo provides a perfect complement to Poetry’s modern workflow by offering:
Private package hosting: Securely share internal Python packages within your organization
Cost-effective alternative: Save up to 90% compared to JFrog Artifactory or other enterprise solutions
No egress fees: Unlike cloud providers, CloudRepo doesn’t charge for package downloads
Simple authentication: Straightforward configuration that works seamlessly with Poetry
Enterprise features: Support included with all plans, no expensive service contracts
Prerequisites
Before configuring Poetry to work with CloudRepo, you’ll need:
CloudRepo Account and Repository
An active CloudRepo organization account
A Python repository created in the CloudRepo Admin Portal
A repository user with appropriate permissions
Note
For security purposes, your admin user cannot access repositories directly. You must create a dedicated repository user in the CloudRepo Admin Portal.
If you haven’t completed these steps, please refer to:
Poetry Installation
Install Poetry using the official installer:
Installing Poetry (Recommended Method)curl -sSL https://install.python-poetry.org | python3 -
Or via pip (though the installer is preferred):
Installing Poetry via pippip install poetry
Python Environment
Python 3.8 or higher
A project initialized with Poetry (
poetry init
or existingpyproject.toml
)
Configuration
Basic Repository Configuration
Configure your pyproject.toml
to use CloudRepo as a package source:
1[[tool.poetry.source]]
2name = "cloudrepo"
3url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
4priority = "supplemental" # or "primary" if you want CloudRepo to be the main source
The priority
setting determines how Poetry uses your CloudRepo repository:
primary
: Check CloudRepo first for all packagessupplemental
: Only check CloudRepo for packages not found on PyPIexplicit
: Only use CloudRepo when explicitly specified in dependencies
Authentication Configuration
Poetry provides multiple methods for authentication. Choose the one that best fits your workflow:
Method 1: Using Poetry Config (Recommended for Development)
# Set credentials for your CloudRepo repository
poetry config http-basic.cloudrepo [repository-user-email] [repository-user-password]
# Verify the configuration
poetry config --list | grep cloudrepo
Method 2: Environment Variables (Recommended for CI/CD)
export POETRY_HTTP_BASIC_CLOUDREPO_USERNAME="[repository-user-email]"
export POETRY_HTTP_BASIC_CLOUDREPO_PASSWORD="[repository-user-password]"
Method 3: Keyring Integration (Most Secure for Development)
Poetry can integrate with your system’s keyring for secure credential storage:
# Install keyring support
pip install keyring
# Store credentials in keyring
keyring set poetry-repository-cloudrepo [repository-user-email]
# You'll be prompted for the password
# Poetry will automatically use keyring when available
Multiple Repository Configuration
For projects that need packages from both PyPI and CloudRepo:
1[[tool.poetry.source]]
2name = "PyPI"
3priority = "primary"
4
5[[tool.poetry.source]]
6name = "cloudrepo"
7url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
8priority = "supplemental"
9
10[[tool.poetry.source]]
11name = "cloudrepo-ml" # Example: Separate repo for ML packages
12url = "https://[organization-id].mycloudrepo.io/repositories/[ml-repository-id]/simple"
13priority = "explicit" # Only use when explicitly referenced
Publishing Packages
Building Your Package
Poetry simplifies the build process with a single command:
# Build both wheel and source distribution
poetry build
# Build only wheel
poetry build -f wheel
# Build only source distribution
poetry build -f sdist
This creates artifacts in the dist/
directory ready for publishing.
Publishing to CloudRepo
Configure CloudRepo as a publishing repository and upload your package:
# Configure the repository for publishing (one-time setup)
poetry config repositories.cloudrepo https://[organization-id].mycloudrepo.io/repositories/[repository-id]
# Configure authentication (if not already done)
poetry config http-basic.cloudrepo [repository-user-email] [repository-user-password]
# Publish your package
poetry publish --repository cloudrepo
# Build and publish in one command
poetry publish --build --repository cloudrepo
Version Management
Poetry makes version management straightforward:
# Bump patch version (1.0.0 -> 1.0.1)
poetry version patch
# Bump minor version (1.0.1 -> 1.1.0)
poetry version minor
# Bump major version (1.1.0 -> 2.0.0)
poetry version major
# Set specific version
poetry version 2.3.4
# Use pre-release versions
poetry version prepatch # 1.0.0 -> 1.0.1-alpha.0
poetry version prerelease # 1.0.1-alpha.0 -> 1.0.1-alpha.1
Pre-release Versions
Publishing pre-release versions for testing:
1[tool.poetry]
2name = "my-package"
3version = "1.0.0-alpha.1" # Alpha release
4# version = "1.0.0-beta.1" # Beta release
5# version = "1.0.0-rc.1" # Release candidate
# Automatic pre-release versioning
poetry version prerelease # Increments pre-release number
poetry version prepatch # Creates new patch pre-release
poetry version preminor # Creates new minor pre-release
poetry version premajor # Creates new major pre-release
# Publish the pre-release
poetry publish --repository cloudrepo
Platform-Specific Wheels
When building platform-specific wheels (e.g., with C extensions):
# Install build dependencies
poetry install --with dev
# Build wheels for current platform
poetry build -f wheel
# For multiple platforms, use cibuildwheel
pip install cibuildwheel
cibuildwheel --platform linux
# Upload all wheels to CloudRepo
poetry publish --repository cloudrepo
For complex multi-platform builds, configure cibuildwheel
in your pyproject.toml
:
1[tool.cibuildwheel]
2build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*"]
3skip = ["*-win32", "*-manylinux_i686"]
4
5[tool.cibuildwheel.linux]
6manylinux-x86_64-image = "manylinux2014"
7manylinux-aarch64-image = "manylinux2014"
Consuming Dependencies
Adding CloudRepo Packages
Install private packages from CloudRepo:
# Add a private package from CloudRepo
poetry add my-private-package
# Add with version constraints
poetry add my-private-package@^2.0.0
# Add from specific source (when using explicit priority)
poetry add my-ml-package --source cloudrepo-ml
# Add as development dependency
poetry add --group dev my-test-utils
Dependency Groups and Extras
Poetry supports organizing dependencies into groups:
1[tool.poetry.dependencies]
2python = "^3.8"
3my-core-lib = {version = "^1.0.0", source = "cloudrepo"}
4
5[tool.poetry.group.dev.dependencies]
6my-test-framework = {version = "^2.0.0", source = "cloudrepo"}
7pytest = "^7.0.0"
8
9[tool.poetry.group.docs]
10optional = true
11
12[tool.poetry.group.docs.dependencies]
13my-doc-theme = {version = "^1.0.0", source = "cloudrepo"}
14sphinx = "^5.0.0"
15
16[tool.poetry.extras]
17ml = ["tensorflow", "my-ml-utils"]
18web = ["fastapi", "my-web-framework"]
Install specific groups or extras:
# Install with all non-optional groups
poetry install
# Install including optional docs group
poetry install --with docs
# Install without dev dependencies
poetry install --without dev
# Install with specific extras
poetry install --extras "ml web"
# Install all extras
poetry install --all-extras
Lock File Management
Poetry’s lock file ensures reproducible installs:
# Generate/update lock file without installing
poetry lock
# Update specific packages in lock file
poetry update requests my-private-lib
# Update all dependencies to latest compatible versions
poetry update
# Install exactly what's in the lock file
poetry install --no-root
# Export lock file to requirements.txt format
poetry export -f requirements.txt --output requirements.txt
poetry export -f requirements.txt --with-credentials --output requirements-with-auth.txt
Mixing Public and Private Dependencies
Configure Poetry to efficiently handle both public and private packages:
1[[tool.poetry.source]]
2name = "PyPI"
3priority = "primary" # Check PyPI first for public packages
4
5[[tool.poetry.source]]
6name = "cloudrepo"
7url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
8priority = "supplemental" # Fallback to CloudRepo for private packages
9
10[tool.poetry.dependencies]
11python = "^3.8"
12# Public packages (from PyPI)
13requests = "^2.28.0"
14pandas = "^2.0.0"
15
16# Private packages (from CloudRepo) - will be found via supplemental source
17my-private-utils = "^1.2.0"
18company-auth-lib = "^3.0.0"
19
20# Explicitly specify source if needed
21special-internal-tool = {version = "^2.0.0", source = "cloudrepo"}
Advanced Topics
Monorepo Support with Poetry
Poetry works well with monorepo structures. Here’s how to organize multiple packages:
my-monorepo/
├── pyproject.toml # Root workspace configuration
├── packages/
│ ├── core-lib/
│ │ ├── pyproject.toml
│ │ └── src/
│ ├── web-api/
│ │ ├── pyproject.toml
│ │ └── src/
│ └── cli-tool/
│ ├── pyproject.toml
│ └── src/
└── poetry.lock
Root workspace configuration:
1[tool.poetry]
2name = "my-monorepo"
3version = "1.0.0"
4description = "Monorepo workspace"
5authors = ["Your Team <team@example.com>"]
6packages = [
7 {include = "packages/core-lib"},
8 {include = "packages/web-api"},
9 {include = "packages/cli-tool"}
10]
11
12[tool.poetry.dependencies]
13python = "^3.8"
14
15[build-system]
16requires = ["poetry-core>=1.0.0"]
17build-backend = "poetry.core.masonry.api"
Individual package configuration:
1[tool.poetry]
2name = "company-core-lib"
3version = "2.1.0"
4description = "Shared core library"
5
6[tool.poetry.dependencies]
7python = "^3.8"
8
9[[tool.poetry.source]]
10name = "cloudrepo"
11url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
12priority = "supplemental"
Publishing from monorepo:
# Navigate to specific package
cd packages/core-lib
# Build and publish
poetry build
poetry publish --repository cloudrepo
# Or use a script to publish all packages
for pkg in packages/*; do
cd "$pkg"
poetry build
poetry publish --repository cloudrepo
cd ../..
done
Plugin Development and Distribution
Create and distribute Poetry plugins through CloudRepo:
1[tool.poetry]
2name = "poetry-cloudrepo-plugin"
3version = "1.0.0"
4description = "Custom Poetry plugin for CloudRepo integration"
5
6[tool.poetry.dependencies]
7python = "^3.8"
8poetry = "^1.5.0"
9
10[tool.poetry.plugins."poetry.application.plugin"]
11cloudrepo = "poetry_cloudrepo_plugin:CloudRepoPlugin"
12
13[[tool.poetry.source]]
14name = "cloudrepo"
15url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
1from poetry.plugins.application_plugin import ApplicationPlugin
2from cleo.commands.command import Command
3
4class CloudRepoCommand(Command):
5 name = "cloudrepo:sync"
6 description = "Sync packages with CloudRepo"
7
8 def handle(self) -> int:
9 self.line("Syncing with CloudRepo...")
10 # Implementation here
11 return 0
12
13class CloudRepoPlugin(ApplicationPlugin):
14 def activate(self, application):
15 application.add(CloudRepoCommand())
Dependency Caching
Optimize Poetry’s performance with CloudRepo:
# Configure Poetry cache directory
poetry config cache-dir /path/to/cache
# Use CloudRepo as primary source to reduce PyPI lookups
poetry config repositories.cloudrepo https://[organization-id].mycloudrepo.io/repositories/[repository-id]
poetry config repositories.cloudrepo --priority primary
# Enable parallel downloads
poetry config installer.parallel true
# For CI/CD, pre-download dependencies
poetry export -f requirements.txt | pip download -r /dev/stdin -d ./cache
Using CloudRepo as Primary Index
Configure CloudRepo as your primary package index:
1[[tool.poetry.source]]
2name = "cloudrepo"
3url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
4priority = "primary"
5
6[[tool.poetry.source]]
7name = "PyPI"
8priority = "supplemental" # Fallback to PyPI only when needed
This configuration ensures:
All packages are first searched in CloudRepo
Only packages not found in CloudRepo are fetched from PyPI
Reduces external dependencies and improves security
Faster installs for internal packages
CI/CD Integration
GitHub Actions
1name: Python Package CI/CD
2
3on:
4 push:
5 branches: [main, develop]
6 pull_request:
7 branches: [main]
8 release:
9 types: [published]
10
11jobs:
12 test:
13 runs-on: ubuntu-latest
14 strategy:
15 matrix:
16 python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
17
18 steps:
19 - uses: actions/checkout@v3
20
21 - name: Set up Python
22 uses: actions/setup-python@v4
23 with:
24 python-version: ${{ matrix.python-version }}
25
26 - name: Install Poetry
27 run: |
28 curl -sSL https://install.python-poetry.org | python3 -
29 echo "$HOME/.local/bin" >> $GITHUB_PATH
30
31 - name: Configure Poetry
32 env:
33 POETRY_HTTP_BASIC_CLOUDREPO_USERNAME: ${{ secrets.CLOUDREPO_USERNAME }}
34 POETRY_HTTP_BASIC_CLOUDREPO_PASSWORD: ${{ secrets.CLOUDREPO_PASSWORD }}
35 run: |
36 poetry config virtualenvs.create true
37 poetry config virtualenvs.in-project true
38
39 - name: Cache Dependencies
40 uses: actions/cache@v3
41 with:
42 path: .venv
43 key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}
44
45 - name: Install Dependencies
46 run: poetry install --with dev
47
48 - name: Run Tests
49 run: poetry run pytest
50
51 publish:
52 needs: test
53 runs-on: ubuntu-latest
54 if: github.event_name == 'release'
55
56 steps:
57 - uses: actions/checkout@v3
58
59 - name: Set up Python
60 uses: actions/setup-python@v4
61 with:
62 python-version: '3.11'
63
64 - name: Install Poetry
65 run: |
66 curl -sSL https://install.python-poetry.org | python3 -
67 echo "$HOME/.local/bin" >> $GITHUB_PATH
68
69 - name: Configure CloudRepo
70 run: |
71 poetry config repositories.cloudrepo \
72 https://${{ secrets.CLOUDREPO_ORG }}.mycloudrepo.io/repositories/${{ secrets.CLOUDREPO_REPO }}
73 poetry config http-basic.cloudrepo \
74 ${{ secrets.CLOUDREPO_USERNAME }} ${{ secrets.CLOUDREPO_PASSWORD }}
75
76 - name: Build and Publish
77 run: |
78 poetry version $(echo "${{ github.ref }}" | sed 's/refs\/tags\/v//')
79 poetry build
80 poetry publish --repository cloudrepo
GitLab CI
1stages:
2 - test
3 - build
4 - publish
5
6variables:
7 PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
8 POETRY_HOME: "$CI_PROJECT_DIR/.poetry"
9 POETRY_VIRTUALENVS_IN_PROJECT: "true"
10 POETRY_HTTP_BASIC_CLOUDREPO_USERNAME: "${CLOUDREPO_USERNAME}"
11 POETRY_HTTP_BASIC_CLOUDREPO_PASSWORD: "${CLOUDREPO_PASSWORD}"
12
13before_script:
14 - apt-get update -y
15 - apt-get install -y curl
16 - curl -sSL https://install.python-poetry.org | python3 -
17 - export PATH="$POETRY_HOME/bin:$PATH"
18 - poetry config repositories.cloudrepo ${CLOUDREPO_URL}
19
20cache:
21 paths:
22 - .cache/pip
23 - .venv
24
25test:
26 stage: test
27 image: python:3.11
28 script:
29 - poetry install --with dev
30 - poetry run pytest --cov=my_package tests/
31 artifacts:
32 reports:
33 coverage_report:
34 coverage_format: cobertura
35 path: coverage.xml
36
37build:
38 stage: build
39 image: python:3.11
40 script:
41 - poetry build
42 artifacts:
43 paths:
44 - dist/
45 expire_in: 1 week
46
47publish:
48 stage: publish
49 image: python:3.11
50 only:
51 - tags
52 dependencies:
53 - build
54 script:
55 - poetry publish --repository cloudrepo
Troubleshooting
Common Issues and Solutions
Authentication Failures
# Check current configuration
poetry config --list | grep cloudrepo
# Clear cached credentials
poetry config --unset http-basic.cloudrepo
# Re-set credentials
poetry config http-basic.cloudrepo [email] [password]
# Test authentication
poetry search my-package --repository cloudrepo
SSL Certificate Issues
# For development only - not recommended for production
poetry config certificates.cloudrepo.cert false
# Better solution - add corporate CA certificate
poetry config certificates.cloudrepo.cert /path/to/ca-bundle.crt
Dependency Resolution Conflicts
# Clear Poetry cache
poetry cache clear pypi --all
poetry cache clear cloudrepo --all
# Update lock file with verbose output
poetry lock -vvv
# Show dependency tree
poetry show --tree
# Check why a package is included
poetry show --tree my-package
Slow Package Downloads
1[[tool.poetry.source]]
2name = "cloudrepo"
3url = "https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple"
4priority = "primary" # Check CloudRepo first
5
6[tool.poetry]
7# Enable parallel installer
8installer = { parallel = true }
Package Not Found Errors
# List all configured sources
poetry source show
# Search for package in specific repository
poetry search my-package --repository cloudrepo
# Check if package exists in CloudRepo
curl -u [email]:[password] \
https://[organization-id].mycloudrepo.io/repositories/[repository-id]/simple/my-package/
# Force refresh of package list
poetry cache clear cloudrepo --all
poetry lock --no-update
Version Mismatch Issues
# Show all available versions
poetry show my-package --all
# Update to specific version
poetry add my-package@2.0.0
# Allow pre-releases
poetry add my-package --allow-prereleases
# Use version range
poetry add "my-package>=1.0,<2.0"
Best Practices
Always commit poetry.lock: This ensures reproducible builds across your team
Use semantic versioning: Follow SemVer for your package versions
Separate dev dependencies: Use dependency groups to keep production dependencies minimal
Configure CI/CD credentials securely: Use environment variables or secrets management
Regular dependency updates: Run
poetry update
periodically and test thoroughlyDocument custom sources: Include CloudRepo configuration instructions in your README
Use primary/supplemental wisely: Configure source priorities based on your package distribution
Getting Help
If you encounter issues not covered in this documentation:
Check the Poetry documentation
Review CloudRepo’s Knowledge Base
Contact CloudRepo support at support@cloudrepo.io
CloudRepo support is included with all plans - we typically respond within a few business hours and are here to help you succeed with your Python package management.
See also
Python Repositories - Traditional Python repository setup with pip and twine
Continuous Integration and Deployment - Detailed CI/CD integration examples
Repository Management - Managing CloudRepo repositories
Poetry Documentation - Official Poetry documentation