Files
dotfiles/zsh/functions/python-templates.zsh
2025-12-16 20:37:11 -05:00

1447 lines
32 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================================
# Python Project Template Functions
# ============================================================================
# Quick project scaffolding with virtual environments
#
# Usage:
# py-new <project_name> # Create new Python project
# py-django <project_name> # Create Django project
# py-flask <project_name> # Create Flask project
# py-fastapi <project_name> # Create FastAPI project
# py-data <project_name> # Create data science project
# py-cli <project_name> # Create CLI tool project
#
# Add to .zshrc:
# source ~/.dotfiles/zsh/functions/python-templates.zsh
# ============================================================================
# ============================================================================
# Configuration
# ============================================================================
typeset -g PY_TEMPLATE_BASE_DIR="${PY_TEMPLATE_BASE_DIR:-$HOME/projects}"
typeset -g PY_TEMPLATE_PYTHON="${PY_TEMPLATE_PYTHON:-python3}"
typeset -g PY_TEMPLATE_VENV_NAME="${PY_TEMPLATE_VENV_NAME:-venv}"
typeset -g PY_TEMPLATE_USE_POETRY="${PY_TEMPLATE_USE_POETRY:-false}"
typeset -g PY_TEMPLATE_GIT_INIT="${PY_TEMPLATE_GIT_INIT:-true}"
# Colors
typeset -g PY_GREEN=$'\033[0;32m'
typeset -g PY_BLUE=$'\033[0;34m'
typeset -g PY_YELLOW=$'\033[1;33m'
typeset -g PY_CYAN=$'\033[0;36m'
typeset -g PY_NC=$'\033[0m'
# ============================================================================
# Helper Functions
# ============================================================================
_py_print_step() {
echo -e "${PY_BLUE}==>${PY_NC} $1"
}
_py_print_success() {
echo -e "${PY_GREEN}${PY_NC} $1"
}
_py_print_info() {
echo -e "${PY_CYAN}${PY_NC} $1"
}
_py_check_project_name() {
local name="$1"
if [[ -z "$name" ]]; then
echo -e "${PY_YELLOW}${PY_NC} Project name required"
return 1
fi
if [[ -d "$name" ]]; then
echo -e "${PY_YELLOW}${PY_NC} Directory '$name' already exists"
return 1
fi
return 0
}
_py_create_venv() {
local project_dir="$1"
_py_print_step "Creating virtual environment"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]] && command -v poetry &>/dev/null; then
cd "$project_dir"
poetry init --no-interaction
poetry env use "$PY_TEMPLATE_PYTHON"
_py_print_success "Poetry environment created"
else
"$PY_TEMPLATE_PYTHON" -m venv "$project_dir/$PY_TEMPLATE_VENV_NAME"
_py_print_success "Virtual environment created: $PY_TEMPLATE_VENV_NAME"
fi
}
_py_create_gitignore() {
local project_dir="$1"
cat > "$project_dir/.gitignore" << 'EOF'
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual Environment
venv/
env/
ENV/
.venv
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/
.hypothesis/
# Environment variables
.env
.env.local
.env.*.local
# Logs
*.log
logs/
# Database
*.db
*.sqlite
*.sqlite3
# Distribution / packaging
.Python
build/
dist/
*.egg-info/
# Poetry
poetry.lock
# Jupyter Notebook
.ipynb_checkpoints
*.ipynb
# MyPy
.mypy_cache/
.dmypy.json
dmypy.json
# Type checking
.pyre/
.pytype/
EOF
_py_print_success "Created .gitignore"
}
_py_create_readme() {
local project_name="$1"
local project_dir="$2"
local description="$3"
cat > "$project_dir/README.md" << EOF
# $project_name
$description
## Setup
### Using venv
\`\`\`bash
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate # Linux/Mac
# or
venv\\Scripts\\activate # Windows
# Install dependencies
pip install -r requirements.txt
\`\`\`
### Using Poetry (alternative)
\`\`\`bash
poetry install
poetry shell
\`\`\`
## Development
\`\`\`bash
# Activate virtual environment
source venv/bin/activate
# Run the application
python main.py
\`\`\`
## Testing
\`\`\`bash
# Install dev dependencies
pip install pytest pytest-cov
# Run tests
pytest
# Run tests with coverage
pytest --cov=src tests/
\`\`\`
## Project Structure
\`\`\`
$project_name/
├── src/ # Source code
├── tests/ # Test files
├── docs/ # Documentation
├── .gitignore
├── README.md
├── requirements.txt
└── setup.py
\`\`\`
## License
MIT
EOF
_py_print_success "Created README.md"
}
_py_init_git() {
local project_dir="$1"
if [[ "$PY_TEMPLATE_GIT_INIT" == "true" ]]; then
cd "$project_dir"
git init
git add .
git commit -m "Initial commit: project scaffolding"
_py_print_success "Git repository initialized"
fi
}
_py_show_next_steps() {
local project_name="$1"
local has_venv="$2"
echo
echo -e "${PY_CYAN}Next steps:${PY_NC}"
echo
echo " cd $project_name"
if [[ "$has_venv" == "true" ]]; then
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
echo " poetry shell"
else
echo " source $PY_TEMPLATE_VENV_NAME/bin/activate"
fi
fi
echo " # Start coding!"
echo
}
# ============================================================================
# Base Python Project Template
# ============================================================================
py-new() {
local project_name="$1"
local project_type="${2:-basic}"
_py_check_project_name "$project_name" || return 1
echo -e "${PY_BLUE}╔════════════════════════════════════════════════════════════╗${PY_NC}"
echo -e "${PY_BLUE}${PY_NC} Creating Python Project: $project_name"
echo -e "${PY_BLUE}╚════════════════════════════════════════════════════════════╝${PY_NC}"
echo
# Create project structure
_py_print_step "Creating project structure"
mkdir -p "$project_name"/{src,tests,docs}
# Create __init__.py files
touch "$project_name/src/__init__.py"
touch "$project_name/tests/__init__.py"
# Create main.py
cat > "$project_name/src/main.py" << 'EOF'
#!/usr/bin/env python3
"""
Main module for the application.
"""
def main():
"""Main entry point."""
print("Hello from Python!")
if __name__ == "__main__":
main()
EOF
# Create basic test
cat > "$project_name/tests/test_main.py" << 'EOF'
"""Tests for main module."""
import pytest
from src.main import main
def test_main():
"""Test main function runs without error."""
main()
EOF
# Create requirements.txt
cat > "$project_name/requirements.txt" << 'EOF'
# Production dependencies
# Development dependencies (uncomment as needed)
# pytest>=7.0.0
# pytest-cov>=4.0.0
# black>=23.0.0
# flake8>=6.0.0
# mypy>=1.0.0
# pylint>=2.17.0
EOF
# Create setup.py
cat > "$project_name/setup.py" << EOF
from setuptools import setup, find_packages
setup(
name="$project_name",
version="0.1.0",
packages=find_packages(),
install_requires=[],
python_requires=">=3.8",
)
EOF
_py_print_success "Project structure created"
# Create virtual environment
_py_create_venv "$project_name"
# Create .gitignore
_py_create_gitignore "$project_name"
# Create README
_py_create_readme "$project_name" "$project_name" "A Python project"
# Initialize git
_py_init_git "$project_name"
echo
_py_print_success "Project '$project_name' created successfully!"
_py_show_next_steps "$project_name" "true"
}
# ============================================================================
# Django Project Template
# ============================================================================
py-django() {
local project_name="$1"
_py_check_project_name "$project_name" || return 1
echo -e "${PY_BLUE}╔════════════════════════════════════════════════════════════╗${PY_NC}"
echo -e "${PY_BLUE}${PY_NC} Creating Django Project: $project_name"
echo -e "${PY_BLUE}╚════════════════════════════════════════════════════════════╝${PY_NC}"
echo
# Create project directory
mkdir -p "$project_name"
# Create virtual environment first
_py_create_venv "$project_name"
# Install Django
_py_print_step "Installing Django"
cd "$project_name"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
poetry add django
else
"$PY_TEMPLATE_VENV_NAME/bin/pip" install django
fi
# Create Django project
_py_print_step "Creating Django project structure"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
poetry run django-admin startproject config .
else
"$PY_TEMPLATE_VENV_NAME/bin/django-admin" startproject config .
fi
# Create requirements.txt
cat > "requirements.txt" << 'EOF'
Django>=4.2.0
python-decouple>=3.8
psycopg2-binary>=2.9.0 # PostgreSQL adapter
django-environ>=0.11.0
# Development
django-debug-toolbar>=4.2.0
django-extensions>=3.2.0
EOF
# Create .env.example
cat > ".env.example" << 'EOF'
SECRET_KEY=your-secret-key-here
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
# Database
DATABASE_URL=sqlite:///db.sqlite3
# DATABASE_URL=postgresql://user:password@localhost:5432/dbname
EOF
# Create README
cat > "README.md" << EOF
# $project_name
A Django web application.
## Setup
\`\`\`bash
# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Copy environment file
cp .env.example .env
# Edit .env with your settings
# Run migrations
python manage.py migrate
# Create superuser
python manage.py createsuperuser
# Run development server
python manage.py runserver
\`\`\`
## Development
\`\`\`bash
# Create a new app
python manage.py startapp myapp
# Make migrations
python manage.py makemigrations
# Run tests
python manage.py test
# Collect static files
python manage.py collectstatic
\`\`\`
## Project Structure
\`\`\`
$project_name/
├── config/ # Django settings
├── apps/ # Django apps
├── static/ # Static files
├── templates/ # HTML templates
├── media/ # Uploaded files
├── manage.py
└── requirements.txt
\`\`\`
EOF
# Create directories
mkdir -p apps static templates media
_py_create_gitignore "."
_py_init_git "."
cd ..
echo
_py_print_success "Django project '$project_name' created!"
_py_print_info "Don't forget to set SECRET_KEY in .env"
_py_show_next_steps "$project_name" "true"
}
# ============================================================================
# Flask Project Template
# ============================================================================
py-flask() {
local project_name="$1"
_py_check_project_name "$project_name" || return 1
echo -e "${PY_BLUE}╔════════════════════════════════════════════════════════════╗${PY_NC}"
echo -e "${PY_BLUE}${PY_NC} Creating Flask Project: $project_name"
echo -e "${PY_BLUE}╚════════════════════════════════════════════════════════════╝${PY_NC}"
echo
# Create project structure
mkdir -p "$project_name"/{app/{templates,static/{css,js,img}},tests}
# Create virtual environment
_py_create_venv "$project_name"
cd "$project_name"
# Install Flask
_py_print_step "Installing Flask"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
poetry add flask
else
"$PY_TEMPLATE_VENV_NAME/bin/pip" install flask
fi
# Create app/__init__.py
cat > "app/__init__.py" << 'EOF'
"""Flask application factory."""
from flask import Flask
def create_app(config=None):
"""Create and configure the Flask application."""
app = Flask(__name__)
if config:
app.config.from_object(config)
# Register blueprints
from app.routes import main
app.register_blueprint(main)
return app
EOF
# Create app/routes.py
cat > "app/routes.py" << 'EOF'
"""Application routes."""
from flask import Blueprint, render_template
main = Blueprint('main', __name__)
@main.route('/')
def index():
"""Home page."""
return render_template('index.html')
@main.route('/api/health')
def health():
"""Health check endpoint."""
return {'status': 'healthy'}
EOF
# Create app.py
cat > "app.py" << 'EOF'
#!/usr/bin/env python3
"""Flask application entry point."""
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
EOF
chmod +x app.py
# Create base template
cat > "app/templates/base.html" << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Flask App{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<main>
{% block content %}{% endblock %}
</main>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>
EOF
# Create index template
cat > "app/templates/index.html" << 'EOF'
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Welcome to Flask!</h1>
<p>Your app is running.</p>
{% endblock %}
EOF
# Create basic CSS
cat > "app/static/css/style.css" << 'EOF'
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
line-height: 1.6;
padding: 2rem;
}
main {
max-width: 1200px;
margin: 0 auto;
}
EOF
# Create basic JS
cat > "app/static/js/main.js" << 'EOF'
console.log('Flask app loaded');
EOF
# Create requirements.txt
cat > "requirements.txt" << 'EOF'
Flask>=3.0.0
python-decouple>=3.8
# Development
flask-debugtoolbar>=0.14.0
EOF
# Create .env.example
cat > ".env.example" << 'EOF'
FLASK_APP=app.py
FLASK_ENV=development
SECRET_KEY=your-secret-key-here
EOF
# Create README
cat > "README.md" << EOF
# $project_name
A Flask web application.
## Setup
\`\`\`bash
# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Copy environment file
cp .env.example .env
# Run the application
python app.py
\`\`\`
Visit: http://localhost:5000
## Development
\`\`\`bash
# Run with auto-reload
export FLASK_ENV=development
python app.py
# Run tests
pytest
\`\`\`
## Project Structure
\`\`\`
$project_name/
├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── templates/
│ └── static/
├── tests/
├── app.py
└── requirements.txt
\`\`\`
EOF
_py_create_gitignore "."
_py_init_git "."
cd ..
echo
_py_print_success "Flask project '$project_name' created!"
_py_show_next_steps "$project_name" "true"
}
# ============================================================================
# FastAPI Project Template
# ============================================================================
py-fastapi() {
local project_name="$1"
_py_check_project_name "$project_name" || return 1
echo -e "${PY_BLUE}╔════════════════════════════════════════════════════════════╗${PY_NC}"
echo -e "${PY_BLUE}${PY_NC} Creating FastAPI Project: $project_name"
echo -e "${PY_BLUE}╚════════════════════════════════════════════════════════════╝${PY_NC}"
echo
# Create project structure
mkdir -p "$project_name"/{app/{api,models,schemas,services},tests}
# Create virtual environment
_py_create_venv "$project_name"
cd "$project_name"
# Install FastAPI
_py_print_step "Installing FastAPI and dependencies"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
poetry add fastapi uvicorn pydantic
else
"$PY_TEMPLATE_VENV_NAME/bin/pip" install fastapi uvicorn[standard] pydantic
fi
# Create app/__init__.py
touch "app/__init__.py"
# Create main.py
cat > "app/main.py" << 'EOF'
"""FastAPI application."""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api import router
app = FastAPI(
title="My API",
description="FastAPI application",
version="0.1.0"
)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include routers
app.include_router(router, prefix="/api")
@app.get("/")
def root():
"""Root endpoint."""
return {"message": "Welcome to FastAPI"}
@app.get("/health")
def health():
"""Health check."""
return {"status": "healthy"}
EOF
# Create api/__init__.py
cat > "app/api/__init__.py" << 'EOF'
"""API routes."""
from fastapi import APIRouter
router = APIRouter()
@router.get("/items")
def list_items():
"""List all items."""
return {"items": []}
@router.get("/items/{item_id}")
def get_item(item_id: int):
"""Get a specific item."""
return {"id": item_id, "name": f"Item {item_id}"}
EOF
# Create schemas/__init__.py
cat > "app/schemas/__init__.py" << 'EOF'
"""Pydantic schemas."""
from pydantic import BaseModel
class ItemBase(BaseModel):
"""Base item schema."""
name: str
description: str | None = None
class ItemCreate(ItemBase):
"""Schema for creating items."""
pass
class Item(ItemBase):
"""Full item schema."""
id: int
class Config:
from_attributes = True
EOF
# Create models, services __init__.py
touch "app/models/__init__.py"
touch "app/services/__init__.py"
# Create requirements.txt
cat > "requirements.txt" << 'EOF'
fastapi>=0.104.0
uvicorn[standard]>=0.24.0
pydantic>=2.5.0
python-decouple>=3.8
# Optional
# sqlalchemy>=2.0.0
# alembic>=1.12.0
# python-jose[cryptography]>=3.3.0
# passlib[bcrypt]>=1.7.4
# Development
pytest>=7.4.0
httpx>=0.25.0
EOF
# Create run.py
cat > "run.py" << 'EOF'
#!/usr/bin/env python3
"""Run the FastAPI application."""
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
host="0.0.0.0",
port=8000,
reload=True
)
EOF
chmod +x run.py
# Create .env.example
cat > ".env.example" << 'EOF'
API_KEY=your-api-key
DATABASE_URL=sqlite:///./app.db
SECRET_KEY=your-secret-key
EOF
# Create README
cat > "README.md" << EOF
# $project_name
A FastAPI application.
## Setup
\`\`\`bash
# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Copy environment file
cp .env.example .env
# Run the application
python run.py
\`\`\`
Visit:
- API: http://localhost:8000
- Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
## Development
\`\`\`bash
# Run with auto-reload
uvicorn app.main:app --reload
# Run tests
pytest
\`\`\`
## Project Structure
\`\`\`
$project_name/
├── app/
│ ├── api/ # API routes
│ ├── models/ # Database models
│ ├── schemas/ # Pydantic schemas
│ ├── services/ # Business logic
│ └── main.py
├── tests/
├── run.py
└── requirements.txt
\`\`\`
EOF
_py_create_gitignore "."
_py_init_git "."
cd ..
echo
_py_print_success "FastAPI project '$project_name' created!"
_py_print_info "Docs will be at: http://localhost:8000/docs"
_py_show_next_steps "$project_name" "true"
}
# ============================================================================
# Data Science Project Template
# ============================================================================
py-data() {
local project_name="$1"
_py_check_project_name "$project_name" || return 1
echo -e "${PY_BLUE}╔════════════════════════════════════════════════════════════╗${PY_NC}"
echo -e "${PY_BLUE}${PY_NC} Creating Data Science Project: $project_name"
echo -e "${PY_BLUE}╚════════════════════════════════════════════════════════════╝${PY_NC}"
echo
# Create project structure
mkdir -p "$project_name"/{data/{raw,processed,external},notebooks,src,models,reports/{figures}}
# Create virtual environment
_py_create_venv "$project_name"
cd "$project_name"
# Install data science packages
_py_print_step "Installing data science packages"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
poetry add pandas numpy matplotlib seaborn jupyter
else
"$PY_TEMPLATE_VENV_NAME/bin/pip" install pandas numpy matplotlib seaborn jupyter notebook
fi
# Create requirements.txt
cat > "requirements.txt" << 'EOF'
# Core
pandas>=2.1.0
numpy>=1.24.0
matplotlib>=3.8.0
seaborn>=0.13.0
# Machine Learning
scikit-learn>=1.3.0
# tensorflow>=2.14.0
# torch>=2.1.0
# Jupyter
jupyter>=1.0.0
notebook>=7.0.0
ipykernel>=6.25.0
# Utilities
python-decouple>=3.8
# Development
pytest>=7.4.0
black>=23.9.0
pylint>=2.17.0
EOF
# Create starter notebook
cat > "notebooks/01_exploration.ipynb" << 'EOF'
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data Exploration\n",
"\n",
"Initial data exploration and analysis."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"\n",
"%matplotlib inline\n",
"sns.set_style('whitegrid')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Load data\n",
"# df = pd.read_csv('../data/raw/data.csv')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
EOF
# Create src/__init__.py
touch "src/__init__.py"
# Create example processing script
cat > "src/process_data.py" << 'EOF'
#!/usr/bin/env python3
"""Data processing utilities."""
import pandas as pd
def load_raw_data(filepath):
"""Load raw data from file."""
return pd.read_csv(filepath)
def clean_data(df):
"""Clean and preprocess data."""
# Remove duplicates
df = df.drop_duplicates()
# Handle missing values
df = df.dropna()
return df
def main():
"""Main processing pipeline."""
# Load data
df = load_raw_data('data/raw/data.csv')
# Clean data
df = clean_data(df)
# Save processed data
df.to_csv('data/processed/data_clean.csv', index=False)
print(f"Processed {len(df)} rows")
if __name__ == '__main__':
main()
EOF
# Create README
cat > "README.md" << EOF
# $project_name
A data science project.
## Setup
\`\`\`bash
# Create and activate virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Install Jupyter kernel
python -m ipykernel install --user --name=$project_name
\`\`\`
## Usage
\`\`\`bash
# Start Jupyter Notebook
jupyter notebook
# Run processing script
python src/process_data.py
\`\`\`
## Project Structure
\`\`\`
$project_name/
├── data/
│ ├── raw/ # Original, immutable data
│ ├── processed/ # Cleaned, processed data
│ └── external/ # External data sources
├── notebooks/ # Jupyter notebooks
├── src/ # Source code
├── models/ # Trained models
├── reports/ # Analysis reports
│ └── figures/ # Generated graphics
└── requirements.txt
\`\`\`
## Data
Place your raw data files in \`data/raw/\`.
## Notebooks
1. \`01_exploration.ipynb\` - Initial data exploration
2. Add more notebooks as needed
## Guidelines
- Keep raw data immutable
- Document your analysis in notebooks
- Extract reusable code to \`src/\`
- Save processed data to \`data/processed/\`
- Save figures to \`reports/figures/\`
EOF
# Create data README
cat > "data/README.md" << 'EOF'
# Data Directory
## Structure
- `raw/` - Original, immutable data dump
- `processed/` - Cleaned and processed data
- `external/` - Data from third party sources
## Guidelines
- Never modify files in `raw/`
- Document data sources
- Include data dictionaries where applicable
EOF
_py_create_gitignore "."
# Update gitignore for data science
cat >> ".gitignore" << 'EOF'
# Data Science specific
*.pkl
*.h5
*.hdf5
*.parquet
# Data files (comment out if you want to track them)
data/raw/*
data/processed/*
!data/raw/.gitkeep
!data/processed/.gitkeep
# Model files
models/*.pkl
models/*.h5
# Jupyter
.ipynb_checkpoints
# Large files
*.csv
*.tsv
*.dat
EOF
# Create .gitkeep files
touch data/raw/.gitkeep data/processed/.gitkeep data/external/.gitkeep
_py_init_git "."
cd ..
echo
_py_print_success "Data science project '$project_name' created!"
_py_print_info "Start Jupyter: jupyter notebook"
_py_show_next_steps "$project_name" "true"
}
# ============================================================================
# CLI Tool Project Template
# ============================================================================
py-cli() {
local project_name="$1"
_py_check_project_name "$project_name" || return 1
echo -e "${PY_BLUE}╔════════════════════════════════════════════════════════════╗${PY_NC}"
echo -e "${PY_BLUE}${PY_NC} Creating CLI Tool Project: $project_name"
echo -e "${PY_BLUE}╚════════════════════════════════════════════════════════════╝${PY_NC}"
echo
# Create project structure
mkdir -p "$project_name"/{src/$project_name,tests}
# Create virtual environment
_py_create_venv "$project_name"
cd "$project_name"
# Install click
_py_print_step "Installing click for CLI"
if [[ "$PY_TEMPLATE_USE_POETRY" == "true" ]]; then
poetry add click
else
"$PY_TEMPLATE_VENV_NAME/bin/pip" install click
fi
# Create package __init__.py
cat > "src/$project_name/__init__.py" << 'EOF'
"""CLI tool package."""
__version__ = "0.1.0"
EOF
# Create cli.py
cat > "src/$project_name/cli.py" << 'EOF'
#!/usr/bin/env python3
"""Command-line interface."""
import click
@click.group()
@click.version_option()
def cli():
"""CLI tool - A command-line utility."""
pass
@cli.command()
@click.argument('name', default='World')
@click.option('--greeting', default='Hello', help='Greeting to use')
def greet(name, greeting):
"""Greet someone."""
click.echo(f"{greeting}, {name}!")
@cli.command()
@click.option('--count', default=1, help='Number of times to repeat')
@click.argument('message')
def repeat(message, count):
"""Repeat a message."""
for _ in range(count):
click.echo(message)
if __name__ == '__main__':
cli()
EOF
chmod +x "src/$project_name/cli.py"
# Create __main__.py
cat > "src/$project_name/__main__.py" << EOF
"""Allow running as python -m $project_name"""
from $project_name.cli import cli
if __name__ == '__main__':
cli()
EOF
# Create setup.py
cat > "setup.py" << EOF
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="$project_name",
version="0.1.0",
author="Your Name",
author_email="you@example.com",
description="A command-line tool",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourusername/$project_name",
packages=find_packages(where="src"),
package_dir={"": "src"},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.8",
install_requires=[
"click>=8.0.0",
],
entry_points={
"console_scripts": [
"$project_name=$project_name.cli:cli",
],
},
)
EOF
# Create requirements.txt
cat > "requirements.txt" << 'EOF'
click>=8.1.0
# Development
pytest>=7.4.0
black>=23.9.0
EOF
# Create README
cat > "README.md" << EOF
# $project_name
A command-line tool built with Python and Click.
## Installation
\`\`\`bash
# Development installation
pip install -e .
# Or install from source
pip install .
\`\`\`
## Usage
\`\`\`bash
# Show help
$project_name --help
# Example commands
$project_name greet
$project_name greet Alice
$project_name greet --greeting "Hi" Bob
$project_name repeat "Hello" --count 3
\`\`\`
## Development
\`\`\`bash
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install in development mode
pip install -e .
# Run tests
pytest
# Format code
black src/
\`\`\`
## Project Structure
\`\`\`
$project_name/
├── src/
│ └── $project_name/
│ ├── __init__.py
│ ├── __main__.py
│ └── cli.py
├── tests/
├── setup.py
└── requirements.txt
\`\`\`
## Adding Commands
Add new commands to \`src/$project_name/cli.py\`:
\`\`\`python
@cli.command()
@click.argument('arg')
def mycommand(arg):
"""Description of command."""
click.echo(f"Running with: {arg}")
\`\`\`
EOF
_py_create_gitignore "."
_py_init_git "."
cd ..
echo
_py_print_success "CLI tool project '$project_name' created!"
_py_print_info "Install with: pip install -e $project_name"
_py_show_next_steps "$project_name" "true"
}
# ============================================================================
# Aliases
# ============================================================================
alias pynew='py-new'
alias pydjango='py-django'
alias pyflask='py-flask'
alias pyfast='py-fastapi'
alias pydata='py-data'
alias pycli='py-cli'
# Quick venv activation
venv() {
if [[ -d "venv" ]]; then
source venv/bin/activate
elif [[ -d ".venv" ]]; then
source .venv/bin/activate
elif [[ -d "env" ]]; then
source env/bin/activate
else
echo "No virtual environment found (venv, .venv, or env)"
return 1
fi
}
# ============================================================================
# Initialization Message
# ============================================================================
# Uncomment to show on load:
# echo "Python templates loaded. Use: py-new, py-django, py-flask, py-fastapi, py-data, py-cli"