Skip to main content

A Python port of Github's Scientist lib.

Project description

A Python library for carefully refactoring critical paths (and a port of GitHub’s Scientist).

Why?

See GitHub’s blog post — http://githubengineering.com/scientist/

But how?

Imagine you’ve implemented a complex caching strategy for some objects in your database and a stale cache is simply not acceptable. How could you test this and ensure parity with your previous implementation, under load, with production data? Run it in production!

Laboratory will:

  • Run both the new and the old code

  • Compare their results

  • Record timing information about all code

  • Swallow and record exceptions in the new code

  • Publish all of this information

Of course, you’re still unsure your candidate code works correctly, so laboratory will always return the result from the control block.

import laboratory

experiment = laboratory.Experiment()
with experiment.control() as c:
    c.record(get_objects_from_database())

with experiment.candidate() as c:
    c.record(get_objects_from_cache())

objects = experiment.run()

Publishing results

This data is useless unless we can do something with it. Laboratory makes no assumptions about how to do this — it’s entirely for you to implement to suit your needs. For example, timing data can be sent to graphite, and mismatches can be placed in a capped collection in redis for debugging later.

The publish method is passed a Result instance, with control and candidate data is available in Result.control and Result.observations respectively.

class MyExperiment(laboratory.Experiment):
    def publish(self, result):
        statsd.timing('MyExperiment.control', result.control.duration)
        for o in result.observations:
            statsd.timing('MyExperiment.%s' % o.name, o.duration)

Controlling comparison

Not all data is created equal. By default laboratory compares using ==, but sometimes you may need to tweak this to suit your needs. It’s easy enough — just subclass Experiment and implement the compare(control, observation) method.

class MyExperiment(Experiment):
    def compare(self, control, observation):
        return control.value['id'] == observation.value['id']

Adding context

A lot of the time there’s going to be extra context around an experiment that’s useful to use in publishing or comparisons. You can set this data in a few ways.

# The first is experiment-wide context, which will be set on every observation laboratory makes.

experiment = laboratory.Experiment(name='Object Cache Experiment', context={'user': user})


# Observation-specific context can be updated before or as the experiment is running.

with experiment.control(name='Object DB Strategy', context={'using': 'db'}) as e:
    e.update_context({'uuid': uuid})

    e.get_context() # ==
    # {
    #     'user': <User>,
    #     'uuid': 'c08d46f1-92a6-46e5-9185-82d90dcb5af1',
    #     'using': 'db',
    # }


with experiment.candidate(name='Object Cache Strategy', context={'using': 'cache'}) as e:
    e.update_context({'uuid': uuid})

    e.get_context() # ==
    # {
    #     'user': <User>,
    #     'using': 'cache',
    # }

Installation

Installing from pypi is recommended

$ pip install laboratory

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

laboratory-0.1.0.tar.gz (4.0 kB view details)

Uploaded Source

Built Distribution

laboratory-0.1.0-py2.py3-none-any.whl (6.9 kB view details)

Uploaded Python 2 Python 3

File details

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

File metadata

  • Download URL: laboratory-0.1.0.tar.gz
  • Upload date:
  • Size: 4.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for laboratory-0.1.0.tar.gz
Algorithm Hash digest
SHA256 40b41848c0447e62432da7166c1e0c59bc907393880acb53145c887c6770890b
MD5 bed76f0cac67f41ffeb805a1052771a1
BLAKE2b-256 a60b388f441b84fa164acf89632472709fbcccbd5c4ad8777fb8815f9d2e7a1f

See more details on using hashes here.

File details

Details for the file laboratory-0.1.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for laboratory-0.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 d18d10f8e0f924c8dea20478facd8e2be4d9f8b9f19c9c7a9335d32ee5c68385
MD5 1d0e346a79bc31d87f8cccae4daad503
BLAKE2b-256 3f2574a8649f7d7d1bc9ab0aa0591f26fe4e27a2e09e10290b6431e4950de373

See more details on using hashes here.

Supported by

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