Metadata-Version: 2.4
Name: mocka-api
Version: 0.1.0
Summary: Spin up a fake REST API from a dict or preset — for testing and prototyping
Author-email: mocka-api contributors <mocka-api@example.com>
License: MIT License
        
        Copyright (c) 2024 mockapi contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/MohitDhaker07/mocka-api-v1-1.0.01
Project-URL: Documentation, https://github.com/MohitDhaker07/mocka-api-v1-1.0.01#readme
Project-URL: Issues, https://github.com/MohitDhaker07/mocka-api-v1-1.0.01/issues
Project-URL: Changelog, https://github.com/MohitDhaker07/mocka-api-v1-1.0.01/blob/main/CHANGELOG.md
Keywords: mock,api,rest,testing,fake,server,pytest,flask
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Framework :: Flask
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: flask>=3.0
Requires-Dist: werkzeug>=3.0
Provides-Extra: presets
Requires-Dist: faker>=24.0; extra == "presets"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: requests; extra == "dev"
Requires-Dist: faker>=24.0; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: flask>=3.0; extra == "dev"
Requires-Dist: werkzeug>=3.0; extra == "dev"
Dynamic: license-file

# mocka

[![PyPI version](https://img.shields.io/pypi/v/mocka-api.svg)](https://pypi.org/project/mocka-api/)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Tests passing](https://img.shields.io/badge/tests-passing-brightgreen.svg)](https://github.com/yourname/mocka-api/actions)

**Spin up a fake REST API from a Python dict or built-in preset — for testing and prototyping.**

No Node.js required. No external service required. Just Python.

---

## Installation

```bash
# Core (custom schemas only)
pip install mocka-api

# With built-in presets (requires faker)
pip install mocka-api[presets]
```

---

## Quick start

### Custom schema

```python
from mockapi import MockAPI

api = MockAPI({
    "users": [{"id": 1, "name": "Alice", "email": "alice@example.com"}],
    "posts": [{"id": 1, "user_id": 1, "title": "Hello world", "body": "..."}]
})
api.serve(port=8080)
```

Full CRUD endpoints are immediately available:

```
GET    /users          → list all users
GET    /users/1        → get user 1
POST   /users          → create a user
PUT    /users/1        → replace user 1
PATCH  /users/1        → partial update user 1
DELETE /users/1        → delete user 1
```

### Context manager (pytest integration)

```python
import requests
from mockapi import MockAPI

def test_get_users():
    schema = {"users": [{"id": 1, "name": "Alice", "email": "alice@example.com"}]}
    with MockAPI(schema) as base_url:
        r = requests.get(f"{base_url}/users")
        assert r.status_code == 200
        assert r.json()["data"][0]["name"] == "Alice"
```

### Built-in preset

```python
from mockapi import MockAPI
from mockapi.presets import employees

api = MockAPI(employees(count=50))
api.serve(port=8080)
```

---

## Built-in presets

All presets require `pip install mocka-api[presets]`.

### employees

```python
from mockapi.presets import employees

with MockAPI(employees(count=30)) as base_url:
    # Collections: employees, departments
    pass
```

### healthcare

```python
from mockapi.presets import healthcare

with MockAPI(healthcare(patient_count=20, doctor_count=10)) as base_url:
    # Collections: patients, doctors, appointments
    pass
```

### education

```python
from mockapi.presets import education

with MockAPI(education(student_count=30, course_count=10)) as base_url:
    # Collections: students, courses, grades
    pass
```

### ecommerce

```python
from mockapi.presets import ecommerce

with MockAPI(ecommerce(product_count=50, user_count=20, order_count=40)) as base_url:
    # Collections: products, users, orders, categories
    pass
```

### movies / shows

```python
from mockapi.presets import movies, shows

with MockAPI(movies(count=30, genre="Action")) as base_url:
    # Collection: movies
    pass

with MockAPI(shows(count=20)) as base_url:
    # Collection: shows
    pass
```

---

## Query parameters

All `GET /<collection>` endpoints support:

| Parameter | Type | Description | Example |
|-----------|------|-------------|---------|
| `_limit` | int | Max records to return | `?_limit=10` |
| `_page` | int | Page number (1-based, requires `_limit`) | `?_limit=10&_page=2` |
| `_sort` | string | Field name to sort by | `?_sort=name` |
| `_order` | string | `asc` or `desc` (default: `asc`) | `?_sort=name&_order=desc` |
| `<field>` | any | Filter by exact value (strings: substring match) | `?status=active` |

### Examples

```bash
# Pagination
GET /users?_limit=10&_page=1

# Sorting
GET /users?_sort=name&_order=asc

# Filtering
GET /users?status=active&role=admin

# Combined
GET /users?status=active&_sort=name&_limit=5&_page=1
```

---

## Response format

### List response (`GET /<collection>`)

```json
{
  "data": [
    {"id": 1, "name": "Alice", "email": "alice@example.com"}
  ],
  "meta": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "pages": 10
  }
}
```

When no pagination params are provided, `page`, `limit`, and `pages` are `null`.

### Single record (`GET /<collection>/<id>`)

```json
{"id": 1, "name": "Alice", "email": "alice@example.com"}
```

### Error response

```json
{
  "error": "RecordNotFoundError",
  "message": "Record with id=999 does not exist in collection 'users'.",
  "status": 404
}
```

---

## Pytest integration

```python
import requests
import pytest
from mockapi import MockAPI

SCHEMA = {
    "students": [
        {"id": 1, "name": "Alice", "grade": "A"},
        {"id": 2, "name": "Bob", "grade": "B"},
    ]
}

@pytest.fixture
def api():
    with MockAPI(SCHEMA) as base_url:
        yield base_url

def test_list_students(api):
    r = requests.get(f"{api}/students")
    assert r.status_code == 200
    assert r.json()["meta"]["total"] == 2

def test_get_student(api):
    r = requests.get(f"{api}/students/1")
    assert r.status_code == 200
    assert r.json()["name"] == "Alice"

def test_create_student(api):
    r = requests.post(
        f"{api}/students",
        json={"name": "Charlie", "grade": "A+"},
        headers={"Content-Type": "application/json"},
    )
    assert r.status_code == 201
    assert r.json()["id"] == 3
```

---

## CLI usage

```bash
# Serve from a JSON schema file
mockapi serve --schema schema.json --port 8080 --delay 100

# Serve a built-in preset
mockapi preset employees --count 50 --port 8080

# List all available presets
mockapi presets list
```

### CLI flags

| Flag | Description | Default |
|------|-------------|---------|
| `--port` | Port to bind | `8080` |
| `--host` | Host to bind | `127.0.0.1` |
| `--delay` | Artificial response delay (ms) | `0` |
| `--quiet` | Suppress startup banner | `false` |

---

## Configuration reference

```python
MockAPI(
    schema,          # dict: required — your data
    port=8080,       # int: preferred port (auto-retries if busy)
    host="127.0.0.1",# str: bind address
    delay=0,         # int: ms of artificial latency added to every response
    quiet=False,     # bool: suppress startup banner in serve()
    reset_on_exit=True, # bool: reset store to seed data on context exit
)
```

### Methods

| Method | Description |
|--------|-------------|
| `serve(port, host, open_browser)` | Start server; blocks until Ctrl+C |
| `start()` | Start server; returns base URL (non-blocking) |
| `stop()` | Stop server |
| `url()` | Return base URL |
| `reset(collection=None)` | Reset all or one collection to seed data |
| `snapshot()` | Return deep copy of current store state |

---

## Contributing

1. Fork the repository
2. Install dev dependencies: `pip install -e ".[dev]"`
3. Run the test suite: `pytest`
4. Run linting: `ruff check . && mypy mockapi/`
5. Open a pull request

See [CONTRIBUTING.md](CONTRIBUTING.md) for full details.

---

## License

[MIT License](LICENSE) — Copyright 2024 mocka-api contributors
