Skip to content
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

fix: coerce pydantic AnyUri to str when needed #377

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions nmdc_runtime/site/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from fastjsonschema import JsonSchemaValueException
from frozendict import frozendict
from linkml_runtime.dumpers import json_dumper
from pydantic import BaseModel
from pydantic import BaseModel, AnyUrl
from pymongo import MongoClient, ReplaceOne, InsertOne
from terminusdb_client import WOQLClient
from toolz import get_in
Expand Down Expand Up @@ -194,15 +194,17 @@ def get_object_bytes(self, object_id) -> requests.Response:
access = AccessURL(
**self.get_object_access(object_id, method.access_id).json()
)
if access.url.startswith(
if str(access.url).startswith(
Copy link
Collaborator

@eecavanna eecavanna Nov 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: Maybe there's already a way to get the url property of access as a string, rather than casting it here. I noticed the AccessURL class has this method defined (I don't know what the decorator does yet).

class AccessURL(BaseModel):
headers: Optional[Dict[str, str]] = None
url: AnyUrl
@field_serializer("url")
def serialize_url(self, url: AnyUrl, _info):
return str(url)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the field_serializer decorator ensures that when .model_dump() is called on a model, url is stringified, but this doesn't hold for direct attribute access, i.e. <model>.url.

os.getenv("API_HOST_EXTERNAL")
) and self.base_url == os.getenv("API_HOST"):
access.url = access.url.replace(
os.getenv("API_HOST_EXTERNAL"), os.getenv("API_HOST")
access.url = AnyUrl(
str(access.url).replace(
os.getenv("API_HOST_EXTERNAL"), os.getenv("API_HOST")
)
)
else:
access = AccessURL(url=method.access_url.url)
return requests.get(access.url)
return requests.get(str(access.url))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: Instead of casting it 3x, we could store the casted result as access_url_str.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I considered that. we get some url (format) validation by keeping to the model until the return.


def list_jobs(self, list_request=None):
if list_request is None:
Expand Down