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

FE2 API Updates #348

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7801265
Added project resource and fe2 models
JR-Morgan Oct 18, 2024
6c03dc8
black + isort
JR-Morgan Oct 18, 2024
537a504
removed unimplemented file
JR-Morgan Oct 18, 2024
225d4f0
Merge remote-tracking branch 'origin/main' into jedd/cxpla-95-add-fe2…
JR-Morgan Oct 21, 2024
09ca501
project integration tests & pydantic serializaiton
JR-Morgan Oct 21, 2024
976a52b
models
JR-Morgan Oct 21, 2024
a10b259
version resource
JR-Morgan Oct 22, 2024
cc004c8
active user
JR-Morgan Oct 24, 2024
6096cd2
project_invites
JR-Morgan Oct 25, 2024
280927b
active user update overloads
JR-Morgan Oct 25, 2024
0f1f00d
Other user resource
JR-Morgan Oct 25, 2024
6b6ff80
Fixed issues
JR-Morgan Oct 28, 2024
2acf4c4
fixed tests
JR-Morgan Oct 28, 2024
3bd849c
imports
JR-Morgan Oct 28, 2024
3642731
Wrapping up tests
JR-Morgan Oct 30, 2024
bb62109
Fixed subscription tests
JR-Morgan Oct 30, 2024
7e09d4f
pr clean up
JR-Morgan Oct 30, 2024
b7933e0
pre-commit stuff
JR-Morgan Oct 30, 2024
f843bb0
Fixed up client auth error handling
JR-Morgan Oct 30, 2024
ab41d3c
last fixes
JR-Morgan Oct 30, 2024
be8fae3
removed unused subscription functions
JR-Morgan Oct 30, 2024
1b45f50
removed dead code in client
JR-Morgan Oct 30, 2024
c78a780
Use the correct subscription resource in integration tests
JR-Morgan Oct 30, 2024
eae6016
reverted changes to old subscription resource
JR-Morgan Oct 30, 2024
e978e4f
Re-export deprecated resources and models
JR-Morgan Oct 31, 2024
040a4e2
fixed tests
JR-Morgan Oct 31, 2024
170d2f0
isort
JR-Morgan Oct 31, 2024
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
26 changes: 22 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ httpx = "^0.25.0"
black = "23.11.0"
isort = "^5.7.0"
pytest = "^7.1.3"
pytest-asyncio = "^0.23.0"
pytest-ordering = "^0.6"
pytest-cov = "^3.0.0"
devtools = "^0.8.0"
Expand Down
48 changes: 43 additions & 5 deletions src/specklepy/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

from specklepy.api.credentials import Account
from specklepy.api.resources import (
active_user,
ActiveUserResource,
ModelResource,
OtherUserResource,
ProjectInviteResource,
ProjectResource,
SubscriptionResource,
VersionResource,
branch,
commit,
object,
other_user,
server,
stream,
subscriptions,
Expand Down Expand Up @@ -67,24 +72,57 @@ def _init_resources(self) -> None:
self.server = server.Resource(
account=self.account, basepath=self.url, client=self.httpclient
)

server_version = None
try:
server_version = self.server.version()
except Exception:
pass
self.user = user.Resource(

self.other_user = OtherUserResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.active_user = ActiveUserResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.project = ProjectResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.project_invite = ProjectInviteResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.model = ModelResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.other_user = other_user.Resource(
self.version = VersionResource(
account=self.account,
basepath=self.url,
client=self.httpclient,
server_version=server_version,
)
self.active_user = active_user.Resource(
self.subscription = SubscriptionResource(
account=self.account,
basepath=self.ws_url,
client=self.wsclient,
# todo: why doesn't this take a server version
)
# Deprecated Resources
self.user = user.Resource(
account=self.account,
basepath=self.url,
client=self.httpclient,
Expand Down
File renamed without changes.
48 changes: 40 additions & 8 deletions src/specklepy/api/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
import pkgutil
import sys
from importlib import import_module
from specklepy.api.resources.current.active_user_resource import ActiveUserResource
from specklepy.api.resources.current.model_resource import ModelResource
from specklepy.api.resources.current.other_user_resource import OtherUserResource
from specklepy.api.resources.current.project_invite_resource import (
ProjectInviteResource,
)
from specklepy.api.resources.current.project_resource import ProjectResource
from specklepy.api.resources.current.server_resource import ServerResource
from specklepy.api.resources.current.subscription_resource import SubscriptionResource
from specklepy.api.resources.current.version_resource import VersionResource
from specklepy.api.resources.deprecated import (
active_user,
branch,
commit,
object,
other_user,
server,
stream,
subscriptions,
user,
)

for _, name, _ in pkgutil.iter_modules(__path__):
imported_module = import_module("." + name, package=__name__)

if hasattr(imported_module, "Resource"):
setattr(sys.modules[__name__], name, imported_module)
__all__ = [
"ActiveUserResource",
"ModelResource",
"OtherUserResource",
"ProjectInviteResource",
"ProjectResource",
"ServerResource",
"SubscriptionResource",
"VersionResource",
"active_user",
"branch",
"commit",
"object",
"other_user",
"server",
"stream",
"subscriptions",
"user",
]
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
from datetime import datetime
from typing import List, Optional

from specklepy.api.models import PendingStreamCollaborator, User
from specklepy.core.api.resources.active_user import Resource as CoreResource
from typing import List, Optional, overload

from deprecated import deprecated

from specklepy.core.api.inputs.project_inputs import UserProjectsFilter
from specklepy.core.api.inputs.user_inputs import UserUpdateInput
from specklepy.core.api.models import (
PendingStreamCollaborator,
Project,
ResourceCollection,
User,
)
from specklepy.core.api.models.deprecated import (
FE1_DEPRECATION_REASON,
FE1_DEPRECATION_VERSION,
)
from specklepy.core.api.resources import ActiveUserResource as CoreResource
from specklepy.logging import metrics


class Resource(CoreResource):
class ActiveUserResource(CoreResource):
"""API Access class for users. This class provides methods to get and update
the user profile, fetch user activity, and manage pending stream invitations."""

Expand All @@ -19,37 +32,64 @@
)
self.schema = User

def get(self) -> User:
"""Gets the profile of the current authenticated user's profile
(as extracted from the authorization header).

Returns:
User -- the retrieved user
"""
metrics.track(metrics.SDK, custom_props={"name": "User Active Get"})
def get(self) -> Optional[User]:
metrics.track(metrics.SDK, self.account, {"name": "Active User Get"})
return super().get()

@deprecated("Use UserUpdateInput overload", version=FE1_DEPRECATION_VERSION)
@overload
def update(
self,
name: Optional[str] = None,
company: Optional[str] = None,
bio: Optional[str] = None,
avatar: Optional[str] = None,
):
"""Updates your user profile. All arguments are optional.
) -> User:
...

Check warning on line 48 in src/specklepy/api/resources/current/active_user_resource.py

View check run for this annotation

Codecov / codecov/patch

src/specklepy/api/resources/current/active_user_resource.py#L48

Added line #L48 was not covered by tests

Args:
name (Optional[str]): The user's name.
company (Optional[str]): The company the user works for.
bio (Optional[str]): A brief user biography.
avatar (Optional[str]): A URL to an avatar image for the user.
@overload
def update(self, *, input: UserUpdateInput) -> User:
...

Check warning on line 52 in src/specklepy/api/resources/current/active_user_resource.py

View check run for this annotation

Codecov / codecov/patch

src/specklepy/api/resources/current/active_user_resource.py#L52

Added line #L52 was not covered by tests

Returns @deprecated(version=DEPRECATION_VERSION, reason=DEPRECATION_TEXT):
bool -- True if your profile was updated successfully
"""
metrics.track(metrics.SDK, self.account, {"name": "User Active Update"})
return super().update(name, company, bio, avatar)
def update(
self,
name: Optional[str] = None,
company: Optional[str] = None,
bio: Optional[str] = None,
avatar: Optional[str] = None,
*,
input: Optional[UserUpdateInput] = None,
) -> User:
metrics.track(metrics.SDK, self.account, {"name": "Active User Update"})
if isinstance(input, UserUpdateInput):
return super()._update(input=input)
else:
return super()._update(
input=UserUpdateInput(
name=name,
company=company,
bio=bio,
avatar=avatar,
)
)

def get_projects(
self,
*,
limit: int = 25,
cursor: Optional[str] = None,
filter: Optional[UserProjectsFilter] = None,
) -> ResourceCollection[Project]:
metrics.track(metrics.SDK, self.account, {"name": "Active User Get Projects"})
return super().get_projects(limit=limit, cursor=cursor, filter=filter)

def get_project_invites(self) -> List[PendingStreamCollaborator]:
metrics.track(
metrics.SDK, self.account, {"name": "Active User Get Project Invites"}
)
return super().get_project_invites()

@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
def activity(
self,
limit: int = 20,
Expand Down Expand Up @@ -78,6 +118,7 @@
metrics.track(metrics.SDK, self.account, {"name": "User Active Activity"})
return super().activity(limit, action_type, before, after, cursor)

@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
def get_all_pending_invites(self) -> List[PendingStreamCollaborator]:
"""Fetches all of the current user's pending stream invitations.

Expand All @@ -89,6 +130,7 @@
)
return super().get_all_pending_invites()

@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
def get_pending_invite(
self, stream_id: str, token: Optional[str] = None
) -> Optional[PendingStreamCollaborator]:
Expand Down
74 changes: 74 additions & 0 deletions src/specklepy/api/resources/current/model_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from typing import Optional

from specklepy.core.api.inputs.model_inputs import (
CreateModelInput,
DeleteModelInput,
ModelVersionsFilter,
UpdateModelInput,
)
from specklepy.core.api.inputs.project_inputs import ProjectModelsFilter
from specklepy.core.api.models import Model, ModelWithVersions, ResourceCollection
from specklepy.core.api.resources import ModelResource as CoreResource
from specklepy.logging import metrics


class ModelResource(CoreResource):
"""API Access class for models"""

def __init__(self, account, basepath, client, server_version) -> None:
super().__init__(
account=account,
basepath=basepath,
client=client,
server_version=server_version,
)

def get(self, model_id: str, project_id: str) -> Model:
metrics.track(metrics.SDK, self.account, {"name": "Model Get"})
return super().get(model_id, project_id)

def get_with_versions(
self,
model_id: str,
project_id: str,
*,
versions_limit: int = 25,
versions_cursor: Optional[str] = None,
versions_filter: Optional[ModelVersionsFilter] = None,
) -> ModelWithVersions:
metrics.track(metrics.SDK, self.account, {"name": "Model Get With Versions"})
return super().get_with_versions(
model_id,
project_id,
versions_limit=versions_limit,
versions_cursor=versions_cursor,
versions_filter=versions_filter,
)

def get_models(
self,
project_id: str,
*,
models_limit: int = 25,
models_cursor: Optional[str] = None,
models_filter: Optional[ProjectModelsFilter] = None,
) -> ResourceCollection[Model]:
metrics.track(metrics.SDK, self.account, {"name": "Model Get Models"})
return super().get_models(
project_id,
models_limit=models_limit,
models_cursor=models_cursor,
models_filter=models_filter,
)

def create(self, input: CreateModelInput) -> Model:
metrics.track(metrics.SDK, self.account, {"name": "Model Create"})
return super().create(input)

def delete(self, input: DeleteModelInput) -> bool:
metrics.track(metrics.SDK, self.account, {"name": "Model Delete"})
return super().delete(input)

def update(self, input: UpdateModelInput) -> Model:
metrics.track(metrics.SDK, self.account, {"name": "Model Update"})
return super().update(input)
Loading