Metadata-Version: 2.5
Name: mock-api-py
Version: 0.1.0
Summary: Modern Instant Mock CRUD Engine with FastAPI, Rich CLI, and Chaos Testing
Author: Alexandr Motologa
License-Expression: MIT
License-File: LICENSE
Keywords: api,chaos,fastapi,json-server,mock,rest,testing
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.11
Requires-Dist: faker>=25.0.0
Requires-Dist: fastapi>=0.115.0
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: rich>=13.7.0
Requires-Dist: typer>=0.12.0
Requires-Dist: uvicorn[standard]>=0.30.0
Provides-Extra: dev
Requires-Dist: httpx>=0.27.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# ⚡ mock-api-py (fastmock)

[![Tests](https://github.com/alexandrmotologa/mock-api-py/actions/workflows/test.yml/badge.svg)](https://github.com/alexandrmotologa/mock-api-py/actions/workflows/test.yml)
[![Python](https://img.shields.io/badge/Python-3.11%2B%20%7C%203.12-blue?logo=python&logoColor=white)](https://www.python.org/)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.115%2B-009688?logo=fastapi&logoColor=white)](https://fastapi.tiangolo.com/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

> **Modern Instant Mock CRUD Engine with FastAPI, Rich CLI, and Chaos Testing.**  
> Spin up a full RESTful backend with filtering, sorting, pagination, and interactive Swagger documentation in under a second from a simple JSON file.

---

## 🚀 Why `mock-api-py`?

If you loved `json-server`, you will love `mock-api-py` even more:

- ⚡ **Lightning Fast**: Powered by ASGI and Uvicorn with async I/O.
- 📖 **Interactive Swagger UI**: Full OpenAPI docs automatically available at `/docs` and `/redoc`.
- 🎨 **Modern Console UX**: Styled Rich terminal output with detected resource tables and live-colored HTTP request logs.
- 🎲 **Built-in Chaos Engine**: Simulate realistic network conditions with latency jitter (`--delay 200-800`) and random 500 error injection (`--error-rate 0.1`) to test frontend resilience.
- 🔍 **Advanced Query Engine**:
  - Exact property filtering (`category=electronics&inStock=true`)
  - Comparative operators (`price_gt=25`, `price_gte=50`, `price_lt=100`, `price_lte=100`, `price_ne=29.99`)
  - Substring matching (`title_like=mouse`)
  - Full-text search across all object fields (`q=wireless`)
  - Multi-property sorting (`_sort=price&_order=desc`)
  - RFC-compliant pagination with `X-Total-Count` and `Link` headers (`_page=1&_limit=10`)
- 🔗 **Nested Relational Routes**: Automatically detects foreign keys (e.g. `userId` in `products` -> `GET /users/1/products`).
- 📘 **Auto TypeScript Generator**: One-click generation of fully-typed TypeScript interfaces for all collections (`GET /_types` and Studio viewer).
- 🔄 **Instant Database Reset**: Reset in-memory or persisted datasets back to initial boot state on-demand (`POST /_reset` or Studio button).
- 📤 **Mock File Uploads**: Upload images/documents via `POST /upload` with immediate static hosting at `/uploads/<filename>`.
- 🔌 **Smart Auto-Port Fallback**: Never crash due to a busy port; automatically finds and switches to the next free port.
- 🛡️ **Mock Authentication Engine**: Real HS256 JWT tokens, `/auth/login`, `/auth/register`, `/auth/me`, and bearer token protection on mutations (`--auth`).
- 🔀 **Custom URL Rewriter**: Map custom prefixes (`/api/*`), parameter aliases (`/articles/:id`), and query rewrites with `routes.json` (`--routes`).
- 💻 **Embedded Web Studio Dashboard**: Sleek dark-mode glassmorphic SPA at `/_admin` with live table/JSON views, search, query builder, TypeScript copy, and DB reset.
- 💾 **Safe Atomic Persistence**: In-memory speed by default with optional atomic write-back (`--save`) or strict `--read-only` mode.
- 👀 **Live Watch Mode**: Auto-reload in-memory data store when the JSON file changes on disk (`--watch`).
- 📁 **Static File Serving**: Serve static assets alongside mock APIs (`--static ./public`).

---

## 📦 Installation

Run directly with `uvx` (no installation required):
```bash
uvx mock-api-py db.json
```

Or install via `pip` / `uv`:
```bash
pip install mock-api-py
# or
uv tool install mock-api-py
```

---

## 🖥️ Console Interface

When you run `mock-api`, your terminal greets you with a clean, informative dashboard:

```
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                     ⚡ mock-api v0.1.0 ⚡                         ┃
┃           Modern Instant Mock CRUD Server for Developers         ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
 🚀 Server running at: http://127.0.0.1:8000
 📖 Interactive API Docs: http://127.0.0.1:8000/docs
 ⏱️  Simulated Delay: 300ms | 💾 Auto-save: ON
 📦 Detected Resources:
   • GET /products       [4 items]
   • GET /users          [2 items]
   • GET /profile        [1 object]

[2026-09-08 22:30:15] GET    /products?category=electronics - 200 OK (304.1ms)
[2026-09-08 22:30:18] POST   /products - 201 (301.5ms)
[2026-09-08 22:30:22] DELETE /products/1 - 200 OK (300.8ms)
```

---

## 🏁 Quickstart

### 1. Create a `db.json`
```json
{
  "products": [
    { "id": 1, "title": "Wireless Mouse", "price": 29.99, "category": "electronics", "inStock": true, "userId": 1 },
    { "id": 2, "title": "Mechanical Keyboard", "price": 89.99, "category": "electronics", "inStock": false, "userId": 1 }
  ],
  "users": [
    { "id": 1, "name": "Alice Johnson", "email": "alice@example.com" }
  ],
  "profile": {
    "name": "Alexandr",
    "theme": "dark"
  }
}
```

### 2. Start the Server
```bash
mock-api db.json
```

Visit:
- **API**: [http://127.0.0.1:8000/products](http://127.0.0.1:8000/products)
- **Interactive Docs**: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)

---

## 🛠️ CLI Usage & Flags

```bash
mock-api [DB_FILE] [OPTIONS]
```

### Options

| Flag | Short | Default | Description |
|------|-------|---------|-------------|
| `--port` | `-p` | `8000` | Port to bind the server to |
| `--host` | `-h` | `127.0.0.1` | Host address to bind |
| `--delay` | `-d` | `None` | Artificial latency in ms. Supports fixed (`300`) or jitter range (`200-800`) |
| `--error-rate` | `-e` | `0.0` | Random 500 error injection rate between `0.0` and `1.0` (e.g. `0.1` = 10%) |
| `--save` / `--write-back` | | `False` | Automatically persist POST/PUT/PATCH/DELETE mutations back to disk |
| `--read-only` | | `False` | Disallow all mutating HTTP methods (POST, PUT, PATCH, DELETE) |
| `--watch` | `-w` | `False` | Auto-reload in-memory database when the file is modified externally on disk |
| `--static` | | `None` | Directory to mount as static file server at `/static` |
| `--auth` | | `False` | Enable mock authentication and require JWT Bearer tokens for mutations |
| `--routes` | `-r` | `None` | Path to JSON custom routes rewriter file (e.g. `routes.json`) |

---

## 💻 Web Studio Dashboard (`/_admin`)

Access an interactive, modern dark-mode admin interface in your browser:
```
http://127.0.0.1:8000/_admin
```
Features:
- Live resource explorer showing all collections and singletons with real-time record counts.
- Instant full-text search (`q=`) and interactive sort controls.
- Single-click toggle between responsive data table and syntax-highlighted JSON viewer.
- **📘 TypeScript Modal**: Preview and copy auto-generated TypeScript interfaces with a single click.
- **🔄 Reset DB Button**: Revert the database back to its initial boot snapshot instantly.
- Direct links to Swagger OpenAPI documentation.

---

## 📘 TypeScript Types Generator (`/_types`)

Frontend developers can instantly generate strict TypeScript models matching their mock database:

```bash
# Fetch directly from CLI or build scripts
curl http://127.0.0.1:8000/_types > src/types/api.ts
```

Example generated output:
```typescript
export interface User {
  id: number;
  name: string;
  email: string;
  role?: string;
}

export interface Product {
  id: number;
  title: string;
  price: number;
  category: string;
  inStock: boolean;
}

export interface Database {
  users: User[];
  products: Product[];
}
```

---

## 🔄 Instant Database Reset (`/_reset`)

Testing destructive flows like deleting items or wiping profiles? Reset the database to its exact server-boot state at any time:

```bash
curl -X POST http://127.0.0.1:8000/_reset
```

Or simply click the **"🔄 Reset DB"** button in the Web Studio (`/_admin`).

---

## 📤 Mock File Uploads (`/upload`)

Simulate avatar uploads, attachments, or image pickers without setting up S3 or local storage:

```bash
curl -F "file=@avatar.png" http://127.0.0.1:8000/upload
```

Response:
```json
{
  "url": "/uploads/avatar.png",
  "filename": "avatar.png",
  "size": 42150,
  "contentType": "image/png"
}
```
The file is immediately accessible at `http://127.0.0.1:8000/uploads/avatar.png`.

---

## 🔌 Smart Auto-Port Fallback

Never get frustrated by `Error: [Errno 48] Address already in use`. If port 8000 is occupied by another app (or another `mock-api` instance), the engine smoothly seeks the next available port (8001, 8002, etc.) and starts right up with an alert in the console:

```
⚠️  Port 8000 is busy. Auto-switched to available port 8001.
```

---

## 🛡️ Mock Authentication & JWT

Simulate token-based authentication workflows in your frontend:

```bash
mock-api db.json --auth
```

When `--auth` is enabled:
1. Public endpoints: `GET` collection requests and Swagger docs remain accessible.
2. Mutating endpoints (`POST`, `PUT`, `PATCH`, `DELETE`) require an `Authorization: Bearer <token>` header, returning `401 Unauthorized` if missing or invalid.
3. Authenticate and obtain tokens:
   - `POST /auth/login` with `{ "email": "alice@example.com", "password": "any" }`
   - `POST /auth/register` with `{ "name": "Charlie", "email": "charlie@example.com" }`
   - `GET /auth/me` with `Authorization: Bearer <token>`

---

## 🔀 Custom URL Rewriter

Rewrite API paths, map legacy endpoints, or add global prefixes using a `routes.json` file:

```bash
mock-api db.json --routes routes.json
```

**`routes.json`**:
```json
{
  "/api/*": "/$1",
  "/articles/:id": "/posts/:id",
  "/top-products": "/products?_sort=price&_order=desc"
}
```
Now:
- `GET /api/users` ➔ routes to `GET /users`
- `GET /articles/42` ➔ routes to `GET /posts/42`
- `GET /top-products` ➔ routes to `GET /products?_sort=price&_order=desc`

---

## 🎲 Chaos Engineering Examples

Test how your React, Vue, or mobile frontend handles flaky networks and server errors:

```bash
# Add fixed 500ms latency to every request
mock-api db.json --delay 500

# Simulate variable 3G mobile network (jitter between 200ms and 900ms)
mock-api db.json --delay 200-900

# Inject a 15% random failure rate to test Error Boundaries
mock-api db.json --error-rate 0.15

# Combine jitter, chaos errors, and auto-save
mock-api db.json --delay 100-400 --error-rate 0.1 --save
```

---

## 🤖 Synthetic Data Generation

Need test data immediately? Generate realistic datasets with Faker:

```bash
mock-api generate --output data.json --schema "users:20,products:50,posts:30,comments:100"
```

Then boot it right up:
```bash
mock-api data.json
```

Supported built-in schemas: `users`, `products`, `posts`, `comments`, `todos`, `companies`, plus generic custom names.

---

## 📡 REST API & Query Reference

### Standard CRUD Endpoints
- `GET    /products` - List products with query filtering
- `GET    /products/1` - Get product by ID
- `POST   /products` - Create product (auto-generates unique ID)
- `PUT    /products/1` - Replace product
- `PATCH  /products/1` - Partially update product
- `DELETE /products/1` - Delete product

### Singleton Endpoints
- `GET   /profile` - Get singleton object
- `PATCH /profile` - Update singleton fields

### Query Parameters

| Feature | Example | Description |
|---------|---------|-------------|
| **Exact Filter** | `?category=electronics&inStock=true` | Filter by scalar attributes |
| **Greater Than or Equal** | `?price_gte=50` | Numeric or string comparison |
| **Less Than or Equal** | `?price_lte=100` | Numeric or string comparison |
| **Not Equal** | `?category_ne=furniture` | Exclude matching values |
| **Full-Text Search** | `?q=wireless` | Case-insensitive search across all fields |
| **Sort** | `?_sort=price&_order=desc` | Sort by field ascending or descending |
| **Pagination** | `?_page=1&_limit=10` | Returns items with `X-Total-Count` and RFC `Link` headers |
| **Nested Routes** | `GET /users/1/products` | Returns products belonging to `userId: 1` |

For detailed documentation, see [docs/api.md](docs/api.md).

---

## 🧪 Running Tests

```bash
# Create virtualenv and install dependencies
uv venv
uv pip install -e ".[dev]"

# Run full test suite
uv run pytest -v
```

---

## 📄 License

MIT © [Alexandr Motologa](LICENSE)
