Usage

The basicsynbio API extends the Biopython library. Extensive knowledge of Biopython is not required but basic knowledge of key objects would aid users.

basicsynbio workflow

The core basicsynbio workflow has the following steps associated with it:

  1. Get the parts (either from collections or externally)

  2. Create the assemblies

  3. Create the build

  4. Export your data

1a. Accessing BASIC part collections

  • The basicsynbio package contains collections of parts and linkers compatible with BASIC DNA assembly.

  • Each collection can have multiple versions e.g. "v0.1", with changes only in minor numbers indicating backwards compatibility e.g. "v0.1" would be compatible with "v0.2".

  • Within each version of a collection are individual part or linker objects. For instance, to access the BASIC backbone with ampicilin resistance and a pUC ori (equivalent to SEVA 18), input the following:

import basicsynbio as bsb
basic_seva18 = bsb.BASIC_SEVA_PARTS["v0.1"]["18"]
  • A list of selected part and linker collections is given in Browse selected collections.

  • The contents of each collection can also be displayed using the print function e.g.

print(bsb.BASIC_SEVA_PARTS["v0.1"])

1b. Import parts from external sources

Compatible BASIC parts can be imported from multiple sources. To import one BASIC part from a local file (e.g. genbank file) run:

import basicsynbio as bsb

basic_part = bsb.import_part("basic_part.gb", "genbank")

Otherwise mutliple BASIC parts from the same gb file are imported as follows:

basic_parts = bsb.import_parts("basic_parts.gb", "genbank")

Convert Biopython SeqRecords or similar objects into BASIC parts. This is useful for accessing sequences via NCBI Entrez directly. The following leverages BioPython and Entrez to generate a new BASIC part encoding sfGFP from KJ541673.2:

from Bio import Entrez, SeqIO
import basicsynbio as bsb
from basicsynbio.utils import feature_from_qualifier
Entrez.email = "hainesm6@gmail.com"
with Entrez.efetch(db="nucleotide", id="KJ541673.2", rettype="gb", retmode="text") as handle:
    kj541673 = SeqIO.read(handle, "genbank")
    sfgfp_feature = feature_from_qualifier(kj541673, "gene", ["sfGFP"])
    sfgfp = kj541673[sfgfp_feature.location.start:sfgfp_feature.location.end]
sfgfp_part = bsb.seqrec2part(sfgfp, add_i_seqs=True)

For parts specified in SBOL the following imports them as a generator object:

basic_parts = bsb.import_sbol_part("basic_parts.rdf")

All BasicPart objects require flanking iP and iS sequences. To add these when creating your object, use the optional add_i_seqs argument, available for all the above functions e.g.

basic_part = bsb.seqrec2part(SeqRecord, add_i_seqs=True)

To physically generate BasicParts from external sources – referred to as domestication – users can amplify DNA lacking iP and iS sequences with primers that contain them. The BasicPart class contains a domesticating_primers() method to aid this. This method works by running primer3-py under the hood, returning an object containing left and right primers, in addition to associated data as attributes. The primer attributes are easily exported to a .tsv file, a format accepted by various DNA synthesis companies. For additional examples of bsb.export_sequences_to_file() refer to 4. Export your data:

domesticating_primers = basic_part.domesticating_primers()
bsb.export_sequences_to_file(
    (domesticating_primers.left_primer, domesticating_primers.right_primer),
    "primers_for_domesticating_parts.tsv",
    "tsv"
)

2. Create the assemblies

Create a BasicAssembly object from your imported BASIC parts using any Biolegio Linkers contained within the BIOLEGIO_LINKERS collection:

import basicsynbio as bsb
my_basic_part = bsb.import_part("my_basic_part.gb", "genbank")
assembly = bsb.BasicAssembly(
    "my_first_basic_assembly",
    bsb.BASIC_BIOLEGIO_LINKERS["v0.1"]["LMP"],
    my_basic_part,
    bsb.BASIC_BIOLEGIO_LINKERS["v0.1"]["LMS"],
    bsb.BASIC_SEVA_PARTS["v0.1"]["18"]
)

This creates a BasicAssembly object where my_basic_part has been cloned into the BASIC_SEVA_18 backbone.

A desirable feature of BASIC DNA Assembly is its single-tier format (Introduction). This ensures any assembly flanked by LMP and LMS linkers can be used in a subsequent hierarchical assembly. Use the return_part() method on a BasicAssembly object to simulate this behaviour:

new_part = assembly.return_part(name="new part from assembly")
hierarchical_assembly = bsb.BasicAssembly(
    new_part,
    ...
)

3. Create the build

More often than not, a collection of BASIC assemblies are constructed in parallel. To aid this process users should create a BasicBuild object using multiple BasicAssembly objects:

promoter_assemblies = (
    bsb.BasicAssembly(
        f"promoter_construct_{ind}",
        bsb.BASIC_SEVA_PARTS["v0.1"]["26"],
        bsb.BASIC_BIOLEGIO_LINKERS["v0.1"]["LMP"],
        promoter,
        bsb.BASIC_BIOLEGIO_LINKERS["v0.1"]["UTR1-RBS2"],
        bsb.BASIC_CDS_PARTS["v0.1"]["sfGFP"],
        bsb.BASIC_BIOLEGIO_LINKERS["v0.1"]["LMS"],
    )
    for ind, promoter in enumerate(bsb.BASIC_PROMOTER_PARTS["v0.1"].values())
)
build = bsb.BasicBuild(*promoter_assemblies)

The build instance contains data describing the unique BasicParts, BasicLinkers and ClipReactions objects associated with this build. These objects together provide a description of the materials and steps required to construct your assemblies.

4. Export your data

BasicBuild objects can be serialised as JSON objects which are compliant with the BasicBuild Open Standard. These provide a minimum description of the build, necessary to manufacture associated BASIC DNA assemblies.

To serialise the build, the json API can be used, in the following case yielding (build.json):

import json

with open("build.json", "w") as json_file:
    json.dump(build, json_file, cls=bsb.BuildEncoder, indent=4, ensure_ascii=False)

Depending on the file format, the resulting output contains data on the unique BasicParts (unique_parts), BasicLinkers (unique_linkers) and ClipReactions (clips_data) objects required to build the assemblies (assembly_data). This data can be further processed to inform manual or liquid handling workflows. We have already generated several functions accessible via the API that generate additional data types using BasicBuild objects as arguments.

For instance, The export_csvs() function generates a zip file, containing clips.csv and assemblies.csv:

bsb.export_csvs(build)

The bsb.pdf_instructions() function creates pdf instructions for manual assembly of the build in the lab. An example can be seen here

bsb.pdf_instructions(build)

The bsb.export_echo_assembly(build) function creates Echo liquid handling instructions to combine purified clip reactions with buffer and water, yielding assemblies for transformation. The following echo_clips_1.csv and echo_water_buffer_1.csv are example outputs.

bsb.export_echo_assembly(build)

In addition to exporting manufacturing data, it is recommended to export annotated BasicAssembly objects and the unique BasicParts associated with the build. Annotated BasicAssembly objects are useful for illustrating resulting constructs while unique BasicParts are required for completely decoding serialised BasicBuild objects, described in the next section. Any collection of BasicPart 1 or BasicAssembly objects can be exported using the formats supported by BioPython, with the default being genbank:

unique_parts = build.unique_parts
bsb.export_sequences_to_file(unique_parts, "the_parts_i_need.gb")
bsb.export_sequences_to_file(promoter_assemblies, "promoter_assemblies.gb")

Importing from build.json

It is possible to decode build.json objects, restoring the BasicBuild object. Users have two options:

  1. The first method uses only the build.json file and results in correct sequences, although, with a loss of metainformation e.g. annotations, features etc.

  2. The second method extends the first, updating the decoded BasicBuild object using the original BasicParts with the correct annotations.

To partially decode a build.json file:

import basicsynbio as bsb
import json

with open("build.json") as build_json:
    partially_decoded_build = json.load(build_json, cls=bsb.BuildDecoder)

To completely decode this file:

original_parts = bsb.import_parts("the_parts_i_need.gb", "genbank")
decoded_build.update_parts(*original_parts)

Generating oligonucleotides for new linkers

Users may wish to design their own linkers. For instance, linkers more suited to specific organisms. The basicsynbio API provide users with the ability to generate oligonucleotide sequences required for new linkers. We do not currently provide users with the functionality to design new linker sequences. Linker sequences have previously been designed using R2oDNA Designer and DNA Chisel. For an example of a neutral linker being designed using DNA Chisel, users can consult the following jupyter notebook.

To generate linker oligonucleotides, users need to supply values for the overhang_slice_params argument when initiating a BasicLinker instance. This argument is described further in the main.py section of the API documentation under the BasicLinker class. In a similar manner to that implemented for domesticating primer sequences, users can export sequences encoding long and adapter oligonucleotides for each prefix and suffix linker half to a tsv file enabling subsequent ordering. This is illustrated in the example below:

 my_new_linker = bsb.BasicLinker(
    seq=linker_sequence_designed_with_dna_chisel,
    id="foobar",
    name="my_new_linker",
    overhang_indicies = (
        len(bsb.BasicLinker.UPSTREAM_SCAR) + 12,
        len(bsb.BasicLinker.UPSTREAM_SCAR) + 12 + 21
    )
)
bb_linker.id = seqrecord_hexdigest(bb_linker)
SeqIO.write(
    my_new_linker.linker_oligos.all_oligo_seqrecs(),
    path_to_seqs / "alternative_formats" / "tsv" / "my_new_linker.tsv",
    "tab"
)

Footnotes

1

This also applies to any Biopython SeqRecord-like object.