opencloning 0.2.6.4__tar.gz → 0.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {opencloning-0.2.6.4 → opencloning-0.2.7}/PKG-INFO +1 -1
- {opencloning-0.2.6.4 → opencloning-0.2.7}/pyproject.toml +1 -1
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/primer_design.py +81 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/LICENSE +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/README.md +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/__init__.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/api_config_utils.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/app_settings.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/assembly2.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/EBIC/__init__.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/EBIC/barcode.gb +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/EBIC/common_plasmid.gb +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/EBIC/example.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/EBIC/primer_design_settings.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/__init__.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/index.html +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/__init__.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/index.html +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_all.sh +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_clone.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_gather.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_get_primers.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_summary.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/ziqiang_et_al2024/__init__.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/ziqiang_et_al2024/index.html +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/ziqiang_et_al2024/ziqiang_et_al2024.json +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/dna_functions.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/dna_utils.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/ebic/__init__.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/ebic/primer_design.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/ebic/primer_design_settings.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/annotation.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/assembly.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/external_import.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/no_assembly.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/no_input.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/endpoints/other.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/gateway.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/get_router.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/main.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/ncbi_requests.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/primer_design.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/pydantic_models.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/request_examples.py +0 -0
- {opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/utils.py +0 -0
|
@@ -3,7 +3,7 @@ authors = ["Manuel Lera-Ramirez <manulera14@gmail.com>"]
|
|
|
3
3
|
description = "Backend of OpenCloning, a web application to generate molecular cloning strategies in json format, and share them with others."
|
|
4
4
|
license = "MIT"
|
|
5
5
|
name = "opencloning"
|
|
6
|
-
version = "v0.2.
|
|
6
|
+
version = "v0.2.7"
|
|
7
7
|
package-mode = true
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
repository = "https://github.com/manulera/OpenCloning_backend"
|
|
@@ -2,6 +2,9 @@ from fastapi import Body, Query, HTTPException
|
|
|
2
2
|
from pydantic import create_model
|
|
3
3
|
import re
|
|
4
4
|
from Bio.Restriction import RestrictionBatch
|
|
5
|
+
from Bio.SeqUtils import gc_fraction
|
|
6
|
+
from primer3 import bindings
|
|
7
|
+
from itertools import product
|
|
5
8
|
|
|
6
9
|
from ..dna_functions import get_invalid_enzyme_names
|
|
7
10
|
from ..pydantic_models import PrimerModel, PrimerDesignQuery
|
|
@@ -13,6 +16,7 @@ from ..primer_design import (
|
|
|
13
16
|
)
|
|
14
17
|
from ..get_router import get_router
|
|
15
18
|
from ..ebic.primer_design import ebic_primers
|
|
19
|
+
from pydantic import BaseModel
|
|
16
20
|
|
|
17
21
|
router = get_router()
|
|
18
22
|
|
|
@@ -235,3 +239,80 @@ async def primer_design_ebic(
|
|
|
235
239
|
# raise HTTPException(400, *e.args)
|
|
236
240
|
|
|
237
241
|
# return {'primers': primers}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class ThermodynamicResult(BaseModel):
|
|
245
|
+
melting_temperature: float
|
|
246
|
+
deltaG: float
|
|
247
|
+
figure: str | None
|
|
248
|
+
|
|
249
|
+
@classmethod
|
|
250
|
+
def from_binding(cls, result):
|
|
251
|
+
return cls(
|
|
252
|
+
melting_temperature=result.tm,
|
|
253
|
+
deltaG=result.dg,
|
|
254
|
+
figure='\n'.join(result.ascii_structure_lines),
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def get_sequence_thermodynamic_result(sequences: list[str], method: callable) -> ThermodynamicResult | None:
|
|
259
|
+
"""Get the thermodynamic result for a sequence, if the sequence is longer than primer3 60bp limit, it will be split into two
|
|
260
|
+
and the result with the lowest deltaG will be returned."""
|
|
261
|
+
results = [method(seq, output_structure=True) for seq in sequences]
|
|
262
|
+
results = [r for r in results if r.structure_found]
|
|
263
|
+
if len(results) == 0:
|
|
264
|
+
return None
|
|
265
|
+
|
|
266
|
+
result = min(results, key=lambda r: r.dg)
|
|
267
|
+
return ThermodynamicResult.from_binding(result)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class PrimerDetailsResponse(BaseModel):
|
|
271
|
+
melting_temperature: float
|
|
272
|
+
gc_content: float
|
|
273
|
+
homodimer: ThermodynamicResult | None
|
|
274
|
+
hairpin: ThermodynamicResult | None
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@router.get('/primer_details', response_model=PrimerDetailsResponse)
|
|
278
|
+
async def primer_details(
|
|
279
|
+
sequence: str = Query(..., description='Primer sequence', regex=r'^[ACGTacgt]+$'),
|
|
280
|
+
):
|
|
281
|
+
"""Get information about a primer"""
|
|
282
|
+
sequence = sequence.upper()
|
|
283
|
+
tm = bindings.calc_tm(sequence)
|
|
284
|
+
gc_content = gc_fraction(sequence)
|
|
285
|
+
|
|
286
|
+
thermodynamic_sequences = [sequence]
|
|
287
|
+
if len(sequence) > 60:
|
|
288
|
+
thermodynamic_sequences = [sequence[:60], sequence[-60:]]
|
|
289
|
+
homodimer = get_sequence_thermodynamic_result(thermodynamic_sequences, bindings.calc_homodimer)
|
|
290
|
+
hairpin = get_sequence_thermodynamic_result(thermodynamic_sequences, bindings.calc_hairpin)
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
'melting_temperature': tm,
|
|
294
|
+
'gc_content': gc_content,
|
|
295
|
+
'homodimer': homodimer,
|
|
296
|
+
'hairpin': hairpin,
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@router.get('/primer_heterodimer', response_model=ThermodynamicResult | None)
|
|
301
|
+
async def primer_heterodimer(
|
|
302
|
+
sequence1: str = Query(..., description='First primer sequence', regex=r'^[ACGTacgt]+$'),
|
|
303
|
+
sequence2: str = Query(..., description='Second primer sequence', regex=r'^[ACGTacgt]+$'),
|
|
304
|
+
):
|
|
305
|
+
"""Get information about a primer pair"""
|
|
306
|
+
|
|
307
|
+
if len(sequence1) <= 60 or len(sequence2) <= 60:
|
|
308
|
+
sequence_pairs = [(sequence1, sequence2)]
|
|
309
|
+
else:
|
|
310
|
+
sequence_pairs = list(product((sequence1[:60], sequence1[-60:]), (sequence2[:60], sequence2[-60:])))
|
|
311
|
+
|
|
312
|
+
results = [bindings.calc_heterodimer(s1, s2, output_structure=True) for s1, s2 in sequence_pairs]
|
|
313
|
+
results = [r for r in results if r.structure_found]
|
|
314
|
+
if len(results) == 0:
|
|
315
|
+
return None
|
|
316
|
+
|
|
317
|
+
result = min(results, key=lambda r: r.dg)
|
|
318
|
+
return ThermodynamicResult.from_binding(result)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/EBIC/common_plasmid.gb
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_clone.py
RENAMED
|
File without changes
|
{opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_gather.py
RENAMED
|
File without changes
|
{opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_get_primers.py
RENAMED
|
File without changes
|
{opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/pombe/pombe_summary.py
RENAMED
|
File without changes
|
|
File without changes
|
{opencloning-0.2.6.4 → opencloning-0.2.7}/src/opencloning/batch_cloning/ziqiang_et_al2024/index.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|