opencloning 0.3.7__tar.gz → 0.3.8__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.
Files changed (51) hide show
  1. {opencloning-0.3.7 → opencloning-0.3.8}/PKG-INFO +4 -4
  2. {opencloning-0.3.7 → opencloning-0.3.8}/README.md +2 -2
  3. {opencloning-0.3.7 → opencloning-0.3.8}/pyproject.toml +2 -2
  4. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/app_settings.py +22 -0
  5. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/external_import.py +5 -0
  6. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/http_client.py +8 -20
  7. {opencloning-0.3.7 → opencloning-0.3.8}/LICENSE +0 -0
  8. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/__init__.py +0 -0
  9. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/_version.py +0 -0
  10. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/api_config_utils.py +0 -0
  11. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/assembly2.py +0 -0
  12. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/EBIC/__init__.py +0 -0
  13. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/EBIC/barcode.gb +0 -0
  14. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/EBIC/common_plasmid.gb +0 -0
  15. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/EBIC/example.py +0 -0
  16. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/EBIC/primer_design_settings.py +0 -0
  17. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/__init__.py +0 -0
  18. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/index.html +0 -0
  19. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/__init__.py +0 -0
  20. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/index.html +0 -0
  21. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/pombe_all.sh +0 -0
  22. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/pombe_clone.py +0 -0
  23. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/pombe_gather.py +0 -0
  24. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/pombe_get_primers.py +0 -0
  25. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/pombe/pombe_summary.py +0 -0
  26. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/ziqiang_et_al2024/__init__.py +0 -0
  27. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/ziqiang_et_al2024/index.html +0 -0
  28. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/batch_cloning/ziqiang_et_al2024/ziqiang_et_al2024.json +0 -0
  29. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/bug_fixing/README.md +0 -0
  30. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/bug_fixing/__init__.py +0 -0
  31. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/bug_fixing/backend_v0_3.py +0 -0
  32. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/cre_lox.py +0 -0
  33. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/dna_functions.py +0 -0
  34. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/dna_utils.py +0 -0
  35. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/ebic/__init__.py +0 -0
  36. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/ebic/primer_design.py +0 -0
  37. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/ebic/primer_design_settings.py +0 -0
  38. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/annotation.py +0 -0
  39. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/assembly.py +0 -0
  40. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/no_assembly.py +0 -0
  41. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/no_input.py +0 -0
  42. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/other.py +0 -0
  43. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/endpoints/primer_design.py +0 -0
  44. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/gateway.py +0 -0
  45. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/get_router.py +0 -0
  46. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/main.py +0 -0
  47. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/ncbi_requests.py +0 -0
  48. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/primer_design.py +0 -0
  49. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/pydantic_models.py +0 -0
  50. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/request_examples.py +0 -0
  51. {opencloning-0.3.7 → opencloning-0.3.8}/src/opencloning/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: opencloning
3
- Version: 0.3.7
3
+ Version: 0.3.8
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
  Author: Manuel Lera-Ramirez
@@ -19,7 +19,7 @@ Requires-Dist: opencloning-linkml (==0.3.0a0)
19
19
  Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
20
20
  Requires-Dist: packaging (>=25.0,<26.0)
21
21
  Requires-Dist: pandas (>=2.2.3,<3.0.0)
22
- Requires-Dist: primer3-py (==2.0.3)
22
+ Requires-Dist: primer3-py (==2.2.0)
23
23
  Requires-Dist: pydantic (>=2.7.1,<3.0.0)
24
24
  Requires-Dist: pydna (==5.5.0)
25
25
  Requires-Dist: python-multipart
@@ -86,8 +86,8 @@ poetry install
86
86
  # Install the pre-commit hooks
87
87
  pre-commit install
88
88
 
89
- # Activate the virtual environment
90
- poetry shell
89
+ # Activate the virtual environment (used to be `poetry shell`)
90
+ poetry env activate
91
91
 
92
92
  ```
93
93
 
@@ -55,8 +55,8 @@ poetry install
55
55
  # Install the pre-commit hooks
56
56
  pre-commit install
57
57
 
58
- # Activate the virtual environment
59
- poetry shell
58
+ # Activate the virtual environment (used to be `poetry shell`)
59
+ poetry env activate
60
60
 
61
61
  ```
62
62
 
@@ -8,7 +8,7 @@ authors = ["Manuel Lera-Ramirez <manulera14@gmail.com>"]
8
8
  description = "Backend of OpenCloning, a web application to generate molecular cloning strategies in json format, and share them with others."
9
9
  license = "MIT"
10
10
  name = "opencloning"
11
- version = "0.3.7"
11
+ version = "0.3.8"
12
12
  package-mode = true
13
13
  readme = "README.md"
14
14
  repository = "https://github.com/manulera/OpenCloning_backend"
@@ -27,7 +27,7 @@ pandas = "^2.2.3"
27
27
  openpyxl = "^3.1.5"
28
28
  pyyaml = "^6.0.2"
29
29
  opencloning-linkml = "0.3.0a0"
30
- primer3-py = "2.0.3"
30
+ primer3-py = "2.2.0"
31
31
  biopython = "1.84"
32
32
  packaging = "^25.0"
33
33
 
@@ -31,6 +31,25 @@ if PLANNOTATE_URL is not None and not PLANNOTATE_URL.endswith('/'):
31
31
  PROXY_URL = os.environ.get('PROXY_URL')
32
32
  PROXY_CERT_FILE = os.environ.get('PROXY_CERT_FILE')
33
33
 
34
+ # Allowed external URLs ===========================================
35
+ default_allowed_urls = [
36
+ 'https://www.addgene.org/',
37
+ 'https://media.addgene.org/',
38
+ 'https://seva-plasmids.com/',
39
+ 'https://api.ncbi.nlm.nih.gov/datasets/v2alpha/',
40
+ 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/',
41
+ 'https://www.snapgene.com/local/fetch.php',
42
+ 'https://benchling.com/',
43
+ 'https://assets.opencloning.org/annotated-igem-distribution',
44
+ 'http://www.euroscarf.de/',
45
+ 'https://wekwikgene.wllsb.edu.cn',
46
+ ]
47
+
48
+ if os.environ.get('ALLOWED_EXTERNAL_URLS') is not None:
49
+ ALLOWED_EXTERNAL_URLS = os.environ['ALLOWED_EXTERNAL_URLS'].split(',')
50
+ else:
51
+ ALLOWED_EXTERNAL_URLS = default_allowed_urls
52
+
34
53
 
35
54
  class Settings(BaseModel):
36
55
  SERVE_FRONTEND: bool
@@ -43,6 +62,8 @@ class Settings(BaseModel):
43
62
  PROXY_URL: str | None
44
63
  # Must be a full path to the proxy certificate file
45
64
  PROXY_CERT_FILE: str | None
65
+ # Allowed external URLs
66
+ ALLOWED_EXTERNAL_URLS: list[str]
46
67
 
47
68
 
48
69
  settings = Settings(
@@ -55,4 +76,5 @@ settings = Settings(
55
76
  PLANNOTATE_TIMEOUT=PLANNOTATE_TIMEOUT,
56
77
  PROXY_URL=PROXY_URL,
57
78
  PROXY_CERT_FILE=PROXY_CERT_FILE,
79
+ ALLOWED_EXTERNAL_URLS=ALLOWED_EXTERNAL_URLS,
58
80
  )
@@ -216,6 +216,11 @@ def repository_id_http_error_handler(exception: HTTPError, source: RepositoryIdS
216
216
  404,
217
217
  f'{source.repository_name} returned: {exception} - Likely you inserted a wrong {source.repository_name} id',
218
218
  )
219
+ elif exception.code == 403:
220
+ raise HTTPException(
221
+ 403,
222
+ f'Request to {source.repository_name} is not allowed. Please check that the URL is whitelisted.',
223
+ )
219
224
 
220
225
 
221
226
  # Redirect to the right repository
@@ -6,36 +6,24 @@ from httpx import ( # noqa: F401
6
6
  TimeoutException,
7
7
  AsyncHTTPTransport,
8
8
  Request,
9
- RequestError,
10
9
  )
10
+ from urllib.error import HTTPError
11
11
  import ssl
12
12
  import certifi
13
13
  from .app_settings import settings
14
- import re
15
-
16
- white_listed_urls = {
17
- r'^https://www.addgene.org/',
18
- r'^https://media.addgene.org/',
19
- r'^https://wekwikgene.wllsb.edu.cn',
20
- r'^https://seva-plasmids.com/',
21
- r'^https://api.ncbi.nlm.nih.gov/datasets/v2alpha/',
22
- r'^https://eutils.ncbi.nlm.nih.gov/entrez/eutils/',
23
- r'^https://www.snapgene.com/local/fetch.php',
24
- r'^https://benchling.com/',
25
- r'^https://assets.opencloning.org/annotated-igem-distribution',
26
- r'^http://www.euroscarf.de/',
27
- }
14
+
15
+ allowed_external_urls = settings.ALLOWED_EXTERNAL_URLS
28
16
 
29
17
  if settings.PLANNOTATE_URL:
30
- white_listed_urls.add(settings.PLANNOTATE_URL)
18
+ allowed_external_urls.append(settings.PLANNOTATE_URL)
31
19
 
32
20
 
33
- class WhiteListTransport(AsyncHTTPTransport):
21
+ class AllowedExternalUrlsTransport(AsyncHTTPTransport):
34
22
  async def handle_async_request(self, request: Request) -> Response:
35
- if any(re.match(url, str(request.url)) for url in white_listed_urls):
23
+ if any(str(request.url).startswith(url) for url in allowed_external_urls):
36
24
  return await super().handle_async_request(request)
37
25
 
38
- raise RequestError(f'Request to {request.url} is not whitelisted')
26
+ raise HTTPError(request.url, 403, f'Request to {request.url} is not allowed', None, None)
39
27
 
40
28
 
41
29
  proxy = None
@@ -44,7 +32,7 @@ if settings.PROXY_URL:
44
32
 
45
33
 
46
34
  def get_http_client():
47
- transport = WhiteListTransport()
35
+ transport = AllowedExternalUrlsTransport()
48
36
  client_ctx = None
49
37
  if proxy is not None:
50
38
  client_ctx = ssl.create_default_context(cafile=certifi.where())
File without changes