The Modular Autonomous Discovery for Science (MADSci) Resource Manager.
Project description
MADSci Resource Manager
The MADSci Resource Manager provides tooling for tracking and managing the full lifecycle of all the resources (including assets, consumables, samples, containers, and any other physical object) used in an automated/autonomous laboratory.
Notable Features
- Provides a robust Resource Type library and hierarchy for different "archetypes" of resource.
- Complete history for every tracked resource, and support for restoring deleted/removed resources
- Supports querying both active resources and history
- Provides a REST-based API compatible with the MADSci Resource Client (see MADSci Clients).
- Enforces logical constraints on resources based on their properties, helping to catch errors like accidental virtual duplication of physical objects or nonsensical outcomes like negative quantities or overflows.
Core Concepts
Resource Types and the Type Hierarchy
MADSci Resource Manager supports various resource types, including:
- Resource: Base class for all resources.
- Asset: Tracked resources that aren't consumed (e.g., samples, labware).
- Consumable: Resources that are consumed (e.g., reagents, pipette tips).
- Container: Resources that can hold other resources (e.g., racks, plates).
- Collection: Containers that support random access.
- Row: Single-dimensional containers.
- Grid: Two-dimensional containers.
- VoxelGrid: Three-dimensional containers.
- Slot: A container that supports exactly zero or one child. Ideal for things like plate nests.
- Stack: Single-dimensional containers supporting LIFO access.
- Queue: Single-dimensional containers supporting FIFO access.
- Pool: Containers for holding consumables that are mixed or collocated.
You can define a resource using the ResourceDefinition types included in madsci.common.types.resource_types.definitions. These resource definitions can be used to query, create new, or attach to existing Resources.
Usage
Manager
To create and run a new MADSci Resource Manager, do the following in your MADSci lab directory:
- If you're not using docker compose, provision and configure an SQL database (we recommend and test against PostgreSQL, but other flavors may work).
- If you're using docker compose, create or add something like the following to your Lab's
compose.yaml, defining your docker compose services for the ResourceManager and a PostgreSQL database to store your resources.
name: madsci_example_lab
services:
postgres:
container_name: postgres
image: postgres:17
environment:
- POSTGRES_USER=...
- POSTGRES_PASSWORD=...
- POSTGRES_DB=resources
ports:
- 5432:5432
resource_manager:
container_name: resource_manager
image: ghcr.io/ad-sdl/madsci:latest
build:
context: ..
dockerfile: Dockerfile
environment:
- USER_ID=1000
- GROUP_ID=1000
network_mode: host
volumes:
- /path/to/your/lab/directory:/home/madsci/lab/
- .madsci:/home/madsci/.madsci/
command: python -m madsci.resource_manager.resource_server
depends_on:
- postgres
# Create a new Resource Manager Definition
madsci manager add -t resource_manager
# Start the database and Resource Manager's REST Server
docker compose up
# OR
python -m madsci.resource_manager.resource_server
You should see a REST server started on the configured host and port. Navigate in your browser to the URL you configured (default: http://localhost:8003/) to see if it's working.
You can see up-to-date documentation on the endpoints provided by your resource manager, and try them out, via the swagger page served at http://your-server-url-here/docs.
Client
Ensure you have access to the Resource Manager API and initialize the client:
from madsci.client.resource_client import ResourceClient
url = "http://localhost:8003"
client = ResourceClient(url=url)
Adding a Resource
This saves a new resource to the resource database.
from madsci.common.types.resource_types import Resource
resource = Resource(
resource_name="Sample Resource",
resource_class="sample",
)
added_resource = client.add_resource(resource)
print(added_resource)
Initializing a Resource
This saves a new resource to the resource database, if a matching resource doesn't exist already, or attaches to the existing resource if it does.
from madsci.common.types.resource_types.definitions import ResourceDefinition
resource = ResourceDefinition(
resource_name="Sample Resource",
resource_class="sample",
)
initialized_resource = client.init_resource(resource)
print(intialized_resource)
Updating a Resource
Updates an existing resource.
resource.resource_name = "Updated Sample Resource"
updated_resource = client.update_resource(resource)
print(updated_resource)
Getting a Resource
Get the current state of a given resource.
fetched_resource = client.get_resource(resource_id=added_resource.resource_id)
print(fetched_resource)
Querying Resources
Query for a resource(s) that matches the provided parameters. Can specify whether to return multiple or require that there is a unique matching result.
resources = client.query_resource(resource_class="sample", multiple=True)
for resource in resources:
print(resource)
Removing a Resource
Delete a resource (the resource is preserved in the History table)
removed_resource = client.remove_resource(resource_id=added_resource.resource_id)
print(removed_resource)
Querying Resource History
Get the entire history of a resource, from creation to deletion and every change in between.
history = client.query_history(resource_id=added_resource.resource_id)
print(history)
import datetime
history = client.query_history(start_date=datetime.now(), change_type="Updated")
print(history)
Restoring a Deleted Resource
Restore the latest version of a deleted resource.
restored_resource = client.restore_deleted_resource(resource_id=added_resource.resource_id)
print(restored_resource)
Pushing a Resource to a Stack, Queue, or Slot
Push a child resource onto a container, for containers that don't support random access.
from madsci.common.types.resource_types import Stack
stack = Stack(resource_name="Sample Stack")
added_stack = client.add_resource(stack)
pushed_resource = client.push(resource=added_stack, child=added_resource)
print(pushed_resource)
Popping a Resource from a Stack, Queue, or Slot
Pop a child resource from a non-random access container.
popped_resource, updated_stack = client.pop(resource=added_stack)
print(popped_resource, updated_stack)
Setting a Child Resource in a Container
Set a child at a specific key of a random access container.
from madsci.common.types.resource_types import Grid
grid = Grid(resource_name="Sample Grid", columns=8, rows=12)
added_grid = client.add_resource(grid)
set_child_resource = client.set_child(resource=added_grid, key=(0, 0), child=added_resource)
print(set_child_resource)
Removing a Child Resource from a Container
Remove a child from a specific key of a random access container.
removed_child_resource = client.remove_child(resource=added_grid, key=(0, 0))
print(removed_child_resource)
Setting the Quantity of a Consumable
Set the quantity of a consumable resource.
from madsci.common.types.resource_types import Consumable
consumable = Consumable(resource_name="Sample Consumable", quantity=10)
added_consumable = client.add_resource(consumable)
updated_consumable = client.set_quantity(resource=added_consumable, quantity=20)
print(updated_consumable)
Changing the Quantity of a Consumable
Increase or decrease the quantity of a consumable by an amount.
changed_consumable = client.change_quantity_by(resource=added_consumable, amount=5)
print(changed_consumable)
Increasing the Quantity of a Consumable
Strictly increase the quantity of a consumable by an amount.
increased_consumable = client.increase_quantity(resource=added_consumable, amount=5)
print(increased_consumable)
Decreasing the Quantity of a Consumable
Strictly decrease the quantity of a consumable by an amount.
decreased_consumable = client.decrease_quantity(resource=added_consumable, amount=5)
print(decreased_consumable)
Setting the Capacity of a Resource
Set the capacity (i.e., maximum quantity) of a resource.
updated_capacity_resource = client.set_capacity(resource=added_consumable, capacity=50)
print(updated_capacity_resource)
Removing the Capacity Limit of a Resource
Remove the capacity (i.e., maximum quantity) of a resource.
removed_capacity_resource = client.remove_capacity_limit(resource=added_consumable)
print(removed_capacity_resource)
Emptying a Resource
Empty a consumable or container resource.
emptied_resource = client.empty(resource=added_consumable)
print(emptied_resource)
Filling a Resource
Fill a consumable resource.
filled_resource = client.fill(resource=added_consumable)
print(filled_resource)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file madsci_resource_manager-0.4.1.tar.gz.
File metadata
- Download URL: madsci_resource_manager-0.4.1.tar.gz
- Upload date:
- Size: 27.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.25.2 CPython/3.9.22 Linux/6.11.0-1015-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f80ae5c5074e917ec437792f8492cde07b2c65b2f3d45ed8be5b7e2dda495a1
|
|
| MD5 |
d0cb05a45cf4aa1a3a6a300c63c6a90d
|
|
| BLAKE2b-256 |
e3b38558e6e5f7c6263ff8b7868eeb85e6f4b43ba07fa1ddae965561eda1a8f3
|
File details
Details for the file madsci_resource_manager-0.4.1-py3-none-any.whl.
File metadata
- Download URL: madsci_resource_manager-0.4.1-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: pdm/2.25.2 CPython/3.9.22 Linux/6.11.0-1015-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26f0047fb9b6cbde0ea0617fb08c7602cc0d8921b54b4b137c37f2178f953c87
|
|
| MD5 |
4ef96961d741b2db924c7dbba02a6c50
|
|
| BLAKE2b-256 |
2c779f2f490aa2e2a307b6efe774be1600a744706debf71afd8ea61ae6e38480
|