Skip to content

Commit de70f64

Browse files
authored
iGEM as sequence source (#242)
* working version of #240 * update to new conventions * update linkml library to pypi
1 parent 34f9e49 commit de70f64

File tree

5 files changed

+70
-6
lines changed

5 files changed

+70
-6
lines changed

main.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
OverlapExtensionPCRLigationSource,
5050
GatewaySource,
5151
AnnotationSource,
52+
IGEMSource,
5253
)
5354
from fastapi.middleware.cors import CORSMiddleware
5455
from Bio.Restriction.Restriction import RestrictionBatch
@@ -474,6 +475,22 @@ async def get_from_repository_id_euroscarf(source: EuroscarfSource):
474475
repository_id_http_error_handler(exception, source)
475476

476477

478+
@router.post(
479+
'/repository_id/igem',
480+
response_model=create_model(
481+
'IGEMResponse', sources=(list[IGEMSource], ...), sequences=(list[TextFileSequence], ...)
482+
),
483+
)
484+
async def get_from_repository_id_igem(source: IGEMSource):
485+
try:
486+
dseq = (await get_sequences_from_gb_file_url(source.sequence_file_url))[0]
487+
return {'sequences': [format_sequence_genbank(dseq, source.output_name)], 'sources': [source]}
488+
except HTTPError as exception:
489+
repository_id_http_error_handler(exception, source)
490+
except URLError as exception:
491+
repository_id_url_error_handler(exception, source)
492+
493+
477494
@router.post(
478495
'/genome_coordinates',
479496
response_model=create_model(

poetry.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pydantic_models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
GatewaySource as _GatewaySource,
4141
InFusionSource as _InFusionSource,
4242
AnnotationSource as _AnnotationSource,
43+
IGEMSource as _IGEMSource,
4344
)
4445
from pydna.utils import shift_location as _shift_location
4546
from assembly2 import edge_representation2subfragment_representation, subfragment_representation2edge_representation
@@ -128,6 +129,15 @@ class EuroscarfSource(SourceCommonClass, _EuroscarfSource):
128129
pass
129130

130131

132+
class IGEMSource(SourceCommonClass, _IGEMSource):
133+
134+
@model_validator(mode='after')
135+
def validate_repository_id(self):
136+
file_name = self.sequence_file_url.split('/')[-1]
137+
assert file_name.endswith('.gb'), 'The sequence file must be a GenBank file'
138+
return self
139+
140+
131141
class GenomeCoordinatesSource(SourceCommonClass, _GenomeCoordinatesSource):
132142
pass
133143

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pydna = {git = "https://github.com/BjornFJohansson/pydna", rev = "9d112d71534194
1717
requests = "^2.31.0"
1818
regex = "^2023.10.3"
1919
pydantic = "^2.7.1"
20-
shareyourcloning-linkml = "0.1.10a0"
20+
shareyourcloning-linkml = "0.1.11a0"
2121
pandas = "^2.2.3"
2222
openpyxl = "^3.1.5"
2323

test_endpoints.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
SnapGenePlasmidSource,
3030
GatewaySource,
3131
AnnotationSource,
32+
IGEMSource,
3233
)
3334
from pydna.dseqrecord import Dseqrecord
3435
import unittest
@@ -2714,5 +2715,41 @@ def test_get_gateway_sites(self):
27142715
self.assertIn('attP1', payload)
27152716

27162717

2718+
class IGEMSourceTest(unittest.TestCase):
2719+
good_url = 'https://raw.githubusercontent.com/manulera/annotated-igem-distribution/master/results/plasmids/1.gb'
2720+
no_gb_url = 'https://blah.com/1.txt'
2721+
wrong_url = (
2722+
'https://raw.githubusercontent.com/manulera/annotated-igem-distribution/master/results/plasmids/dummy.gb'
2723+
)
2724+
2725+
def test_igem(self):
2726+
source = IGEMSource(
2727+
id=0, repository_name='igem', repository_id='BBa_C0062-dummy', sequence_file_url=self.good_url
2728+
)
2729+
response = client.post('/repository_id/igem', json=source.model_dump())
2730+
payload = response.json()
2731+
self.assertEqual(response.status_code, 200)
2732+
self.assertEqual(payload['sources'][0]['repository_id'], 'BBa_C0062-dummy')
2733+
self.assertEqual(payload['sources'][0]['repository_name'], 'igem')
2734+
2735+
def test_errors(self):
2736+
2737+
# The repository_id does not start with the part_name, even if url is valid
2738+
source = IGEMSource(
2739+
id=0, repository_name='igem', repository_id='BBa_C0062-dummy', sequence_file_url=self.good_url
2740+
)
2741+
2742+
# The url is not a GenBank file
2743+
source_json = source.model_dump()
2744+
source_json['sequence_file_url'] = self.no_gb_url
2745+
response = client.post('/repository_id/igem', json=source_json)
2746+
self.assertEqual(response.status_code, 422)
2747+
2748+
# The url does not exist
2749+
source = IGEMSource(id=0, repository_name='igem', repository_id='dummy-test', sequence_file_url=self.wrong_url)
2750+
response = client.post('/repository_id/igem', json=source.model_dump())
2751+
self.assertEqual(response.status_code, 404)
2752+
2753+
27172754
if __name__ == '__main__':
27182755
unittest.main()

0 commit comments

Comments
 (0)