Skip to content

Latest commit

 

History

History
499 lines (359 loc) · 12.1 KB

File metadata and controls

499 lines (359 loc) · 12.1 KB

Contributing to Flash Examples

Thank you for your interest in contributing to Runpod Flash Examples! This guide will help you create high-quality examples that benefit the community.

Table of Contents

Types of Contributions

New Examples

Add examples that demonstrate:

  • Common use cases not yet covered
  • Novel ML model deployments
  • Production patterns and best practices
  • Integration with third-party services
  • Performance optimization techniques

Improvements to Existing Examples

  • Bug fixes
  • Performance optimizations
  • Documentation improvements
  • Additional features
  • Better error handling

Documentation

  • Clarifying existing documentation
  • Adding diagrams and visualizations
  • Improving deployment guides
  • Adding troubleshooting sections

Example Standards

All examples must meet these standards:

1. Functional Requirements

  • Runs successfully with flash run
  • All endpoints return correct responses
  • Error handling is implemented
  • Environment variables are documented
  • Dependencies are declared in pyproject.toml
  • Runtime deps declared in Endpoint(dependencies=[...])
  • Example discovered by flash run from project root

2. Code Quality

  • Clear, readable code
  • Type hints for function signatures
  • Async functions where appropriate
  • No hardcoded credentials
  • Proper logging (not print statements)

3. Documentation

  • Comprehensive README.md
  • Code comments for complex logic
  • API endpoint documentation
  • Deployment instructions
  • Cost estimates (if applicable)

4. Production Readiness

  • Input validation
  • Error handling with meaningful messages
  • Resource configuration (workers, timeout)
  • Graceful degradation
  • Security best practices

Submission Process

Creating a New Example

IMPORTANT: Start with flash init

⚠️ Always use flash init to create new examples. Never copy-paste or duplicate existing example directories.

When creating a new example:

  1. Navigate to the appropriate category directory
  2. Use flash init to create a clean project structure:
    cd 03_advanced_workers
    flash init my_new_example
    cd my_new_example
  3. Review existing examples in your category to understand patterns
  4. Implement your example with fresh code (don't copy-paste)
  5. Follow the structure and standards in the sections below

Why flash init?

  • Ensures standard, up-to-date project structure
  • Prevents propagation of outdated patterns
  • Generates clean boilerplate
  • Maintains consistency across examples

For AI Coding Assistants: If you're using Claude Code, Cursor, or similar tools, see CLAUDE.md for detailed AI-specific guidelines.

1. Choose the Right Category

Place your example in the appropriate directory:

  • 01_getting_started/ - Basic concepts, simple examples
  • 02_ml_inference/ - ML model serving
  • 03_advanced_workers/ - Worker patterns and optimizations
  • 04_scaling_performance/ - Production scaling patterns
  • 05_data_workflows/ - Data handling and pipelines
  • 06_real_world/ - Complete applications
  • misc/ - Experimental or specialized examples

2. Fork and Clone

git clone https://github.com/YOUR_USERNAME/flash-examples.git
cd flash-examples

3. Create Your Example

Follow the standard example structure.

4. Test Locally

cd your_category/your_example
flash run
# Test all endpoints

5. Verify Discovery

flash run auto-discovers all .py files containing @Endpoint functions. Verify your example loads:

# From the repository root
flash run
# Check http://localhost:8888/docs for your new endpoints

Runtime dependencies (torch, transformers, etc.) are declared in Endpoint(dependencies=[...]) and installed on the remote worker, not locally.

6. Create Pull Request

git checkout -b add-example-name
git add .
git commit -m "Add example: your_example_name"
git push origin add-example-name

Create a PR with:

  • Clear title: "Add example: [name]"
  • Description of what the example demonstrates
  • Any special requirements or considerations
  • Screenshots/output examples (if applicable)

Example Structure

Standard Structure

Each example is a flat directory with self-contained worker files (named *_worker.py by convention):

your_example/
├── README.md              # Required: comprehensive documentation
├── gpu_worker.py          # Required: GPU worker with @Endpoint decorator
├── cpu_worker.py          # Optional: CPU worker with @Endpoint decorator
├── pyproject.toml         # Required: project metadata and dependencies
├── .flashignore           # Optional: files to exclude from deployment
├── tests/                 # Recommended: test files
│   ├── test_workers.py
│   └── conftest.py
└── assets/                # Optional: images, diagrams, etc.
    └── architecture.png

flash run discovers all .py files with @Endpoint functions automatically -- no main.py, no workers/ directories, no router wiring.

Minimal Worker (gpu_worker.py)

from runpod_flash import Endpoint, GpuType

@Endpoint(name="your-worker", gpu=GpuType.NVIDIA_GEFORCE_RTX_4090, dependencies=["torch"])
async def your_function(payload: dict) -> dict:
    """
    Clear docstring explaining what this function does.

    Args:
        payload: Description of expected input

    Returns:
        Description of output format
    """
    import torch

    # your implementation
    result = process(payload)

    return {"status": "success", "result": result}

# Test locally
if __name__ == "__main__":
    import asyncio

    test_data = {"key": "value"}
    result = asyncio.run(your_function(test_data))
    print(result)

Documentation Requirements

README.md Template

Your example's README.md must include:

# Example Name

Brief one-line description.

## What This Demonstrates

- Concept 1
- Concept 2
- Concept 3

## Prerequisites

- Python 3.10+
- Runpod API key
- Any special requirements

## Quick Start

1. Install dependencies
2. Configure environment
3. Run locally
4. Test endpoints

## Architecture

Explain the design and data flow.

## Configuration

Document all environment variables and settings.

## Endpoints

Document each API endpoint with examples.

## Deployment

Step-by-step deployment instructions.

## Cost Estimates

Provide rough cost estimates for running this example.

## Troubleshooting

Common issues and solutions.

## Next Steps

Suggestions for extending the example.

Code Comments

  • Document why, not what
  • Explain non-obvious decisions
  • Add references to external docs
  • Note performance considerations
  • Highlight security concerns

Testing Guidelines

Local Testing

Test your example thoroughly:

# Run the application
flash run

# Test health endpoint
curl http://localhost:8888/health

# Test your endpoints
curl -X POST http://localhost:8888/your/endpoint \
  -H "Content-Type: application/json" \
  -d '{"test": "data"}'

# Check API docs
open http://localhost:8888/docs

VS Code Debugging

The repository includes VS Code debug configurations for endpoint development:

Setup:

  1. Copy the root .env.example to .env:

    cp .env.example .env
  2. Add your Runpod API key to .env:

    RUNPOD_API_KEY=your_actual_api_key_here
  3. Ensure you have the Python extension installed in VS Code

Debugging:

Two debug configurations are available:

  • Python Debugger: Current File - Debug any Python file
  • Flash Worker: Debug Endpoint - Debug worker endpoint files with async support

To debug a worker:

  1. Open any *_worker.py file (e.g., 01_getting_started/01_hello_world/hello_worker.py)
  2. Set breakpoints in your worker functions
  3. Press F5 or select "Debug: Start Debugging"
  4. Choose the appropriate debug configuration
  5. The debugger will execute the if __name__ == "__main__" test block

The .env file is automatically loaded, so your RUNPOD_API_KEY is available during debugging.

Unit Tests (Recommended)

Add tests for your worker functions:

# tests/test_workers.py
import pytest
from your_example.gpu_worker import your_function

@pytest.mark.asyncio
async def test_your_function():
    payload = {"key": "value"}
    result = await your_function(payload)

    assert result["status"] == "success"
    assert "result" in result

Run tests:

pytest tests/

Deployment Testing

Test deployment to verify it works on Runpod:

flash build
flash deploy new staging
flash deploy send staging
# Test the deployed endpoints

Code Style

Python Style

  • Follow PEP 8
  • Use type hints
  • Prefer async/await over callbacks
  • Use descriptive variable names
  • Keep functions focused and small

File Organization

  • Group related functionality
  • Separate concerns (routing, logic, config)
  • Use clear module names
  • Avoid circular imports

Environment Variables

# Good
import os
from dotenv import load_dotenv

load_dotenv()

RUNPOD_API_KEY = os.getenv("RUNPOD_API_KEY")
if not RUNPOD_API_KEY:
    raise ValueError("RUNPOD_API_KEY is required")

# Bad
RUNPOD_API_KEY = "hardcoded_key"  # Never do this!

Error Handling

# Good - handle errors within @Endpoint functions
from runpod_flash import Endpoint, GpuType

# Good
@Endpoint(name="processor", gpu=GpuType.NVIDIA_GEFORCE_RTX_4090)
async def process(data: dict) -> dict:
    try:
        result = do_work(data)
        return {"status": "success", "result": result}
    except ValueError as e:
        return {"status": "error", "detail": str(e)}

# Bad
@Endpoint(name="processor", gpu=GpuType.NVIDIA_GEFORCE_RTX_4090)
async def process(data: dict) -> dict:
    result = do_work(data)  # no error handling
    return result

Dependencies

pyproject.toml

Each example declares only its local development dependencies in pyproject.toml. Runtime deps needed on the GPU (torch, transformers, etc.) go in Endpoint(dependencies=[...]):

[project]
name = "your-example"
version = "0.1.0"
description = "Brief description"
requires-python = ">=3.10"
dependencies = [
    "runpod-flash",
]

The root requirements.txt is a generated lockfile -- do not add per-example requirements.txt files.

Security Best Practices

  1. Never commit secrets

    • Use .env files (gitignored)
    • The root .env.example documents required variables
    • Do not add per-example .env.example files
  2. Validate inputs

    • Use Pydantic models
    • Sanitize user input
    • Set reasonable limits
  3. Authentication

    • Document if authentication is needed
    • Provide example implementation
    • Use secure token handling
  4. Dependencies

    • Keep dependencies up to date
    • Review security advisories
    • Pin versions to avoid surprises

Review Process

Pull requests will be reviewed for:

  1. Functionality: Does it work as described?
  2. Code Quality: Is it clean and maintainable?
  3. Documentation: Is it well documented?
  4. Standards: Does it follow guidelines?
  5. Security: Are there security concerns?
  6. Value: Does it add value to the repository?

Reviews typically take 2-7 days. Be patient and responsive to feedback.

Getting Help

Code of Conduct

  • Be respectful and inclusive
  • Provide constructive feedback
  • Focus on the code, not the person
  • Help others learn and grow

License

By contributing, you agree that your contributions will be licensed under the MIT License.

Thank you for contributing to Flash Examples! Your examples help the community build better AI applications.