Skip to main content

A lightweight async-compatible experiment framework for safely comparing candidate code paths to control logic.

Project description

Scientist-Py

A lightweight, async-compatible Python port of GitHub's Scientist for testing candidate code paths against a control in production without affecting users.

Features

  • 🧪 Run control and candidate functions safely
  • ⏱️ Measure execution time of each path
  • ⚠️ Compare results and log mismatches
  • ✅ Support for async functions
  • 🎯 Sampling to control experiment frequency
  • 🛡️ Ignore known exceptions
  • 📊 Metric logging out-of-the-box

What are Control and Candidate in Scientist?

Control = The current, trusted, production logic.

Candidate = The new or experimental logic you're testing against the control.

Why use this?

It’s the safest way to test new implementations without breaking stuff. You can:

Rewrite a function (e.g., old regex → new parser)

Replace a service call (e.g., REST → GraphQL)

Try a new algorithm or optimization

All while continuing to serve the real user with the proven control.


Installation

Simply copy the Experiment class into your project. No external dependencies required.


Usage

Basic Example

from experiment import Experiment

exp = Experiment("add-function")

@exp.control
def control():
    return 2 + 2

@exp.candidate
def candidate():
    return 2 + 2  # or some experimental logic

result = await exp.run()

With async functions

@exp.control
async def control():
    await asyncio.sleep(0.1)
    return 2 + 2

@exp.candidate
async def candidate():
    await asyncio.sleep(0.1)
    return 4

Add a custom comparator

exp.compare_with(lambda a, b: round(a, 2) == round(b, 2))

Ignore known exceptions

exp.ignore_exceptions(ValueError)

Enable sampling (e.g. 10% of the time)

exp.sample(0.1)

Logging Output

When a mismatch is found, logs look like:

[Experiment: add-function] Mismatch detected!
 - Control result: 4
 - Candidate result: 5
[Experiment: add-function] Metrics:
 - Control duration: 0.000120 sec
 - Candidate duration: 0.000150 sec
 - Match: False

License

MIT (or adapt as needed for internal tools)


Inspired By


TODO

  • Persistent result storage (e.g., file/DB)
  • Dashboard or reporting
  • Integration with Prometheus or StatsD

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

scientist_py-0.1.0.tar.gz (4.6 kB view details)

Uploaded Source

Built Distribution

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

scientist_py-0.1.0-py3-none-any.whl (4.6 kB view details)

Uploaded Python 3

File details

Details for the file scientist_py-0.1.0.tar.gz.

File metadata

  • Download URL: scientist_py-0.1.0.tar.gz
  • Upload date:
  • Size: 4.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for scientist_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0e0a38bbba9e9362970a28fe4e11757bbcff9ee80f462796304ddc0fb0c9a8da
MD5 b4e90a0d1e3710f36ac1baa3f5f439d5
BLAKE2b-256 4df9c20c711c0100734912c5add42647e604688ab7397f2abc20b6e7bfb59a40

See more details on using hashes here.

File details

Details for the file scientist_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: scientist_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 4.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for scientist_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d0d98b598773bb9e5e4a6c089aa1a0d80a6ccfec7e7c481bd6d7db418f3ec8f1
MD5 93681db705c20539685659094f9f5ce0
BLAKE2b-256 ba2f77e1cf5960f7976c0fd63cf57b9b548b9fce381c080c80b9eb12fc7013d2

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