7373import os
7474from record_stub_route import RecordStubRoute
7575from starlette .responses import RedirectResponse
76- from primer_design import homologous_recombination_primers , gibson_assembly_primers , simple_pair_primers
76+ from primer_design import (
77+ homologous_recombination_primers ,
78+ gibson_assembly_primers ,
79+ simple_pair_primers ,
80+ )
7781import asyncio
7882import re
7983import warnings
@@ -1171,10 +1175,10 @@ def annotate(x):
11711175 return resp
11721176
11731177
1174- @ router . post (
1175- '/primer_design/homologous_recombination' ,
1176- response_model = create_model ( 'HomologousRecombinationPrimerDesignResponse' , primers = ( list [ PrimerModel ], ...)),
1177- )
1178+ PrimerDesignResponse = create_model ( 'PrimerDesignResponse' , primers = ( list [ PrimerModel ], ...))
1179+
1180+
1181+ @ router . post ( '/primer_design/homologous_recombination' , response_model = PrimerDesignResponse )
11781182async def primer_design_homologous_recombination (
11791183 pcr_template : PrimerDesignQuery ,
11801184 homologous_recombination_target : PrimerDesignQuery ,
@@ -1223,21 +1227,7 @@ async def primer_design_homologous_recombination(
12231227 return {'primers' : [forward_primer , reverse_primer ]}
12241228
12251229
1226- # A primer design endpoint for Gibson assembly
1227- # This is how the request data will look like from javascript code:
1228- # const requestData = {
1229- # queries: templateEntities.map((e, index) => ({
1230- # sequence: e,
1231- # location: selectedRegion2SequenceLocation(amplifyRegions[index]),
1232- # orientation: fragmentOrientations[index],
1233- # })),
1234- # };
1235-
1236-
1237- @router .post (
1238- '/primer_design/gibson_assembly' ,
1239- response_model = create_model ('GibsonAssemblyPrimerDesignResponse' , primers = (list [PrimerModel ], ...)),
1240- )
1230+ @router .post ('/primer_design/gibson_assembly' , response_model = PrimerDesignResponse )
12411231async def primer_design_gibson_assembly (
12421232 pcr_templates : list [PrimerDesignQuery ],
12431233 spacers : list [str ] | None = Body (
@@ -1277,11 +1267,7 @@ async def primer_design_gibson_assembly(
12771267 return {'primers' : primers }
12781268
12791269
1280- @router .post (
1281- '/primer_design/simple_pair' ,
1282- response_model = create_model ('SimplePairPrimerDesignResponse' , primers = (list [PrimerModel ], ...)),
1283- summary = 'Design primers for PCR, you can also include restriction enzyme sites with filler bases.' ,
1284- )
1270+ @router .post ('/primer_design/simple_pair' , response_model = PrimerDesignResponse )
12851271async def primer_design_simple_pair (
12861272 pcr_template : PrimerDesignQuery ,
12871273 spacers : list [str ] | None = Body (
@@ -1372,6 +1358,41 @@ async def annotate_with_plannotate(
13721358 return {'sources' : [source ], 'sequences' : [format_sequence_genbank (seqr , source .output_name )]}
13731359
13741360
1361+ # @router.post('/primer_design/gateway_attB', response_model=PrimerDesignResponse)
1362+ # async def primer_design_gateway_attB(
1363+ # template: PrimerDesignQuery,
1364+ # left_site: str = Query(..., description='The left attB site to recombine.', regex=r'^attB[1-5]$'),
1365+ # right_site: str = Query(..., description='The right attB site to recombine.', regex=r'^attB[1-5]$'),
1366+ # spacers: list[str] | None = Body(None, description='Spacers to add between the attB site and the primer.'),
1367+ # filler_bases: str = Query(
1368+ # 'GGGG',
1369+ # description='These bases are added to the 5\' end of the primer to ensure proper restriction enzyme digestion.',
1370+ # ),
1371+ # minimal_hybridization_length: int = Query(
1372+ # ..., description='The minimal length of the hybridization region in bps.'
1373+ # ),
1374+ # target_tm: float = Query(
1375+ # ..., description='The desired melting temperature for the hybridization part of the primer.'
1376+ # ),
1377+ # ):
1378+ # """Design primers for Gateway attB"""
1379+ # dseqr = read_dsrecord_from_json(template.sequence)
1380+ # location = template.location.to_biopython_location(dseqr.circular, len(dseqr))
1381+ # template = location.extract(dseqr)
1382+ # if not template.forward_orientation:
1383+ # template = template.reverse_complement()
1384+ # template.name = dseqr.name
1385+ # template.id = dseqr.id
1386+ # try:
1387+ # primers = gateway_attB_primers(
1388+ # template, minimal_hybridization_length, target_tm, (left_site, right_site), spacers, filler_bases
1389+ # )
1390+ # except ValueError as e:
1391+ # raise HTTPException(400, *e.args)
1392+
1393+ # return {'primers': primers}
1394+
1395+
13751396@router .post (
13761397 '/validate' ,
13771398 summary = 'Validate a cloning strategy' ,
@@ -1393,6 +1414,20 @@ async def rename_sequence(
13931414 return format_sequence_genbank (dseqr , name )
13941415
13951416
1417+ @router .post ('/annotation/get_gateway_sites' , response_model = dict [str , list [str ]])
1418+ async def get_gateway_sites (
1419+ sequence : TextFileSequence , greedy : bool = Query (False , description = 'Whether to use the greedy algorithm.' )
1420+ ) -> dict [str , list [str ]]:
1421+ """
1422+ Get a dictionary with the names of the gateway sites present in the sequence and their locations as strings.
1423+ """
1424+ dseqr = read_dsrecord_from_json (sequence )
1425+ sites_dict = find_gateway_sites (dseqr , greedy )
1426+ for site in sites_dict :
1427+ sites_dict [site ] = [str (loc ) for loc in sites_dict [site ]]
1428+ return sites_dict
1429+
1430+
13961431if not SERVE_FRONTEND :
13971432
13981433 @router .get ('/' )
0 commit comments