Metadata-Version: 2.4
Name: sample_generator
Version: 0.5.0
Summary: Generate sample data from JSON schema or OAS models
Project-URL: Homepage, https://github.com/bartoszm/sample_generator
Project-URL: Repository, https://github.com/bartoszm/sample_generator
Project-URL: Issues, https://github.com/bartoszm/sample_generator/issues
Project-URL: Documentation, https://github.com/bartoszm/sample_generator#readme
Author-email: Bartosz Michalik <bartosz.michalik@gmail.com>
License: MIT
License-File: LICENSE
Keywords: fixtures,generator,json,jsonschema,oas,openapi,testing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: faker==37.1.0
Requires-Dist: jsonref~=1.1
Requires-Dist: jsonschema~=4.23
Requires-Dist: pydantic==2.11.3
Requires-Dist: pyyaml~=6.0
Requires-Dist: rstr==3.2.2
Provides-Extra: dev
Requires-Dist: black>=24.4; extra == 'dev'
Requires-Dist: ipykernel>=6.29; extra == 'dev'
Requires-Dist: isort>=5.13; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# json_sample_generator

Generate sample data from JSON Schema or OpenAPI (OAS) schemas. Create realistic samples for tests, examples, and fixtures.

[![CI](https://github.com/bartoszm/sample_generator/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bartoszm/sample_generator/actions/workflows/ci.yml)
[![PyPI version](https://img.shields.io/pypi/v/sample-generator.svg)](https://pypi.org/project/sample-generator/)
[![PyPI downloads/month](https://img.shields.io/pypi/dm/sample-generator.svg)](https://pypi.org/project/sample-generator/)
[![License](https://img.shields.io/github/license/bartoszm/sample_generator.svg)](https://github.com/bartoszm/sample_generator/blob/main/LICENSE)
[![Python versions](https://img.shields.io/pypi/pyversions/sample-generator.svg)](https://pypi.org/project/sample-generator/)

## Installation

From PyPI:

```bash
pip install sample-generator
# importable module name remains `json_sample_generator`
```

Or with uv:

```bash
uv add sample-generator
```

## Quickstart

Prerequisites:
- Python 3.12+
- uv installed

Install uv (Linux/macOS):
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Set up the project:
```bash
# Clone the repo
git clone https://github.com/<your-username>/json_sample_generator.git
cd json_sample_generator

# (Optional) create a virtualenv managed by uv
uv venv  # creates .venv/

# Install runtime deps
uv sync

# For development (tests, tools, etc.)
uv sync --group dev
```

Run tests:
```bash
uv run pytest -q
```

Run examples:
```bash
uv run python examples/simple_value_example.py
```

## Developer guide

Code quality tools used by the project

- uv (astral.sh/uv) — virtualenv + task runner used in CI
- ruff — linting (CI runs `uvx ruff check .`)
- black — formatting (CI runs `uvx black --check .`)
- isort — import sorting (CI runs `uvx isort --check-only .`)
- pytest — test runner (CI runs `uv run pytest -q`)

Automated-fix hints

- Run ruff's auto-fixer to apply quick lint fixes:
	```uvx ruff check . --fix```
- Reformat code with black:
	```uvx black .```
- Sort imports with isort:
	```uvx isort .```
- Run the full CI steps locally (create venv first):
	```bash
    uv venv
	uv sync --group dev
	uvx ruff check .
	uvx black --check . && uvx isort --check-only .
	uv run pytest -q
    ```

These commands mirror what GitHub Actions runs so you can reproduce and fix CI failures locally.

Build and publish reminders

The repository's publish workflow builds with `uv build` and uses the pypa/gh-action-pypi-publish action; for first-time releases you may need a PyPI API token (or configure OIDC/trusted publishing on PyPI).

Pre-commit (recommended):
```bash
uvx pre-commit install
uvx pre-commit run --all-files
```

## User guide: Scenarios

Scenarios let you override generated values per field path with simple values or callables, and optionally with pattern-based rules. They accept a Context so overrides can depend on other fields.

See the full guide (including `default_data`) in [`docs/SCENARIOS.md`](docs/SCENARIOS.md).

## User guide: Loading from OpenAPI (OAS)

To load a component schema from an OpenAPI Specification:

```python
import yaml
from src.json_sample_generator import JSONSchemaGenerator
from src.json_sample_generator.models import Schema

with open("api.yaml") as f:
    oas = yaml.safe_load(f)

schema = Schema.from_oas(oas, name="Pet")
gen = JSONSchemaGenerator(schema)
sample = gen.generate()
```

This correctly resolves cross-component `$ref` pointers. See the full guide in [`docs/OPENAPI.md`](docs/OPENAPI.md) for advanced usage, the `jsonref` caching details, and when to use `from_raw_data` vs `from_oas`.

## User guide: Break Scenarios

Break scenarios take a valid generated sample and intentionally corrupt it so that it fails JSON Schema validation — useful for negative-path tests, validator error-message testing, and schema-evolution checks.

See the full guide in [`docs/BREAK_SCENARIOS.md`](docs/BREAK_SCENARIOS.md).

## User guide: Capping array size with `generator_max_items`

When a schema declares a large `maxItems` (e.g. `10000`) the generator will, by default, pick a random length up to that bound and produce that many child elements. For deeply nested schemas this can be very slow and produce huge payloads that are not useful for tests or fixtures.

Pass `generator_max_items` to the `JSONSchemaGenerator` constructor to apply a *generator-wide* upper bound on array length. It does **not** replace the schema's `maxItems`; it only caps it from above.

```python
from json_sample_generator import JSONSchemaGenerator
from json_sample_generator.models import Schema

schema = Schema(data={
    "type": "object",
    "properties": {
        "tags": {
            "type": "array",
            "maxItems": 10000,           # schema permits very large arrays
            "items": {"type": "string"},
        }
    },
    "required": ["tags"],
})

# Cap every array generated by this instance at 5 elements.
gen = JSONSchemaGenerator(schema, generator_max_items=5)
sample = gen.generate()
assert len(sample["tags"]) <= 5
```

### Algorithm

For each array node, the effective upper bound is computed as:

1. If the schema **does not** declare `maxItems`:
   - use `generator_max_items` when it is set,
   - otherwise fall back to `max(minItems, 2)` (the legacy default).
2. If the schema **does** declare `maxItems`:
   - use `min(maxItems, generator_max_items)` when the cap is set,
   - otherwise use `maxItems` as-is.
3. The final element count is `random.randint(minItems, max_items)`.

Consequences:

- `generator_max_items=None` (the default) preserves existing behavior — no global cap is applied.
- When a schema omits `maxItems`, setting `generator_max_items=N` lets arrays grow up to `N` (instead of being silently capped at the `2` default).
- The schema's `minItems` is always respected. If a schema demands `minItems: 10` but you set `generator_max_items=5`, `random.randint(10, 5)` will raise `ValueError`. Choose a cap that is not lower than any `minItems` you expect to encounter.
- The schema's `maxItems` still wins when it is *smaller* than the global cap (`min(...)` semantics).
- Applies to every array node in the schema for that generator instance — there is no per-path override. Use `scenario.overrides` if you need to control a specific array's contents.

### When to use it

- Generating fixtures from third-party OpenAPI specs that declare unrealistically large `maxItems`.
- Speeding up property-based tests where the array size is incidental.
- Producing compact sample payloads for documentation or examples.

## Contributing

See `CONTRIBUTING.md`.

## License

MIT. See `LICENSE`.