Skip to content

Commit

Permalink
add resource Visibility enum and operations (#196)
Browse files Browse the repository at this point in the history
* add visibility enum and operations

* changelog

* fixes

* black
  • Loading branch information
shouples authored Oct 23, 2023
1 parent 78467d7 commit 8cdfdc0
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ For pre-1.0 releases, see [0.0.35 Changelog](https://github.com/noteable-io/orig

### [1.1.3] - 2023-10-23
### Added
- Programmatically share access to Spaces, Projects, and Notebooks/Files by email and access level. E.g. `await api_client.share_file(file_id, email, 'viewer')`
- Programmatically share access to Spaces, Projects, and Notebooks/Files by email and access level. E.g. `await api_client.share_file(file_id, email, 'viewer')`, as well as change Space/Project/File visibility (e.g. `private`, `open`, `public`)

### Changed
- Removed `RuntimeError` in RTUClient catastrophic failure, top level applications (e.g. PA, Origamist) should define that behavior
Expand Down
105 changes: 105 additions & 0 deletions origami/clients/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ def from_str(cls, s: str):
raise ValueError(f"Invalid access level {s}")


class Visibility(enum.Enum):
"""Visibility levels associated with a specific Resource.
Private = only invited users can access
Open = any member can access
Public = anyone can access
"""

private = "private"
open = "open"
public = "public"

@classmethod
def from_str(cls, s: str):
for vis in cls:
if vis.name == s:
return vis
raise ValueError(f"Invalid visibility {s}")


class Resource(enum.Enum):
spaces = "spaces"
projects = "projects"
Expand Down Expand Up @@ -128,6 +148,43 @@ async def unshare_resource(self, resource: Resource, resource_id: uuid.UUID, ema
unshare_resp.raise_for_status()
return len(users)

async def change_resource_visibility(
self,
resource: Resource,
resource_id: uuid.UUID,
visibility: Visibility,
visibility_default_access_level: Optional[AccessLevel] = None,
):
"""
Change overall visibility of a Resource.
visibility_default_access_level is only required when visibility is not private.
"""
if isinstance(visibility, str):
visibility = Visibility.from_str(visibility)

if visibility is not Visibility.private and visibility_default_access_level is None:
raise ValueError(
"visibility_default_access_level must be set when visibility is not private"
)

patch_body = {"visibility": visibility.value}
if isinstance(visibility_default_access_level, str):
visibility_default_access_level = AccessLevel.from_str(
visibility_default_access_level
).value

# always set this as either None or a valid (string) value
patch_body["visibility_default_access_level"] = visibility_default_access_level

endpoint = f"/{resource.value}/{resource_id}"
resp = await self.client.patch(
endpoint,
json=patch_body,
)
resp.raise_for_status()
return resp.json()

# Spaces are collections of Projects. Some "scoped" resources such as Secrets and Datasources
# can also be attached to a Space and made available to all users of that Space.
async def create_space(self, name: str, description: Optional[str] = None) -> Space:
Expand Down Expand Up @@ -176,6 +233,22 @@ async def unshare_space(self, space_id: uuid.UUID, email: str) -> int:
"""
return await self.unshare_resource(Resource.spaces, space_id, email)

async def change_space_visibility(
self,
space_id: uuid.UUID,
visibility: Visibility,
visibility_default_access_level: Optional[AccessLevel] = None,
) -> Visibility:
"""
Change overall visibility of a Space
"""
return await self.change_resource_visibility(
Resource.spaces,
space_id,
visibility,
visibility_default_access_level,
)

# Projects are collections of Files, including Notebooks. When a Kernel is launched for a
# Notebook, all Files in the Project are volume mounted into the Kernel container at startup.
async def create_project(
Expand Down Expand Up @@ -228,6 +301,22 @@ async def unshare_project(self, project_id: uuid.UUID, email: str) -> int:
"""
return await self.unshare_resource(Resource.projects, project_id, email)

async def change_project_visibility(
self,
project_id: uuid.UUID,
visibility: Visibility,
visibility_default_access_level: Optional[AccessLevel] = None,
) -> Visibility:
"""
Change overall visibility of a Project
"""
return await self.change_resource_visibility(
Resource.projects,
project_id,
visibility,
visibility_default_access_level,
)

async def list_project_files(self, project_id: uuid.UUID) -> List[File]:
"""List all Files in a Project. Files do not have presigned download urls included here."""
self.add_tags_and_contextvars(project_id=str(project_id))
Expand Down Expand Up @@ -369,6 +458,22 @@ async def unshare_file(self, file_id: uuid.UUID, email: str) -> int:
"""
return await self.unshare_resource(Resource.files, file_id, email)

async def change_file_visibility(
self,
file_id: uuid.UUID,
visibility: Visibility,
visibility_default_access_level: Optional[AccessLevel] = None,
) -> Visibility:
"""
Change overall visibility of a Notebook or File
"""
return await self.change_resource_visibility(
Resource.files,
file_id,
visibility,
visibility_default_access_level,
)

async def get_datasources_for_notebook(self, file_id: uuid.UUID) -> List[DataSource]:
"""Return a list of Datasources that can be used in SQL cells within a Notebook"""
self.add_tags_and_contextvars(file_id=str(file_id))
Expand Down

0 comments on commit 8cdfdc0

Please sign in to comment.