Skip to content
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
24 changes: 23 additions & 1 deletion sbs_server/app/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sbol2
import sbol2build as s2b
from sbol2build import abstract_translator as at
from sbol2build import bacterial_transformation

from typing import List, Tuple

Expand Down Expand Up @@ -54,4 +55,25 @@ def sbol2build_moclo(part_documents: List[sbol2.Document], backbone_doc: sbol2.D

composite_list = assembly_obj.run()

return assembly_doc
return assembly_doc

def generate_transformation_metadata(plasmid_uris: List[str], chassis_uri: str, transformation_machine: str, protocol: str, params: str, sbh: sbol2.PartShop) -> sbol2.Document:
plasmid_docs = []

for uri in plasmid_uris:
temp_doc = sbol2.Document()
sbh.pull(
uri,
temp_doc
)
plasmid_docs.append(temp_doc)

chassis_doc = sbol2.Document()
sbh.pull(
chassis_uri,
chassis_doc
)

return bacterial_transformation(sbol2.Document(), chassis_doc, plasmid_docs, transformation_machine, protocol, params)


51 changes: 50 additions & 1 deletion sbs_server/app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
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
from .utils import abstract_design_2_plasmids, sbol2build_moclo, generate_transformation_metadata
import sys
import os
import json
Expand Down Expand Up @@ -180,6 +180,55 @@ def upload_assembly():

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

@app.route('/upload_transformation', methods=['POST'])
def upload_transformation():
if 'auth_token' not in request.form:
return jsonify({"error": "Missing SynBioHub Authentication Token"}), 400
if 'registry_url' not in request.form:
return jsonify({"error": "Missing SynBioHub Registry URL"}), 400
if 'collection_uri' not in request.form:
return jsonify({"error": "Missing recipient SynBioHub collection URI"}), 400

if 'plasmid_uris' not in request.form:
return jsonify({"error": "Missing plasmid URIs"}), 400
if 'chassis_uri' not in request.form:
return jsonify({"error": "Missing chassis URI"}), 400
if 'machine' not in request.form:
return jsonify({"error": "Missing machine"}), 400
if 'protocol' not in request.form:
return jsonify({"error": "Missing protocol"}), 400
if 'params' not in request.form:
return jsonify({"error": "Missing trasnformation parameters"}), 400

auth_token = request.form.get("auth_token")
sbh_registry = request.form.get("registry_url")
recipient_collection_uri = request.form.get("collection_uri")

plasmid_uris = request.form.get("plasmid_uris")
chassis_uri = request.form.get("chassis_uri")
machine_name = request.form.get("machine")
protocol = request.form.get("protocol")
parameters = request.form.get("params")
Comment on lines +208 to +212

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Treat plasmid_uris as a list before transformation

Here plasmid_uris is pulled from request.form.get as a single string (line 208) and then passed to generate_transformation_metadata (line 218), which iterates for uri in plasmid_uris (utils.py line 63) expecting a list. With a normal form post such as plasmid_uris=https://example.com/plasmid1, the function will iterate over each character (h, t, …) and call sbh.pull with those, resulting in immediate pull failures and a 500 response for any valid request. Parse the field to a list (e.g., getlist/JSON) before invoking the helper so the endpoint can handle real plasmid URIs.

Useful? React with 👍 / 👎.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct the fact that it gets a string does not means that what it gets is a list. It actually gets a list which is stored in "plasmid_uris". So the function is Ok.


sbh = sbol2.PartShop(sbh_registry)
sbh.key = auth_token

try:
transformation_doc = generate_transformation_metadata(plasmid_uris, chassis_uri, machine_name, protocol, parameters, sbh)

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

except ValueError as e:
return jsonify({"error": str(e)}), 400

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

@app.route('/build_pudu', methods=['POST'])
def build_pudu():
Expand Down