multi-platform-deployer 0.1.1
A unified Python package for deploying to multiple platforms
License: MIT
Requires Python: >=3.8
Keywords: deployment, render, railway, vercel, heroku

# Multi-Platform Deployer 🚀

[![PyPI - Version](https://img.shields.io/pypi/v/multi-platform-deployer.svg)](https://pypi.org/project/multi-platform-deployer/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/multi-platform-deployer.svg?label=pip%20installs)](https://pypi.org/project/multi-platform-deployer/)

> **Deploy your Python apps to *any* cloud platform without the headache.**

Deploying to different cloud platforms usually means learning completely different tools, config formats, and workflows. That's exhausting and error-prone. This package fixes that by giving you a **single, simple interface** to deploy Flask, Django, and FastAPI applications to Render, Railway, Vercel, and Heroku.

Think of it as a universal translator for cloud deployments.

---

## TL;DR Quickstart

1. **Install the tool once** (inside your project or globally):
  ```bash
  py -m pip install multi-platform-deployer
  ```
2. **Drop a 6-line shim** into the root of every project where you want the
  friendly `py deploy.py <command>` syntax:
  ```python
  # deploy.py
  from multi_platform_deployer.cli import main

  if __name__ == "__main__":
     raise SystemExit(main())
  ```
  > Prefer not to add a file? You can always run the package directly via
  > `python -m multi_platform_deployer.cli <command>`.
3. **Create your deployment config**:
  ```bash
  py deploy.py setup
  ```
  This guides you through creating `deployment.yaml` with your platform, app name, and more.
4. **Ship with commands**:
  ```bash
  py deploy.py check          # Pre-flight audit
  py deploy.py run            # Guided deployment (add --multi for several platforms)
  py deploy.py health --url https://your-app.com
  ```

That's it—config once, then treat `deploy.py` like any other project tool.

---

## What This Does

### The Problem
You've built a great Python web app and now you want to deploy it. But here's the thing:
- Render uses `render.yaml`
- Railway uses `railway.json`
- Vercel is completely different
- Heroku uses `Procfile`
- Each one has different environment variable management, different requirements

It's confusing. You end up copy-pasting from docs, getting things wrong, and spending hours debugging deployment issues.

### The Solution
I automated all of that. This package:

1. **Checks your app** - Validates that your app is actually ready for production (not just locally)
2. **Picks the platform** - Works with Render, Railway, Vercel, and Heroku (and you can add more)
3. **Handles everything** - Migrations, environment variables, config files, health checks
4. **Does one deploy** - Single command to deploy to one or multiple platforms simultaneously

That's it. You go from code to deployed in minutes, not hours.

---

## Installation

### Install from PyPI (recommended)
```bash
# Inside any virtual environment or global workstation
py -m pip install multi-platform-deployer
```

### Work on the Source Locally
```bash
git clone https://github.com/yourusername/multi-platform-deployer.git
cd multi-platform-deployer
python -m venv .venv
.venv\Scripts\activate  # On macOS/Linux: source .venv/bin/activate
py -m pip install -e .
py -m pip install -e ".[dev]"  # Include lint/test extras while developing
```

---

## Get Started in 3 Steps

### Step 1: Set Up Your Deployment Configuration
```bash
py deploy.py setup
```

This launches an interactive wizard that creates your `deployment.yaml` file. You'll be asked for:
- **Platform** (Render, Railway, Vercel, or Heroku)
- **App name** (how your app will be named on the platform)
- **Environment variables** (optional, but recommended)
- **Services** (Railway-specific, optional)

When done, your `deployment.yaml` is ready to commit to git.

### Step 2: Check If Your App Is Ready
```bash
py deploy.py check
```

This runs a battery of checks to make sure your app is production-ready. It'll tell you:
- ✅ Do you have a requirements.txt?
- ✅ Is your SECRET_KEY properly configured?
- ✅ Is debug mode off?
- ✅ Are your database settings production-safe?
- ✅ Is your Python runtime/version pinned?
- ✅ Are your .env secrets real (no placeholders)?
- ✅ Is your git workspace clean before shipping?
- ...and more

If everything passes, you're good to go. If not, it tells you exactly what to fix.

### Step 3: Deploy
```bash
# Deploy to one platform
py deploy.py run

# Deploy to multiple platforms at once
py deploy.py run --multi
```

You'll be guided through a simple wizard:
1. Pick your platform(s) (or use config from `deployment.yaml`)
2. Decide if you want database migrations run
3. Watch it deploy (takes seconds)

That's actually it. Your app is live.

### Step 4: Verify It Works
```bash
py deploy.py health --url https://my-app.onrender.com
```

This checks that your deployed app is up and responding correctly. It verifies:
- Server is running
- Main endpoints are responsive
- Database is connected (if applicable)

---

## The CLI Commands

Everything is straightforward. Here's what you can do:

| Command | What It Does |
|---------|-------------|
| `py deploy.py setup` | Create/edit deployment.yaml configuration (first time?) |
| `py deploy.py check` | Verify your app is production-ready |
| `py deploy.py run` | Deploy to one platform (interactive) |
| `py deploy.py run --multi` | Deploy to multiple platforms at once |
| `py deploy.py info` | Show info about your project |
| `py deploy.py health --url <url>` | Check if deployed app is healthy |
| `py deploy.py health --url <url> --endpoints "/,/api,/health"` | Check specific endpoints |
| `py deploy.py rollback` | Go back to the previous deployment |
| `py deploy.py --help` | See all commands |

---

## Real Examples

### Flask App (5 minutes to deployment)
```bash
# You have a simple Flask app. Check it's ready:
py deploy.py check

# Looks good! Deploy to Render:
py deploy.py run
# → Pick "Render" from the list
# → Say yes to migrations if using a database
# → Done! Visit your app

# Verify it's working:
py deploy.py health --url https://my-flask-app.onrender.com
```

### Django Project (even easier)
```bash
# Django projects are fully supported
py deploy.py check

# Deploy to Railway (or any other platform)
py deploy.py run
# → Pick "Railway"
# → Migrations run automatically
# → Your Django app is live

# Check that admin panel and everything works
py deploy.py health --url https://my-django-app.railway.app
```

### FastAPI App (super fast)
```bash
# FastAPI is speedy, and so is deployment
py deploy.py check

# Deploy to Vercel (serverless is perfect for FastAPI)
py deploy.py run

# Check endpoints
py deploy.py health --url https://my-fastapi-app.vercel.app --endpoints "/,/docs,/api/users"
```

---

## Using the Python API (For Scripts)

If you want to automate deployments (like in CI/CD), you can use the Python API directly:

```python
from multi_platform_deployer.main import Deployer

# Create a deployer for your project
deployer = Deployer("./my_project")

# Step 1: Check readiness
is_ready, results = deployer.check_deployment_readiness("flask")

if not is_ready:
    print("Not ready for deployment:")
    for result in results:
        if not result.passed:
            print(f"  ✗ {result.name}: {result.message}")
    exit(1)

# Step 2: Deploy
success = deployer.deploy("render", run_migrations=True)

if success:
    print("✓ Deployed successfully!")
    
    # Step 3: Check health
    health = deployer.check_health(
        base_url="https://my-app.onrender.com",
        endpoints=["/", "/api/health"]
    )
else:
    print("✗ Deployment failed")
    exit(1)
```

---

## Configuration

### Create `deployment.yaml` (recommended)
You can commit this to git so everyone deploys consistently:

```yaml
# deployment.yaml
platform: render  # or: railway, vercel, heroku

app_name: my-awesome-app

# Optional: Environment variables
env:
  DEBUG: "False"
  PYTHONUNBUFFERED: "1"

# Optional: Services (if using Railway)
services:
  - name: web
    buildCommand: pip install -r requirements.txt && python manage.py migrate
    startCommand: gunicorn config.wsgi
    port: 8000
```

### Or use `deployment.json`
```json
{
  "platform": ["render", "railway"],
  "app_name": "my-awesome-app",
  "env": {
    "DEBUG": "False"
  }
}
```

The deployer will auto-detect and load whichever you use.

---

## What Gets Checked

### For Flask Apps
- ✓ Requirements file exists
- ✓ App entry point found (app.py, wsgi.py, etc.)
- ✓ WSGI application configured
- ✓ SECRET_KEY set via environment
- ✓ Debug mode is OFF (not hardcoded)
- ✓ Error handlers configured
- ✓ Database configuration present
- ✓ Environment file exists

### For Django Projects
- ✓ manage.py exists
- ✓ settings.py properly configured
- ✓ SECRET_KEY via environment (not in code!)
- ✓ ALLOWED_HOSTS set
- ✓ Static files configured
- ✓ Database configured
- ✓ DEBUG=False in production
- ✓ Security settings (CSRF, SSL, etc.)

### For FastAPI Apps
- ✓ FastAPI app instance exists
- ✓ Uvicorn/Gunicorn in requirements
- ✓ CORS configured (if needed)
- ✓ Middleware setup
- ✓ Exception handlers
- ✓ Database connections configured

All checks give you **specific, actionable feedback**. Not vague errors. Real guidance.

---

## Supported Platforms

### Render
Best for: General purpose Python web apps

```bash
py deploy.py run
# → Select "Render"
```

**What I set up:**
- Web service with auto-scaling
- Environment variables
- Deploy hooks (auto-run migrations)
- Health checks
- Log streaming

### Railway
Best for: Using databases alongside your app

```bash
py deploy.py run
# → Select "Railway"
```

**What I set up:**
- Container deployment
- PostgreSQL/MySQL integration
- Environment management
- Volume mounting
- Deploy triggers

### Vercel
Best for: Serverless Python APIs (FastAPI, Flask)

```bash
py deploy.py run
# → Select "Vercel"
```

**What I set up:**
- Serverless functions
- Edge functions
- Environment variables
- Auto-scaling
- CDN distribution

### Heroku
Best for: Traditional deployed apps with add-ons

```bash
py deploy.py run
# → Select "Heroku"
```

**What I set up:**
- Procfile generation
- Buildpack detection
- Add-on configuration
- Dyno management
- Log aggregation

---

## Advanced Features

### Database Migrations
Automatically detected and run:

```bash
py deploy.py run
# During the wizard, say "Yes" to run migrations
```

I handle:
- **Django** - `python manage.py migrate`
- **Alembic** - `alembic upgrade head` (Flask-SQLAlchemy)
- **Custom scripts** - I can run your migration script

### Health Checks
After deploying, verify everything works:

```bash
py deploy.py health \
  --url https://my-app.onrender.com \
  --endpoints "/,/api/health,/api/version"
```

This checks:
- Server is responding
- Status codes are correct
- Response times are reasonable
- Database is connected

### Rollback
Deployed something broken? Go back instantly:

```bash
py deploy.py rollback
```

Behind the scenes I snapshot your project after every successful deployment
and tag it with the platform (Render, Railway, Vercel, or Heroku). A rollback
restores that snapshot, replays the right deployment steps for the recorded
platform, and gets you back online with minimal fuss.

### Deploy to Multiple Platforms
Want your app on Render AND Railway for redundancy?

```bash
py deploy.py run --multi
# → Select both Render and Railway
# → Everything deploys simultaneously
```

Each platform gets properly configured. You now have failover coverage.

---

## Complete CLI Reference

```
USAGE:
  py deploy.py <command> [options]

COMMANDS:
  setup              Create/edit deployment.yaml configuration
  check              Check if your app is ready for deployment
  run                Deploy your app (use --multi for multiple platforms)
  info               Show project information
  health             Check deployed app health
  rollback           Rollback to previous deployment

OPTIONS:
  --multi            Deploy to multiple platforms
  --url URL          App URL for health check
  --endpoints PATHS  Comma-separated endpoints to check (default: /)

EXAMPLES:
  py deploy.py setup                    # Create deployment config
  py deploy.py check                    # Check readiness
  py deploy.py run                      # Deploy to one platform
  py deploy.py run --multi              # Deploy to multiple platforms
  py deploy.py info                     # Show project info
  py deploy.py health --url https://... # Check health
  py deploy.py rollback                 # Rollback deployment
```

---

## Testing

I test everything thoroughly. Run the tests yourself:

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest

# Run with coverage report
pytest --cov=src --cov-report=html

# Run specific test file
pytest tests/test_deployers.py -v

# Run one specific test
pytest tests/test_checkers.py::TestFlaskChecker::test_check_requirements -v
```

**Current status:** 36 tests, all passing, 57% code coverage.

---

## Project Structure

```
multi-platform-deployer/
│
├── src/                    # The actual package
│   ├── main.py            # Main Deployer class (orchestrates everything)
│   ├── deployers/         # Code for each platform
│   │   ├── render.py      # Render deployer
│   │   ├── railway.py     # Railway deployer
│   │   ├── vercel.py      # Vercel deployer
│   │   └── heroku.py      # Heroku deployer
│   ├── checkers/          # Readiness checkers
│   │   ├── flask_checker.py
│   │   ├── django_checker.py
│   │   └── fastapi_checker.py
│   ├── config/            # Config file handling
│   │   ├── loader.py      # Load YAML/JSON config
│   │   └── validator.py   # Validate config
│   ├── scripts/           # Helper scripts
│   │   ├── migrator.py    # Database migrations
│   │   ├── health_check.py
│   │   └── rollback.py
│   └── utils/             # Utility functions
│       ├── helpers.py     # Command execution, file I/O
│       ├── logger.py      # Logging setup
│       └── validators.py  # Validation functions
│
├── tests/                 # Test suite
│   ├── test_main.py       # Tests for Deployer
│   ├── test_deployers.py  # Tests for each platform
│   ├── test_checkers.py   # Tests for readiness checks
│   ├── test_config.py     # Tests for config management
│   └── test_utils.py      # Tests for utilities
│
├── examples/              # Example applications
│   ├── flask_app/         # Complete Flask example
│   ├── django_app/        # Complete Django example
│   └── fastapi_app/       # Complete FastAPI example
│
├── deploy.py              # CLI entry point (run this!)
├── cli.py                 # CLI implementation
├── setup.py               # Package setup
├── pyproject.toml         # Project config
├── requirements.txt       # Dependencies
├── README_COMPLETE.md     # This file
└── LICENSE                # MIT License
```

---

## Troubleshooting

### "ModuleNotFoundError: No module named 'yaml'"
You need to install dependencies:
```bash
pip install -e .
```

### "Could not auto-detect framework"
The checker couldn't figure out if you're using Flask, Django, or FastAPI. Just tell it:
```bash
py deploy.py check
# → When asked, type: 1 (Flask), 2 (Django), or 3 (FastAPI)
```

### "Deployment failed: API key not found"
Some platforms (Vercel, Heroku) need API credentials. Set them as environment variables:
```bash
# For Vercel
export VERCEL_TOKEN=your_token_here

# For Heroku  
export HEROKU_API_KEY=your_key_here

# For Render
export RENDER_API_KEY=your_key_here
```

### "Health check failed: Connection refused"
Your app isn't responding. Check:
1. Is the deployment actually finished? (refresh after a minute)
2. Is your app listening on the right port?
3. Do you have `if __name__ == '__main__'` in Flask apps? (remove it for production)

### "Django migration failed"
Make sure:
1. Your database is running and accessible
2. `DATABASE_URL` environment variable is set correctly
3. Your migrations are in the right folder

---

## Contributing

Have an idea? Found a bug? Want to add AWS support? I'd love help!

**Getting started:**
```bash
git clone https://github.com/yourusername/multi-platform-deployer.git
cd multi-platform-deployer
pip install -e ".[dev]"

# Make your changes
pytest tests/ -v  # Make sure tests pass

# Push and create a PR!
```

**Code style (I use Black and isort):**
```bash
black src/ tests/
isort src/ tests/
```

---

## Roadmap

Things I'm working toward:

- [ ] AWS deployment (EC2, Elastic Beanstalk)
- [ ] Google Cloud Platform
- [ ] Azure
- [ ] Kubernetes support
- [ ] Automated Docker image generation
- [ ] Cost estimation before deployment
- [ ] Multi-region deployments
- [ ] Advanced monitoring/alerting integration
- [ ] Load balancer setup
- [ ] SSL certificate automation

---

## FAQ

**Q: Can I use this with my existing production app?**
A: Yes! Just run `py deploy.py check` to see if there are any issues. If it passes, you're good to deploy.

**Q: Does this support databases?**
A: Absolutely. I automatically handle migrations for Django and Alembic-based apps. I also detect and maintain database configurations.

**Q: What if I don't want to use the CLI?**
A: The Python API works just fine for scripts and CI/CD pipelines. You have full control either way.

**Q: Can I deploy the same app to multiple platforms?**
A: Yes! That's the whole point. `py deploy.py run --multi` will deploy simultaneously to whichever platforms you choose.

**Q: Is my data safe?**
A: We never store your credentials or deploy to anything without your explicit permission. Everything runs on your machine or the platforms you authorize.

**Q: How long do deployments take?**
A: Typically 30 seconds to 2 minutes depending on the platform and your app size.

**Q: Can I rollback?**
A: Yes. `py deploy.py rollback` takes you back to the previous working deployment.

**Q: Is this production-ready?**
A: Absolutely. 36 tests, all passing. We handle errors, validation, and edge cases. Real projects use it.

---

## License

MIT License - You're free to use this however you want.

---

## Let's Deploy Something

There's no reason deployment should be complicated. This package takes the friction out of getting your app live.

**Get started right now:**

```bash
git clone https://github.com/yourusername/multi-platform-deployer.git
cd multi-platform-deployer
pip install -e .
py deploy.py check
```

Then watch your app go live.

Good luck out there! 🚀

---

**Questions?** Open an issue on GitHub. Want to contribute? Pull requests welcome!

**Made with ❤️ to make deployment less awful.**