Metadata-Version: 2.4
Name: jaysoft-rewind
Version: 0.1.0a3
Summary: Capture Python request failures and replay their dependency observations locally
Author-email: Jay Prakash Sonkar <iamjpsonkar@gmail.com>
Maintainer-email: Jay Prakash Sonkar <iamjpsonkar@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/iamjpsonkar/JaySoft-Rewind
Project-URL: Repository, https://github.com/iamjpsonkar/JaySoft-Rewind
Project-URL: Documentation, https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/index.md
Project-URL: Changelog, https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/iamjpsonkar/JaySoft-Rewind/issues
Keywords: debugging,replay,httpx,fastapi,testing
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: httpx
Requires-Dist: httpx<0.29,>=0.28; extra == "httpx"
Provides-Extra: fastapi
Requires-Dist: httpx<0.29,>=0.28; extra == "fastapi"
Requires-Dist: fastapi<1,>=0.115; extra == "fastapi"
Provides-Extra: flask
Requires-Dist: flask<4,>=3; extra == "flask"
Requires-Dist: httpx<0.29,>=0.28; extra == "flask"
Provides-Extra: sqlalchemy
Requires-Dist: sqlalchemy<3,>=2; extra == "sqlalchemy"
Provides-Extra: redis
Requires-Dist: redis<7,>=5; extra == "redis"
Provides-Extra: all
Requires-Dist: httpx<0.29,>=0.28; extra == "all"
Requires-Dist: fastapi<1,>=0.115; extra == "all"
Requires-Dist: flask<4,>=3; extra == "all"
Requires-Dist: sqlalchemy<3,>=2; extra == "all"
Requires-Dist: redis<7,>=5; extra == "all"
Provides-Extra: dev
Requires-Dist: httpx<0.29,>=0.28; extra == "dev"
Requires-Dist: fastapi<1,>=0.115; extra == "dev"
Requires-Dist: flask<4,>=3; extra == "dev"
Requires-Dist: sqlalchemy<3,>=2; extra == "dev"
Requires-Dist: redis<7,>=5; extra == "dev"
Requires-Dist: pytest<10,>=8; extra == "dev"
Requires-Dist: pytest-asyncio<2,>=0.24; extra == "dev"
Requires-Dist: ruff>=0.9; extra == "dev"
Requires-Dist: mypy>=1.14; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Provides-Extra: release
Requires-Dist: build>=1.2; extra == "release"
Requires-Dist: twine<7,>=6; extra == "release"
Dynamic: license-file

# Rewind

**Capture a Python failure. Replay the observations that caused it.**

Rewind records selected dependency calls while your application runs, then uses
those recorded observations to reproduce the outcome locally. Replay checks the
call order, arguments, and result; a missing or different observation produces
a divergence report instead of falling back to a live dependency.

Install the **`jaysoft-rewind`** distribution, import **`rewind`**, and use the
**`rewind`** command. The project is maintained by Jay Prakash Sonkar and licensed
under the MIT license.

[Documentation](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/index.md)
· [Getting started](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/getting-started.md)
· [Source](https://github.com/iamjpsonkar/JaySoft-Rewind)
· [Changelog](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/CHANGELOG.md)

## Install 0.1.0a3

This guide covers **Rewind `0.1.0a3`**, an alpha release for Python 3.11 and 3.12.

```sh
python -m pip install "jaysoft-rewind==0.1.0a3"
rewind --version
```

The core package has no mandatory third-party runtime dependencies. Install an
optional integration with the matching extra: `httpx`, `fastapi`, `flask`,
`sqlalchemy`, `redis`, or `all`. For example:

```sh
python -m pip install "jaysoft-rewind[fastapi]==0.1.0a3"
# Or, for Redis:
python -m pip install "jaysoft-rewind[redis]==0.1.0a3"
```

See the [installation guide](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/installation.md)
for environment setup and version selection.

## What you can capture in 0.1.0a3

- **Functions and requests:** synchronous or asynchronous callables, FastAPI/ASGI
  HTTP requests, and Flask/WSGI requests.
- **Dependency observations:** HTTPX requests, synchronous SQLite DB-API and
  SQLAlchemy SQLite operations, and supported Redis commands and pipelines.
- **Sources of variation:** explicit time, date, UUID, random, environment, and
  wait observations through Rewind's source APIs.
- **Optional diagnostics:** bounded function-entry, return, exception, and named
  span events, with dropped-event counts.

The developer tools inspect recordings, replay them in a fresh process, compare
changed source against an explicit expected outcome, generate pytest cases, and
export or import validated portable archives. Storage, capture limits, retention
conditions, and optional background persistence control the amount of data kept.

Adapters are explicit: installing Rewind alone does not intercept your clients
or instrument your application. The
[support matrix](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/support-matrix.md)
provides the tested contracts and exclusions for each integration.

## Try a failure and its replay

Save this as `rewind_demo.py` and run
`python rewind_demo.py`. It uses only synthetic fixture data and the core package.

```python
from tempfile import TemporaryDirectory

from rewind import CapturePolicy, LocalStore, Retention, Rewind

with TemporaryDirectory() as directory:
    store = LocalStore(directory)
    recorder = Rewind(
        application="checkout-demo",
        code_paths=[__file__],
        store=store,
        policy=CapturePolicy.synthetic(),
        retain=Retention(always=True),
    )
    live_calls = 0

    def payment_reply():
        global live_calls
        live_calls += 1
        return {"status": "accepted"}  # The fixture is missing receipt_id.

    def checkout():
        reply = recorder.value("payment.reply", payment_reply)
        return reply["receipt_id"]

    try:
        recorder.run_sync(checkout)
    except KeyError:
        pass

    snapshot = store.load(store.ids()[0])
    report = recorder.replay_sync(snapshot, checkout)
    assert report.reproduced, report.to_dict()
    assert live_calls == 1
    print(report.status)
    print(f"Live provider calls: {live_calls}")
```

Expected output:

```text
reproduced
Live provider calls: 1
```

The original execution raises `KeyError`. Replay produces the same failure from
the recorded reply without calling `payment_reply` again. Reproducing a failure
means it was faithfully observed; it does not mean the application has been
fixed. Use an explicit expected outcome when comparing a proposed fix.

The temporary recording is removed when this example ends. The
[getting-started guide](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/getting-started.md)
shows how to keep artifacts and connect the workflow to your application.

## Capture policy and replay boundaries

Capture defaults exclude application values and bodies. The synthetic policy in
the example opts into fixture values and exception arguments; use it only with
data you know contains no secrets. Named-field redaction, capture limits, and
unsupported operations can make an artifact incomplete. Incomplete artifacts
remain inspectable and are not eligible for strict replay.

Strict reproduction requires a compatible application fingerprint, Python and
adapter environment, policy, and entry point. Changed-source comparison is an
explicit separate mode. Replay reproduces supported observations; it does not
reconstruct a whole operating system, arbitrary native code, or a distributed
service environment. The default fresh-process Python audit guard is a
Python-level boundary. Network-disabled Docker verification provides a separate
OS-level network boundary for the included examples.

## Next steps

- [HTTPX and FastAPI](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/http-and-fastapi.md)
- [SQLite and SQLAlchemy](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/database.md)
- [Redis commands and pipelines](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/redis.md)
- [Explicit deterministic sources](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/sources.md)
- [Command-line reference](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/cli.md)
- [Troubleshooting](https://github.com/iamjpsonkar/JaySoft-Rewind/blob/main/docs/troubleshooting.md)
- [Report an issue](https://github.com/iamjpsonkar/JaySoft-Rewind/issues)
