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

User can now use alias to pull objects from Coop #1562

Merged
merged 1 commit into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
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
79 changes: 61 additions & 18 deletions edsl/coop/coop.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
from edsl.jobs.Jobs import Jobs
from edsl.surveys.Survey import Survey

from edsl.exceptions.coop import CoopNoUUIDError, CoopServerResponseError
from edsl.exceptions.coop import (
CoopInvalidURLError,
CoopNoUUIDError,
CoopServerResponseError,
)
from edsl.coop.utils import (
EDSLObject,
ObjectRegistry,
Expand Down Expand Up @@ -285,17 +289,46 @@ def _json_handle_none(self, value: Any) -> Any:
if value is None:
return "null"

def _resolve_uuid(
def _resolve_uuid_or_alias(
self, uuid: Union[str, UUID] = None, url: str = None
) -> Union[str, UUID]:
) -> tuple[Optional[str], Optional[str], Optional[str]]:
"""
Resolve the uuid from a uuid or a url.
Resolve the uuid or alias information from a uuid or a url.
Returns a tuple of (uuid, owner_username, alias)
- For content/<uuid> URLs: returns (uuid, None, None)
- For content/<username>/<alias> URLs: returns (None, username, alias)
"""
if not url and not uuid:
raise CoopNoUUIDError("No uuid or url provided for the object.")

if not uuid and url:
uuid = url.split("/")[-1]
return uuid
parts = (
url.replace("http://", "")
.replace("https://", "")
.rstrip("/")
.split("/")
)

# Remove domain
parts = parts[1:]

if len(parts) < 2 or parts[0] != "content":
raise CoopInvalidURLError(
f"Invalid URL format. The URL must end with /content/<uuid> or /content/<username>/<alias>: {url}"
)

if len(parts) == 2:
obj_uuid = parts[1]
return obj_uuid, None, None
elif len(parts) == 3:
username, alias = parts[1], parts[2]
return None, username, alias
else:
raise CoopInvalidURLError(
f"Invalid URL format. The URL must end with /content/<uuid> or /content/<username>/<alias>: {url}"
)

return str(uuid), None, None

@property
def edsl_settings(self) -> dict:
Expand Down Expand Up @@ -361,22 +394,31 @@ def get(
expected_object_type: Optional[ObjectType] = None,
) -> EDSLObject:
"""
Retrieve an EDSL object by its uuid or its url.
Retrieve an EDSL object by its uuid/url or by owner username and alias.
- If the object's visibility is private, the user must be the owner.
- Optionally, check if the retrieved object is of a certain type.

:param uuid: the uuid of the object either in str or UUID format.
:param url: the url of the object.
:param url: the url of the object (can be content/uuid or content/username/alias format).
:param expected_object_type: the expected type of the object.

:return: the object instance.
"""
uuid = self._resolve_uuid(uuid, url)
response = self._send_server_request(
uri=f"api/v0/object",
method="GET",
params={"uuid": uuid},
)
obj_uuid, owner_username, alias = self._resolve_uuid_or_alias(uuid, url)

if obj_uuid:
response = self._send_server_request(
uri=f"api/v0/object",
method="GET",
params={"uuid": obj_uuid},
)
else:
response = self._send_server_request(
uri=f"api/v0/object/alias",
method="GET",
params={"owner_username": owner_username, "alias": alias},
)

self._resolve_server_response(response)
json_string = response.json().get("json_string")
object_type = response.json().get("object_type")
Expand Down Expand Up @@ -414,12 +456,13 @@ def delete(self, uuid: Union[str, UUID] = None, url: str = None) -> dict:
"""
Delete an object from the server.
"""
uuid = self._resolve_uuid(uuid, url)
obj_uuid, _, _ = self._resolve_uuid_or_alias(uuid, url)
response = self._send_server_request(
uri=f"api/v0/object",
method="DELETE",
params={"uuid": uuid},
params={"uuid": obj_uuid},
)

self._resolve_server_response(response)
return response.json()

Expand All @@ -438,11 +481,11 @@ def patch(
"""
if description is None and visibility is None and value is None:
raise Exception("Nothing to patch.")
uuid = self._resolve_uuid(uuid, url)
obj_uuid, _, _ = self._resolve_uuid_or_alias(uuid, url)
response = self._send_server_request(
uri=f"api/v0/object",
method="PATCH",
params={"uuid": uuid},
params={"uuid": obj_uuid},
payload={
"description": description,
"alias": alias,
Expand Down
4 changes: 4 additions & 0 deletions edsl/exceptions/coop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ class CoopErrors(Exception):
pass


class CoopInvalidURLError(CoopErrors):
pass


class CoopNoUUIDError(CoopErrors):
pass

Expand Down
Loading