Add centralized reliability handling for Aurora and OSDG API integrations#50
Open
mayur-rane024 wants to merge 4 commits into
Open
Add centralized reliability handling for Aurora and OSDG API integrations#50mayur-rane024 wants to merge 4 commits into
mayur-rane024 wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a small backend reliability layer around the Aurora and OSDG upstream API calls (timeouts, retries/backoff, local rate limiting, and typed exceptions) and wires it into the existing Flask endpoints while aiming to keep the frontend contract unchanged.
Changes:
- Added
APIClient+ typed upstream exceptions + in-memory sliding-window rate limiter underbackend/services/. - Introduced provider-specific wrappers (
classify_with_aurora,classify_with_osdg) and updated Aurora/OSDG integrations to use them. - Added pytest coverage for retries/backoff, timeouts, rate limiting, and invalid upstream responses.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
backend/services/errors.py |
Adds typed exceptions for upstream failures. |
backend/services/rate_limiter.py |
Adds a thread-safe in-memory sliding window rate limiter. |
backend/services/api_client.py |
Adds centralized request handling with timeouts, retries, and JSON parsing. |
backend/services/external_apis.py |
Adds provider-specific wrappers for Aurora/OSDG calls. |
backend/aurora_api.py |
Switches Aurora integration to use the centralized wrapper/client. |
backend/app.py |
Updates Flask endpoints to use typed upstream error handling for Aurora/OSDG. |
backend/tests/conftest.py |
Ensures tests can import backend modules via sys.path. |
backend/tests/test_api_client.py |
Adds no-network tests for retry/timeout/limiting/response validation. |
backend/services/__init__.py |
Declares the services package. |
.gitignore |
Ignores Python bytecode and pytest cache artifacts. |
Comments suppressed due to low confidence (1)
backend/app.py:190
- The OSDG handler catches
UpstreamAPIErrorbut always returns HTTP 500 and doesn’t surfaceprovider/status_code, which defeats the purpose of typed upstream errors and is inconsistent with the Aurora endpoint above. Consider returninge.status_code or 502(or similar) and includinge.providerin the response for easier debugging.
try:
osdg_result = classify_with_osdg(projectDescription)
except UpstreamAPIError as e:
print(f"OSDG API request failed: {str(e)}")
return jsonify({
"error": f"Failed to connect to OSDG API: {str(e)}",
"message": "OSDG API classification failed"
}), 500
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+20
to
+34
| def __init__( | ||
| self, | ||
| timeout=10, | ||
| max_retries=2, | ||
| backoff_seconds=0.25, | ||
| rate_limiter=DEFAULT_RATE_LIMITER, | ||
| session=None, | ||
| sleeper=None, | ||
| ): | ||
| self.timeout = timeout | ||
| self.max_retries = max_retries | ||
| self.backoff_seconds = backoff_seconds | ||
| self.rate_limiter = rate_limiter | ||
| self.session = session or requests.Session() | ||
| self._sleep = sleeper or time.sleep |
Comment on lines
+37
to
+43
| if self.rate_limiter: | ||
| self.rate_limiter.check(provider) | ||
|
|
||
| request_timeout = kwargs.pop("timeout", self.timeout) | ||
| last_error = None | ||
|
|
||
| for attempt in range(self.max_retries + 1): |
| AURORA_CLASSIFY_URL = ( | ||
| "https://aurora-sdg.labs.vu.nl/classifier/classify/elsevier-sdg-multi" | ||
| ) | ||
| OSDG_LABEL_URL = "http://20.73.166.85/label_text" |
86ae323 to
c50146a
Compare
Signed-off-by: MAYURESH SHAILESH RANE <ranemayuresh075@gmail.com>
Signed-off-by: MAYURESH SHAILESH RANE <ranemayuresh075@gmail.com>
Signed-off-by: MAYURESH SHAILESH RANE <ranemayuresh075@gmail.com>
Signed-off-by: MAYURESH SHAILESH RANE <ranemayuresh075@gmail.com>
c50146a to
881a520
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a focused backend reliability layer for external Aurora and OSDG API integrations.
The goal is to improve resilience around upstream API interactions while preserving existing frontend contracts and application behavior.
Why
The current backend integrations with Aurora and OSDG rely on direct upstream API calls with limited retry, timeout, and resilience handling.
This PR introduces a small centralized reliability layer to improve:
while intentionally preserving the existing frontend/API behavior and keeping the implementation modular.
What this PR adds
Scope intentionally avoided
To keep this PR modular and reviewable, this does NOT include:
Files added
backend/services/errors.pybackend/services/rate_limiter.pybackend/services/api_client.pybackend/services/external_apis.pyIntegration updates
backend/aurora_api.pybackend/app.pyTests
Added isolated pytest coverage for:
Verification
Executed successfully:
Result:
Notes
This PR intentionally keeps the implementation small and focused to avoid overlap with existing deployment, frontend caching, logging, and response-standardization work already being discussed in the repository.