GO-CAM AI Demo¶

This notebook demonstrates the key functionality of the noctua-py library for programmatically manipulating GO-CAM models via the Noctua/Minerva/Barista API stack.

Setup¶

First, ensure you have noctua-py installed:

pip install noctua-py
# or with uv:
uv add noctua-py

Environment Setup¶

You'll need a Barista token to interact with the API. For development/testing, you can use the dev server token:

Environment configured for dev server

1. Creating a Barista Client¶

The BaristaClient is your main interface to the GO-CAM API:

Client configured for: http://barista-dev.berkeleybop.org
Namespace: minerva_public_dev

2. Listing Models¶

List all available GO-CAM models with filtering options:

Found 5 total models, showing 5:

ID: gomodel:R-HSA-1660516
   Title: Synthesis of PIPs at the early endosome membrane - imported from: Reactome
   State: development

ID: gomodel:R-HSA-1660514
   Title: Synthesis of PIPs at the Golgi membrane - imported from: Reactome
   State: development

ID: gomodel:68cc36ee00000000
   Title: enabled by undefined
   State: development

ID: gomodel:68af725b00000031
   Title: enabled by Abca12 Rnor
   State: development

ID: gomodel:68af725b00000008
   Title: enabled by Brpf1 Mmus
   State: development

3. Creating a New Model¶

Create a new empty GO-CAM model:

Successfully created model: gomodel:68d6f96e00000222

4. Getting Model Details¶

Retrieve the full details of a GO-CAM model:

Model ID: gomodel:68d6f96e00000222
State: development
Number of individuals: 0
Number of facts/edges: 0

5. Adding Individuals (Nodes)¶

Add molecular function individuals to the model:

Added GTPase activity: gomodel:68d6f96e00000222/68d6f96e00000223
Added protein serine/threonine kinase activity: gomodel:68d6f96e00000222/68d6f96e00000224
Added MAP kinase activity: gomodel:68d6f96e00000222/68d6f96e00000225

6. Adding Facts (Edges)¶

Connect individuals with causal relationships:

Added edge: RAS -> RAF
Added edge: RAF -> ERK

7. Adding Evidence¶

Add evidence annotations to support facts:

Successfully added evidence to RAS->RAF edge

8. Exporting Models¶

Export models in different formats:

Model structure (native Minerva JSON):
- Model ID: gomodel:68d6f96e00000222
- Individuals: 4
- Facts: 2

Compact view:
{
  "id": "gomodel:68d6f96e00000222",
  "individuals_count": 4,
  "facts_count": 2,
  "annotations": [
    {
      "key": "state",
      "value": "development"
    },
    {
      "key": "contributor",
      "value": "https://orcid.org/0000-0002-6601-2165"
    },
    {
      "key": "date",
      "value": "2025-09-28"
    },
    {
      "key": "providedBy",
      "value": "http://geneontology.org"
    }
  ]
}

9. Converting to GO-CAM Format¶

Convert the Minerva JSON to standard GO-CAM format (if the model has proper structure):

Missing RO:0002333 facts in defaultdict(<class 'list'>, {'RO:0002413': [{'subject': 'gomodel:68d6f96e00000222/68d6f96e00000223', 'property': 'RO:0002413', 'property-label': 'provides input for', 'object': 'gomodel:68d6f96e00000222/68d6f96e00000224', 'annotations': [{'key': 'evidence', 'value': 'gomodel:68d6f96e00000222/68d6f96e00000226', 'value-type': 'IRI'}, {'key': 'contributor', 'value': 'https://orcid.org/0000-0002-6601-2165'}, {'key': 'date', 'value': '2025-09-28'}, {'key': 'providedBy', 'value': 'http://geneontology.org'}]}, {'subject': 'gomodel:68d6f96e00000222/68d6f96e00000224', 'property': 'RO:0002413', 'property-label': 'provides input for', 'object': 'gomodel:68d6f96e00000222/68d6f96e00000225', 'annotations': [{'key': 'contributor', 'value': 'https://orcid.org/0000-0002-6601-2165'}, {'key': 'date', 'value': '2025-09-28'}, {'key': 'providedBy', 'value': 'http://geneontology.org'}]}]})
Note: Model doesn't follow standard GO-CAM structure: 'title'
This is normal for models without enabled_by facts linking to gene products

10. Deleting Model Elements¶

Remove edges and individuals from the model:

Successfully deleted RAF->ERK edge
Successfully deleted ERK individual: gomodel:68d6f96e00000222/68d6f96e00000225

11. Clearing a Model¶

Remove all content from a model (use with caution!):

Failed to clear: {'packet-id': '44e1426a6e8b7117f', 'uid': 'https://orcid.org/0000-0002-6601-2165', 'provided-by': ['http://geneontology.org'], 'is-reasoned': False, 'intention': 'action', 'message-type': 'error', 'message': "Could not successfully handle batch request. Exception: org.geneontology.minerva.MolecularModelManager$UnknownIdentifierException. No individual found for id: 'gomodel:68d6f96e00000222/68d6f96e00000226' and IRI: http://model.geneontology.org/68d6f96e00000222/68d6f96e00000226 in model: http://model.geneontology.org/68d6f96e00000222", 'commentary': "org.geneontology.minerva.MolecularModelManager$UnknownIdentifierException: No individual found for id: 'gomodel:68d6f96e00000222/68d6f96e00000226' and IRI: http://model.geneontology.org/68d6f96e00000222/68d6f96e00000226 in model: http://model.geneontology.org/68d6f96e00000222\n\tat org.geneontology.minerva.server.handler.OperationsImpl.getIndividual(OperationsImpl.java:112)\n\tat org.geneontology.minerva.server.handler.OperationsImpl.handleRequestForIndividual(OperationsImpl.java:186)\n\tat org.geneontology.minerva.server.handler.JsonOrJsonpBatchHandler.m3Batch(JsonOrJsonpBatchHandler.java:149)\n\tat org.geneontology.minerva.server.handler.JsonOrJsonpBatchHandler.m3Batch(JsonOrJsonpBatchHandler.java:125)\n\tat org.geneontology.minerva.server.handler.JsonOrJsonpBatchHandler.m3BatchPostPrivileged(JsonOrJsonpBatchHandler.java:84)\n\tat jdk.internal.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\n\tat org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)\n\tat org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)\n\tat org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)\n\tat org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219)\n\tat org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)\n\tat org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)\n\tat org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)\n\tat org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)\n\tat org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:253)\n\tat org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)\n\tat org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)\n\tat org.glassfish.jersey.internal.Errors.process(Errors.java:292)\n\tat org.glassfish.jersey.internal.Errors.process(Errors.java:274)\n\tat org.glassfish.jersey.internal.Errors.process(Errors.java:244)\n\tat org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)\n\tat org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)\n\tat org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)\n\tat org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:392)\n\tat org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)\n\tat org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:365)\n\tat org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:318)\n\tat org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)\n\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:769)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)\n\tat org.eclipse.jetty.server.Server.handle(Server.java:497)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)\n\tat org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:610)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:539)\n\tat java.base/java.lang.Thread.run(Thread.java:829)\n"}

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:

  1. Client Setup - Configuring BaristaClient for dev/production servers
  2. Model Management - Creating, listing, and retrieving models
  3. Building Models - Adding individuals (nodes) and facts (edges)
  4. Evidence - Annotating facts with evidence and references
  5. Export Formats - Native Minerva JSON, GO-CAM JSON, and YAML
  6. Model Editing - Deleting elements and clearing models
  7. CLI Usage - Command-line interface for all operations

For more information:

  • GO-CAM Documentation
  • noctua-py GitHub Repository