packwise-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursorrules +23 -0
- package/CLAUDE.md +25 -0
- package/README.md +295 -0
- package/audit.md +224 -0
- package/bin/packwise.js +155 -0
- package/package.json +31 -0
- package/skill.md +719 -0
- package/sub-skills/ai/local-llm.md +183 -0
- package/sub-skills/ai/python-ml.md +164 -0
- package/sub-skills/backend/go-server.md +184 -0
- package/sub-skills/backend/java-spring.md +241 -0
- package/sub-skills/backend/node-server.md +164 -0
- package/sub-skills/backend/php-laravel.md +175 -0
- package/sub-skills/backend/python-server.md +164 -0
- package/sub-skills/backend/rust-backend.md +118 -0
- package/sub-skills/cli/python-cli.md +236 -0
- package/sub-skills/cli/sdk-library.md +497 -0
- package/sub-skills/cloud/ci-cd-pipelines.md +350 -0
- package/sub-skills/cloud/docker.md +191 -0
- package/sub-skills/cloud/kubernetes.md +277 -0
- package/sub-skills/cloud/payment-integration.md +307 -0
- package/sub-skills/cross-platform/multiplatform.md +252 -0
- package/sub-skills/desktop/electron.md +783 -0
- package/sub-skills/desktop/game-dev.md +443 -0
- package/sub-skills/desktop/native-app.md +123 -0
- package/sub-skills/desktop/scenarios.md +443 -0
- package/sub-skills/desktop/smart-platforms.md +324 -0
- package/sub-skills/desktop/tauri.md +428 -0
- package/sub-skills/desktop/vr-ar.md +252 -0
- package/sub-skills/desktop/web-to-desktop.md +153 -0
- package/sub-skills/embedded/car-infotainment.md +129 -0
- package/sub-skills/embedded/esp32.md +184 -0
- package/sub-skills/embedded/ros.md +150 -0
- package/sub-skills/embedded/stm32.md +160 -0
- package/sub-skills/mobile/android.md +322 -0
- package/sub-skills/mobile/capacitor.md +232 -0
- package/sub-skills/mobile/flutter-mobile.md +138 -0
- package/sub-skills/mobile/harmonyos.md +150 -0
- package/sub-skills/mobile/ios.md +245 -0
- package/sub-skills/mobile/react-native.md +443 -0
- package/sub-skills/mobile/wearables.md +230 -0
- package/sub-skills/plugins/browser-extension.md +308 -0
- package/sub-skills/plugins/jetbrains-plugin.md +226 -0
- package/sub-skills/plugins/vscode-extension.md +204 -0
- package/sub-skills/security/security-tools.md +174 -0
- package/sub-skills/web/monorepo.md +274 -0
- package/sub-skills/web/pwa.md +220 -0
- package/sub-skills/web/serverless-edge.md +295 -0
- package/sub-skills/web/spa.md +266 -0
- package/sub-skills/web/ssr.md +228 -0
- package/sub-skills/web/wasm.md +243 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Python Backend Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Build Python backend services (FastAPI/Django/Flask/Litestar).
|
|
4
|
+
|
|
5
|
+
**Current version**: Python 3.12+ / 3.13 (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- REST API / GraphQL API
|
|
10
|
+
- Web application backend
|
|
11
|
+
- AI/ML model serving
|
|
12
|
+
- Data processing service
|
|
13
|
+
- Research/academic projects
|
|
14
|
+
- Admin panels / internal tools
|
|
15
|
+
|
|
16
|
+
## Framework Quick Start
|
|
17
|
+
|
|
18
|
+
### FastAPI (Recommended for new projects)
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from fastapi import FastAPI
|
|
22
|
+
app = FastAPI()
|
|
23
|
+
|
|
24
|
+
@app.get("/health")
|
|
25
|
+
async def health():
|
|
26
|
+
return {"status": "ok"}
|
|
27
|
+
|
|
28
|
+
@app.get("/api/users/{user_id}")
|
|
29
|
+
async def get_user(user_id: int):
|
|
30
|
+
return {"user_id": user_id}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Django (Full-featured, batteries-included)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
django-admin startproject myproject
|
|
41
|
+
cd myproject
|
|
42
|
+
python manage.py migrate
|
|
43
|
+
python manage.py collectstatic
|
|
44
|
+
python manage.py runserver
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Flask (Lightweight, minimal)
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from flask import Flask
|
|
51
|
+
app = Flask(__name__)
|
|
52
|
+
|
|
53
|
+
@app.route("/health")
|
|
54
|
+
def health():
|
|
55
|
+
return {"status": "ok"}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Framework Comparison
|
|
59
|
+
|
|
60
|
+
| Framework | Performance | Async | ORM | Admin | Best For |
|
|
61
|
+
|-----------|------------|-------|-----|-------|---------|
|
|
62
|
+
| FastAPI | Highest | Native | SQLAlchemy | Via admin | APIs, microservices, ML serving |
|
|
63
|
+
| Django | Good | ASGI (since 4.1) | Built-in | Built-in | Full-stack web apps, CMS |
|
|
64
|
+
| Flask | Moderate | Via extensions | SQLAlchemy | Via extensions | Simple APIs, microservices |
|
|
65
|
+
| Litestar | High | Native | SQLAlchemy | Built-in | FastAPI alternative |
|
|
66
|
+
|
|
67
|
+
## Build & Package
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# FastAPI/Flask: run directly, no compilation needed
|
|
71
|
+
# Django:
|
|
72
|
+
python manage.py collectstatic # Collect static files
|
|
73
|
+
python manage.py migrate # Database migration
|
|
74
|
+
|
|
75
|
+
# Production WSGI/ASGI server
|
|
76
|
+
# FastAPI/ASGI:
|
|
77
|
+
pip install uvicorn[standard]
|
|
78
|
+
uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
|
|
79
|
+
|
|
80
|
+
# Django/Flask/WSGI:
|
|
81
|
+
pip install gunicorn
|
|
82
|
+
gunicorn -w 4 -b 0.0.0.0:8000 myapp.wsgi:application
|
|
83
|
+
|
|
84
|
+
# Gunicorn + Uvicorn workers (async WSGI)
|
|
85
|
+
gunicorn app:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Docker
|
|
89
|
+
|
|
90
|
+
```dockerfile
|
|
91
|
+
FROM python:3.13-slim AS builder
|
|
92
|
+
WORKDIR /app
|
|
93
|
+
COPY requirements.txt .
|
|
94
|
+
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
|
|
95
|
+
|
|
96
|
+
FROM python:3.13-slim
|
|
97
|
+
WORKDIR /app
|
|
98
|
+
COPY --from=builder /install /usr/local
|
|
99
|
+
COPY . .
|
|
100
|
+
RUN groupadd -r appuser && useradd -r -g appuser appuser && \
|
|
101
|
+
chown -R appuser:appuser /app
|
|
102
|
+
USER appuser
|
|
103
|
+
EXPOSE 8000
|
|
104
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
|
|
105
|
+
CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:8000", "app:app"]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Dependency Management
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# pip + requirements.txt (traditional)
|
|
112
|
+
pip freeze > requirements.txt
|
|
113
|
+
pip install -r requirements.txt
|
|
114
|
+
|
|
115
|
+
# Poetry (recommended for new projects)
|
|
116
|
+
poetry init
|
|
117
|
+
poetry add fastapi uvicorn sqlalchemy
|
|
118
|
+
poetry export -f requirements.txt --output requirements.txt
|
|
119
|
+
|
|
120
|
+
# uv (fastest, Rust-based, pip-compatible)
|
|
121
|
+
pip install uv
|
|
122
|
+
uv pip install fastapi uvicorn
|
|
123
|
+
uv pip compile requirements.in -o requirements.txt
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Gunicorn + Nginx
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Gunicorn (production WSGI server)
|
|
130
|
+
gunicorn -w 4 -b 127.0.0.1:8000 myapp.wsgi:application
|
|
131
|
+
|
|
132
|
+
# Nginx reverse proxy
|
|
133
|
+
# upstream backend { server 127.0.0.1:8000; }
|
|
134
|
+
# server {
|
|
135
|
+
# listen 80;
|
|
136
|
+
# server_name example.com;
|
|
137
|
+
# location / { proxy_pass http://backend; proxy_set_header Host $host; }
|
|
138
|
+
# }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Cloud Platforms
|
|
142
|
+
|
|
143
|
+
| Platform | Method | Best For |
|
|
144
|
+
|----------|--------|---------|
|
|
145
|
+
| Railway | Git push | Quick deploy |
|
|
146
|
+
| Render | Git push | Quick deploy |
|
|
147
|
+
| Fly.io | Docker | Global deploy |
|
|
148
|
+
| AWS Lambda | Mangum (ASGI adapter) | Serverless |
|
|
149
|
+
| Vercel | Serverless Functions | FastAPI (limited) |
|
|
150
|
+
| Aliyun FC | Serverless | China market |
|
|
151
|
+
|
|
152
|
+
## Common Pitfalls
|
|
153
|
+
|
|
154
|
+
| Issue | Fix |
|
|
155
|
+
|-------|-----|
|
|
156
|
+
| Dependency install failure | Pin exact versions; use `pip-compile` for locked deps |
|
|
157
|
+
| Database migration | Run `alembic upgrade head` or `python manage.py migrate` in production |
|
|
158
|
+
| Static files 404 | Nginx serves static files directly; Django: `collectstatic` |
|
|
159
|
+
| Async not working | FastAPI: use `async def`; Django: enable ASGI; Flask: use Quart for async |
|
|
160
|
+
| Python version mismatch | Specify `python:3.13-slim` in Dockerfile; match local and production |
|
|
161
|
+
| `ModuleNotFoundError` | Ensure virtualenv activated; check `sys.path` |
|
|
162
|
+
| WSGI vs ASGI confusion | FastAPI = ASGI (uvicorn); Django = WSGI (gunicorn) or ASGI (uvicorn) |
|
|
163
|
+
| CORS error | FastAPI: `CORSMiddleware`; Django: `django-cors-headers`; Flask: `flask-cors` |
|
|
164
|
+
| Memory leak in workers | Gunicorn: `--max-requests 1000` to restart workers periodically |
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Rust Backend Build Sub-Skill
|
|
2
|
+
|
|
3
|
+
Build and package Rust backend services (Axum/Actix-Web/Rocket/Warp).
|
|
4
|
+
|
|
5
|
+
**Current version**: Rust 1.82+ / Axum 0.7 / Actix-Web 4.x (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- High-performance API services
|
|
10
|
+
- Microservices requiring low latency and minimal memory
|
|
11
|
+
- WebSocket servers
|
|
12
|
+
- System-level services (CLI backends, daemons)
|
|
13
|
+
- Security-sensitive backends (memory safety guaranteed by compiler)
|
|
14
|
+
|
|
15
|
+
## Build
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Standard build
|
|
19
|
+
cargo build --release
|
|
20
|
+
# Output: target/release/myapp
|
|
21
|
+
|
|
22
|
+
# With version embedding
|
|
23
|
+
cargo build --release
|
|
24
|
+
# In build.rs:
|
|
25
|
+
# println!("cargo:rustc-env=APP_VERSION={}", env!("CARGO_PKG_VERSION"));
|
|
26
|
+
|
|
27
|
+
# Static binary (no system dependencies)
|
|
28
|
+
RUSTFLAGS='-C target-feature=+crt-static' cargo build --release --target x86_64-unknown-linux-gnu
|
|
29
|
+
|
|
30
|
+
# Cross-compile
|
|
31
|
+
cargo install cross
|
|
32
|
+
cross build --release --target x86_64-unknown-linux-gnu
|
|
33
|
+
cross build --release --target aarch64-unknown-linux-gnu
|
|
34
|
+
cross build --release --target x86_64-pc-windows-gnu
|
|
35
|
+
cross build --release --target x86_64-apple-darwin
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Framework Quick Start
|
|
39
|
+
|
|
40
|
+
### Axum (Recommended — Tokio team)
|
|
41
|
+
|
|
42
|
+
```rust
|
|
43
|
+
use axum::{routing::get, Router};
|
|
44
|
+
use std::net::SocketAddr;
|
|
45
|
+
|
|
46
|
+
#[tokio::main]
|
|
47
|
+
async fn main() {
|
|
48
|
+
let app = Router::new()
|
|
49
|
+
.route("/", get(|| async { "Hello, World!" }))
|
|
50
|
+
.route("/health", get(|| async { "OK" }));
|
|
51
|
+
|
|
52
|
+
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
|
|
53
|
+
axum::serve(tokio::net::TcpListener::bind(addr).await.unwrap(), app)
|
|
54
|
+
.await
|
|
55
|
+
.unwrap();
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Actix-Web (Highest raw performance)
|
|
60
|
+
|
|
61
|
+
```rust
|
|
62
|
+
use actix_web::{web, App, HttpServer, HttpResponse};
|
|
63
|
+
|
|
64
|
+
#[actix_web::main]
|
|
65
|
+
async fn main() -> std::io::Result<()> {
|
|
66
|
+
HttpServer::new(|| {
|
|
67
|
+
App::new()
|
|
68
|
+
.route("/", web::get().to(|| async { HttpResponse::Ok().body("Hello!") }))
|
|
69
|
+
.route("/health", web::get().to(|| async { HttpResponse::Ok().body("OK") }))
|
|
70
|
+
})
|
|
71
|
+
.bind("0.0.0.0:8080")?
|
|
72
|
+
.run()
|
|
73
|
+
.await
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Docker
|
|
78
|
+
|
|
79
|
+
```dockerfile
|
|
80
|
+
FROM rust:1.82-slim AS builder
|
|
81
|
+
WORKDIR /app
|
|
82
|
+
COPY Cargo.toml Cargo.lock ./
|
|
83
|
+
# Cache dependencies (create dummy src)
|
|
84
|
+
RUN mkdir src && echo 'fn main(){}' > src/main.rs && cargo build --release && rm -rf src
|
|
85
|
+
COPY src/ src/
|
|
86
|
+
RUN touch src/main.rs && cargo build --release
|
|
87
|
+
|
|
88
|
+
FROM debian:bookworm-slim
|
|
89
|
+
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && \
|
|
90
|
+
rm -rf /var/lib/apt/lists/* && \
|
|
91
|
+
groupadd -r appuser && useradd -r -g appuser appuser
|
|
92
|
+
COPY --from=builder /app/target/release/myapp /myapp
|
|
93
|
+
USER appuser
|
|
94
|
+
EXPOSE 8080
|
|
95
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8080/health || exit 1
|
|
96
|
+
CMD ["/myapp"]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Selection Guide
|
|
100
|
+
|
|
101
|
+
| Framework | Async Runtime | Performance | Ecosystem | Best For |
|
|
102
|
+
|-----------|--------------|-------------|-----------|----------|
|
|
103
|
+
| Axum | Tokio | High | Growing fast | New projects, middleware-heavy |
|
|
104
|
+
| Actix-Web | Tokio | Highest | Mature | Maximum throughput |
|
|
105
|
+
| Rocket | Tokio | High | Good | Rapid prototyping, ergonomic API |
|
|
106
|
+
| Warp | Tokio | High | Smaller | Filter-based routing |
|
|
107
|
+
| Poem | Tokio | High | Growing | OpenAPI integration |
|
|
108
|
+
|
|
109
|
+
## Common Pitfalls
|
|
110
|
+
|
|
111
|
+
| Issue | Fix |
|
|
112
|
+
|-------|-----|
|
|
113
|
+
| Binary too large | Use `strip = true` in Cargo.toml `[profile.release]`; use `upx --best` |
|
|
114
|
+
| Slow compile | Use `sccache`; enable incremental compilation; reduce dependencies |
|
|
115
|
+
| Cross-compile fails | Use `cross` tool; or Docker-based cross-compilation |
|
|
116
|
+
| `openssl` build fails | Use `rustls` (pure Rust TLS) instead of native OpenSSL |
|
|
117
|
+
| Missing system libs in Docker | Use `debian:bookworm-slim` (not `alpine`) for glibc compatibility |
|
|
118
|
+
| Static linking issues | Use `x86_64-unknown-linux-musl` target for fully static binary |
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Python CLI Tool Packaging Sub-Skill
|
|
2
|
+
|
|
3
|
+
Package and distribute Python command-line tools as standalone executables or pip packages.
|
|
4
|
+
|
|
5
|
+
**Current version**: Python 3.12+ / PyInstaller 6.x / Nuitka 2.x / uv (2025-2026)
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- Automation scripts for distribution to non-Python users
|
|
10
|
+
- DevOps/infrastructure tools
|
|
11
|
+
- Data processing pipelines
|
|
12
|
+
- Security tools, scanners
|
|
13
|
+
- Research tools for academic distribution
|
|
14
|
+
|
|
15
|
+
## Packaging Options Comparison
|
|
16
|
+
|
|
17
|
+
| Method | Size | Startup | Cross-compile | Best For |
|
|
18
|
+
|--------|------|---------|--------------|----------|
|
|
19
|
+
| PyInstaller | 15–80MB | 1–3s | No (build per platform) | Universal distribution |
|
|
20
|
+
| Nuitka | 10–50MB | < 1s | No | Performance, AV false positive avoidance |
|
|
21
|
+
| pip/PyPI | 0 (source) | Instant | N/A | Developer tools |
|
|
22
|
+
| pipx | 0 (isolated) | Instant | N/A | CLI tools for developers |
|
|
23
|
+
| Docker | 50–200MB | 1–2s | Yes | Server/container environments |
|
|
24
|
+
| uv | 0 (source) | Instant | N/A | Fast Python package management |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## PyInstaller (Most Universal)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install pyinstaller
|
|
32
|
+
|
|
33
|
+
# Single file mode (self-extracting)
|
|
34
|
+
pyinstaller --onefile --name mytool mytool.py
|
|
35
|
+
|
|
36
|
+
# Directory mode (faster startup, recommended for production)
|
|
37
|
+
pyinstaller --name mytool mytool.py
|
|
38
|
+
|
|
39
|
+
# With hidden imports (common for dynamic imports)
|
|
40
|
+
pyinstaller --onefile \
|
|
41
|
+
--hidden-import=cryptography \
|
|
42
|
+
--hidden-import=paramiko \
|
|
43
|
+
--hidden-import=click \
|
|
44
|
+
--name mytool mytool.py
|
|
45
|
+
|
|
46
|
+
# Console app (default) vs GUI app
|
|
47
|
+
pyinstaller --onefile --console mytool.py # Console
|
|
48
|
+
pyinstaller --onefile --windowed mytool.py # GUI (no console window)
|
|
49
|
+
|
|
50
|
+
# Output: dist/mytool (Linux/macOS) or dist/mytool.exe (Windows)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Cross-Platform Build (GitHub Actions)
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
name: Build CLI
|
|
57
|
+
on:
|
|
58
|
+
push:
|
|
59
|
+
tags: ['v*']
|
|
60
|
+
jobs:
|
|
61
|
+
build:
|
|
62
|
+
strategy:
|
|
63
|
+
matrix:
|
|
64
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
65
|
+
runs-on: ${{ matrix.os }}
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v4
|
|
68
|
+
- uses: actions/setup-python@v5
|
|
69
|
+
with:
|
|
70
|
+
python-version: '3.13'
|
|
71
|
+
- run: pip install pyinstaller
|
|
72
|
+
- run: pyinstaller --onefile --name mytool mytool.py
|
|
73
|
+
- uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: mytool-${{ matrix.os }}
|
|
76
|
+
path: dist/
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Nuitka (Better Performance)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install nuitka
|
|
85
|
+
|
|
86
|
+
# Standalone binary
|
|
87
|
+
python -m nuitka \
|
|
88
|
+
--standalone \
|
|
89
|
+
--onefile \
|
|
90
|
+
--output-filename=mytool \
|
|
91
|
+
--enable-plugin=anti-bloat \
|
|
92
|
+
mytool.py
|
|
93
|
+
|
|
94
|
+
# With module support
|
|
95
|
+
python -m nuitka \
|
|
96
|
+
--standalone \
|
|
97
|
+
--onefile \
|
|
98
|
+
--include-module=cryptography \
|
|
99
|
+
--include-package=click \
|
|
100
|
+
mytool.py
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## pip Distribution (PyPI)
|
|
106
|
+
|
|
107
|
+
```toml
|
|
108
|
+
# pyproject.toml
|
|
109
|
+
[build-system]
|
|
110
|
+
requires = ["setuptools>=75.0", "wheel"]
|
|
111
|
+
build-backend = "setuptools.backends._legacy:_Backend"
|
|
112
|
+
|
|
113
|
+
[project]
|
|
114
|
+
name = "mytool"
|
|
115
|
+
version = "1.0.0"
|
|
116
|
+
description = "My awesome CLI tool"
|
|
117
|
+
readme = "README.md"
|
|
118
|
+
license = "MIT"
|
|
119
|
+
requires-python = ">=3.10"
|
|
120
|
+
dependencies = [
|
|
121
|
+
"click>=8.0",
|
|
122
|
+
"requests>=2.28",
|
|
123
|
+
"rich>=13.0",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
[project.scripts]
|
|
127
|
+
mytool = "mytool.cli:main"
|
|
128
|
+
|
|
129
|
+
[project.urls]
|
|
130
|
+
Homepage = "https://github.com/user/mytool"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Build
|
|
135
|
+
python -m build
|
|
136
|
+
# Output: dist/mytool-1.0.0-py3-none-any.whl + dist/mytool-1.0.0.tar.gz
|
|
137
|
+
|
|
138
|
+
# Publish to PyPI
|
|
139
|
+
pip install twine
|
|
140
|
+
twine upload dist/*
|
|
141
|
+
|
|
142
|
+
# Or: use trusted publishing (recommended)
|
|
143
|
+
# Configure on pypi.org → Your project → Publishing → Add GitHub Actions
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## pipx (Isolated Installation)
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Install pipx
|
|
152
|
+
pip install pipx
|
|
153
|
+
pipx ensurepath
|
|
154
|
+
|
|
155
|
+
# Install CLI tool in isolated environment
|
|
156
|
+
pipx install mytool
|
|
157
|
+
|
|
158
|
+
# Install from local wheel
|
|
159
|
+
pipx install dist/mytool-1.0.0-py3-none-any.whl
|
|
160
|
+
|
|
161
|
+
# Install from Git
|
|
162
|
+
pipx install git+https://github.com/user/mytool.git
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Docker Distribution
|
|
168
|
+
|
|
169
|
+
```dockerfile
|
|
170
|
+
FROM python:3.13-slim
|
|
171
|
+
WORKDIR /app
|
|
172
|
+
COPY requirements.txt .
|
|
173
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
174
|
+
COPY . .
|
|
175
|
+
RUN pip install .
|
|
176
|
+
RUN groupadd -r tooluser && useradd -r -g tooluser tooluser
|
|
177
|
+
USER tooluser
|
|
178
|
+
ENTRYPOINT ["mytool"]
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Rich CLI Framework (Recommended for Beautiful CLIs)
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# mytool/cli.py
|
|
187
|
+
import click
|
|
188
|
+
from rich.console import Console
|
|
189
|
+
from rich.table import Table
|
|
190
|
+
|
|
191
|
+
console = Console()
|
|
192
|
+
|
|
193
|
+
@click.group()
|
|
194
|
+
@click.version_option(version="1.0.0")
|
|
195
|
+
def cli():
|
|
196
|
+
"""My awesome CLI tool."""
|
|
197
|
+
pass
|
|
198
|
+
|
|
199
|
+
@cli.command()
|
|
200
|
+
@click.argument("name")
|
|
201
|
+
@click.option("--verbose", "-v", is_flag=True, help="Verbose output")
|
|
202
|
+
def greet(name: str, verbose: bool):
|
|
203
|
+
"""Greet someone."""
|
|
204
|
+
if verbose:
|
|
205
|
+
console.print(f"[dim]Processing request...[/dim]")
|
|
206
|
+
console.print(f"[bold green]Hello, {name}![/bold green]")
|
|
207
|
+
|
|
208
|
+
@cli.command()
|
|
209
|
+
def table():
|
|
210
|
+
"""Show a beautiful table."""
|
|
211
|
+
t = Table(title="Data")
|
|
212
|
+
t.add_column("Name", style="cyan")
|
|
213
|
+
t.add_column("Value", style="green")
|
|
214
|
+
t.add_row("Python", "3.13")
|
|
215
|
+
t.add_row("CLI", "mytool 1.0.0")
|
|
216
|
+
console.print(t)
|
|
217
|
+
|
|
218
|
+
if __name__ == "__main__":
|
|
219
|
+
cli()
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Common Pitfalls
|
|
225
|
+
|
|
226
|
+
| Issue | Fix |
|
|
227
|
+
|-------|-----|
|
|
228
|
+
| PyInstaller missing hidden imports | Use `--hidden-import`; check with `pyi-archive_viewer` |
|
|
229
|
+
| Antivirus false positive (PyInstaller) | Switch to Nuitka; sign binaries; submit to AV vendors |
|
|
230
|
+
| Cross-platform build fails | Build on each platform separately; use CI matrix builds |
|
|
231
|
+
| Large binary size | Use Nuitka (smaller); exclude unused packages; use `--exclude-module` |
|
|
232
|
+
| Slow startup (PyInstaller) | Use directory mode instead of `--onefile` |
|
|
233
|
+
| `pkg_resources` deprecation | Migrate to `importlib.metadata`; use `setuptools>=70` |
|
|
234
|
+
| pip install fails on Windows | Use `python -m pip install`; check PATH |
|
|
235
|
+
| Permission denied on Linux/macOS | `chmod +x dist/mytool` |
|
|
236
|
+
| Entry point not found | Check `[project.scripts]` in `pyproject.toml`; verify module path |
|