Source profileQuality 89/100

jaechang-hits/SciAgent-Skills/skills/lab-automation/benchling-integration/SKILL.md

benchling-integration

Benchling R&D Python SDK: CRUD on registry entities (DNA, RNA, proteins, custom), inventory, ELN, workflow automation. Needs Benchling account and API key. Use biopython for local sequence analysis; pubchem for chemical DBs.

Source repository stars
295
Declared platforms
0
Static risk flags
1
Last source update
2026-08-06
Source checked
2026-08-06

Decision brief

What it does—and where it fits

Benchling R&D Python SDK: CRUD on registry entities (DNA, RNA, proteins, custom), inventory, ELN, workflow automation. Needs Benchling account and API key.

Best for

  • Creating, updating, or querying biological sequences (DNA, RNA, proteins) in Benchling registry
  • Automating inventory operations (containers, boxes, locations, sample transfers)
  • Creating or querying electronic lab notebook (ELN) entries programmatically

Not for

  • Tasks that require unconfirmed production actions or broad system permissions.
  • Environments where the pinned source and install steps cannot be inspected.

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/jaechang-hits/SciAgent-Skills --skill "skills/lab-automation/benchling-integration"
Safe inspection promptEditorial

Inspect the Agent Skill "benchling-integration" from https://github.com/jaechang-hits/SciAgent-Skills/blob/0d18706fe1a51239f12b395f046c8aa30fe632b4/skills/lab-automation/benchling-integration/SKILL.md at commit 0d18706fe1a51239f12b395f046c8aa30fe632b4. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Quick Start

    python from benchlingsdk.benchling import Benchling from benchlingsdk.auth.apikeyauth import ApiKeyAuth from benchlingsdk.models import DnaSequenceCreate import os

    python from benchlingsdk.benchling import Benchling from benchlingsdk.auth.apikeyauth import ApiKeyAuth from benchlingsdk.models import DnaSequenceCreate import osbenchling = Benchling( url="https://your-tenant.benchling.com", authmethod=ApiKeyAuth(os.environ["BENCHLINGAPIKEY"]) )
  2. 02

    5. Workflow Automation

    Create and manage workflow tasks for lab process automation.

    Create and manage workflow tasks for lab process automation.python from benchlingsdk.models import WorkflowTaskCreate, WorkflowTaskUpdate
  3. 03

    Create workflow task

    task = benchling.workflowtasks.create( WorkflowTaskCreate( name="PCR Amplification", workflowid="wfabc123", assigneeid="userabc123", fields=benchling.models.fields({"template": "seqabc123"}) ) ) print(f"Task: {task.id}, Status: {task.status}")

    task = benchling.workflowtasks.create( WorkflowTaskCreate( name="PCR Amplification", workflowid="wfabc123", assigneeid="userabc123", fields=benchling.models.fields({"template": "seqabc123"}) ) ) print(f"Task: {task.id},…
  4. 04

    Workflow: Bulk Import from FASTA

    Review the “Workflow: Bulk Import from FASTA” section in the pinned source before continuing.

    Review and apply the “Workflow: Bulk Import from FASTA” source section.
  5. 05

    Workflow: Inventory Audit Report

    Review the “Workflow: Inventory Audit Report” section in the pinned source before continuing.

    Review and apply the “Workflow: Inventory Audit Report” source section.

Permission review

Static risk signals and limitations

Network access

medium · line 34

The documentation includes network, browsing, or remote request actions.

url="https://your-tenant.benchling.com",

Network access

medium · line 44

The documentation includes network, browsing, or remote request actions.

url="https://your-tenant.benchling.com",

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score89/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars295SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
jaechang-hits/SciAgent-Skills
Skill path
skills/lab-automation/benchling-integration/SKILL.md
Commit
0d18706fe1a51239f12b395f046c8aa30fe632b4
License
NOASSERTION
Collected
2026-08-06
Default branch
main
View the original SKILL.md

Benchling Integration — R&D Platform SDK

Overview

Benchling is a cloud platform for life sciences R&D. The Python SDK provides programmatic access to registry entities (DNA, proteins), inventory, electronic lab notebooks, and workflows. All operations require a Benchling tenant URL and API key or OAuth credentials.

When to Use

  • Creating, updating, or querying biological sequences (DNA, RNA, proteins) in Benchling registry
  • Automating inventory operations (containers, boxes, locations, sample transfers)
  • Creating or querying electronic lab notebook (ELN) entries programmatically
  • Building workflow automations (task creation, status updates, bulk operations)
  • Bulk importing entities from FASTA files or spreadsheets into Benchling
  • Exporting Benchling data to CSV or external databases for analysis
  • Syncing Benchling with external systems via event-driven integrations
  • For local sequence analysis (BLAST, alignment), use biopython instead
  • For chemical compound databases, use pubchem-compound-search instead

Prerequisites

pip install benchling-sdk

Authentication setup: Obtain an API key from Benchling Profile Settings. Store securely in environment variables — never commit to version control.

import os
from benchling_sdk.benchling import Benchling
from benchling_sdk.auth.api_key_auth import ApiKeyAuth

benchling = Benchling(
    url="https://your-tenant.benchling.com",
    auth_method=ApiKeyAuth(os.environ["BENCHLING_API_KEY"])
)

OAuth (for multi-user apps):

from benchling_sdk.auth.client_credentials_oauth2 import ClientCredentialsOAuth2

benchling = Benchling(
    url="https://your-tenant.benchling.com",
    auth_method=ClientCredentialsOAuth2(
        client_id=os.environ["BENCHLING_CLIENT_ID"],
        client_secret=os.environ["BENCHLING_CLIENT_SECRET"]
    )
)

API rate limits: Benchling enforces per-tenant rate limits. The SDK automatically retries on 429 responses with exponential backoff (up to 5 retries by default). For bulk operations, add time.sleep(0.5) between batches.

Quick Start

from benchling_sdk.benchling import Benchling
from benchling_sdk.auth.api_key_auth import ApiKeyAuth
from benchling_sdk.models import DnaSequenceCreate
import os

benchling = Benchling(
    url="https://your-tenant.benchling.com",
    auth_method=ApiKeyAuth(os.environ["BENCHLING_API_KEY"])
)

# Create a DNA sequence
seq = benchling.dna_sequences.create(
    DnaSequenceCreate(name="GFP-insert", bases="ATGGTGAGCAAGGGC", is_circular=False, folder_id="fld_abc123")
)
print(f"Created: {seq.name} ({seq.id})")

Core API

1. Registry — Entity CRUD

Registry entities include DNA sequences, RNA sequences, AA sequences, custom entities, and mixtures. All entity types follow the same create/read/update/archive pattern.

from benchling_sdk.models import DnaSequenceCreate, DnaSequenceUpdate

# Create
sequence = benchling.dna_sequences.create(
    DnaSequenceCreate(
        name="My Plasmid",
        bases="ATCGATCG",
        is_circular=True,
        folder_id="fld_abc123",
        schema_id="ts_abc123",
        fields=benchling.models.fields({"gene_name": "GFP"})
    )
)
print(f"Created: {sequence.id}")

# Read
seq = benchling.dna_sequences.get_by_id(sequence.id)
print(f"Name: {seq.name}, Length: {len(seq.bases)} bp")

# Update (partial — unspecified fields unchanged)
updated = benchling.dna_sequences.update(
    sequence_id=sequence.id,
    dna_sequence=DnaSequenceUpdate(
        name="Updated Plasmid",
        fields=benchling.models.fields({"gene_name": "mCherry"})
    )
)

# Archive
benchling.dna_sequences.archive(ids=[sequence.id], reason="RETIRED")
# Register entity in registry (with auto-generated ID)
registered = benchling.dna_sequences.create(
    DnaSequenceCreate(
        name="Production Plasmid",
        bases="ATCGATCG",
        is_circular=True,
        folder_id="fld_abc123",
        entity_registry_id="src_abc123",
        naming_strategy="NEW_IDS"  # or "IDS_FROM_NAMES"
    )
)
print(f"Registry ID: {registered.entity_registry_id}")

# Entity types available via SDK:
# benchling.dna_sequences, benchling.rna_sequences,
# benchling.aa_sequences, benchling.custom_entities, benchling.mixtures

2. Registry — Listing and Pagination

All list operations return paginated generators for memory efficiency.

# List with pagination
sequences = benchling.dna_sequences.list()
total = sequences.estimated_count()
print(f"Total sequences: {total}")

for page in sequences:
    for seq in page:
        print(f"  {seq.name} ({seq.id}): {len(seq.bases)} bp")

# Filter by schema
filtered = benchling.dna_sequences.list(schema_id="ts_abc123")
for page in filtered:
    for seq in page:
        print(f"  {seq.name}")

3. Inventory Management

Manage physical samples, containers, boxes, and locations.

from benchling_sdk.models import ContainerCreate, BoxCreate

# Create container (sample tube)
container = benchling.containers.create(
    ContainerCreate(
        name="Sample Tube 001",
        schema_id="cont_schema_abc123",
        parent_storage_id="box_abc123",
        fields=benchling.models.fields({"concentration": "100 ng/uL"})
    )
)
print(f"Container: {container.id}, Barcode: {container.barcode}")

# Create box
box = benchling.boxes.create(
    BoxCreate(
        name="Freezer Box A1",
        schema_id="box_schema_abc123",
        parent_storage_id="loc_abc123"
    )
)

# Transfer container to new location
benchling.containers.transfer(
    container_id=container.id,
    destination_id="box_xyz789"
)
print(f"Transferred {container.name} to new box")

4. Notebook Entries (ELN)

Create and manage electronic lab notebook entries.

from benchling_sdk.models import EntryCreate

# Create notebook entry
entry = benchling.entries.create(
    EntryCreate(
        name="Experiment 2026-02-17",
        folder_id="fld_abc123",
        schema_id="entry_schema_abc123",
        fields=benchling.models.fields({
            "objective": "Test gene expression levels",
            "protocol": "Standard qPCR"
        })
    )
)
print(f"Entry: {entry.id}")

# Link entity to entry
benchling.entry_links.create(
    entry_id=entry.id,
    entity_id="seq_xyz789"
)

5. Workflow Automation

Create and manage workflow tasks for lab process automation.

from benchling_sdk.models import WorkflowTaskCreate, WorkflowTaskUpdate

# Create workflow task
task = benchling.workflow_tasks.create(
    WorkflowTaskCreate(
        name="PCR Amplification",
        workflow_id="wf_abc123",
        assignee_id="user_abc123",
        fields=benchling.models.fields({"template": "seq_abc123"})
    )
)
print(f"Task: {task.id}, Status: {task.status}")

# Update task status
benchling.workflow_tasks.update(
    task_id=task.id,
    workflow_task=WorkflowTaskUpdate(status_id="status_complete_abc123")
)

# Wait for async operations
from benchling_sdk.helpers.tasks import wait_for_task

result = wait_for_task(
    benchling, task_id="task_abc123",
    interval_wait_seconds=2, max_wait_seconds=300
)
print(f"Async task completed: {result}")

6. Error Handling and Retry

from benchling_sdk.retry import RetryStrategy
from benchling_sdk.errors import BenchlingError

# Custom retry strategy
benchling = Benchling(
    url="https://your-tenant.benchling.com",
    auth_method=ApiKeyAuth(os.environ["BENCHLING_API_KEY"]),
    retry_strategy=RetryStrategy(max_retries=3)
)
# SDK auto-retries on 429 (rate limit), 502, 503, 504

# Error handling
try:
    seq = benchling.dna_sequences.get_by_id("seq_nonexistent")
except BenchlingError as e:
    print(f"API error: {e.status_code} — {e.message}")

Key Concepts

Entity Type Mapping

Benchling TypeSDK AccessorUse Case
DNA Sequencebenchling.dna_sequencesPlasmids, primers, gene inserts
RNA Sequencebenchling.rna_sequencesmRNA, gRNA, siRNA
AA Sequencebenchling.aa_sequencesProteins, antibodies, enzymes
Custom Entitybenchling.custom_entitiesCell lines, reagents, samples
Mixturebenchling.mixturesBuffers, media, compound formulations
Containerbenchling.containersTubes, wells, vials
Boxbenchling.boxesStorage boxes, racks
Entrybenchling.entriesLab notebook entries
Workflow Taskbenchling.workflow_tasksProcess steps, assignments

Schema Fields

Benchling entities use schema-defined custom fields. Always use the fields() helper:

# Correct: use fields() helper
fields = benchling.models.fields({
    "concentration": "100 ng/uL",
    "date_prepared": "2026-02-17",
    "passage_number": 5
})

# Fields are typed by schema — string, number, date, entity link, dropdown

Pagination Pattern

All list() calls return paginated generators. Never call list() without iterating:

# Correct: iterate through pages
for page in benchling.dna_sequences.list():
    for item in page:
        process(item)

# Get count without loading all data
count = benchling.dna_sequences.list().estimated_count()

Common Workflows

Workflow: Bulk Import from FASTA

import os, time
from Bio import SeqIO
from benchling_sdk.benchling import Benchling
from benchling_sdk.auth.api_key_auth import ApiKeyAuth
from benchling_sdk.models import DnaSequenceCreate

benchling = Benchling(
    url="https://your-tenant.benchling.com",
    auth_method=ApiKeyAuth(os.environ["BENCHLING_API_KEY"])
)

created = []
for record in SeqIO.parse("sequences.fasta", "fasta"):
    seq = benchling.dna_sequences.create(
        DnaSequenceCreate(
            name=record.id,
            bases=str(record.seq),
            is_circular=False,
            folder_id="fld_abc123",
            fields=benchling.models.fields({
                "description": record.description,
                "source": "FASTA import"
            })
        )
    )
    created.append(seq.id)
    time.sleep(0.5)  # Rate limit compliance
    print(f"Created: {record.id} -> {seq.id}")

print(f"Imported {len(created)} sequences")

Workflow: Inventory Audit Report

import os, csv
from benchling_sdk.benchling import Benchling
from benchling_sdk.auth.api_key_auth import ApiKeyAuth

benchling = Benchling(
    url="https://your-tenant.benchling.com",
    auth_method=ApiKeyAuth(os.environ["BENCHLING_API_KEY"])
)

audit = []
containers = benchling.containers.list(parent_storage_id="loc_freezer01")
for page in containers:
    for c in page:
        audit.append({
            "id": c.id,
            "name": c.name,
            "barcode": c.barcode,
            "location": c.parent_storage_id,
            "created": str(c.created_at)
        })

with open("inventory_audit.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=audit[0].keys())
    writer.writeheader()
    writer.writerows(audit)
print(f"Audit complete: {len(audit)} containers")

Workflow: Automated QC Workflow

  1. List pending workflow tasks: benchling.workflow_tasks.list(workflow_id=..., status="pending")
  2. For each task, read associated entity via benchling.dna_sequences.get_by_id()
  3. Run automated validation checks (sequence length, GC content, restriction sites)
  4. Update task status to "complete" or "failed" via benchling.workflow_tasks.update()
  5. Log results to a notebook entry via benchling.entries.create()

Key Parameters

ParameterFunction/EndpointDefaultOptionsEffect
folder_idAll create operationsRequiredfld_...Target folder for new entity
schema_idAll create operationsOptionalts_..., cont_...Schema defining custom fields
entity_registry_idEntity registrationOptionalsrc_...Registry to register entity in
naming_strategyEntity registrationNEW_IDS, IDS_FROM_NAMESHow registry IDs are generated
parent_storage_idContainers, boxesOptionalbox_..., loc_...Storage location for inventory
max_retriesRetryStrategy50–10Number of retry attempts on failure
interval_wait_secondswait_for_task21–60Polling interval for async tasks
max_wait_secondswait_for_task30010–3600Maximum wait for async completion

Best Practices

  1. Always use environment variables for credentials: Never hardcode API keys. Use os.environ["BENCHLING_API_KEY"].

  2. Use the fields() helper for custom schema fields: Raw dicts will not work — the SDK requires typed Fields objects.

  3. Anti-pattern — loading all entities into memory: Use the paginated generator pattern. Never convert list() to a Python list for large datasets.

  4. Add rate limit delays for bulk operations: Insert time.sleep(0.5) between create/update calls when processing >50 entities.

  5. Use OAuth for production apps, API keys for scripts: API keys are user-scoped; OAuth allows app-level permissions and rotation.

  6. Anti-pattern — using both entity_registry_id and naming_strategy: These are mutually exclusive on create. Use one or the other.

  7. Handle BenchlingError explicitly: Catch SDK exceptions and log the status code and message for debugging.

Common Recipes

Recipe: Export Sequences by Schema

import csv

export = []
for page in benchling.dna_sequences.list(schema_id="ts_target_schema"):
    for seq in page:
        export.append({
            "registry_id": seq.entity_registry_id,
            "name": seq.name,
            "length": len(seq.bases),
            "bases": seq.bases[:50] + "..." if len(seq.bases) > 50 else seq.bases
        })

with open("sequences_export.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=export[0].keys())
    writer.writeheader()
    writer.writerows(export)
print(f"Exported {len(export)} sequences")

Recipe: Find Entities by Custom Field

# Search entities with specific field values
# Note: SDK list() supports limited filtering; for complex queries use Data Warehouse
results = []
for page in benchling.custom_entities.list(schema_id="ts_cell_lines"):
    for entity in page:
        fields = entity.fields or {}
        if fields.get("organism", {}).get("value") == "Human":
            results.append(entity)
            print(f"Found: {entity.name} ({entity.id})")
print(f"Total human cell lines: {len(results)}")

Recipe: Batch Archive Old Entities

import time
from datetime import datetime, timedelta

cutoff = datetime.now() - timedelta(days=365)
to_archive = []

for page in benchling.custom_entities.list():
    for entity in page:
        if entity.modified_at and entity.modified_at < cutoff:
            to_archive.append(entity.id)

# Archive in batches
batch_size = 50
for i in range(0, len(to_archive), batch_size):
    batch = to_archive[i:i+batch_size]
    benchling.custom_entities.archive(ids=batch, reason="RETIRED")
    print(f"Archived batch {i//batch_size + 1}: {len(batch)} entities")
    time.sleep(1)
print(f"Total archived: {len(to_archive)}")

Troubleshooting

ProblemCauseSolution
401 UnauthorizedInvalid or expired API keyRegenerate key in Benchling Profile Settings; check env var is set
403 ForbiddenInsufficient permissionsAPI key inherits user permissions; check user role in Benchling admin
404 Not FoundWrong entity ID or tenant URLVerify ID format (seq_, fld_, etc.); check tenant URL matches
429 Too Many RequestsRate limit exceededSDK auto-retries; add time.sleep() between bulk operations
fields ignored on createUsing raw dict instead of fields() helperUse benchling.models.fields({...}) for custom schema fields
naming_strategy errorUsed with entity_registry_idThese are mutually exclusive — use one or the other
Pagination memory issuesCollecting all items into a listIterate page-by-page with for page in .list() pattern
OAuth token expiredClient credentials not refreshingSDK handles refresh automatically; check client_id/secret are valid

Related Skills

  • biopython-molecular-biology — local sequence analysis (BLAST, alignment) before uploading to Benchling
  • opentrons-protocol-api — automate lab protocols that feed samples into Benchling inventory

References

Alternatives

Compare before choosing

Computed 9132,785

K-Dense-AI/scientific-agent-skills

benchling-integration

Benchling Python SDK and REST API integration for registry entities, inventory, ELN entries, workflows, Benchling Apps, and Data Warehouse queries. Use when automating lab data with benchling-sdk or the v2 API.

Computed 9832,785

K-Dense-AI/scientific-agent-skills

dask

Distributed computing for larger-than-RAM pandas/NumPy workflows. Use when you need to scale existing pandas/NumPy code beyond memory or across clusters. Best for parallel file processing, distributed ML, integration with existing pandas code. For out-of-core analytics on single machine use vaex; for in-memory speed use polars.

Computed 9832,785

K-Dense-AI/scientific-agent-skills

neurokit2

Use NeuroKit2 to build or audit reproducible research workflows for physiological time-series preprocessing, event/interval analysis, multimodal alignment, variability, and complexity. Trigger when code imports neurokit2 or needs its current APIs, schemas, and method-aware validation—not for diagnosis or device validation.

Computed 974,969

dotnet/skills

test-tagging

Analyzes test suites in any language and tags each test with standardized traits (positive, negative, critical-path, boundary, smoke, regression, integration, performance, security). Use when the user wants to categorize, audit, or label tests with traits. Works across .NET (MSTest/xUnit/NUnit/TUnit), Python (pytest), TS/JS (Jest/Vitest), Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, and C++ — auto-editing when the framework has canonical tag syntax, otherwise report-only. Do not use for writ