Skip to content
This repository was archived by the owner on Jan 21, 2026. It is now read-only.
Merged
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
57 changes: 57 additions & 0 deletions sbs_server/app/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import sbol2
import sbol2build as s2b
from sbol2build import abstract_translator as at

from typing import List, Tuple

def abstract_design_2_plasmids(abstract_design_uri: str, plasmid_collection_uri: str, plasmid_vector_uri: str, sbh: sbol2.PartShop) -> Tuple[List[sbol2.Document], sbol2.Document, str]:
abstract_design_doc = sbol2.Document()
sbh.pull(
abstract_design_uri,
abstract_design_doc
)

abstract_design_id = at.extract_toplevel_definition(abstract_design_doc).displayId

plasmid_collection_doc = sbol2.Document()
sbh.pull(
plasmid_collection_uri,
plasmid_collection_doc
)

backbone_doc = sbol2.Document()
sbh.pull(
plasmid_vector_uri,
backbone_doc,
)

mocloplasmid_list = at.translate_abstract_to_plasmids(
abstract_design_doc, plasmid_collection_doc, backbone_doc
)

part_documents = []
for mocloPlasmid in mocloplasmid_list:
temp_doc = sbol2.Document()
mocloPlasmid.definition.copy(temp_doc)
at.copy_sequences(
mocloPlasmid.definition,
temp_doc,
plasmid_collection_doc
)
part_documents.append(temp_doc)

return part_documents, backbone_doc, abstract_design_id

def sbol2build_moclo(part_documents: List[sbol2.Document], backbone_doc: sbol2.Document, abstract_design_id: str) -> sbol2.Document:
assembly_doc = sbol2.Document()
assembly_obj = s2b.golden_gate_assembly_plan(
f"{abstract_design_id}_assembly_plan",
part_documents,
backbone_doc,
"BsaI",
assembly_doc
)

composite_list = assembly_obj.run()

return assembly_doc
40 changes: 15 additions & 25 deletions sbs_server/app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
from flask import Flask, render_template, request, jsonify
from flask_cors import CORS
from .main import app
from .utils import abstract_design_2_plasmids, sbol2build_moclo
import sys
import os
import json
import xml.etree.ElementTree as ET

import sbol2build
import tricahue
import sbol2 as sb2
import pudu
Expand Down Expand Up @@ -132,24 +132,6 @@ def upload_file_from_sbs_post_up():
"status": "success"
}
return jsonify(sbs_upload_response_dict)



@app.route('/sbol_2_build_golden_gate', methods=['POST'])
def sbol_2_build_golden_gate():
# Error checking in the request
print("request", request.files)

if 'plasmid_backbone' not in request.files:
return jsonify({"error": "Missing plasmid backbone"}), 400
if 'insert_parts' not in request.files:
return jsonify({"error": "Missing insert parts"}), 400
if 'wizard_selections' not in request.form:
return jsonify({"error": "Missing wizard selections"}), 400

wizard_selection = request.form.get('wizard_selections')
plasmid_backbone = request.files.get('plasmid_backbone')
insert_parts = request.files.getlist('insert_parts')

# Parse the json

Expand Down Expand Up @@ -177,16 +159,24 @@ def sbol_2_build_golden_gate():
assembly_obj = sbol2build.golden_gate_assembly_plan('testassem', part_docs, bb_doc, restriction_enzyme, assembly_doc)

try:
composites = assembly_obj.run()
# Run abstract translator to get plasmids
plasmid_documents, vector_doc, design_id = abstract_design_2_plasmids(abstract_design_uri, plasmid_collection_uri, plasmid_vector_uri, sbh)

# Run plasmids through sbol2build to generate assembly plan
assembly_plan_doc = sbol2build_moclo(plasmid_documents, vector_doc, design_id)
assembly_plan_doc.displayId = f"{design_id}_assembly"

return_string = assembly_doc.writeString()

# Return the file as a response
return return_string

sbh_response = sbh.submit(
doc=assembly_plan_doc,
collection=recipient_collection_uri,
overwrite=2
)
return sbh_response.text, sbh_response.status_code

except ValueError as e:
# catch sbol2build errors and return to frontend
return jsonify({"error": str(e)}), 400

except Exception as e:
return jsonify({"error": f"Unexpected server error: {str(e)}"}), 500

Expand Down