Metadata-Version: 2.4
Name: placemy
Version: 1.0.0
Summary: Your cloud architect — command-line VM placement for AWS, Azure, and GCP.
Author: Peter Hughes
License: MIT
Requires-Python: >=3.12
Requires-Dist: boto3<2.0,>=1.35.0
Requires-Dist: google-auth<3.0,>=2.30.0
Requires-Dist: google-cloud-billing<2.0,>=1.19.0
Requires-Dist: google-cloud-compute<2.0,>=1.19.0
Requires-Dist: google-cloud-monitoring<3.0,>=2.22.0
Requires-Dist: jinja2<4.0,>=3.1.0
Requires-Dist: numpy<3.0,>=2.0.0
Requires-Dist: pandas<4.0,>=3.0.0
Requires-Dist: pydantic-settings<3.0,>=2.1.0
Requires-Dist: pydantic<3.0,>=2.6.0
Requires-Dist: requests<3.0,>=2.31.0
Requires-Dist: rich<15.0,>=13.7.0
Requires-Dist: structlog<26.0,>=24.1.0
Requires-Dist: typer<1.0,>=0.12.0
Provides-Extra: dev
Requires-Dist: httpx<1.0,>=0.27.0; extra == 'dev'
Requires-Dist: mypy<2.0,>=1.10.0; extra == 'dev'
Requires-Dist: pre-commit<5.0,>=3.7.0; extra == 'dev'
Requires-Dist: pytest-cov<8.0,>=5.0.0; extra == 'dev'
Requires-Dist: pytest<10.0,>=8.0.0; extra == 'dev'
Requires-Dist: ruff<1.0,>=0.4.0; extra == 'dev'
Provides-Extra: package
Requires-Dist: build<2.0,>=1.2.0; extra == 'package'
Requires-Dist: pyinstaller<7.0,>=6.5.0; extra == 'package'
Description-Content-Type: text/markdown

# placemy.cloud

**Your Cloud Architect.** Multi-cloud workload placement and rightsizing as a
fat-client CLI that runs on your own machine, uses your existing cloud SDK
session, and syncs scan results to a state bucket inside *your* cloud account.

![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)
![Tests](https://img.shields.io/badge/tests-188%20passing-brightgreen)
![License](https://img.shields.io/badge/license-MIT-blue)

> This repository used to host a hosted SaaS (`app.placemy.cloud`). On
> 2026-04-09 the product pivoted to a fat-client architecture — the
> SaaS shell was deleted in Stage 10 of
> [`docs/fat-client-pivot-plan.md`](docs/fat-client-pivot-plan.md).
> The previous code lives on the `archive/saas-shell` branch.

## What it does

`placemy scan` discovers your running cloud workloads, profiles their actual
utilisation, compares them against every plausible VM SKU in the same region,
and produces a ranked list of rightsizing and placement recommendations — plus
a single-file branded HTML report you can hand to a client.

The dissertation evidence that backs the engine shows **19–67% savings across
5 test cases with a 32.5% median**.

## Architecture

```
┌────────────────────────┐               ┌──────────────────────────┐
│  placemy.cloud website │               │  PlaceMy CLI (fat client)│
│                        │               │                          │
│  - landing / pricing   │               │  - python, typer + rich  │
│  - Stripe checkout     │  licence key  │  - uses customer's local │
│  - licence issuance    │ ────────────► │    cloud SDK session     │
│  - download dashboard  │               │  - generates HTML reports│
│  - account / billing   │               │  - syncs to tenant bucket│
└────────────────────────┘               └──────────────────────────┘
                                                      │
                                                      │ scan data
                                                      ▼
                                         ┌──────────────────────────┐
                                         │  Customer's own cloud    │
                                         │                          │
                                         │  s3://placemy-state-…    │
                                         │  Azure Blob container    │
                                         │  gs://placemy-state-…    │
                                         │                          │
                                         │  Customer's IAM = ACL    │
                                         │  Customer's CloudTrail   │
                                         │    = audit log           │
                                         └──────────────────────────┘
```

**PlaceMy holds zero customer cloud data.** The website only stores
`email + licence_key + plan + status`. Everything else lives inside the
customer's own cloud account.

## Install

### Via pipx (users with Python ≥ 3.12)

```sh
pipx install placemy
```

### Via native binary (everyone else)

Download the binary for your platform from the latest release on GitHub,
`chmod +x`, and run. See [`docs/distribution.md`](docs/distribution.md).

## Quickstart

```sh
# 1. Authenticate to your cloud (PlaceMy never sees credentials)
aws sso login                                   # AWS
az login                                        # Azure
gcloud auth application-default login           # GCP

# 2. Activate your licence
placemy auth login

# 3. First-run setup — provisions the state bucket in your cloud
placemy bootstrap --provider aws

# 4. Scan
placemy scan --provider aws --json scan.json
placemy report --from scan.json --output report.html
placemy sync push scan.json --provider aws

# 5. Pull a previous scan on a different machine
placemy sync list --provider aws
placemy sync pull --provider aws --output previous.json
```

## Commands

```
placemy version
placemy whoami                         # which cloud tenants are active
placemy scan                           # discover → profile → recommend
placemy report --from scan.json        # render branded HTML report
placemy bootstrap                      # first-run state-bucket setup
placemy sync push|pull|list            # scan history in your state bucket
placemy auth login|status              # licence activation
```

The full surface is locked by
[`docs/fat-client-pivot-plan.md`](docs/fat-client-pivot-plan.md) §5.

## Development

```sh
# Install dev extras
pip install -e .[dev]

# Run tests
pytest -q

# Build a native binary for the current platform
pip install -e .[package]
scripts/build_binary.sh
```

## Repository layout

```
src/placemy/
    cli.py           # typer entry point (placemy console script)
    engine/          # scan() — the top-level pipeline entry
    cloud/           # AWS / Azure / GCP discovery + pricing (dissertation IP)
    pipeline/        # normalise, profile, candidates, decision packs
    analysis/        # classification + statistics
    models/          # dataclasses
    identity/        # tenant identification per cloud
    state/           # state-bucket discovery + sync backends
    bootstrap/       # guided first-run setup per cloud
    licence/         # licence validation + 30-day offline grace
    report/          # jinja2 HTML report renderer + branded template
    config.py        # pydantic-settings for engine knobs
    log.py
docs/
    fat-client-pivot-plan.md
    distribution.md
packaging/
    placemy.spec     # pyinstaller spec used by scripts/build_binary.sh
scripts/
    build_binary.sh
.github/workflows/
    ci.yml
    release.yml      # tag-driven wheel + 3-platform binary build
```

## Licence

MIT. See [LICENSE](LICENSE).
