opencloning 0.4.8__py3-none-any.whl → 0.5__py3-none-any.whl
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/app_settings.py +7 -0
- opencloning/batch_cloning/pombe/__init__.py +2 -2
- opencloning/batch_cloning/pombe/pombe_clone.py +31 -112
- opencloning/batch_cloning/pombe/pombe_summary.py +20 -8
- opencloning/batch_cloning/ziqiang_et_al2024/__init__.py +8 -8
- opencloning/batch_cloning/ziqiang_et_al2024/ziqiang_et_al2024.json +2 -9
- opencloning/bug_fixing/backend_v0_3.py +13 -5
- opencloning/catalogs/__init__.py +36 -0
- opencloning/catalogs/igem2024.yaml +2172 -0
- opencloning/catalogs/openDNA_collections.yaml +1161 -0
- opencloning/catalogs/readme.txt +1 -0
- opencloning/catalogs/seva.tsv +231 -0
- opencloning/catalogs/snapgene.yaml +2837 -0
- opencloning/dna_functions.py +155 -158
- opencloning/dna_utils.py +45 -62
- opencloning/ebic/primer_design.py +1 -1
- opencloning/endpoints/annotation.py +9 -13
- opencloning/endpoints/assembly.py +157 -378
- opencloning/endpoints/endpoint_utils.py +52 -0
- opencloning/endpoints/external_import.py +169 -124
- opencloning/endpoints/no_assembly.py +23 -39
- opencloning/endpoints/no_input.py +32 -47
- opencloning/endpoints/other.py +1 -1
- opencloning/endpoints/primer_design.py +2 -1
- opencloning/http_client.py +2 -2
- opencloning/ncbi_requests.py +113 -47
- opencloning/primer_design.py +1 -1
- opencloning/pydantic_models.py +10 -510
- opencloning/request_examples.py +10 -22
- opencloning/temp_functions.py +50 -0
- {opencloning-0.4.8.dist-info → opencloning-0.5.dist-info}/METADATA +18 -8
- opencloning-0.5.dist-info/RECORD +51 -0
- {opencloning-0.4.8.dist-info → opencloning-0.5.dist-info}/WHEEL +1 -1
- opencloning/cre_lox.py +0 -116
- opencloning/gateway.py +0 -154
- opencloning-0.4.8.dist-info/RECORD +0 -45
- {opencloning-0.4.8.dist-info → opencloning-0.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencloning
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5
|
|
4
4
|
Summary: Backend of OpenCloning, a web application to generate molecular cloning strategies in json format, and share them with others.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,14 +17,13 @@ Requires-Dist: beautifulsoup4 (>=4.11.1,<5.0.0)
|
|
|
17
17
|
Requires-Dist: biopython (>=1.85,<2.0)
|
|
18
18
|
Requires-Dist: fastapi
|
|
19
19
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
20
|
-
Requires-Dist: opencloning-linkml (==0.4.4)
|
|
21
20
|
Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
|
|
22
21
|
Requires-Dist: packaging (>=25.0,<26.0)
|
|
23
22
|
Requires-Dist: pairwise-alignments-to-msa (>=0.1.1,<0.2.0)
|
|
24
23
|
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
|
25
|
-
Requires-Dist: primer3-py (
|
|
24
|
+
Requires-Dist: primer3-py (>=2.3,<3.0)
|
|
26
25
|
Requires-Dist: pydantic (>=2.7.1,<3.0.0)
|
|
27
|
-
Requires-Dist: pydna (
|
|
26
|
+
Requires-Dist: pydna (>=5.5.5,<6.0.0)
|
|
28
27
|
Requires-Dist: python-multipart
|
|
29
28
|
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
|
30
29
|
Requires-Dist: regex (>=2024.11.6,<2025.0.0)
|
|
@@ -47,9 +46,9 @@ Read [main project readme](https://github.com/manulera/OpenCloning) first.
|
|
|
47
46
|
|
|
48
47
|
This API provides a series of entry points. The API documentation can be accessed [here](https://api.opencloning.org/docs). You can use the documentation page to try some request directly on the browser. Otherwise, the API is open for you to make requests from a python script or command line at: [https://api.opencloning.org/](https://api.opencloning.org/).
|
|
49
48
|
|
|
50
|
-
## Scripting
|
|
49
|
+
## Scripting with pydna
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
You can write python scripts to automate cloning using the python library [pydna](https://github.com/pydna-group/pydna), which is now integrated with the OpenCloning data model. See [the documentation](https://github.com/pydna-group/pydna/blob/master/docs/notebooks/history.ipynb) for how to get started.
|
|
53
52
|
|
|
54
53
|
## Migrating between model versions and fixing model bugs
|
|
55
54
|
|
|
@@ -117,7 +116,7 @@ docker run -d --name backendcontainer -p 8000:8000 manulera/opencloningbackend
|
|
|
117
116
|
|
|
118
117
|
```
|
|
119
118
|
|
|
120
|
-
If you don't want to download the repository and build the image, you can fetch the latest image from dockerhub
|
|
119
|
+
If you don't want to download the repository and build the image, you can fetch the latest image from dockerhub.
|
|
121
120
|
|
|
122
121
|
```bash
|
|
123
122
|
docker pull manulera/opencloningbackend
|
|
@@ -167,7 +166,7 @@ pytest -v -ks
|
|
|
167
166
|
### Ping a particular library version from github:
|
|
168
167
|
|
|
169
168
|
```
|
|
170
|
-
poetry add git+https://github.com/
|
|
169
|
+
poetry add git+https://github.com/pydna-group/pydna#4fd760d075f77cceeb27969e017e04b42f6d0aa3
|
|
171
170
|
```
|
|
172
171
|
|
|
173
172
|
When installing the last version, sometimes poetry may not be able to access the latest version
|
|
@@ -188,3 +187,14 @@ RECORD_STUBS=1 uvicorn opencloning.main:app --reload --reload-exclude='.venv'
|
|
|
188
187
|
|
|
189
188
|
This will record the stubs (requests and responses) in the `stubs` folder.
|
|
190
189
|
|
|
190
|
+
|
|
191
|
+
### Catalogs
|
|
192
|
+
|
|
193
|
+
Catalogs are used to map ids to urls for several plasmid collections. They are stored in the `src/opencloning/catalogs` folder.
|
|
194
|
+
|
|
195
|
+
To update the catalogs, run the following command:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
poetry run python scripts/update_catalogs.py
|
|
199
|
+
```
|
|
200
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
opencloning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
opencloning/_version.py,sha256=6QbWXLSZypjtWL_CwJFHH4dzMRK3AUH4B0YudzvGz9s,200
|
|
3
|
+
opencloning/api_config_utils.py,sha256=inAXPGYNDz-DuEoSqitImj0Vv5TpQSbMZH9D3dQb5P0,4319
|
|
4
|
+
opencloning/app_settings.py,sha256=O67vY7TxyKsXepOxUNc_O0JO70lf7tEL9cqIMsiTXWE,3220
|
|
5
|
+
opencloning/batch_cloning/__init__.py,sha256=uDxAa45g30_S6dJScNMlIxubQXlLRUsWoLX4S4y-l88,244
|
|
6
|
+
opencloning/batch_cloning/index.html,sha256=HDqPHrJxrrKfGmy_dwYHhOsdUgZHHIch7Z0ey8qyvZI,1332
|
|
7
|
+
opencloning/batch_cloning/pombe/__init__.py,sha256=dVbRBba4ZcmA1x4eEn7I5kndDImQVT6-K-iqIGaDi3c,3343
|
|
8
|
+
opencloning/batch_cloning/pombe/index.html,sha256=3YchoKGpcKDfvTOW1Rdih4PkbZIkMjKIQ0PaVXfV3e8,8348
|
|
9
|
+
opencloning/batch_cloning/pombe/pombe_clone.py,sha256=BwnEGkz9skbIqR-W0Y1iB3wYgWH35hADp0PcUTaXKUk,3985
|
|
10
|
+
opencloning/batch_cloning/pombe/pombe_gather.py,sha256=qI-biMZGLxVDV-vOf3sT6bS1BawtTihZNcSYNlnnEi8,2432
|
|
11
|
+
opencloning/batch_cloning/pombe/pombe_get_primers.py,sha256=nrn6V4_l8FWWfqS4WU3qPt95KwzvCXxETh8E-zWbRhM,3968
|
|
12
|
+
opencloning/batch_cloning/pombe/pombe_summary.py,sha256=GkmKZpR3fIBZd9HzyihZpITAoXgUiKe9W5l0GyLk-aU,4691
|
|
13
|
+
opencloning/batch_cloning/ziqiang_et_al2024/__init__.py,sha256=PPfNUth03WWeiAwlPCPD7_uTJpgWybrUpgTTkXN_jf0,7162
|
|
14
|
+
opencloning/batch_cloning/ziqiang_et_al2024/index.html,sha256=EDncANDhhQkhi5FjnnAP6liHkG5srf4_Y46IrnMUG5g,4607
|
|
15
|
+
opencloning/batch_cloning/ziqiang_et_al2024/ziqiang_et_al2024.json,sha256=uR1emjNhCDk6uYCJC4MJwz9MJ9U5RQZk9j5cKPbqNXE,156906
|
|
16
|
+
opencloning/bug_fixing/README.md,sha256=eak5x1NTyTxsklaZ1BzB3RYH26MC_2gNuH-gHvuNpKY,4441
|
|
17
|
+
opencloning/bug_fixing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
opencloning/bug_fixing/backend_v0_3.py,sha256=_kxYPcUmBFGL1WEwtpl6ySwSSN0WRk9qZwX2Kc4eAUs,4608
|
|
19
|
+
opencloning/catalogs/__init__.py,sha256=hHalYzJimaHWM39RPAMGduSxSWpjHy8UBqO-utOmp88,1103
|
|
20
|
+
opencloning/catalogs/igem2024.yaml,sha256=CWayosovGycGCfDG-EOgPRjOMUYsDCsFy5DoHGJGwc4,49247
|
|
21
|
+
opencloning/catalogs/openDNA_collections.yaml,sha256=JPnPLJd9ynJkqJAumu0f7-E5E0WSDN2pjB7rNa3wJLA,38655
|
|
22
|
+
opencloning/catalogs/readme.txt,sha256=SPBPLfqszGH0zl7EZYddNwi9nE90or82o8aHNMscSkw,87
|
|
23
|
+
opencloning/catalogs/seva.tsv,sha256=FFGZDDgsExYke1S0g_KCzM5YL680_RS-1XNEJbiqFJo,16125
|
|
24
|
+
opencloning/catalogs/snapgene.yaml,sha256=Zi0i4l9KBOhoHnr7i2nYWD58IIYgBbEaNF5m4qzm2ks,47359
|
|
25
|
+
opencloning/dna_functions.py,sha256=vyy2UDyYj3IfVmWf1z07j8T7D53JM-wFQFawcLzZt-k,15967
|
|
26
|
+
opencloning/dna_utils.py,sha256=n_XRBr9xeEQSoMUWdgH7UigZN2KtU7AxmIwW18aFQdY,6814
|
|
27
|
+
opencloning/ebic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
opencloning/ebic/primer_design.py,sha256=e_PkEhnlkeV7D3iCeDL8s1p-FkNWj17zWNaq-x9Uz8E,3149
|
|
29
|
+
opencloning/ebic/primer_design_settings.py,sha256=OnFsuh0QCvplUEPXLZouzRo9R7rm4nLbcd2LkDCiIDM,1896
|
|
30
|
+
opencloning/endpoints/annotation.py,sha256=_jQGvwcP-LvoLJKaRG2_YyMLyOzk1R9lUlYNHFc7afY,2126
|
|
31
|
+
opencloning/endpoints/assembly.py,sha256=e6PFNp0ZmAQ7niI54vAZkuTgjTg1NIf0vCnVfebF184,13373
|
|
32
|
+
opencloning/endpoints/endpoint_utils.py,sha256=KIbYA-XPFArHzVTQ8RfxDR4eI3WypOZPJx64_GmjGHY,2061
|
|
33
|
+
opencloning/endpoints/external_import.py,sha256=IdhI1mBvBF77v6DB4Sfc5-RSzW90MzGjTc-zX7aeaxI,19671
|
|
34
|
+
opencloning/endpoints/no_assembly.py,sha256=dOyfh_nfQOmnJx6Vwhwo7EBIIbMRwGf_Ap_VsjSQc40,4031
|
|
35
|
+
opencloning/endpoints/no_input.py,sha256=1NSiuyS2zWwK3Ae34tFChhqEZ7645w75ibNW9RREYVw,3752
|
|
36
|
+
opencloning/endpoints/other.py,sha256=e_GXJDnqQFREU9GcOruI-8yQJpK-eVtDH1ZiVPL7WQU,4028
|
|
37
|
+
opencloning/endpoints/primer_design.py,sha256=2XSflQXQ1vOqY6vyvalrOU3baC2-fn-oSV5294c5cXI,13017
|
|
38
|
+
opencloning/get_router.py,sha256=l2DXaTbeL2tDqlnVMlcewutzt1sjaHlxku1X9HVUwJk,252
|
|
39
|
+
opencloning/http_client.py,sha256=9f0mqYPwQmWr0B6hMSoYT80g4RT2itKA2iokAknY5yY,1239
|
|
40
|
+
opencloning/main.py,sha256=l9PrPBMtGMEWxAPiPWR15Qv2oDNnRoNd8H8E3bZW6Do,3750
|
|
41
|
+
opencloning/ncbi_requests.py,sha256=jO3UWlGMENE3YPDCfo-pZWO5iJa1C0x7rahIf0cLCRk,8936
|
|
42
|
+
opencloning/primer3_functions.py,sha256=R29jic_tb7qhXnDb4RGCx2xaViVCnxTyaVU89KMUIjQ,3584
|
|
43
|
+
opencloning/primer_design.py,sha256=vHi4cBjxEOimzEABvt0sEcDZeXvZLkpnj7k9K7qu9qw,9249
|
|
44
|
+
opencloning/pydantic_models.py,sha256=cKXRHQyPdQDxkdzEwKgwvmQy0UjFjDVFR-eKIsBSZbE,2964
|
|
45
|
+
opencloning/request_examples.py,sha256=rg-v9a5ttzwu5tKY5h3tiT_kVkIZOicS8c01MxrEcEY,2653
|
|
46
|
+
opencloning/temp_functions.py,sha256=wRh26uW_JT9sy3070jIizTT82CE_hS8-GRW3vXEd1GQ,2029
|
|
47
|
+
opencloning/utils.py,sha256=0Lvw1h1AsUJTK2b9mNzYVi_DBeWmWCFA5dIPl_gERcI,1479
|
|
48
|
+
opencloning-0.5.dist-info/METADATA,sha256=4ZQGH31rO4f_p9WIxTpu7UfKK8H6D1D_YilCscz1XUc,9501
|
|
49
|
+
opencloning-0.5.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
|
|
50
|
+
opencloning-0.5.dist-info/licenses/LICENSE,sha256=VSdVE1f8axjIh6gvo9ZZygJdTVkRFMcwCW_hvjOHC_w,1058
|
|
51
|
+
opencloning-0.5.dist-info/RECORD,,
|
opencloning/cre_lox.py
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
from itertools import product
|
|
2
|
-
from pydna.dseqrecord import Dseqrecord
|
|
3
|
-
from Bio.Data.IUPACData import ambiguous_dna_values
|
|
4
|
-
from Bio.Seq import reverse_complement
|
|
5
|
-
from .dna_utils import compute_regex_site, dseqrecord_finditer
|
|
6
|
-
from Bio.SeqFeature import Location, SimpleLocation, SeqFeature
|
|
7
|
-
from pydna.utils import shift_location
|
|
8
|
-
|
|
9
|
-
# We create a dictionary to map ambiguous bases to their consensus base
|
|
10
|
-
# For example, ambigous_base_dict['ACGT'] -> 'N'
|
|
11
|
-
ambiguous_base_dict = {}
|
|
12
|
-
for ambiguous, bases in ambiguous_dna_values.items():
|
|
13
|
-
ambiguous_base_dict[''.join(sorted(bases))] = ambiguous
|
|
14
|
-
|
|
15
|
-
# To handle N values
|
|
16
|
-
ambiguous_base_dict['N'] = 'N'
|
|
17
|
-
|
|
18
|
-
# This is the original loxP sequence, here for reference
|
|
19
|
-
LOXP_SEQUENCE = 'ATAACTTCGTATAGCATACATTATACGAAGTTAT'
|
|
20
|
-
|
|
21
|
-
loxP_sequences = [
|
|
22
|
-
# https://blog.addgene.org/plasmids-101-cre-lox
|
|
23
|
-
# loxP
|
|
24
|
-
'ATAACTTCGTATANNNTANNNTATACGAAGTTAT',
|
|
25
|
-
# PMID:12202778
|
|
26
|
-
# lox66
|
|
27
|
-
'ATAACTTCGTATANNNTANNNTATACGAACGGTA',
|
|
28
|
-
# lox71
|
|
29
|
-
'TACCGTTCGTATANNNTANNNTATACGAAGTTAT',
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
loxP_consensus = ''
|
|
33
|
-
|
|
34
|
-
for pos in range(len(LOXP_SEQUENCE)):
|
|
35
|
-
all_letters = set(seq[pos] for seq in loxP_sequences)
|
|
36
|
-
key = ''.join(sorted(all_letters))
|
|
37
|
-
loxP_consensus += ambiguous_base_dict[key]
|
|
38
|
-
|
|
39
|
-
# We compute the regex for the forward and reverse loxP sequences
|
|
40
|
-
loxP_regex = (compute_regex_site(loxP_consensus), compute_regex_site(reverse_complement(loxP_consensus)))
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def cre_loxP_overlap(x: Dseqrecord, y: Dseqrecord, _l: None = None) -> list[tuple[int, int, int]]:
|
|
44
|
-
"""Find matching loxP sites between two sequences."""
|
|
45
|
-
out = list()
|
|
46
|
-
for pattern in loxP_regex:
|
|
47
|
-
matches_x = dseqrecord_finditer(pattern, x)
|
|
48
|
-
matches_y = dseqrecord_finditer(pattern, y)
|
|
49
|
-
|
|
50
|
-
for match_x, match_y in product(matches_x, matches_y):
|
|
51
|
-
value_x = match_x.group()
|
|
52
|
-
value_y = match_y.group()
|
|
53
|
-
if value_x[13:21] == value_y[13:21]:
|
|
54
|
-
out.append((match_x.start() + 13, match_y.start() + 13, 8))
|
|
55
|
-
# Unique values (keeping the order)
|
|
56
|
-
unique_out = []
|
|
57
|
-
for item in out:
|
|
58
|
-
if item not in unique_out:
|
|
59
|
-
unique_out.append(item)
|
|
60
|
-
return unique_out
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
loxP_dict = {
|
|
64
|
-
'loxP': 'ATAACTTCGTATANNNTANNNTATACGAAGTTAT',
|
|
65
|
-
'lox66': 'ATAACTTCGTATANNNTANNNTATACGAACGGTA',
|
|
66
|
-
'lox71': 'TACCGTTCGTATANNNTANNNTATACGAAGTTAT',
|
|
67
|
-
'loxP_mutant': 'TACCGTTCGTATANNNTANNNTATACGAACGGTA',
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def get_regex_dict(original_dict: dict[str, str]) -> dict[str, str]:
|
|
72
|
-
"""Get the regex dictionary for the original dictionary."""
|
|
73
|
-
out = dict()
|
|
74
|
-
for site in original_dict:
|
|
75
|
-
consensus_seq = original_dict[site]
|
|
76
|
-
is_palindromic = consensus_seq == reverse_complement(consensus_seq)
|
|
77
|
-
out[site] = {
|
|
78
|
-
'forward_regex': compute_regex_site(original_dict[site]),
|
|
79
|
-
'reverse_regex': None if is_palindromic else compute_regex_site(reverse_complement(original_dict[site])),
|
|
80
|
-
}
|
|
81
|
-
return out
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def find_loxP_sites(seq: Dseqrecord) -> dict[str, list[Location]]:
|
|
85
|
-
"""Find all gateway sites in a sequence and return a dictionary with the name and positions of the sites."""
|
|
86
|
-
|
|
87
|
-
out = dict()
|
|
88
|
-
regex_dict = get_regex_dict(loxP_dict)
|
|
89
|
-
for site in loxP_dict:
|
|
90
|
-
|
|
91
|
-
for pattern in ['forward_regex', 'reverse_regex']:
|
|
92
|
-
# Palindromic sequences have no reverse complement
|
|
93
|
-
if regex_dict[site][pattern] is None:
|
|
94
|
-
continue
|
|
95
|
-
matches = list(dseqrecord_finditer(regex_dict[site][pattern], seq))
|
|
96
|
-
for match in matches:
|
|
97
|
-
if site not in out:
|
|
98
|
-
out[site] = []
|
|
99
|
-
strand = 1 if pattern == 'forward_regex' else -1
|
|
100
|
-
loc = SimpleLocation(match.start(), match.end(), strand)
|
|
101
|
-
loc = shift_location(loc, 0, len(seq))
|
|
102
|
-
out[site].append(loc)
|
|
103
|
-
return out
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def annotate_loxP_sites(seq: Dseqrecord) -> Dseqrecord:
|
|
107
|
-
sites = find_loxP_sites(seq)
|
|
108
|
-
for site in sites:
|
|
109
|
-
for loc in sites[site]:
|
|
110
|
-
# Don't add the same feature twice
|
|
111
|
-
if not any(
|
|
112
|
-
f.location == loc and f.type == 'protein_bind' and f.qualifiers.get('label', []) == [site]
|
|
113
|
-
for f in seq.features
|
|
114
|
-
):
|
|
115
|
-
seq.features.append(SeqFeature(loc, type='protein_bind', qualifiers={'label': [site]}))
|
|
116
|
-
return seq
|
opencloning/gateway.py
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
from Bio.Seq import reverse_complement
|
|
2
|
-
from pydna.dseqrecord import Dseqrecord as _Dseqrecord
|
|
3
|
-
import re
|
|
4
|
-
import itertools as _itertools
|
|
5
|
-
from Bio.SeqFeature import SimpleLocation, SeqFeature
|
|
6
|
-
from pydna.utils import shift_location
|
|
7
|
-
from .dna_utils import compute_regex_site, dseqrecord_finditer
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
raw_gateway_common = {
|
|
11
|
-
'attB1': 'CHWVTWTGTACAAAAAANNNG',
|
|
12
|
-
'attB2': 'CHWVTWTGTACAAGAAANNNG',
|
|
13
|
-
'attB3': 'CHWVTWTGTATAATAAANNNG',
|
|
14
|
-
'attB4': 'CHWVTWTGTATAGAAAANNNG',
|
|
15
|
-
'attB5': 'CHWVTWTGTATACAAAANNNG',
|
|
16
|
-
'attL1': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTACAAAAAANNNG',
|
|
17
|
-
'attL2': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTACAAGAAANNNG',
|
|
18
|
-
'attL3': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTATAATAAANNNG',
|
|
19
|
-
'attL4': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTATAGAAAANNNG',
|
|
20
|
-
'attL5': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTATACAAAANNNG',
|
|
21
|
-
'attR1': 'CHWVTWTGTACAAAAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
22
|
-
'attR2': 'CHWVTWTGTACAAGAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
23
|
-
'attR3': 'CHWVTWTGTATAATAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
24
|
-
'attR4': 'CHWVTWTGTATAGAAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
25
|
-
'attR5': 'CHWVTWTGTATACAAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
26
|
-
'overlap_1': 'twtGTACAAAaaa',
|
|
27
|
-
'overlap_2': 'twtGTACAAGaaa',
|
|
28
|
-
'overlap_3': 'twtGTATAATaaa',
|
|
29
|
-
'overlap_4': 'twtGTATAGAaaa',
|
|
30
|
-
'overlap_5': 'twtGTATACAaaa',
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
raw_gateway_sites_greedy = {
|
|
35
|
-
**raw_gateway_common,
|
|
36
|
-
'attP1': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTACAAAAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
37
|
-
'attP2': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTACAAGAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
38
|
-
'attP3': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTATAATAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
39
|
-
'attP4': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTATAGAAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
40
|
-
'attP5': 'VAAWWAWKRWTTTWWTTYGACTGATAGTGACCTGTWCGTYGMAACAVATTGATRAGCAATKMTTTYYTATAWTGHCMASTWTGTATACAAAAGYWGARCGAGAARCGTAARRTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATRCTGTAARACACAACATATBCAGTCV',
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
raw_gateway_sites_conservative = {
|
|
44
|
-
**raw_gateway_common,
|
|
45
|
-
'attP1': 'AAAWWAWKRWTTTWWTTTGACTGATAGTGACCTGTTCGTTGCAACAMATTGATRAGCAATGCTTTYTTATAATGCCMASTTTGTACAAAAAAGYWGAACGAGAARCGTAAARTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATACTGTAAAACACAACATATSCAGTCACTATGAAYCAACTACTTAGATGGTATTAGTGACCTGTA',
|
|
46
|
-
'attP2': 'AAAWWAWKRWTTTWWTTTGACTGATAGTGACCTGTTCGTTGCAACAMATTGATRAGCAATGCTTTYTTATAATGCCMASTTTGTACAAGAAAGYWGAACGAGAARCGTAAARTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATACTGTAAAACACAACATATSCAGTCACTATGAAYCAACTACTTAGATGGTATTAGTGACCTGTA',
|
|
47
|
-
'attP3': 'AAAWWAWKRWTTTWWTTTGACTGATAGTGACCTGTTCGTTGCAACAMATTGATRAGCAATGCTTTYTTATAATGCCMASTTTGTATAATAAAGYWGAACGAGAARCGTAAARTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATACTGTAAAACACAACATATSCAGTCACTATGAAYCAACTACTTAGATGGTATTAGTGACCTGTA',
|
|
48
|
-
'attP4': 'AAAWWAWKRWTTTWWTTTGACTGATAGTGACCTGTTCGTTGCAACAMATTGATRAGCAATGCTTTYTTATAATGCCMASTTTGTATAGAAAAGYWGAACGAGAARCGTAAARTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATACTGTAAAACACAACATATSCAGTCACTATGAAYCAACTACTTAGATGGTATTAGTGACCTGTA',
|
|
49
|
-
'attP5': 'AAAWWAWKRWTTTWWTTTGACTGATAGTGACCTGTTCGTTGCAACAMATTGATRAGCAATGCTTTYTTATAATGCCMASTTTGTATACAAAAGYWGAACGAGAARCGTAAARTGATATAAATATCAATATATTAAATTAGAYTTTGCATAAAAAACAGACTACATAATACTGTAAAACACAACATATSCAGTCACTATGAAYCAACTACTTAGATGGTATTAGTGACCTGTA',
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
gateway_sites_greedy = {
|
|
53
|
-
k: {
|
|
54
|
-
'forward_regex': compute_regex_site(v),
|
|
55
|
-
'reverse_regex': compute_regex_site(reverse_complement(v)),
|
|
56
|
-
'consensus_sequence': v,
|
|
57
|
-
}
|
|
58
|
-
for k, v in raw_gateway_sites_greedy.items()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
gateway_sites_conservative = {
|
|
62
|
-
k: {
|
|
63
|
-
'forward_regex': compute_regex_site(v),
|
|
64
|
-
'reverse_regex': compute_regex_site(reverse_complement(v)),
|
|
65
|
-
'consensus_sequence': v,
|
|
66
|
-
}
|
|
67
|
-
for k, v in raw_gateway_sites_conservative.items()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
# From snapgene - ask Valerie
|
|
71
|
-
primer_design_attB = {
|
|
72
|
-
'attB1': 'ACAAGTTTGTACAAAAAAGCAGGCT',
|
|
73
|
-
'attB2': 'ACCACTTTGTACAAGAAAGCTGGGT',
|
|
74
|
-
'attB3': 'ACAACTTTGTATAATAAAGTTGTA',
|
|
75
|
-
'attB4': 'ACAACTTTGTATAGAAAAGTTGTA',
|
|
76
|
-
'attB5': 'ACAACTTTGTATACAAAAGTTGTA',
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def gateway_overlap(seqx: _Dseqrecord, seqy: _Dseqrecord, reaction: str, greedy: bool) -> list[tuple[int, int, int]]:
|
|
81
|
-
"""Find gateway overlaps"""
|
|
82
|
-
if reaction not in ['BP', 'LR']:
|
|
83
|
-
raise ValueError(f'Invalid overlap type: {reaction}')
|
|
84
|
-
|
|
85
|
-
gateway_sites = gateway_sites_greedy if greedy else gateway_sites_conservative
|
|
86
|
-
out = list()
|
|
87
|
-
# Iterate over the four possible att sites
|
|
88
|
-
for num in range(1, 5):
|
|
89
|
-
# Iterate over the two possible orientations
|
|
90
|
-
# The sites have to be in the same orientation (fwd + fwd or rev + rev)
|
|
91
|
-
for pattern in ['forward_regex', 'reverse_regex']:
|
|
92
|
-
# The overlap regex is the same for all types
|
|
93
|
-
overlap_regex = gateway_sites[f'overlap_{num}'][pattern]
|
|
94
|
-
|
|
95
|
-
# Iterate over pairs B, P and P, B for BP and L, R and R, L for LR
|
|
96
|
-
for site_x, site_y in zip(reaction, reaction[::-1]):
|
|
97
|
-
site_x_regex = gateway_sites[f'att{site_x}{num}'][pattern]
|
|
98
|
-
matches_x = list(dseqrecord_finditer(site_x_regex, seqx))
|
|
99
|
-
if len(matches_x) == 0:
|
|
100
|
-
continue
|
|
101
|
-
|
|
102
|
-
site_y_regex = gateway_sites[f'att{site_y}{num}'][pattern]
|
|
103
|
-
matches_y = list(dseqrecord_finditer(site_y_regex, seqy))
|
|
104
|
-
if len(matches_y) == 0:
|
|
105
|
-
continue
|
|
106
|
-
|
|
107
|
-
for match_x, match_y in _itertools.product(matches_x, matches_y):
|
|
108
|
-
# Find the overlap sequence within each match, and use the
|
|
109
|
-
# core 7 pbs that are constant
|
|
110
|
-
overlap_x = re.search(overlap_regex, match_x.group())
|
|
111
|
-
overlap_y = re.search(overlap_regex, match_y.group())
|
|
112
|
-
|
|
113
|
-
# Sanity check
|
|
114
|
-
assert (
|
|
115
|
-
overlap_x is not None and overlap_y is not None
|
|
116
|
-
), 'Something went wrong, no overlap found within the matches'
|
|
117
|
-
|
|
118
|
-
out.append(
|
|
119
|
-
(
|
|
120
|
-
match_x.start() + overlap_x.start() + 3,
|
|
121
|
-
match_y.start() + overlap_y.start() + 3,
|
|
122
|
-
7,
|
|
123
|
-
)
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
return out
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def find_gateway_sites(seq: _Dseqrecord, greedy: bool) -> dict[str, list[SimpleLocation]]:
|
|
130
|
-
"""Find all gateway sites in a sequence and return a dictionary with the name and positions of the sites."""
|
|
131
|
-
gateway_sites = gateway_sites_greedy if greedy else gateway_sites_conservative
|
|
132
|
-
out = dict()
|
|
133
|
-
for site in gateway_sites:
|
|
134
|
-
if not site.startswith('att'):
|
|
135
|
-
continue
|
|
136
|
-
|
|
137
|
-
for pattern in ['forward_regex', 'reverse_regex']:
|
|
138
|
-
matches = list(dseqrecord_finditer(gateway_sites[site][pattern], seq))
|
|
139
|
-
for match in matches:
|
|
140
|
-
if site not in out:
|
|
141
|
-
out[site] = []
|
|
142
|
-
strand = 1 if pattern == 'forward_regex' else -1
|
|
143
|
-
loc = SimpleLocation(match.start(), match.end(), strand)
|
|
144
|
-
loc = shift_location(loc, 0, len(seq))
|
|
145
|
-
out[site].append(loc)
|
|
146
|
-
return out
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def annotate_gateway_sites(seq: _Dseqrecord, greedy: bool) -> _Dseqrecord:
|
|
150
|
-
sites = find_gateway_sites(seq, greedy)
|
|
151
|
-
for site in sites:
|
|
152
|
-
for loc in sites[site]:
|
|
153
|
-
seq.features.append(SeqFeature(loc, type='protein_bind', qualifiers={'label': [site]}))
|
|
154
|
-
return seq
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
opencloning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
opencloning/_version.py,sha256=6QbWXLSZypjtWL_CwJFHH4dzMRK3AUH4B0YudzvGz9s,200
|
|
3
|
-
opencloning/api_config_utils.py,sha256=inAXPGYNDz-DuEoSqitImj0Vv5TpQSbMZH9D3dQb5P0,4319
|
|
4
|
-
opencloning/app_settings.py,sha256=6gtIgDIVA9FzfBCnv8IJrEkroTjg4qdAGI4lNdxoA9E,2970
|
|
5
|
-
opencloning/batch_cloning/__init__.py,sha256=uDxAa45g30_S6dJScNMlIxubQXlLRUsWoLX4S4y-l88,244
|
|
6
|
-
opencloning/batch_cloning/index.html,sha256=HDqPHrJxrrKfGmy_dwYHhOsdUgZHHIch7Z0ey8qyvZI,1332
|
|
7
|
-
opencloning/batch_cloning/pombe/__init__.py,sha256=Fq7SroO0Fer5CtFBRWdduIvzp1_dTUZwBb8IjBtRQO0,3332
|
|
8
|
-
opencloning/batch_cloning/pombe/index.html,sha256=3YchoKGpcKDfvTOW1Rdih4PkbZIkMjKIQ0PaVXfV3e8,8348
|
|
9
|
-
opencloning/batch_cloning/pombe/pombe_clone.py,sha256=JlaTKcPBH8pR94FVgTPCopGRBCjS2VKvkkxZLjJdyb4,8056
|
|
10
|
-
opencloning/batch_cloning/pombe/pombe_gather.py,sha256=qI-biMZGLxVDV-vOf3sT6bS1BawtTihZNcSYNlnnEi8,2432
|
|
11
|
-
opencloning/batch_cloning/pombe/pombe_get_primers.py,sha256=nrn6V4_l8FWWfqS4WU3qPt95KwzvCXxETh8E-zWbRhM,3968
|
|
12
|
-
opencloning/batch_cloning/pombe/pombe_summary.py,sha256=DBpoSEV1xPFm8TFDhrxS4tjqxJVrfH-ttM_0ELjQqok,4350
|
|
13
|
-
opencloning/batch_cloning/ziqiang_et_al2024/__init__.py,sha256=9-aG8JfZx8Y91qUAchTqRL2Rq5lSrZ34O_VkD8WNyiY,7083
|
|
14
|
-
opencloning/batch_cloning/ziqiang_et_al2024/index.html,sha256=EDncANDhhQkhi5FjnnAP6liHkG5srf4_Y46IrnMUG5g,4607
|
|
15
|
-
opencloning/batch_cloning/ziqiang_et_al2024/ziqiang_et_al2024.json,sha256=JAOe35VPeG3QF1CnDzZxOzqpBTSpeCCtAo2W1mVOFEo,157159
|
|
16
|
-
opencloning/bug_fixing/README.md,sha256=eak5x1NTyTxsklaZ1BzB3RYH26MC_2gNuH-gHvuNpKY,4441
|
|
17
|
-
opencloning/bug_fixing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
opencloning/bug_fixing/backend_v0_3.py,sha256=GfuDRvlmcSBv9emXZSWqW-SktOeI1xH-tl2UET-BSoY,4145
|
|
19
|
-
opencloning/cre_lox.py,sha256=x_OVYzfaLJH5eVyp05_I9YNycT606UL683AswhQ-gjU,4294
|
|
20
|
-
opencloning/dna_functions.py,sha256=O5H5DilNUOIzH8gVFiOuG8SVlrenrbwyo9lKwfxIHnY,16663
|
|
21
|
-
opencloning/dna_utils.py,sha256=NSS_b5q8u8XNzVqCwzCQaxj4I2xHf_Inmw7iBWS9gc8,6746
|
|
22
|
-
opencloning/ebic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
opencloning/ebic/primer_design.py,sha256=DpRD5YjA_5oFi-NLSYGGS7IDT_GkN2hYzEKiiBfyEjo,3128
|
|
24
|
-
opencloning/ebic/primer_design_settings.py,sha256=OnFsuh0QCvplUEPXLZouzRo9R7rm4nLbcd2LkDCiIDM,1896
|
|
25
|
-
opencloning/endpoints/annotation.py,sha256=3rlIXeNQzoqPD9lJUEBGLGxvlhUCTcfkqno814A8P0U,2283
|
|
26
|
-
opencloning/endpoints/assembly.py,sha256=xkvChfwspdh2lnCi9tQFfTQuEhJfNXNjDb4wRKymZV8,21727
|
|
27
|
-
opencloning/endpoints/external_import.py,sha256=Fdjj6zu0bdZg8vRi1f5bMejnKNBlt3So-BxaeD1CLxk,19115
|
|
28
|
-
opencloning/endpoints/no_assembly.py,sha256=F6mRZFGUAASZ0v7EhPyBgmn_O-YLySMR1a_0aUH2U70,4806
|
|
29
|
-
opencloning/endpoints/no_input.py,sha256=0wc5sTD6nL0SrsXmT__x0g-m6m45ID5hq-D8KDKy98Y,4170
|
|
30
|
-
opencloning/endpoints/other.py,sha256=KvsrfaZXmZcfh3R7mCovuoe62O66EXKEb0pZaEAAYr8,3992
|
|
31
|
-
opencloning/endpoints/primer_design.py,sha256=Ni3B6JTWEFBDU4bHYtygFwXR09vPjhVzboGeP70TSls,12957
|
|
32
|
-
opencloning/gateway.py,sha256=pFB3gsCQL715kOFOP1NQOOsQqrkWuQe5qXk4IunF5SA,8486
|
|
33
|
-
opencloning/get_router.py,sha256=l2DXaTbeL2tDqlnVMlcewutzt1sjaHlxku1X9HVUwJk,252
|
|
34
|
-
opencloning/http_client.py,sha256=m8LPCxT4b63XPOWGAMmecaNZ7Ho1uxzJm8z7bbhOMqY,1261
|
|
35
|
-
opencloning/main.py,sha256=l9PrPBMtGMEWxAPiPWR15Qv2oDNnRoNd8H8E3bZW6Do,3750
|
|
36
|
-
opencloning/ncbi_requests.py,sha256=e-sBVaaWJmJpqZ3TDtZEx9C9jiZSJy69UdLcdsHzXjc,5932
|
|
37
|
-
opencloning/primer3_functions.py,sha256=R29jic_tb7qhXnDb4RGCx2xaViVCnxTyaVU89KMUIjQ,3584
|
|
38
|
-
opencloning/primer_design.py,sha256=9h69bwYem8HEqhp30vEnTP5TrfCISVFTwPQdgUAkS1E,9227
|
|
39
|
-
opencloning/pydantic_models.py,sha256=SZDFrITTELkel3jOu9YlPC27RsJHzaAXTEYOMEZvvqs,20048
|
|
40
|
-
opencloning/request_examples.py,sha256=_VvY4lNpgqhLTM6O_OUs1TujhL7RUbRFZ9ptyssbxLk,2934
|
|
41
|
-
opencloning/utils.py,sha256=0Lvw1h1AsUJTK2b9mNzYVi_DBeWmWCFA5dIPl_gERcI,1479
|
|
42
|
-
opencloning-0.4.8.dist-info/METADATA,sha256=YXuwg3KnCyYe4aGPi2b0xTCGU4tqu5-TMs7FBbFsWso,9211
|
|
43
|
-
opencloning-0.4.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
44
|
-
opencloning-0.4.8.dist-info/licenses/LICENSE,sha256=VSdVE1f8axjIh6gvo9ZZygJdTVkRFMcwCW_hvjOHC_w,1058
|
|
45
|
-
opencloning-0.4.8.dist-info/RECORD,,
|
|
File without changes
|