mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-03-28 07:33:45 +08:00
Consolidate skills
This commit is contained in:
@@ -0,0 +1,774 @@
|
||||
# Benchling Python SDK Reference
|
||||
|
||||
## Installation & Setup
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Stable release
|
||||
pip install benchling-sdk
|
||||
|
||||
# With Poetry
|
||||
poetry add benchling-sdk
|
||||
|
||||
# Pre-release/preview versions (not recommended for production)
|
||||
pip install benchling-sdk --pre
|
||||
poetry add benchling-sdk --allow-prereleases
|
||||
```
|
||||
|
||||
### Requirements
|
||||
- Python 3.7 or higher
|
||||
- API access enabled on your Benchling tenant
|
||||
|
||||
### Basic Initialization
|
||||
|
||||
```python
|
||||
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("your_api_key")
|
||||
)
|
||||
```
|
||||
|
||||
## SDK Architecture
|
||||
|
||||
### Main Classes
|
||||
|
||||
**Benchling Client:**
|
||||
The `benchling_sdk.benchling.Benchling` class is the root of all SDK interactions. It provides access to all resource endpoints:
|
||||
|
||||
```python
|
||||
benchling.dna_sequences # DNA sequence operations
|
||||
benchling.rna_sequences # RNA sequence operations
|
||||
benchling.aa_sequences # Amino acid sequence operations
|
||||
benchling.custom_entities # Custom entity operations
|
||||
benchling.mixtures # Mixture operations
|
||||
benchling.containers # Container operations
|
||||
benchling.boxes # Box operations
|
||||
benchling.locations # Location operations
|
||||
benchling.plates # Plate operations
|
||||
benchling.entries # Notebook entry operations
|
||||
benchling.workflow_tasks # Workflow task operations
|
||||
benchling.requests # Request operations
|
||||
benchling.folders # Folder operations
|
||||
benchling.projects # Project operations
|
||||
benchling.users # User operations
|
||||
benchling.teams # Team operations
|
||||
```
|
||||
|
||||
### Resource Pattern
|
||||
|
||||
All resources follow a consistent CRUD pattern:
|
||||
|
||||
```python
|
||||
# Create
|
||||
resource.create(CreateModel(...))
|
||||
|
||||
# Read (single)
|
||||
resource.get(id="resource_id")
|
||||
|
||||
# Read (list)
|
||||
resource.list(optional_filters...)
|
||||
|
||||
# Update
|
||||
resource.update(id="resource_id", UpdateModel(...))
|
||||
|
||||
# Archive/Delete
|
||||
resource.archive(id="resource_id")
|
||||
```
|
||||
|
||||
## Entity Management
|
||||
|
||||
### DNA Sequences
|
||||
|
||||
**Create:**
|
||||
```python
|
||||
from benchling_sdk.models import DnaSequenceCreate
|
||||
|
||||
sequence = benchling.dna_sequences.create(
|
||||
DnaSequenceCreate(
|
||||
name="pET28a-GFP",
|
||||
bases="ATCGATCGATCG",
|
||||
is_circular=True,
|
||||
folder_id="fld_abc123",
|
||||
schema_id="ts_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"gene_name": "GFP",
|
||||
"resistance": "Kanamycin",
|
||||
"copy_number": "High"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
**Read:**
|
||||
```python
|
||||
# Get by ID
|
||||
seq = benchling.dna_sequences.get(sequence_id="seq_abc123")
|
||||
print(f"{seq.name}: {len(seq.bases)} bp")
|
||||
|
||||
# List with filters
|
||||
sequences = benchling.dna_sequences.list(
|
||||
folder_id="fld_abc123",
|
||||
schema_id="ts_abc123",
|
||||
name="pET28a" # Filter by name
|
||||
)
|
||||
|
||||
for page in sequences:
|
||||
for seq in page:
|
||||
print(f"{seq.id}: {seq.name}")
|
||||
```
|
||||
|
||||
**Update:**
|
||||
```python
|
||||
from benchling_sdk.models import DnaSequenceUpdate
|
||||
|
||||
updated = benchling.dna_sequences.update(
|
||||
sequence_id="seq_abc123",
|
||||
dna_sequence=DnaSequenceUpdate(
|
||||
name="pET28a-GFP-v2",
|
||||
fields=benchling.models.fields({
|
||||
"gene_name": "eGFP",
|
||||
"notes": "Codon optimized"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
**Archive:**
|
||||
```python
|
||||
benchling.dna_sequences.archive(
|
||||
sequence_id="seq_abc123",
|
||||
reason="Deprecated construct"
|
||||
)
|
||||
```
|
||||
|
||||
### RNA Sequences
|
||||
|
||||
Similar pattern to DNA sequences:
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import RnaSequenceCreate, RnaSequenceUpdate
|
||||
|
||||
# Create
|
||||
rna = benchling.rna_sequences.create(
|
||||
RnaSequenceCreate(
|
||||
name="gRNA-target1",
|
||||
bases="AUCGAUCGAUCG",
|
||||
folder_id="fld_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"target_gene": "TP53",
|
||||
"off_target_score": "95"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# Update
|
||||
updated_rna = benchling.rna_sequences.update(
|
||||
rna_sequence_id=rna.id,
|
||||
rna_sequence=RnaSequenceUpdate(
|
||||
fields=benchling.models.fields({
|
||||
"validated": "Yes"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Amino Acid (Protein) Sequences
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import AaSequenceCreate
|
||||
|
||||
protein = benchling.aa_sequences.create(
|
||||
AaSequenceCreate(
|
||||
name="Green Fluorescent Protein",
|
||||
amino_acids="MSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKF",
|
||||
folder_id="fld_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"molecular_weight": "27000",
|
||||
"extinction_coefficient": "21000"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Custom Entities
|
||||
|
||||
Custom entities are defined by your tenant's schemas:
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import CustomEntityCreate, CustomEntityUpdate
|
||||
|
||||
# Create
|
||||
cell_line = benchling.custom_entities.create(
|
||||
CustomEntityCreate(
|
||||
name="HEK293T-Clone5",
|
||||
schema_id="ts_cellline_abc123",
|
||||
folder_id="fld_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"passage_number": "15",
|
||||
"mycoplasma_test": "Negative",
|
||||
"freezing_date": "2025-10-15"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# Update
|
||||
updated_cell_line = benchling.custom_entities.update(
|
||||
entity_id=cell_line.id,
|
||||
custom_entity=CustomEntityUpdate(
|
||||
fields=benchling.models.fields({
|
||||
"passage_number": "16",
|
||||
"notes": "Expanded for experiment"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Mixtures
|
||||
|
||||
Mixtures combine multiple components:
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import MixtureCreate, IngredientCreate
|
||||
|
||||
mixture = benchling.mixtures.create(
|
||||
MixtureCreate(
|
||||
name="LB-Amp Media",
|
||||
folder_id="fld_abc123",
|
||||
schema_id="ts_mixture_abc123",
|
||||
ingredients=[
|
||||
IngredientCreate(
|
||||
component_entity_id="ent_lb_base",
|
||||
amount="1000 mL"
|
||||
),
|
||||
IngredientCreate(
|
||||
component_entity_id="ent_ampicillin",
|
||||
amount="100 mg"
|
||||
)
|
||||
],
|
||||
fields=benchling.models.fields({
|
||||
"pH": "7.0",
|
||||
"sterilized": "Yes"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Registry Operations
|
||||
|
||||
**Direct Registry Registration:**
|
||||
```python
|
||||
# Register entity upon creation
|
||||
registered_seq = benchling.dna_sequences.create(
|
||||
DnaSequenceCreate(
|
||||
name="Construct-001",
|
||||
bases="ATCG",
|
||||
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_seq.registry_id}")
|
||||
```
|
||||
|
||||
**Naming Strategies:**
|
||||
- `NEW_IDS`: Benchling generates new registry IDs
|
||||
- `IDS_FROM_NAMES`: Use entity names as registry IDs (names must be unique)
|
||||
|
||||
## Inventory Management
|
||||
|
||||
### Containers
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import ContainerCreate, ContainerUpdate
|
||||
|
||||
# Create
|
||||
container = benchling.containers.create(
|
||||
ContainerCreate(
|
||||
name="Sample-001-Tube",
|
||||
schema_id="cont_schema_abc123",
|
||||
barcode="CONT001",
|
||||
parent_storage_id="box_abc123", # Place in box
|
||||
fields=benchling.models.fields({
|
||||
"concentration": "100 ng/μL",
|
||||
"volume": "50 μL",
|
||||
"sample_type": "gDNA"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# Update location
|
||||
benchling.containers.transfer(
|
||||
container_id=container.id,
|
||||
destination_id="box_xyz789"
|
||||
)
|
||||
|
||||
# Update properties
|
||||
updated = benchling.containers.update(
|
||||
container_id=container.id,
|
||||
container=ContainerUpdate(
|
||||
fields=benchling.models.fields({
|
||||
"volume": "45 μL",
|
||||
"notes": "Used 5 μL for PCR"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# Check out
|
||||
benchling.containers.check_out(
|
||||
container_id=container.id,
|
||||
comment="Taking to bench"
|
||||
)
|
||||
|
||||
# Check in
|
||||
benchling.containers.check_in(
|
||||
container_id=container.id,
|
||||
location_id="bench_location_abc"
|
||||
)
|
||||
```
|
||||
|
||||
### Boxes
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import BoxCreate
|
||||
|
||||
box = benchling.boxes.create(
|
||||
BoxCreate(
|
||||
name="Freezer-A-Box-01",
|
||||
schema_id="box_schema_abc123",
|
||||
parent_storage_id="loc_freezer_a",
|
||||
barcode="BOX001",
|
||||
fields=benchling.models.fields({
|
||||
"box_type": "81-place",
|
||||
"temperature": "-80C"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# List containers in box
|
||||
containers = benchling.containers.list(
|
||||
parent_storage_id=box.id
|
||||
)
|
||||
```
|
||||
|
||||
### Locations
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import LocationCreate
|
||||
|
||||
location = benchling.locations.create(
|
||||
LocationCreate(
|
||||
name="Freezer A - Shelf 2",
|
||||
parent_storage_id="loc_freezer_a",
|
||||
barcode="LOC-A-S2"
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Plates
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import PlateCreate, WellCreate
|
||||
|
||||
# Create 96-well plate
|
||||
plate = benchling.plates.create(
|
||||
PlateCreate(
|
||||
name="PCR-Plate-001",
|
||||
schema_id="plate_schema_abc123",
|
||||
barcode="PLATE001",
|
||||
wells=[
|
||||
WellCreate(
|
||||
position="A1",
|
||||
entity_id="sample_entity_abc"
|
||||
),
|
||||
WellCreate(
|
||||
position="A2",
|
||||
entity_id="sample_entity_xyz"
|
||||
)
|
||||
# ... more wells
|
||||
]
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Notebook Operations
|
||||
|
||||
### Entries
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import EntryCreate, EntryUpdate
|
||||
|
||||
# Create entry
|
||||
entry = benchling.entries.create(
|
||||
EntryCreate(
|
||||
name="Cloning Experiment 2025-10-20",
|
||||
folder_id="fld_abc123",
|
||||
schema_id="entry_schema_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"objective": "Clone GFP into pET28a",
|
||||
"date": "2025-10-20",
|
||||
"experiment_type": "Molecular Biology"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# Update entry
|
||||
updated_entry = benchling.entries.update(
|
||||
entry_id=entry.id,
|
||||
entry=EntryUpdate(
|
||||
fields=benchling.models.fields({
|
||||
"results": "Successful cloning, 10 colonies",
|
||||
"notes": "Colony 5 shows best fluorescence"
|
||||
})
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Linking Entities to Entries
|
||||
|
||||
```python
|
||||
# Link DNA sequence to entry
|
||||
link = benchling.entry_links.create(
|
||||
entry_id="entry_abc123",
|
||||
entity_id="seq_xyz789"
|
||||
)
|
||||
|
||||
# List links for an entry
|
||||
links = benchling.entry_links.list(entry_id="entry_abc123")
|
||||
```
|
||||
|
||||
## Workflow Management
|
||||
|
||||
### Tasks
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import WorkflowTaskCreate, WorkflowTaskUpdate
|
||||
|
||||
# Create task
|
||||
task = benchling.workflow_tasks.create(
|
||||
WorkflowTaskCreate(
|
||||
name="PCR Amplification",
|
||||
workflow_id="wf_abc123",
|
||||
assignee_id="user_abc123",
|
||||
schema_id="task_schema_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"template": "seq_abc123",
|
||||
"primers": "Forward: ATCG, Reverse: CGAT",
|
||||
"priority": "High"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# Update status
|
||||
completed_task = benchling.workflow_tasks.update(
|
||||
task_id=task.id,
|
||||
workflow_task=WorkflowTaskUpdate(
|
||||
status_id="status_complete_abc123",
|
||||
fields=benchling.models.fields({
|
||||
"completion_date": "2025-10-20",
|
||||
"yield": "500 ng"
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
# List tasks
|
||||
tasks = benchling.workflow_tasks.list(
|
||||
workflow_id="wf_abc123",
|
||||
status_ids=["status_pending", "status_in_progress"]
|
||||
)
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Pagination
|
||||
|
||||
The SDK uses generators for memory-efficient pagination:
|
||||
|
||||
```python
|
||||
# Automatic pagination
|
||||
sequences = benchling.dna_sequences.list()
|
||||
|
||||
# Get estimated total count
|
||||
total = sequences.estimated_count()
|
||||
print(f"Total sequences: {total}")
|
||||
|
||||
# Iterate through all pages
|
||||
for page in sequences:
|
||||
for seq in page:
|
||||
process(seq)
|
||||
|
||||
# Manual page size control
|
||||
sequences = benchling.dna_sequences.list(page_size=50)
|
||||
```
|
||||
|
||||
### Async Task Handling
|
||||
|
||||
Some operations are asynchronous and return task IDs:
|
||||
|
||||
```python
|
||||
from benchling_sdk.helpers.tasks import wait_for_task
|
||||
from benchling_sdk.errors import WaitForTaskExpiredError
|
||||
|
||||
# Start async operation
|
||||
response = benchling.some_bulk_operation(...)
|
||||
task_id = response.task_id
|
||||
|
||||
# Wait for completion
|
||||
try:
|
||||
result = wait_for_task(
|
||||
benchling,
|
||||
task_id=task_id,
|
||||
interval_wait_seconds=2, # Poll every 2 seconds
|
||||
max_wait_seconds=600 # Timeout after 10 minutes
|
||||
)
|
||||
print("Task completed successfully")
|
||||
except WaitForTaskExpiredError:
|
||||
print("Task timed out")
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```python
|
||||
from benchling_sdk.errors import (
|
||||
BenchlingError,
|
||||
NotFoundError,
|
||||
ValidationError,
|
||||
UnauthorizedError
|
||||
)
|
||||
|
||||
try:
|
||||
sequence = benchling.dna_sequences.get(sequence_id="seq_invalid")
|
||||
except NotFoundError:
|
||||
print("Sequence not found")
|
||||
except UnauthorizedError:
|
||||
print("Insufficient permissions")
|
||||
except ValidationError as e:
|
||||
print(f"Invalid data: {e}")
|
||||
except BenchlingError as e:
|
||||
print(f"General Benchling error: {e}")
|
||||
```
|
||||
|
||||
### Retry Strategy
|
||||
|
||||
Customize retry behavior:
|
||||
|
||||
```python
|
||||
from benchling_sdk.benchling import Benchling
|
||||
from benchling_sdk.auth.api_key_auth import ApiKeyAuth
|
||||
from benchling_sdk.retry import RetryStrategy
|
||||
|
||||
# Custom retry configuration
|
||||
retry_strategy = RetryStrategy(
|
||||
max_retries=3,
|
||||
backoff_factor=0.5,
|
||||
status_codes_to_retry=[429, 502, 503, 504]
|
||||
)
|
||||
|
||||
benchling = Benchling(
|
||||
url="https://your-tenant.benchling.com",
|
||||
auth_method=ApiKeyAuth("your_api_key"),
|
||||
retry_strategy=retry_strategy
|
||||
)
|
||||
|
||||
# Disable retries
|
||||
benchling = Benchling(
|
||||
url="https://your-tenant.benchling.com",
|
||||
auth_method=ApiKeyAuth("your_api_key"),
|
||||
retry_strategy=RetryStrategy(max_retries=0)
|
||||
)
|
||||
```
|
||||
|
||||
### Custom API Calls
|
||||
|
||||
For unsupported endpoints:
|
||||
|
||||
```python
|
||||
# GET request with model parsing
|
||||
from benchling_sdk.models import DnaSequence
|
||||
|
||||
response = benchling.api.get_modeled(
|
||||
path="/api/v2/dna-sequences/seq_abc123",
|
||||
response_type=DnaSequence
|
||||
)
|
||||
|
||||
# POST request
|
||||
from benchling_sdk.models import DnaSequenceCreate
|
||||
|
||||
response = benchling.api.post_modeled(
|
||||
path="/api/v2/dna-sequences",
|
||||
request_body=DnaSequenceCreate(...),
|
||||
response_type=DnaSequence
|
||||
)
|
||||
|
||||
# Raw requests
|
||||
raw_response = benchling.api.get(
|
||||
path="/api/v2/custom-endpoint",
|
||||
params={"key": "value"}
|
||||
)
|
||||
```
|
||||
|
||||
### Batch Operations
|
||||
|
||||
Efficiently process multiple items:
|
||||
|
||||
```python
|
||||
# Bulk create
|
||||
from benchling_sdk.models import DnaSequenceCreate
|
||||
|
||||
sequences_to_create = [
|
||||
DnaSequenceCreate(name=f"Seq-{i}", bases="ATCG", folder_id="fld_abc")
|
||||
for i in range(100)
|
||||
]
|
||||
|
||||
# Create in batches
|
||||
batch_size = 10
|
||||
for i in range(0, len(sequences_to_create), batch_size):
|
||||
batch = sequences_to_create[i:i+batch_size]
|
||||
for seq in batch:
|
||||
benchling.dna_sequences.create(seq)
|
||||
```
|
||||
|
||||
### Schema Fields Helper
|
||||
|
||||
Convert dictionaries to Fields objects:
|
||||
|
||||
```python
|
||||
# Using fields helper
|
||||
fields_dict = {
|
||||
"concentration": "100 ng/μL",
|
||||
"volume": "50 μL",
|
||||
"quality_score": "8.5",
|
||||
"date_prepared": "2025-10-20"
|
||||
}
|
||||
|
||||
fields = benchling.models.fields(fields_dict)
|
||||
|
||||
# Use in create/update
|
||||
container = benchling.containers.create(
|
||||
ContainerCreate(
|
||||
name="Sample-001",
|
||||
schema_id="schema_abc",
|
||||
fields=fields
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Forward Compatibility
|
||||
|
||||
The SDK handles unknown API values gracefully:
|
||||
|
||||
```python
|
||||
# Unknown enum values are preserved
|
||||
entity = benchling.dna_sequences.get("seq_abc")
|
||||
# Even if API returns new enum value not in SDK, it's preserved
|
||||
|
||||
# Unknown polymorphic types return UnknownType
|
||||
from benchling_sdk.models import UnknownType
|
||||
|
||||
if isinstance(entity, UnknownType):
|
||||
print(f"Unknown type: {entity.type}")
|
||||
# Can still access raw data
|
||||
print(entity.raw_data)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Use Type Hints
|
||||
|
||||
```python
|
||||
from benchling_sdk.models import DnaSequence, DnaSequenceCreate
|
||||
from typing import List
|
||||
|
||||
def create_sequences(names: List[str], folder_id: str) -> List[DnaSequence]:
|
||||
sequences = []
|
||||
for name in names:
|
||||
seq = benchling.dna_sequences.create(
|
||||
DnaSequenceCreate(
|
||||
name=name,
|
||||
bases="ATCG",
|
||||
folder_id=folder_id
|
||||
)
|
||||
)
|
||||
sequences.append(seq)
|
||||
return sequences
|
||||
```
|
||||
|
||||
### Efficient Filtering
|
||||
|
||||
Use API filters instead of client-side filtering:
|
||||
|
||||
```python
|
||||
# Good - filter on server
|
||||
sequences = benchling.dna_sequences.list(
|
||||
folder_id="fld_abc123",
|
||||
schema_id="ts_abc123"
|
||||
)
|
||||
|
||||
# Bad - loads everything then filters
|
||||
all_sequences = benchling.dna_sequences.list()
|
||||
filtered = [s for page in all_sequences for s in page if s.folder_id == "fld_abc123"]
|
||||
```
|
||||
|
||||
### Resource Cleanup
|
||||
|
||||
```python
|
||||
# Archive old entities
|
||||
cutoff_date = "2024-01-01"
|
||||
sequences = benchling.dna_sequences.list()
|
||||
|
||||
for page in sequences:
|
||||
for seq in page:
|
||||
if seq.created_at < cutoff_date:
|
||||
benchling.dna_sequences.archive(
|
||||
sequence_id=seq.id,
|
||||
reason="Archiving old sequences"
|
||||
)
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Import Errors:**
|
||||
```python
|
||||
# Wrong
|
||||
from benchling_sdk import Benchling # ImportError
|
||||
|
||||
# Correct
|
||||
from benchling_sdk.benchling import Benchling
|
||||
```
|
||||
|
||||
**Field Validation:**
|
||||
```python
|
||||
# Fields must match schema
|
||||
# Check schema field types in Benchling UI
|
||||
fields = benchling.models.fields({
|
||||
"numeric_field": "123", # Should be string even for numbers
|
||||
"date_field": "2025-10-20", # Format: YYYY-MM-DD
|
||||
"dropdown_field": "Option1" # Must match dropdown options exactly
|
||||
})
|
||||
```
|
||||
|
||||
**Pagination Exhaustion:**
|
||||
```python
|
||||
# Generators can only be iterated once
|
||||
sequences = benchling.dna_sequences.list()
|
||||
for page in sequences: # First iteration OK
|
||||
pass
|
||||
for page in sequences: # Second iteration returns nothing!
|
||||
pass
|
||||
|
||||
# Solution: Create new generator
|
||||
sequences = benchling.dna_sequences.list() # New generator
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- **SDK Source:** https://github.com/benchling/benchling-sdk
|
||||
- **SDK Docs:** https://benchling.com/sdk-docs/
|
||||
- **API Reference:** https://benchling.com/api/reference
|
||||
- **Common Examples:** https://docs.benchling.com/docs/common-sdk-interactions-and-examples
|
||||
Reference in New Issue
Block a user