Introduction
What is machinable?
machinable is a Python API for research code. It provides an object-oriented skeleton that helps you develop and experiment in a unified interface while handling tedious housekeeping behind the scenes.
The key idea is to unify the running of code and the retrieval of produced results in one abstraction. A detailed discussion of this approach can be found in the about section, but for now, here is a minimal example that illustrates the idea.
- Write some code
from random import random
from pydantic import BaseModel, Field
from machinable import Component
class EstimatePi(Component):
class Config(BaseModel):
samples: int = 100
def __call__(self):
count = 0
for _ in range(self.config.samples):
x, y = random(), random()
count += int((x**2 + y**2) <= 1)
pi = 4 * count / self.config.samples
self.save_file(
"result.json",
{"count": count, "pi": pi},
)
def summary(self):
if self.execution.is_finished():
print(
f"After {self.config.samples} samples, "
f"PI is approximately {self.load_file('result.json')['pi']}."
)
- Run and inspect it using a unified abstraction
from machinable import get
# Imports component in `montecarlo.py` with samples=150;
# if an component with this configuration exists, it
# is automatically reloaded.
experiment = get("montecarlo", {"samples": 150})
# Executes the component unless it's already been computed
experiment.launch()
experiment.summary()
# >>> After 150 samples, PI is approximately 3.1466666666666665.
>>> from machinable import get
>>> experiment = get("montecarlo", {"samples": 150})
>>> experiment.launch()
Component <24aee0f>
>>> experiment.summary()
After 150 samples, PI is approximately 3.1466666666666665.
>>> experiment.execution.nickname
'chocolate_mosquito'
>>> experiment.finished_at().humanize()
'finished just now'
>>> experiment.local_directory()
'./storage/24aee0fd05024400b116593d1436e9f5'
$ machinable montecarlo samples=150 --launch --summary
> After 150 samples, PI is approximately 3.1466666666666665.
The above example demonstrates the two core principles of machinable code:
- Enforced modularity The Monte Carlo algorithm is encapsulated in its own module that can be instantiated with different configuration settings.
- Unified representation Running code is handled through the same interface that is used to retrieve produced results; multiple invocations simply reload and display the results without re-running the experiment.
You may already have questions - don't worry. We will cover the details in the rest of the documentation. For now, please read along so you can have a high-level understanding of what machinable offers.
What it is not
Research is extremely diverse so machinable primarily aims to be an API-spec that leaves concrete feature implementation to the user. Check out the examples to learn what this looks like in practice.
Where to go from here
⚙️ Installation
We recommend installing machinable to try things out while following along.
Designed to learn concepts hands-on. Starts with the bare minimum of concepts necessary to start using machinable. Along the way, it will provide pointers to sections that discuss concepts in more detail or cover more advanced functionality.
➡️ Check out the How-to guides
Explore real-world examples that demonstrate advanced concepts
Describes available APIs in full detail.