Skip to content

Commit 0750c1f

Browse files
committed
Refactor URL mapping and helper functions for improved service configuration and routing
1 parent 469881d commit 0750c1f

File tree

3 files changed

+135
-55
lines changed

3 files changed

+135
-55
lines changed

microSALT/utils/pubmlst/client.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55

66
from microSALT import logger
77
from microSALT.utils.pubmlst.authentication import ClientAuthentication
8-
from microSALT.utils.pubmlst.constants import HTTPMethod, RequestType, ResponseHandler, url_map
8+
from microSALT.utils.pubmlst.constants import HTTPMethod, RequestType, ResponseHandler
99
from microSALT.utils.pubmlst.exceptions import (
1010
InvalidURLError,
1111
PUBMLSTError,
1212
SessionTokenRequestError,
1313
)
14-
from microSALT.utils.pubmlst.helpers import load_auth_credentials, get_service_config
14+
from microSALT.utils.pubmlst.helpers import (
15+
load_auth_credentials,
16+
get_service_config,
17+
get_url_map,
18+
get_service_by_url,
19+
)
1520

1621

1722
class BaseClient:
@@ -44,6 +49,8 @@ def parse_url(self, url: str):
4449
:param url: The URL to parse.
4550
:return: A dictionary containing the extracted parameters.
4651
"""
52+
service: str = get_service_by_url(url)
53+
url_map = get_url_map(service)
4754
adapter = url_map.bind("")
4855
parsed_url = url.split(self.base_api_host)[-1]
4956
try:
Lines changed: 92 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
from enum import Enum
22
from werkzeug.routing import Map, Rule
3+
from microSALT.utils.pubmlst.helpers import add_prefix_to_rules
34

45
CREDENTIALS_KEY: str = "credentials"
56

7+
68
class RequestType(Enum):
79
AUTH = "auth"
810
DB = "db"
911

12+
1013
class CredentialsFile(Enum):
1114
MAIN = "main"
1215
SESSION = "session"
1316

17+
1418
class Encoding(Enum):
1519
UTF8 = "utf-8"
1620

21+
1722
class HTTPMethod(Enum):
1823
GET = "GET"
1924
POST = "POST"
@@ -23,59 +28,95 @@ class HTTPMethod(Enum):
2328
HEAD = "HEAD"
2429
OPTIONS = "OPTIONS"
2530

31+
2632
class ResponseHandler(Enum):
2733
CONTENT = "content"
2834
TEXT = "text"
2935
JSON = "json"
3036

31-
url_map = Map([
32-
Rule('/', endpoint='root'),
33-
Rule('/db', endpoint='db_root'),
34-
Rule('/db/<db>', endpoint='database_root'),
35-
Rule('/db/<db>/classification_schemes', endpoint='classification_schemes'),
36-
Rule('/db/<db>/classification_schemes/<int:classification_scheme_id>', endpoint='classification_scheme'),
37-
Rule('/db/<db>/classification_schemes/<int:classification_scheme_id>/groups', endpoint='classification_scheme_groups'),
38-
Rule('/db/<db>/classification_schemes/<int:classification_scheme_id>/groups/<int:group_id>', endpoint='classification_scheme_group'),
39-
Rule('/db/<db>/loci', endpoint='loci'),
40-
Rule('/db/<db>/loci/<locus>', endpoint='locus'),
41-
Rule('/db/<db>/loci/<locus>/alleles', endpoint='locus_alleles'),
42-
Rule('/db/<db>/loci/<locus>/alleles_fasta', endpoint='locus_alleles_fasta'),
43-
Rule('/db/<db>/loci/<locus>/alleles/<int:allele_id>', endpoint='locus_allele'),
44-
Rule('/db/<db>/loci/<locus>/sequence', endpoint='locus_sequence_post'),
45-
Rule('/db/<db>/sequence', endpoint='sequence_post'),
46-
Rule('/db/<db>/sequences', endpoint='sequences'),
47-
Rule('/db/<db>/schemes', endpoint='schemes'),
48-
Rule('/db/<db>/schemes/<int:scheme_id>', endpoint='scheme'),
49-
Rule('/db/<db>/schemes/<int:scheme_id>/loci', endpoint='scheme_loci'),
50-
Rule('/db/<db>/schemes/<int:scheme_id>/fields/<field>', endpoint='scheme_field'),
51-
Rule('/db/<db>/schemes/<int:scheme_id>/profiles', endpoint='scheme_profiles'),
52-
Rule('/db/<db>/schemes/<int:scheme_id>/profiles_csv', endpoint='scheme_profiles_csv'),
53-
Rule('/db/<db>/schemes/<int:scheme_id>/profiles/<int:profile_id>', endpoint='scheme_profile'),
54-
Rule('/db/<db>/schemes/<int:scheme_id>/sequence', endpoint='scheme_sequence_post'),
55-
Rule('/db/<db>/schemes/<int:scheme_id>/designations', endpoint='scheme_designations_post'),
56-
Rule('/db/<db>/isolates', endpoint='isolates'),
57-
Rule('/db/<db>/genomes', endpoint='genomes'),
58-
Rule('/db/<db>/isolates/search', endpoint='isolates_search_post'),
59-
Rule('/db/<db>/isolates/<int:isolate_id>', endpoint='isolate'),
60-
Rule('/db/<db>/isolates/<int:isolate_id>/allele_designations', endpoint='isolate_allele_designations'),
61-
Rule('/db/<db>/isolates/<int:isolate_id>/allele_designations/<locus>', endpoint='isolate_allele_designation_locus'),
62-
Rule('/db/<db>/isolates/<int:isolate_id>/allele_ids', endpoint='isolate_allele_ids'),
63-
Rule('/db/<db>/isolates/<int:isolate_id>/schemes/<int:scheme_id>/allele_designations', endpoint='isolate_scheme_allele_designations'),
64-
Rule('/db/<db>/isolates/<int:isolate_id>/schemes/<int:scheme_id>/allele_ids', endpoint='isolate_scheme_allele_ids'),
65-
Rule('/db/<db>/isolates/<int:isolate_id>/contigs', endpoint='isolate_contigs'),
66-
Rule('/db/<db>/isolates/<int:isolate_id>/contigs_fasta', endpoint='isolate_contigs_fasta'),
67-
Rule('/db/<db>/isolates/<int:isolate_id>/history', endpoint='isolate_history'),
68-
Rule('/db/<db>/contigs/<int:contig_id>', endpoint='contig'),
69-
Rule('/db/<db>/fields', endpoint='fields'),
70-
Rule('/db/<db>/fields/<field>', endpoint='field'),
71-
Rule('/db/<db>/users/<int:user_id>', endpoint='user'),
72-
Rule('/db/<db>/curators', endpoint='curators'),
73-
Rule('/db/<db>/projects', endpoint='projects'),
74-
Rule('/db/<db>/projects/<int:project_id>', endpoint='project'),
75-
Rule('/db/<db>/projects/<int:project_id>/isolates', endpoint='project_isolates'),
76-
Rule('/db/<db>/submissions', endpoint='submissions'),
77-
Rule('/db/<db>/submissions/<int:submission_id>', endpoint='submission'),
78-
Rule('/db/<db>/submissions/<int:submission_id>/messages', endpoint='submission_messages'),
79-
Rule('/db/<db>/submissions/<int:submission_id>/files', endpoint='submission_files'),
80-
Rule('/db/<db>/submissions/<int:submission_id>/files/<filename>', endpoint='submission_file'),
81-
])
37+
38+
pubmlst_urls = Map(
39+
[
40+
Rule("/", endpoint="root"),
41+
Rule("/db", endpoint="db_root"),
42+
Rule("/db/<db>", endpoint="database_root"),
43+
Rule("/db/<db>/classification_schemes", endpoint="classification_schemes"),
44+
Rule(
45+
"/db/<db>/classification_schemes/<int:classification_scheme_id>",
46+
endpoint="classification_scheme",
47+
),
48+
Rule(
49+
"/db/<db>/classification_schemes/<int:classification_scheme_id>/groups",
50+
endpoint="classification_scheme_groups",
51+
),
52+
Rule(
53+
"/db/<db>/classification_schemes/<int:classification_scheme_id>/groups/<int:group_id>",
54+
endpoint="classification_scheme_group",
55+
),
56+
Rule("/db/<db>/loci", endpoint="loci"),
57+
Rule("/db/<db>/loci/<locus>", endpoint="locus"),
58+
Rule("/db/<db>/loci/<locus>/alleles", endpoint="locus_alleles"),
59+
Rule("/db/<db>/loci/<locus>/alleles_fasta", endpoint="locus_alleles_fasta"),
60+
Rule("/db/<db>/loci/<locus>/alleles/<int:allele_id>", endpoint="locus_allele"),
61+
Rule("/db/<db>/loci/<locus>/sequence", endpoint="locus_sequence_post"),
62+
Rule("/db/<db>/sequence", endpoint="sequence_post"),
63+
Rule("/db/<db>/sequences", endpoint="sequences"),
64+
Rule("/db/<db>/schemes", endpoint="schemes"),
65+
Rule("/db/<db>/schemes/<int:scheme_id>", endpoint="scheme"),
66+
Rule("/db/<db>/schemes/<int:scheme_id>/loci", endpoint="scheme_loci"),
67+
Rule("/db/<db>/schemes/<int:scheme_id>/fields/<field>", endpoint="scheme_field"),
68+
Rule("/db/<db>/schemes/<int:scheme_id>/profiles", endpoint="scheme_profiles"),
69+
Rule("/db/<db>/schemes/<int:scheme_id>/profiles_csv", endpoint="scheme_profiles_csv"),
70+
Rule(
71+
"/db/<db>/schemes/<int:scheme_id>/profiles/<int:profile_id>", endpoint="scheme_profile"
72+
),
73+
Rule("/db/<db>/schemes/<int:scheme_id>/sequence", endpoint="scheme_sequence_post"),
74+
Rule("/db/<db>/schemes/<int:scheme_id>/designations", endpoint="scheme_designations_post"),
75+
Rule("/db/<db>/isolates", endpoint="isolates"),
76+
Rule("/db/<db>/genomes", endpoint="genomes"),
77+
Rule("/db/<db>/isolates/search", endpoint="isolates_search_post"),
78+
Rule("/db/<db>/isolates/<int:isolate_id>", endpoint="isolate"),
79+
Rule(
80+
"/db/<db>/isolates/<int:isolate_id>/allele_designations",
81+
endpoint="isolate_allele_designations",
82+
),
83+
Rule(
84+
"/db/<db>/isolates/<int:isolate_id>/allele_designations/<locus>",
85+
endpoint="isolate_allele_designation_locus",
86+
),
87+
Rule("/db/<db>/isolates/<int:isolate_id>/allele_ids", endpoint="isolate_allele_ids"),
88+
Rule(
89+
"/db/<db>/isolates/<int:isolate_id>/schemes/<int:scheme_id>/allele_designations",
90+
endpoint="isolate_scheme_allele_designations",
91+
),
92+
Rule(
93+
"/db/<db>/isolates/<int:isolate_id>/schemes/<int:scheme_id>/allele_ids",
94+
endpoint="isolate_scheme_allele_ids",
95+
),
96+
Rule("/db/<db>/isolates/<int:isolate_id>/contigs", endpoint="isolate_contigs"),
97+
Rule("/db/<db>/isolates/<int:isolate_id>/contigs_fasta", endpoint="isolate_contigs_fasta"),
98+
Rule("/db/<db>/isolates/<int:isolate_id>/history", endpoint="isolate_history"),
99+
Rule("/db/<db>/contigs/<int:contig_id>", endpoint="contig"),
100+
Rule("/db/<db>/fields", endpoint="fields"),
101+
Rule("/db/<db>/fields/<field>", endpoint="field"),
102+
Rule("/db/<db>/users/<int:user_id>", endpoint="user"),
103+
Rule("/db/<db>/curators", endpoint="curators"),
104+
Rule("/db/<db>/projects", endpoint="projects"),
105+
Rule("/db/<db>/projects/<int:project_id>", endpoint="project"),
106+
Rule("/db/<db>/projects/<int:project_id>/isolates", endpoint="project_isolates"),
107+
Rule("/db/<db>/submissions", endpoint="submissions"),
108+
Rule("/db/<db>/submissions/<int:submission_id>", endpoint="submission"),
109+
Rule("/db/<db>/submissions/<int:submission_id>/messages", endpoint="submission_messages"),
110+
Rule("/db/<db>/submissions/<int:submission_id>/files", endpoint="submission_files"),
111+
Rule(
112+
"/db/<db>/submissions/<int:submission_id>/files/<filename>", endpoint="submission_file"
113+
),
114+
]
115+
)
116+
117+
pasteur_urls = add_prefix_to_rules(url_map, "/api")
118+
119+
URL_MAPS = {
120+
"pubmlst": pubmlst_urls,
121+
"pasteur": pasteur_urls,
122+
}

microSALT/utils/pubmlst/helpers.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
from pathlib import Path
44

5-
5+
from werkzeug.routing import Map, Rule
66

77
from microSALT import app, logger
88

@@ -13,7 +13,7 @@
1313
PUBMLSTError,
1414
SaveSessionError,
1515
)
16-
from microSALT.utils.pubmlst.constants import CREDENTIALS_KEY
16+
from microSALT.utils.pubmlst.constants import CREDENTIALS_KEY, URL_MAPS
1717

1818
folders_config = app.config["folders"]
1919

@@ -80,6 +80,19 @@ def get_service_by_url(url: str):
8080
raise ValueError(f"Unknown client for URL: {url}")
8181

8282

83+
def get_url_map(service: str):
84+
"""
85+
Get the URL map for the specified service.
86+
87+
:param service: The name of the service ('pubmlst' or 'pasteur').
88+
:return: The URL map for the service.
89+
"""
90+
url_map = URL_MAPS.get(service, None)
91+
if url_map is None:
92+
raise ValueError(f"Unknown service: {service}")
93+
return url_map
94+
95+
8396
def load_auth_credentials(service: str):
8497
"""
8598
Load client ID, client secret, access token, and access secret from the credentials file for the specified service.
@@ -177,3 +190,22 @@ def save_session_token(service: str, db: str, token: str, secret: str, expiratio
177190
except Exception as e:
178191
raise SaveSessionError(db, f"Unexpected error: {e}")
179192

193+
194+
def add_prefix_to_rules(url_map: Map, prefix: str):
195+
"""
196+
Add a prefix to all rules in the given URL map.
197+
198+
:param url_map: The original URL map.
199+
:param prefix: The prefix to add (e.g., '/api').
200+
:return: A new URL map with the prefix applied.
201+
"""
202+
new_rules = []
203+
new_rules.extend(
204+
Rule(
205+
f"{prefix}{rule.rule}",
206+
endpoint=rule.endpoint,
207+
methods=rule.methods,
208+
)
209+
for rule in url_map.iter_rules()
210+
)
211+
return Map(new_rules)

0 commit comments

Comments
 (0)