Skip to content

Commit 64778f7

Browse files
authored
Merge pull request #218 from ecmwf-projects/COPDS-2104-None-default-for-rate-limits-file
Set rate limits file default to None
2 parents 9f3d40a + d129091 commit 64778f7

File tree

2 files changed

+39
-25
lines changed

2 files changed

+39
-25
lines changed

cads_processing_api_service/config.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -100,26 +100,26 @@ class RateLimitsConfig(pydantic.BaseModel):
100100
)
101101
process_execution: RateLimitsRouteConfig = pydantic.Field(
102102
default=RateLimitsRouteConfig(),
103-
alias="processes/{process_id}/execution",
103+
alias="/processes/{process_id}/execution",
104104
validate_default=True,
105105
)
106106
jobs: RateLimitsRouteConfig = pydantic.Field(
107-
default=RateLimitsRouteConfig(), alias="jobs", validate_default=True
107+
default=RateLimitsRouteConfig(), alias="/jobs", validate_default=True
108108
)
109109
job: RateLimitsRouteConfig = pydantic.Field(
110-
default=RateLimitsRouteConfig(), alias="jobs/{job_id}", validate_default=True
110+
default=RateLimitsRouteConfig(), alias="/jobs/{job_id}", validate_default=True
111111
)
112112
job_results: RateLimitsRouteConfig = pydantic.Field(
113113
default=RateLimitsRouteConfig(),
114-
alias="jobs/{job_id}/results",
114+
alias="/jobs/{job_id}/results",
115115
validate_default=True,
116116
)
117117

118118
@pydantic.model_validator(mode="after") # type: ignore
119-
def populate_fields_with_default(self) -> None:
119+
def populate_fields_with_default(self) -> pydantic.BaseModel:
120120
default = self.default
121121
if default is RateLimitsRouteConfig():
122-
return
122+
return self
123123
routes = self.model_fields
124124
for route in routes:
125125
if route == "default":
@@ -132,23 +132,24 @@ def populate_fields_with_default(self) -> None:
132132
if not set_value:
133133
default_value = getattr(getattr(default, method), origin)
134134
setattr(getattr(route_config, method), origin, default_value)
135-
return
135+
return self
136136

137137

138-
def load_rate_limits(rate_limits_file: str) -> RateLimitsConfig:
138+
def load_rate_limits(rate_limits_file: str | None) -> RateLimitsConfig:
139139
rate_limits = RateLimitsConfig()
140-
try:
141-
with open(rate_limits_file, "r") as file:
142-
loaded_rate_limits = yaml.safe_load(file)
143-
rate_limits = RateLimitsConfig(**loaded_rate_limits)
144-
except OSError:
145-
logger.exception(
146-
"Failed to read rate limits file", rate_limits_file=rate_limits_file
147-
)
148-
except pydantic.ValidationError:
149-
logger.exception(
150-
"Failed to validate rate limits file", rate_limits_file=rate_limits_file
151-
)
140+
if rate_limits_file is not None:
141+
try:
142+
with open(rate_limits_file, "r") as file:
143+
loaded_rate_limits = yaml.safe_load(file)
144+
rate_limits = RateLimitsConfig(**loaded_rate_limits)
145+
except OSError:
146+
logger.exception(
147+
"Failed to read rate limits file", rate_limits_file=rate_limits_file
148+
)
149+
except pydantic.ValidationError:
150+
logger.exception(
151+
"Failed to validate rate limits file", rate_limits_file=rate_limits_file
152+
)
152153
return rate_limits
153154

154155

@@ -184,7 +185,7 @@ def profiles_api_url(self) -> str:
184185
"{base_url}/datasets/{process_id}?tab=download#manage-licences"
185186
)
186187

187-
rate_limits_file: str = "/etc/retrieve-api/rate-limits.yaml"
188+
rate_limits_file: str | None = None
188189
rate_limits: RateLimitsConfig = pydantic.Field(default=RateLimitsConfig())
189190

190191
@pydantic.model_validator(mode="after") # type: ignore

tests/test_10_config.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,19 @@ def test_validate_rate_limits() -> None:
6161
rate_limits = ["1/second", "10/minute"]
6262
config.validate_rate_limits(rate_limits)
6363

64-
rate_limits = ["not_valid_limit"]
64+
rate_limits = ["invalid_limit"]
6565
with pytest.raises(ValueError):
6666
config.validate_rate_limits(rate_limits)
6767

6868

69-
def test_load_rate_limits(tmp_path: pathlib.Path) -> None:
69+
def test_load_rate_limits(tmp_path: pathlib.Path, caplog) -> None:
70+
rate_limits_file = None
71+
loaded_rate_limits = config.load_rate_limits(rate_limits_file)
72+
assert loaded_rate_limits == config.RateLimitsConfig()
73+
7074
rate_limits_file = str(tmp_path / "rate-limits.yaml")
7175
rate_limits = {
72-
"processes/{process_id}/execution": {
76+
"/processes/{process_id}/execution": {
7377
"post": {"api": ["1/second"], "ui": ["2/second"]}
7478
},
7579
}
@@ -78,6 +82,15 @@ def test_load_rate_limits(tmp_path: pathlib.Path) -> None:
7882
loaded_rate_limits = config.load_rate_limits(rate_limits_file)
7983
assert loaded_rate_limits == config.RateLimitsConfig(**rate_limits)
8084

85+
rate_limits_file = str(tmp_path / "invalid-rate-limits.yaml")
86+
rate_limits = {
87+
"/processes/{process_id}/execution": {"post": {"api": ["invalid_limit"]}},
88+
}
89+
with open(rate_limits_file, "w") as file:
90+
yaml.dump(rate_limits, file)
91+
loaded_rate_limits = config.load_rate_limits(rate_limits_file)
92+
assert loaded_rate_limits == config.RateLimitsConfig()
93+
8194
rate_limits_file = str(tmp_path / "not-found-rate-limits.yaml")
8295
loaded_rate_limits = config.load_rate_limits(rate_limits_file)
8396
assert loaded_rate_limits == config.RateLimitsConfig()
@@ -90,7 +103,7 @@ def test_rate_limits_config_populate_with_default() -> None:
90103
"post": {"api": ["1/second"], "ui": ["2/second"]},
91104
"get": {"api": ["2/second"]},
92105
},
93-
"processes/{process_id}/execution": {"post": {"api": ["1/minute"]}},
106+
"/processes/{process_id}/execution": {"post": {"api": ["1/minute"]}},
94107
}
95108
)
96109
exp_populated_rate_limits_config = {

0 commit comments

Comments
 (0)