0
# Package Building and Distribution
1
2
Comprehensive package building, distribution, and cryptographic verification capabilities for development and deployment workflows.
3
4
## Capabilities
5
6
### Wheel Building
7
8
Build wheel distributions from source packages and requirements.
9
10
```bash { .api }
11
# Build wheel from current directory
12
pip wheel .
13
14
# Build wheel from specific directory
15
pip wheel /path/to/package/
16
17
# Build wheels from requirements
18
pip wheel -r requirements.txt
19
20
# Build wheel to specific directory
21
pip wheel --wheel-dir /path/to/wheels package_name
22
23
# Build without dependencies
24
pip wheel --no-deps package_name
25
26
# Build from source (no binary wheels)
27
pip wheel --no-binary :all: package_name
28
29
# Build only binary wheels
30
pip wheel --only-binary :all: package_name
31
32
# Build with constraints
33
pip wheel -c constraints.txt -r requirements.txt
34
```
35
36
Wheel building options:
37
```bash { .api }
38
# Build configuration
39
pip wheel --global-option="--plat-name" --global-option="linux_x86_64" .
40
pip wheel --build-option="--debug" package_name
41
42
# Index options
43
pip wheel --index-url https://pypi.org/simple/ package_name
44
pip wheel --extra-index-url https://test.pypi.org/simple/ package_name
45
pip wheel --find-links /path/to/wheels package_name
46
47
# Caching and build isolation
48
pip wheel --no-cache-dir package_name
49
pip wheel --no-build-isolation package_name
50
51
# Verbosity
52
pip wheel --verbose package_name
53
pip wheel --quiet package_name
54
```
55
56
### Package Downloading
57
58
Download packages without installing them for offline installation or distribution.
59
60
```bash { .api }
61
# Download package and dependencies
62
pip download package_name
63
64
# Download to specific directory
65
pip download --dest /path/to/downloads package_name
66
67
# Download from requirements file
68
pip download -r requirements.txt
69
70
# Download without dependencies
71
pip download --no-deps package_name
72
73
# Download source distributions only
74
pip download --no-binary :all: package_name
75
76
# Download binary wheels only
77
pip download --only-binary :all: package_name
78
79
# Download specific platform
80
pip download --platform linux_x86_64 --only-binary=:all: package_name
81
82
# Download for specific Python version
83
pip download --python-version 3.9 --only-binary=:all: package_name
84
85
# Download for specific ABI
86
pip download --abi cp39 --only-binary=:all: package_name
87
```
88
89
Platform and architecture options:
90
```bash { .api }
91
# Platform-specific downloads
92
pip download --platform win_amd64 package_name
93
pip download --platform macosx_10_9_x86_64 package_name
94
pip download --platform linux_x86_64 package_name
95
pip download --platform any package_name
96
97
# Implementation-specific
98
pip download --implementation cp package_name # CPython
99
pip download --implementation pp package_name # PyPy
100
```
101
102
### Hash Computation
103
104
Generate cryptographic hashes for package files to ensure integrity and security.
105
106
```bash { .api }
107
# Compute hash for single file
108
pip hash package.tar.gz
109
110
# Compute hashes for multiple files
111
pip hash package1.tar.gz package2.whl
112
113
# Specify hash algorithm
114
pip hash --algorithm sha256 package.tar.gz
115
pip hash --algorithm sha384 package.tar.gz
116
pip hash --algorithm sha512 package.tar.gz
117
118
# Hash remote files
119
pip hash https://files.pythonhosted.org/packages/source/r/requests/requests-2.28.1.tar.gz
120
```
121
122
Hash output format:
123
```text
124
package.tar.gz:
125
--hash=sha256:abcd1234efgh5678ijkl9012mnop3456qrst7890uvwx1234yz567890abcdef12
126
```
127
128
Using hashes in requirements files:
129
```text
130
requests==2.28.1 \
131
--hash=sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97ddf \
132
--hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
133
134
django==4.1.0 \
135
--hash=sha256:a153ffd5143bf26a877bfae2f4ec736ebd8924a46600ca089ad96b54a1d4e28e \
136
--hash=sha256:acb21faa51d5fb02fe81c51e5b9c7403dc71dcb0bd8d5e4a8dced2c1b0aa6272
137
```
138
139
### Offline Installation
140
141
Create offline installation packages and perform installations without internet access.
142
143
```bash { .api }
144
# Download packages for offline installation
145
mkdir offline_packages
146
pip download -d offline_packages -r requirements.txt
147
148
# Install from offline packages
149
pip install --find-links offline_packages --no-index -r requirements.txt
150
151
# Create complete offline bundle
152
pip download --dest offline_bundle \
153
--requirement requirements.txt \
154
--no-binary :all: # Include source distributions
155
```
156
157
### Development Builds
158
159
Build and install packages in development mode for active development.
160
161
```bash { .api }
162
# Editable installation (development mode)
163
pip install -e .
164
pip install -e /path/to/package/
165
166
# Build wheel in development mode
167
pip wheel -e .
168
169
# Install with extras
170
pip install -e ".[dev,test]"
171
172
# Install with constraints in development mode
173
pip install -e . -c constraints.txt
174
```
175
176
### Build System Integration
177
178
Work with different Python build systems and build backends.
179
180
```bash { .api }
181
# Build isolation control
182
pip wheel --no-build-isolation package_name # Use system packages
183
pip wheel --build-isolation package_name # Isolated build (default)
184
185
# Build backend configuration
186
# Controlled by pyproject.toml:
187
# [build-system]
188
# requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.2"]
189
# build-backend = "setuptools.build_meta"
190
191
# Legacy setup.py builds
192
pip wheel --use-pep517 package_name # Use PEP 517 (default)
193
pip wheel --no-use-pep517 package_name # Use legacy setup.py
194
```
195
196
### Programmatic Building
197
198
Use subprocess for programmatic package building and distribution.
199
200
```python { .api }
201
import subprocess
202
import sys
203
import os
204
from pathlib import Path
205
206
def build_wheel(package_path, wheel_dir=None, no_deps=False):
207
"""Build wheel from package directory."""
208
cmd = [sys.executable, '-m', 'pip', 'wheel']
209
210
if wheel_dir:
211
cmd.extend(['--wheel-dir', str(wheel_dir)])
212
if no_deps:
213
cmd.append('--no-deps')
214
215
cmd.append(str(package_path))
216
217
try:
218
subprocess.check_call(cmd)
219
print(f"Successfully built wheel for {package_path}")
220
except subprocess.CalledProcessError as e:
221
print(f"Failed to build wheel: {e}")
222
raise
223
224
def download_packages(requirements_file, dest_dir):
225
"""Download packages for offline installation."""
226
cmd = [
227
sys.executable, '-m', 'pip', 'download',
228
'--dest', str(dest_dir),
229
'-r', str(requirements_file)
230
]
231
232
try:
233
subprocess.check_call(cmd)
234
print(f"Downloaded packages to {dest_dir}")
235
except subprocess.CalledProcessError as e:
236
print(f"Failed to download packages: {e}")
237
raise
238
239
def compute_hash(file_path, algorithm='sha256'):
240
"""Compute hash for package file."""
241
cmd = [
242
sys.executable, '-m', 'pip', 'hash',
243
'--algorithm', algorithm,
244
str(file_path)
245
]
246
247
try:
248
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
249
return result.stdout.strip()
250
except subprocess.CalledProcessError as e:
251
print(f"Failed to compute hash: {e}")
252
return None
253
254
def create_offline_bundle(requirements_file, bundle_dir):
255
"""Create complete offline installation bundle."""
256
bundle_path = Path(bundle_dir)
257
bundle_path.mkdir(exist_ok=True)
258
259
# Download packages
260
download_packages(requirements_file, bundle_path)
261
262
# Create installation script
263
install_script = bundle_path / 'install.py'
264
script_content = f'''#!/usr/bin/env python3
265
import subprocess
266
import sys
267
from pathlib import Path
268
269
def main():
270
bundle_dir = Path(__file__).parent
271
requirements_file = bundle_dir / "requirements.txt"
272
273
cmd = [
274
sys.executable, '-m', 'pip', 'install',
275
'--find-links', str(bundle_dir),
276
'--no-index',
277
'-r', str(requirements_file)
278
]
279
280
subprocess.check_call(cmd)
281
print("Offline installation completed successfully")
282
283
if __name__ == "__main__":
284
main()
285
'''
286
287
with open(install_script, 'w') as f:
288
f.write(script_content)
289
290
# Copy requirements file
291
import shutil
292
shutil.copy2(requirements_file, bundle_path / 'requirements.txt')
293
294
print(f"Offline bundle created in {bundle_dir}")
295
print(f"To install: cd {bundle_dir} && python install.py")
296
297
def build_distribution_package(package_dir, output_dir=None):
298
"""Build both source and wheel distributions."""
299
package_path = Path(package_dir)
300
output_path = Path(output_dir) if output_dir else package_path / 'dist'
301
output_path.mkdir(exist_ok=True)
302
303
# Build wheel
304
wheel_cmd = [
305
sys.executable, '-m', 'pip', 'wheel',
306
'--wheel-dir', str(output_path),
307
'--no-deps',
308
str(package_path)
309
]
310
311
try:
312
subprocess.check_call(wheel_cmd)
313
print(f"Built wheel distribution in {output_path}")
314
except subprocess.CalledProcessError as e:
315
print(f"Failed to build wheel: {e}")
316
raise
317
318
# Build source distribution (if setup.py exists)
319
setup_py = package_path / 'setup.py'
320
if setup_py.exists():
321
sdist_cmd = [
322
sys.executable, str(setup_py), 'sdist',
323
'--dist-dir', str(output_path)
324
]
325
326
try:
327
subprocess.check_call(sdist_cmd, cwd=package_path)
328
print(f"Built source distribution in {output_path}")
329
except subprocess.CalledProcessError as e:
330
print(f"Failed to build source distribution: {e}")
331
332
# Usage examples
333
build_wheel('.', wheel_dir='./dist')
334
download_packages('requirements.txt', './offline_packages')
335
hash_output = compute_hash('package.tar.gz')
336
print(hash_output)
337
338
create_offline_bundle('requirements.txt', './offline_bundle')
339
build_distribution_package('.', './dist')
340
```
341
342
### CI/CD Integration
343
344
Integrate package building into continuous integration and deployment pipelines.
345
346
```bash { .api }
347
# GitHub Actions example build step
348
name: Build Package
349
run: |
350
python -m pip install --upgrade pip build
351
python -m pip wheel --wheel-dir dist .
352
python -m pip hash dist/*.whl
353
354
# Jenkins pipeline build step
355
stage('Build Package') {
356
steps {
357
sh 'python -m pip wheel --wheel-dir dist .'
358
sh 'python -m pip hash dist/*.whl > dist/hashes.txt'
359
archiveArtifacts artifacts: 'dist/*', fingerprint: true
360
}
361
}
362
363
# Docker multi-stage build
364
FROM python:3.9 as builder
365
COPY requirements.txt .
366
RUN pip wheel --wheel-dir /wheels -r requirements.txt
367
368
FROM python:3.9-slim
369
COPY --from=builder /wheels /wheels
370
COPY requirements.txt .
371
RUN pip install --find-links /wheels --no-index -r requirements.txt
372
```