Skip to main content

Live, dynamic network visualization of Python code — static call graph + runtime tracing in your browser.

Project description

Évariste

Live, dynamic network visualization of Python code — see your code as a living graph.

evariste-core gives Python the kind of interactive, in-browser call-graph view that other ecosystems take for granted:

  • Static graph — an AST-based map of your project (like Go to Definition rendered as a network). FastAPI routes are highlighted.
  • Runtime overlay — a @trace decorator streams real calls over a WebSocket; nodes warm, edges light, and timings appear as calls happen.
  • FastAPI Explorer — call your own endpoints from the UI and watch exactly which functions got touched, with captured arg values.

Minimal, zero-frontend-build, MIT-licensed.

Install

pip install evariste-core

The PyPI distribution is called evariste-core (the bare evariste name on PyPI belongs to an unrelated project). The Python import name is still just evariste — nothing in your code changes.

The 60-second tour — drop it into your FastAPI app

One line. That's the integration.

from fastapi import FastAPI
import evariste

app = FastAPI()
evariste.attach(app)      # <-- the whole thing

@app.get("/users/{user_id}")
def get_user(user_id: str):
    return load(user_id)

@app.post("/orders")
def create_order(cart: Cart):
    return checkout(cart)

Run your app normally (uvicorn myapp:app --reload), open http://localhost:8000/__evariste__/ui in a browser, and you'll see:

  • The static graph of every function in your source tree.
  • Endpoints highlighted and browsable from the left drawer.
  • Live runtime overlay — every request lights up its call tree.
  • A FastAPI tab where you can invoke routes from the UI and watch exactly which code paths fired, with captured arg values.

No second server, no extra port, no code changes beyond that one call.

What attach() does under the hood

  • Scans your source tree. Walks up from the caller's file to the outermost Python package to find your project root, then runs the AST analyzer on it.
  • Auto-traces every route. Wraps each registered APIRoute's handler with @evariste.trace so HTTP requests appear in the graph without you decorating anything manually.
  • Mounts the UI + API under /__evariste__/* on your own app — shares your port, your TLS, your reverse proxy.
  • Refuses non-loopback traffic by default. Accidentally shipping attach() to prod does not leak source code.

Safety knobs (all optional)

evariste.attach(
    app,
    # Defaults: loopback-only, no auth, no arg capture.
    allow_hosts=("127.0.0.1", "::1"),       # widen if behind a trusted proxy
    auth_token=None,                         # set a bearer token to gate access
    capture_args=False,                      # include arg/return reprs in events
    source_path=None,                        # override the auto-detected scan root
    prefix="/__evariste__",                  # change the URL mount prefix
    enabled=None,                            # None → defer to EVARISTE_DISABLED env
)

For production: set EVARISTE_DISABLED=1 in your prod environment. The attach() call becomes a no-op with zero code changes. One-line kill-switch your ops team controls.

Install + run an example

A realistic FastAPI demo ships in examples/demo_api.py:

pip install evariste-core
python examples/demo_api.py
# → FastAPI on http://localhost:8000
# → Évariste UI on http://localhost:8000/__evariste__/ui

The demo seeds its own traffic in a background thread so you get something visibly alive the moment you open the UI.

Manual decoration (when you need more control)

attach() auto-traces your endpoints. If you want internal helpers to appear in the live graph too, decorate them explicitly:

import evariste

@evariste.trace
def validate(token: str) -> bool: ...

@evariste.trace
async def fetch_user(user_id: str) -> User: ...

@trace works on sync, async, and methods. It uses functools.wraps so FastAPI's dependency system, Pydantic validation, and every other introspecting tool keep seeing the original signature.

To wrap a whole module at once:

import evariste, myapp.services
evariste.module_trace(myapp.services)

Standalone mode — no FastAPI?

You can still use Évariste with any Python codebase. Decorate what you care about, scan the source, start the server:

import evariste

@evariste.trace
def compute(n):
    return sum(i * i for i in range(n))

@evariste.trace
def handle_request():
    return compute(10_000)

evariste.scan(".")              # populate the static graph
evariste.start()                # http://localhost:7878 opens your browser

for _ in range(50):
    handle_request()

Or skip the code entirely and run the CLI:

evariste view path/to/your/project
# scans + serves the static graph on localhost:7878

Capturing args and return values

Off by default (zero overhead, zero leakage). Turn it on explicitly:

evariste.attach(app, capture_args=True)     # for FastAPI apps
# or
evariste.set_capture(True, max_repr=200)    # anywhere

Captured values appear in the inspector's "last invocation" panel, truncated to max_repr chars, safe-repr'd so broken __repr__ implementations can never break tracing.

Caching events to disk + replay

evariste.set_cache("evariste_events.jsonl")   # append-only JSONL

# Later:
evariste.replay("evariste_events.jsonl", speed=0.5)   # half-speed replay

Or from the CLI:

evariste replay evariste_events.jsonl --speed 1.0

Public API

Symbol Purpose
evariste.attach(app, **kw) FastAPI one-line integration. Scans, auto-traces, mounts the UI.
evariste.trace Decorator — wraps sync & async callables.
evariste.module_trace(module) Auto-wrap every public function/class in a module.
evariste.scan(path, *, module=None) AST analyzer — populate the static graph.
evariste.start(host, port, **kw) Launch the standalone viz server in a background thread.
evariste.stop() Shut the standalone server down.
evariste.set_capture(enabled, *, max_repr=120) Toggle arg/return capture.
evariste.set_cache(path) Persist events to a JSONL file.
evariste.replay(path, *, speed=1.0) Re-emit a cached event stream through the live UI.
evariste.events() Snapshot of the in-memory ring buffer (for tests).

Why "Évariste"?

After Évariste Galois — the mathematician who first saw structure as a graph of relationships.

License

MIT — see LICENSE. Bug reports and PRs welcome.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

evariste_core-0.3.0.tar.gz (103.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

evariste_core-0.3.0-py3-none-any.whl (83.7 kB view details)

Uploaded Python 3

File details

Details for the file evariste_core-0.3.0.tar.gz.

File metadata

  • Download URL: evariste_core-0.3.0.tar.gz
  • Upload date:
  • Size: 103.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for evariste_core-0.3.0.tar.gz
Algorithm Hash digest
SHA256 d413dfa3b94dc48ba0928ead2ac05aaa45f955e17c84435c7c26f157729b882b
MD5 cac443b5ae94d2362c07bbb384afd98e
BLAKE2b-256 cd4dc552fe0601d5d0aba9c584b2e220838e47b23e954622a5010fdbeac7c646

See more details on using hashes here.

File details

Details for the file evariste_core-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: evariste_core-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 83.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for evariste_core-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97ec9518f0e4846bb1423ddff32fba4eab74f6c1b1ec597f8abfb8f286ac9825
MD5 b2d70258fc364777a9ce219f1d1cb6ff
BLAKE2b-256 54ae4f82a53df36c0991d436a0caf27b00d22b2d09b8714921e8b38b6882a1c8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page