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 lazy fuckers like me need to understand their code.

  • 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.

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 of some French math teacher, Kudos to that bro, I'm a French math guy too). The Python import name is still just evariste — nothing in your code changes.

Drop it into your FastAPI app

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.

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 and 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 preferred dying a duel rather than losing face, and wrote Group theory the night before the fight.

Talk about badass.

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.1.tar.gz (106.7 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.1-py3-none-any.whl (86.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: evariste_core-0.3.1.tar.gz
  • Upload date:
  • Size: 106.7 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.1.tar.gz
Algorithm Hash digest
SHA256 aebfd4c5d43241f41c89b343a4ce4d3ccf14fc891f9bb5cad6ac669befbafc68
MD5 2bf98666527a8167f807668ddbec676b
BLAKE2b-256 464cbb742343439648b504b792bc2c692a8b9fcc13797231b6db0c75c45e6b6f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: evariste_core-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 86.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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 946400f5e82a6b9208ca06d270a0e1b56cc0fb4ef15627322d2c60f8d9a35467
MD5 5da67071c1febf8274f42451dbcc4651
BLAKE2b-256 5fb6e24f71fbad996108e4a0678359414e4160c462d364ea8815dfbc499f2451

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