Environment Setup¶
You'll need a Barista token to interact with the API. For development/testing, you can use the dev server token:
import os
import json
from noctua.barista import BaristaClient, BaristaError
# Ensure BARISTA_TOKEN is set in your environment
# For development: Contact the GO team for a dev token
# For production: Get token from Noctua login
if not os.environ.get("BARISTA_TOKEN"):
print("ERROR: BARISTA_TOKEN environment variable not set")
print("Please set: export BARISTA_TOKEN=your-token-here")
raise SystemExit(1)
# Test model ID - change this to an existing model on your server
TEST_MODEL_ID = "gomodel:6796b94c00003233"
print("Environment configured for Barista API")
1. Creating a Barista Client¶
The BaristaClient is your main interface to the GO-CAM API:
2. Listing Models¶
List all available GO-CAM models with filtering options:
# List models with various filters
result = client.list_models(
limit=5, # Limit to 5 models
state="development" # Only development models
)
models = result.get("models", [])
total = result.get("n", 0)
print(f"Found {total} total models, showing {len(models)}:")
print()
for model in models:
model_id = model.get("id", "")
title = model.get("title", "(no title)")
state = model.get("state", "")
print(f"ID: {model_id}")
print(f" Title: {title[:80]}..." if len(title) > 80 else f" Title: {title}")
print(f" State: {state}")
print()
3. Creating a New Model¶
Create a new empty GO-CAM model:
# Create a new model with a title
response = client.create_model(title="Demo GO-CAM Model from Jupyter")
if response.ok:
new_model_id = response.model_id
print(f"Successfully created model: {new_model_id}")
else:
print(f"Failed to create model: {response.raw}")
new_model_id = TEST_MODEL_ID # Fall back to test model
print(f"Using existing test model: {new_model_id}")
4. Getting Model Details¶
Retrieve the full details of a GO-CAM model:
# Get model details
response = client.get_model(new_model_id)
if response.ok:
print(f"Model ID: {response.model_id}")
print(f"State: {response.model_state}")
print(f"Number of individuals: {len(response.individuals)}")
print(f"Number of facts/edges: {len(response.facts)}")
# Show first few individuals if any
if response.individuals:
print("\nFirst 3 individuals:")
for ind in response.individuals[:3]:
ind_id = ind.get("id", "")
types = ind.get("type", [])
if types:
type_str = ", ".join([t.get("label", t.get("id", "")) for t in types if t])
print(f" - {ind_id}: {type_str}")
else:
print(f"Failed to get model: {response.raw}")
5. Adding Individuals (Nodes)¶
Add molecular function individuals to the model:
# Add some molecular function individuals
activities = [
("GO:0003924", "GTPase activity", "ras"),
("GO:0004674", "protein serine/threonine kinase activity", "raf"),
("GO:0004707", "MAP kinase activity", "erk")
]
added_individuals = {}
for go_id, label, var_name in activities:
response = client.add_individual(new_model_id, go_id, assign_var=var_name)
if response.ok:
# Find the newly added individual
for ind in response.individuals:
types = ind.get("type", [])
for t in types:
if t.get("id") == go_id:
added_individuals[var_name] = ind["id"]
print(f"Added {label}: {ind['id']}")
break
else:
print(f"Failed to add {label}: {response.raw.get('message', 'Unknown error')}")
6. Adding Facts (Edges)¶
Connect individuals with causal relationships:
# Add causal relationships if we have individuals
if len(added_individuals) >= 2:
# Get the actual IDs
ras_id = added_individuals.get("ras")
raf_id = added_individuals.get("raf")
erk_id = added_individuals.get("erk")
# Add edges if we have the nodes
if ras_id and raf_id:
response = client.add_fact(
new_model_id,
subject_id=ras_id,
object_id=raf_id,
predicate_id="RO:0002413" # directly positively regulates
)
if response.ok:
print("Added edge: RAS -> RAF")
else:
print(f"Failed to add edge: {response.raw.get('message', '')}")
if raf_id and erk_id:
response = client.add_fact(
new_model_id,
subject_id=raf_id,
object_id=erk_id,
predicate_id="RO:0002413"
)
if response.ok:
print("Added edge: RAF -> ERK")
else:
print(f"Failed to add edge: {response.raw.get('message', '')}")
else:
print("Not enough individuals to create edges")
7. Adding Evidence¶
Add evidence annotations to support facts:
# Add evidence to an edge if we have one
if len(added_individuals) >= 2 and "ras" in added_individuals and "raf" in added_individuals:
ras_id = added_individuals["ras"]
raf_id = added_individuals["raf"]
# Build the evidence requests
evidence_requests = client.req_add_evidence_to_fact(
new_model_id,
subject_id=ras_id,
object_id=raf_id,
predicate_id="RO:0002413",
eco_id="ECO:0000314", # direct assay evidence
sources=["PMID:12345678"],
with_from=["UniProtKB:P01112"] # HRAS
)
# Execute the batch request
response = client.m3_batch(evidence_requests)
if response.ok:
print("Successfully added evidence to RAS->RAF edge")
else:
print(f"Failed to add evidence: {response.raw.get('message', '')}")
else:
print("No edges available to add evidence")
8. Exporting Models¶
Export models in different formats:
# Get the model in native Minerva JSON format
response = client.get_model(new_model_id)
if response.ok:
print("Model structure (native Minerva JSON):")
print(f"- Model ID: {response.model_id}")
print(f"- Individuals: {len(response.individuals)}")
print(f"- Facts: {len(response.facts)}")
# Show compact version
data = response.raw.get("data", {})
compact = {
"id": data.get("id"),
"individuals_count": len(data.get("individuals", [])),
"facts_count": len(data.get("facts", [])),
"annotations": data.get("annotations", [])
}
print("\nCompact view:")
print(json.dumps(compact, indent=2))
else:
print(f"Failed to export: {response.raw}")
9. Converting to GO-CAM Format¶
Convert the Minerva JSON to standard GO-CAM format (if the model has proper structure):
try:
from gocam.translation.minerva_wrapper import MinervaWrapper
# Get the model data
response = client.get_model(new_model_id)
if response.ok:
minerva_data = response.raw.get("data", {})
# Ensure required fields
if "id" not in minerva_data:
minerva_data["id"] = new_model_id
if "title" not in minerva_data:
minerva_data["title"] = "Demo Model"
# Try to convert (may fail if model doesn't have enabled_by facts)
try:
gocam_model = MinervaWrapper.minerva_object_to_model(minerva_data)
print("Successfully converted to GO-CAM format!")
print(f"Model ID: {gocam_model.id}")
print(f"Title: {gocam_model.title}")
if gocam_model.activities:
print(f"Activities: {len(gocam_model.activities)}")
except Exception as e:
print(f"Note: Model doesn't follow standard GO-CAM structure: {e}")
print("This is normal for models without enabled_by facts linking to gene products")
else:
print("Failed to get model")
except ImportError:
print("gocam package not installed. Install with: pip install gocam")
10. Deleting Model Elements¶
Remove edges and individuals from the model:
# Delete an edge if we have one
if len(added_individuals) >= 2 and "raf" in added_individuals and "erk" in added_individuals:
raf_id = added_individuals["raf"]
erk_id = added_individuals["erk"]
response = client.delete_edge(
new_model_id,
subject_id=raf_id,
object_id=erk_id,
predicate_id="RO:0002413"
)
if response.ok:
print("Successfully deleted RAF->ERK edge")
else:
print(f"Failed to delete edge: {response.raw.get('message', '')}")
# Delete an individual
if "erk" in added_individuals:
erk_id = added_individuals["erk"]
response = client.delete_individual(new_model_id, erk_id)
if response.ok:
print(f"Successfully deleted ERK individual: {erk_id}")
else:
print(f"Failed to delete individual: {response.raw.get('message', '')}")
11. Clearing a Model¶
Remove all content from a model (use with caution!):
# Only clear if this is a test model we created
if new_model_id != TEST_MODEL_ID:
try:
response = client.clear_model(new_model_id)
if response.ok:
print(f"Successfully cleared model {new_model_id}")
else:
print(f"Failed to clear: {response.raw}")
except BaristaError as e:
print(f"Cannot clear model: {e}")
else:
print("Not clearing the shared test model")
12. Using the CLI¶
You can also use the command-line interface for all these operations:
# List models
noctua-py barista list-models --limit 10 --state production
# Create a model
noctua-py barista create-model --title "My Model"
# Add an individual
noctua-py barista add-individual --model gomodel:XXX --class GO:0003924
# Add a fact/edge
noctua-py barista add-fact --model gomodel:XXX --subject id1 --object id2 --predicate RO:0002413
# Export model in different formats
noctua-py barista export-model --model gomodel:XXX --format minerva-json
noctua-py barista export-model --model gomodel:XXX --format gocam-json
noctua-py barista export-model --model gomodel:XXX --format gocam-yaml
# Delete elements
noctua-py barista delete-edge --model gomodel:XXX --subject id1 --object id2 --predicate RO:0002413
noctua-py barista delete-individual --model gomodel:XXX --individual id1
# Clear a model
noctua-py barista clear-model --model gomodel:XXX
Add --live
flag to use production server instead of dev server.
Add --dry-run
to see the request without executing it.
Summary¶
This notebook demonstrated:
- Client Setup - Configuring BaristaClient for dev/production servers
- Model Management - Creating, listing, and retrieving models
- Building Models - Adding individuals (nodes) and facts (edges)
- Evidence - Annotating facts with evidence and references
- Export Formats - Native Minerva JSON, GO-CAM JSON, and YAML
- Model Editing - Deleting elements and clearing models
- CLI Usage - Command-line interface for all operations
For more information: - GO-CAM Documentation - noctua-py GitHub Repository