-
Notifications
You must be signed in to change notification settings - Fork 1
Workshop Instructions
Download Docker Desktop:
Mac
Windows
Linux
Download git
Open Terminal/Command Prompt and Docker
Navigate to where you want to store this. E.g.
mkdir iwbdaworkshop
cd iwbdaworkshop
In Terminal:
git clone -b snapshot https://github.com/synbiohub/synbiohub2-docker
docker compose -f ./synbiohub2-docker/docker-compose.yml up
Your Docker app should also show SynBioHub2 Docker running:
Navigate to http://localhost:3333/. This is the default URL for SynBioHub2. You should see the setup page.
You don't need to change anything in this section, as you can use defaults.
Instance Name and Welcome Message: I do like to change these to make sure they're updating correctly. You can always change these later too.
You can also change the primary color of your SynBioHub
These technical details should be kept as the default unless you know you want to change them. The Frontend URL is just the URL you’ll use to view. The Backend URL is the URL to access the API. The URI Prefix can be described as the location where our data is stored. Most of the time, we want to it to be the same as the frontend URL.
Finally, we ‘ll make our first account. This account will default to admin.
With that, we have set up and deployed SynBioHub.
We will use pySBOL2 for this part of the workshop
Open a python environment.
I will use Anaconda’s Jupyter notebook. Install Anaconda
Open Jupyter Notebook and navigate to your iwbdaworkshop
folder.
Part we'll be using for the demo
We need to move the part into the same folder as the Jupyter notebook.
Open a Jupyter Notebook.
First, install pySBOL2. pip install sbol2
from sbol2 import *
There are 4 main parts of using SynBioHub's API - login, submit, search, and download. We will use pySBOL which will be connected to our localhost SynBioHub. Using Python, we can run these commands without needing to go to SynBioHub. Essentially, this will be useful if you would want any of your tools to connect to SynBioHub.
Steps:
- Create SBOL Document with the downloaded part.
- Connect PySBOL to Localhost SynBioHub (note: using something like Google Colab will not allow you to connect to localhost).
- Login to SynBioHub.
- Submit the Document.
- Go back to SynBioHub, Login, and go to Submissions. You can then see the new collection with the added part.
- Search for the part using the API.
- Before the download step, we want to first make the collection public. To make the collection public:
- Navigate to the Submission page.
- Check the box for the collection.
- In the header, click Publish.
- In the pop up box, click as new, then Publish.
- Create a new PartShop connected directly to the newly formed public collection.
- Download the part with the API.
- Go to the file directory to view the downloaded SBOL file.
Example code:
A lot of people want to develop plugins to personalize their SynBioHub. This section will detail how to develop a plugin using our template. For this example, the plugin will look at all sequence parts and return a bar chart of the A, C, T, and G composition of all the sequences. In this example, we will only use one sequence, but this code could be used on a component for example and return the total composition of multiple sequences.
I will be using Visual Studio Code to edit the plugin, but any Python editor would work. Download Visual Studio Code
Now, we need to add our plugin code to the same directory as before. Open a new Terminal for this. Navigate to the iwbdaworkshop
directory.
Link to Github: Plugin Template
git clone https://github.com/SynBioHub/Plugin-Visual-Test.git
Open the new folder and open the Plugin code in VSCode:
cd Plugin-Visual-Test
code -a .
For the plugin, there are 3 distinct endpoints: status, evaluate, and run. Status checks if it's currently running. Evaluate does the calculations for the plugin and run returns the result back to SynBioHub.
There are 4 files of note for the plugin.
The first is app.py
. This will be where we edit most of our code.
The second is the Dockerfile. This contains the instructions for how to run the plugin as a Docker container. We will not edit this file.
The third is the requirements.txt
file. This contains the Python libraries we need.
The last file is the Test.html
file. This is the output result.
First, we will add our two python libraries, pySBOL2 and matplotlib to the requirements.txt
file.
Now, we can move on to the app.py
file. We'll start from the top and work our way down.
- Add our imports that we need. On top of the pySBOL2 and matplotlib we installed, we need to add some IO libraries as well for the bar chart.
from sbol2 import *
import matplotlib.pyplot as plt # Import pyplot explicitly for plotting
import base64 # To encode the image in base64
from io import BytesIO # To handle in-memory bytes for image saving
- On the
/status
endpoint, it just checks the plugin is running. We can leave it as it is. - On the
/evaluate
endpoint, change the accepted file types to only "Sequence".
Finally, we can edit the /run
endpoint. Similar to what we did with the Python API section previously, we want to connect the plugin to SynBioHub to get the sequence.
- For the first section of this endpoint, before the try, we can leave all of this as is.
- Also, remove all of the result.replace lines of code in the editing section.
- We need to get the displayId from the part. This is located in the given URI. So, we can just split the URI string to get the displayId.
- Next, we connect the PartShop to SynBioHub. Note, we use
synbiohub:7777
instead oflocalhost:7777
because the Plugin and SynBioHub are on different Virtual machines. They are not on the same localhost. - A new SBOL document is created, and the sequence element is pulled to the SBOL document. The actual sequence is extracted.
- Using the first helper function, the percentages are calculated.
- Using the second helper function, the percentages are converted into a bar chart.
- Finally, the bar chart is displayed in the output file.
try:
# ~~~~~~~~~~~~ REPLACE THIS SECTION WITH OWN RUN CODE ~~~~~~~~~~~~~~~~~~~
with open(filename, 'r') as htmlfile:
result = htmlfile.read()
# put in the url, uri, and instance given by synbiohub
url = url.replace("localhost:3333", "synbiohub:7777")
displayId = url.split("/")[-2]
parts = PartShop('http://synbiohub:7777/public/test_collection')
doc = Document()
parts.pull(displayId, doc)
data_percents = cumulative_nucleotide_percentage(doc.sequences)
img_str = create_chart(data_percents)
result = result.replace("CHART_IMAGE", f'<img src="data:image/png;base64,{img_str}" alt="Nucleotide Composition"/>')
# ~~~~~~~~~~~~~~~~~~~~~~~~~~ END SECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return result
- The above shows the main code for writing a plugin. We will also use two helper functions. The first helper function is to calculate the percentage of A, C, G, and T given a DNA sequence as a string.
def cumulative_nucleotide_percentage(sequences):
# Initialize totals for each nucleotide count
total_g = total_c = total_a = total_t = 0
total_length = 0
# Accumulate nucleotide counts across all sequences
for sequence in sequences:
sequence_string = sequence.elements
filtered_sequence = [char for char in sequence_string.upper() if char in "ATCG"]
# Update total counts and length
total_g += filtered_sequence.count('G')
total_c += filtered_sequence.count('C')
total_a += filtered_sequence.count('A')
total_t += filtered_sequence.count('T')
total_length += len(filtered_sequence)
# Calculate overall percentages if total_length is non-zero
if total_length > 0:
return {
'G': (total_g / total_length) * 100,
'C': (total_c / total_length) * 100,
'A': (total_a / total_length) * 100,
'T': (total_t / total_length) * 100
}
else:
return {'G': 0.0, 'C': 0.0, 'A': 0.0, 'T': 0.0}
- The second helper function is to create the chart.
def create_chart(data_percents):
labels = ['G', 'C', 'A', 'T']
values = [data_percents['G'], data_percents['C'], data_percents['A'], data_percents['T']]
plt.figure(figsize=(8, 5))
plt.bar(labels, values)
plt.ylim(0, 100)
plt.xlabel('Nucleotide')
plt.ylabel('Percentage (%)')
plt.title('Nucleotide Composition')
# Annotate each bar with the percentage value
for i, v in enumerate(values):
plt.text(i, v + 1, f"{v:.1f}%", ha='center')
# Save the plot to a BytesIO object in memory
buffer = BytesIO()
plt.savefig(buffer, format="png")
plt.close()
buffer.seek(0)
# Encode the image as a base64 string
img_str = base64.b64encode(buffer.getvalue()).decode("utf-8")
buffer.close()
return img_str
- The final step is to edit the Test.html file to only display the
CHART_IMAGE
In order for our plugin to be connected to SynBioHub, we need to add its Dockerfile to the same directory as the SynBioHub Dockerfile.
Download it here: Plugin DockerFile
Move the downloaded .yml
file into the same directory as everything else.
Now, your iwbdaworkshop directory should look like this:
Once the necessary changes are made to the plugin, we need to build a new docker image of the plugin:
cd Plugin-Visual-Test
docker build -t synbiohub/plugin-visual-test:snapshot .
Next, we need to add our new plugin to the docker container of SynBioHub. Navigate to the original Terminal where SynBioHub should still be running. Stop it using ctrl + c
and the run the new command.
docker compose -f ./synbiohub2-docker/docker-compose.yml -f ./docker-compose.pluginVisualTest.yml up
Docker should show it running in parallel with the rest of SynBioHub now.
Go to http://localhost:8081/status
to make sure the plugin is running.
Since we reloaded SynBioHub, we need to refresh back to the home page and re-login. The errors are expected, since the server was restarted.
Go to the admin page of SynBioHub and go to plugins, enter in a name for the plugin and the url as http://pluginVisualTest:5000/
into a new entry in the Rendering section.
Go to submissions, click on your public collection. Then, in the collection, click the member private collection, click the component I0462, and finally, on the left ComponentDefinition metadata panel, click the sequence object link and view the sequence page of the part we submitted to view the plugin. The plugin should be located at the bottom.