-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Issue #3094] Use CDN URLs for attachments instead of S3 URLs #3659
Changes from 3 commits
371ca7f
3bc548e
de4bd08
57ee4f8
90ab8a1
d5caae0
b90c413
40fe954
985a0a0
dcfe46f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,13 @@ | |
from src.api.route_utils import raise_flask_error | ||
from src.db.models.agency_models import Agency | ||
from src.db.models.opportunity_models import Opportunity, OpportunityAttachment, OpportunitySummary | ||
from src.util.file_util import pre_sign_file_location | ||
from src.util.env_config import PydanticBaseEnvConfig | ||
from src.util.file_util import convert_s3_to_cdn_url, pre_sign_file_location | ||
|
||
|
||
class AttachmentConfig(PydanticBaseEnvConfig): | ||
# If the CDN URL is set, we'll use it instead of pre-signing the file locations | ||
cdn_url: str | None = None | ||
|
||
|
||
def _fetch_opportunity( | ||
|
@@ -50,7 +56,14 @@ def get_opportunity(db_session: db.Session, opportunity_id: int) -> Opportunity: | |
db_session, opportunity_id, load_all_opportunity_summaries=False | ||
) | ||
|
||
pre_sign_opportunity_file_location(opportunity.opportunity_attachments) | ||
attachment_config = AttachmentConfig() | ||
if attachment_config.cdn_url is not None: | ||
for opp_att in opportunity.opportunity_attachments: | ||
opp_att.download_path = convert_s3_to_cdn_url( # type: ignore | ||
opp_att.file_location, attachment_config.cdn_url | ||
) | ||
else: | ||
pre_sign_opportunity_file_location(opportunity.opportunity_attachments) | ||
Comment on lines
+67
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure there will be a case where it's not set once we merge this. (NOTE - we should first verify with @coilysiren that the CDN is fully working before we merge this - I think it's still in progress) |
||
|
||
return opportunity | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,3 +153,34 @@ def test_get_opportunity_404_not_found_is_draft(client, api_auth_token, enable_f | |
resp.get_json()["message"] | ||
== f"Could not find Opportunity with ID {opportunity.opportunity_id}" | ||
) | ||
|
||
|
||
def test_get_opportunity_returns_cdn_urls( | ||
client, api_auth_token, monkeypatch_session, enable_factory_create, db_session, mock_s3_bucket | ||
): | ||
monkeypatch_session.setenv("CDN_URL", "https://cdn.example.com") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we set this in some autouse conftest value? Otherwise we'll need to set it for every API test with attachments. Fine to override it here. Also we should set CDN_URL in local.env to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you go to that path, does the file download work? I think for local, it also needs the bucket name (ie. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the bucket name to CDN_URL in local.env and it works. Checking that in shortly. |
||
"""Test that S3 file locations are converted to CDN URLs in the response""" | ||
# Create an opportunity with a specific attachment | ||
opportunity = OpportunityFactory.create(opportunity_attachments=[]) | ||
|
||
object_name = "test_file_1.txt" | ||
file_loc = f"s3://{mock_s3_bucket}/{object_name}" | ||
OpportunityAttachmentFactory.create( | ||
file_location=file_loc, opportunity=opportunity, file_contents="Hello, world" | ||
) | ||
|
||
# Make the GET request | ||
resp = client.get( | ||
f"/v1/opportunities/{opportunity.opportunity_id}", headers={"X-Auth": api_auth_token} | ||
) | ||
|
||
# Check the response | ||
assert resp.status_code == 200 | ||
response_data = resp.get_json()["data"] | ||
|
||
# Verify attachment URL is a CDN URL | ||
assert len(response_data["attachments"]) == 1 | ||
attachment = response_data["attachments"][0] | ||
|
||
assert attachment["download_path"].startswith("https://cdn.") | ||
assert "s3://" not in attachment["download_path"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be in capslock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pydantic will look for
CDN_URL
as an env var. We sometimes also give values an alias if we want a cleaner python name, but doesn't matter too much here.