Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,27 @@ plan = compiler.plan(abstract_designs)
result = compiler.execute(plan)
```


Authenticated and anonymous repository access are both supported:

```python
compiler = BuildCompiler.from_synbiohub(
collections=["https://synbiohub.org/public/igem/igem_collection/1"],
repository_url="https://synbiohub.org",
auth_token="<token>",
)

compiler = BuildCompiler.from_synbiohub(
repository_url="https://synbiohub.org",
email="user@example.org",
password="<password>",
)

compiler = BuildCompiler.from_synbiohub(
repository_url="https://synbiohub.org",
)
```

A convenience wrapper may exist:

```python
Expand Down
210 changes: 210 additions & 0 deletions notebooks/buildcompiler_synbiohub_authenticated_tutorial.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# BuildCompiler SynBioHub Authenticated Tutorial"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This tutorial shows how to authenticate to SynBioHub with email/password, load inventory collections into BuildCompiler's internal SBOL document, and prepare an assembly workflow from an abstract design URI."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from getpass import getpass\n",
"import sbol2\n",
"\n",
"from buildcompiler.api import BuildCompiler"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"repository_url = 'https://synbiohub.org'\n",
"email = input('SynBioHub user/email: ').strip()\n",
"password = getpass('SynBioHub password: ')\n",
"\n",
"abstract_design_uri = 'https://synbiohub.org/user/Gon/abstract_design/standard_GFP/1'\n",
"collections = [\n",
" 'https://synbiohub.org/user/Gon/impl_test/impl_test_collection/1',\n",
" 'https://synbiohub.org/user/Gon/Enzyme_Implementations/Enzyme_Implementations_collection/1',\n",
"]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"doc = sbol2.Document()\n",
"compiler = BuildCompiler.from_synbiohub(\n",
" collections=collections,\n",
" repository_url=repository_url,\n",
" email=email,\n",
" password=password,\n",
" sbol_doc=doc,\n",
")\n",
"\n",
"print(f'Loaded objects: {len(doc.componentDefinitions)} component definitions, {len(doc.implementations)} implementations')\n",
"print('Repository client:', type(compiler.repository_client).__name__)\n",
"print('In-memory auth token available:', compiler.repository_client.auth_token is not None)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What BuildCompiler does with this setup\n",
"\n",
"- Pulls each collection URI using authenticated `sbol2.PartShop` into `sbol_doc`.\n",
"- Reuses the same authenticated pull client for identity-based resolver misses in planning/execution.\n",
"- Uses inventory indexing to find compatible plasmids containing abstract-design parts and compatible backbones/reagents."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Assembly simulation behavior\n",
"\n",
"Legacy Golden Gate simulation now enforces strict digest validation:\n",
"\n",
"- Restriction digest must yield exactly **2 fragments**.\n",
"- For part plasmids, the smaller fragment is selected as the insert.\n",
"- For the backbone plasmid, the larger fragment is selected as the backbone.\n",
"- If digest count is unexpected, simulation fails with a clear error message naming the reactant.\n",
"- Successful assembly encodes reagent usage and links generated product implementations with `wasGeneratedBy` to one assembly activity per assembled design product."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Pull the abstract design into the same in-memory document\n",
"if doc.find(abstract_design_uri) is None:\n",
" compiler.repository_client.pull_identity(abstract_design_uri)\n",
"\n",
"abstract_design = doc.find(abstract_design_uri)\n",
"print('Abstract design found:', abstract_design is not None, type(abstract_design).__name__)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Run full build using the abstract design object\n",
"# Note: this assumes your pulled inventory contains compatible lvl1 part plasmids, backbone, and reagents.\n",
"result = compiler.full_build([abstract_design])\n",
"print('Build status:', result.status)\n",
"print('Stage results:', [(s.stage.value, s.status.value) for s in result.stage_results])\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Check whether lvl1 assembly was selected\n",
"lvl1 = [s for s in result.stage_results if s.stage.value == 'assembly_lvl1']\n",
"print('Lvl1 stage entries:', len(lvl1))\n",
"if lvl1:\n",
" print('Lvl1 status:', lvl1[0].status.value)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Access the best-practice SBOL build document\n",
"build_doc = result.build_document\n",
"print('Build document objects:', len(build_doc.componentDefinitions), 'CDs,', len(build_doc.implementations), 'implementations,', len(build_doc.activities), 'activities')\n",
"# build_doc.write('build_result.xml')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Enable detailed reporting and inspect full diagnostic report when builds fail\n",
"from buildcompiler.api import BuildOptions\n",
"\n",
"debug_options = BuildOptions()\n",
"debug_options.reporting.include_detailed_report = True\n",
"debug_result = compiler.full_build([abstract_design], options=debug_options)\n",
"print('Debug status:', debug_result.status)\n",
"print('Missing inputs:', [m.missing_identity for m in debug_result.missing_inputs])\n",
"print('Warnings:', [w.message if hasattr(w, 'message') else str(w) for w in debug_result.warnings])\n",
"debug_result.report\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Validate full build document\n",
"build_doc.validate()\n",
"print('Full build document validation completed.')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Build a focused assembly-only document and validate\n",
"assembly_doc = sbol2.Document()\n",
"for activity in build_doc.activities:\n",
" if 'assembly' in activity.displayId.lower():\n",
" activity.copy(assembly_doc)\n",
"\n",
"for impl in build_doc.implementations:\n",
" if getattr(impl, 'wasGeneratedBy', None):\n",
" impl.copy(assembly_doc)\n",
" built_obj = build_doc.find(impl.built)\n",
" if built_obj is not None:\n",
" built_obj.copy(assembly_doc)\n",
"\n",
"assembly_doc.validate()\n",
"print('Assembly-only document validation completed.')\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading
Loading