Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0fcc3053ca | |||
| 71ca5318b6 | |||
| 58b04c246a | |||
| 4ff2931eca | |||
| 7d25b6b194 | |||
| f33bbbdbba | |||
| 46b56b9bd3 | |||
| 9358496f49 | |||
| 6c154b034f | |||
| 0a918ae73a | |||
| 3ea301f498 | |||
| 8e0d47b627 | |||
| edfb5158f4 | |||
| eafa6f2230 | |||
| 3362d094ff | |||
| 21249f0a9a | |||
| bd38dfacc7 | |||
| 281483f0fc | |||
| 932838de8f | |||
| a0b39e4c64 | |||
| 759cd0ef58 | |||
| 46c18bbe6b | |||
| 82d39e66fe | |||
| 10f7499182 | |||
| 170d2f0450 | |||
| 040a4e2553 | |||
| e978e4f632 | |||
| eae60160a1 | |||
| c78a780e85 | |||
| 1b45f50697 | |||
| be8fae3b1c | |||
| ab41d3cbe0 | |||
| f843bb0c89 | |||
| b7933e0088 | |||
| 7e09d4f4ce | |||
| bb62109332 | |||
| 3642731f37 | |||
| 3bd849c815 | |||
| 2acf4c41c7 | |||
| 6b6ff80bf2 | |||
| 0f1f00db00 | |||
| 280927b720 | |||
| 6096cd25f6 | |||
| cc004c8e6b | |||
| a10b2594d3 | |||
| 976a52bdc8 | |||
| 09ca501a74 | |||
| 225d4f02d4 | |||
| 537a504121 | |||
| 6c03dc82c8 | |||
| 780126528d |
@@ -2,46 +2,16 @@
|
|||||||
<img src="https://user-images.githubusercontent.com/2679513/131189167-18ea5fe1-c578-47f6-9785-3748178e4312.png" width="150px"/><br/>
|
<img src="https://user-images.githubusercontent.com/2679513/131189167-18ea5fe1-c578-47f6-9785-3748178e4312.png" width="150px"/><br/>
|
||||||
Speckle | specklepy 🐍
|
Speckle | specklepy 🐍
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
<p align="center"><a href="https://twitter.com/SpeckleSystems"><img src="https://img.shields.io/twitter/follow/SpeckleSystems?style=social" alt="Twitter Follow"></a> <a href="https://speckle.community"><img src="https://img.shields.io/discourse/users?server=https%3A%2F%2Fspeckle.community&style=flat-square&logo=discourse&logoColor=white" alt="Community forum users"></a> <a href="https://speckle.systems"><img src="https://img.shields.io/badge/https://-speckle.systems-royalblue?style=flat-square" alt="website"></a> <a href="https://speckle.guide/dev/"><img src="https://img.shields.io/badge/docs-speckle.guide-orange?style=flat-square&logo=read-the-docs&logoColor=white" alt="docs"></a></p>
|
||||||
|
|
||||||
|
> Speckle is the first AEC data hub that connects with your favorite AEC tools. Speckle exists to overcome the challenges of working in a fragmented industry where communication, creative workflows, and the exchange of data are often hindered by siloed software and processes. It is here to make the industry better.
|
||||||
|
|
||||||
<h3 align="center">
|
<h3 align="center">
|
||||||
The Python SDK
|
The Python SDK
|
||||||
</h3>
|
</h3>
|
||||||
<p align="center"><b>Speckle</b> is the data infrastructure for the AEC industry.</p><br/>
|
|
||||||
|
|
||||||
<p align="center"><a href="https://twitter.com/SpeckleSystems"><img src="https://img.shields.io/twitter/follow/SpeckleSystems?style=social" alt="Twitter Follow"></a> <a href="https://speckle.community"><img src="https://img.shields.io/discourse/users?server=https%3A%2F%2Fspeckle.community&style=flat-square&logo=discourse&logoColor=white" alt="Community forum users"></a> <a href="https://speckle.systems"><img src="https://img.shields.io/badge/https://-speckle.systems-royalblue?style=flat-square" alt="website"></a> <a href="https://speckle.guide/dev/"><img src="https://img.shields.io/badge/docs-speckle.guide-orange?style=flat-square&logo=read-the-docs&logoColor=white" alt="docs"></a></p>
|
|
||||||
<p align="center"><a href="https://github.com/specklesystems/specklepy/"><img src="https://circleci.com/gh/specklesystems/specklepy.svg?style=svg&circle-token=76eabd350ea243575cbb258b746ed3f471f7ac29" alt="Speckle-Next"></a><a href="https://codecov.io/gh/specklesystems/specklepy">
|
|
||||||
<img src="https://codecov.io/gh/specklesystems/specklepy/branch/main/graph/badge.svg?token=8KQFL5N0YF"/>
|
|
||||||
</a> </p>
|
|
||||||
|
|
||||||
# About Speckle
|
|
||||||
|
|
||||||
What is Speckle? Check our 
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
- **Object-based:** say goodbye to files! Speckle is the first object based platform for the AEC industry
|
|
||||||
- **Version control:** Speckle is the Git & Hub for geometry and BIM data
|
|
||||||
- **Collaboration:** share your designs collaborate with others
|
|
||||||
- **3D Viewer:** see your CAD and BIM models online, share and embed them anywhere
|
|
||||||
- **Interoperability:** get your CAD and BIM models into other software without exporting or importing
|
|
||||||
- **Real time:** get real time updates and notifications and changes
|
|
||||||
- **GraphQL API:** get what you need anywhere you want it
|
|
||||||
- **Webhooks:** the base for a automation and next-gen pipelines
|
|
||||||
- **Built for developers:** we are building Speckle with developers in mind and got tools for every stack
|
|
||||||
- **Built for the AEC industry:** Speckle connectors are plugins for the most common software used in the industry such as Revit, Rhino, Grasshopper, AutoCAD, Civil 3D, Excel, Unreal Engine, Unity, QGIS, Blender and more!
|
|
||||||
|
|
||||||
### Try Speckle now!
|
|
||||||
|
|
||||||
Give Speckle a try in no time by:
|
|
||||||
|
|
||||||
- [](https://app.speckle.systems) ⇒ creating an account at our public server
|
|
||||||
- [](https://marketplace.digitalocean.com/apps/speckle-server?refcode=947a2b5d7dc1) ⇒ deploying an instance in 1 click
|
|
||||||
|
|
||||||
### Resources
|
|
||||||
|
|
||||||
- [](https://speckle.community) for help, feature requests or just to hang with other speckle enthusiasts, check out our community forum!
|
|
||||||
- [](https://speckle.systems) our tutorials portal is full of resources to get you started using Speckle
|
|
||||||
- [](https://speckle.guide/dev/) reference on almost any end-user and developer functionality
|
|
||||||
|
|
||||||
|
<p align="center"><a href="https://codecov.io/gh/specklesystems/specklepy"><img src="https://codecov.io/gh/specklesystems/specklepy/branch/main/graph/badge.svg?token=8KQFL5N0YF" alt="Codecov"></a></p>
|
||||||
|
|
||||||
# Repo structure
|
# Repo structure
|
||||||
|
|
||||||
|
|||||||
Generated
+22
-4
@@ -1309,6 +1309,24 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-asyncio"
|
||||||
|
version = "0.23.8"
|
||||||
|
description = "Pytest support for asyncio"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"},
|
||||||
|
{file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pytest = ">=7.0.0,<9"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
|
||||||
|
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest-cov"
|
name = "pytest-cov"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
@@ -1717,13 +1735,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "virtualenv"
|
name = "virtualenv"
|
||||||
version = "20.27.0"
|
version = "20.27.1"
|
||||||
description = "Virtual Python Environment builder"
|
description = "Virtual Python Environment builder"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"},
|
{file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"},
|
||||||
{file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"},
|
{file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2019,4 +2037,4 @@ propcache = ">=0.2.0"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.8.0, <4.0"
|
python-versions = ">=3.8.0, <4.0"
|
||||||
content-hash = "3c1df591124eff9dab25ffc2f5678ded27aed3e68e58bf3c66ceb0edafe35e4b"
|
content-hash = "4c914ee1a14f24b46dfdd0718e340a021c50f88a4628cec91f62cafddb2240d5"
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ httpx = "^0.25.0"
|
|||||||
black = "23.11.0"
|
black = "23.11.0"
|
||||||
isort = "^5.7.0"
|
isort = "^5.7.0"
|
||||||
pytest = "^7.1.3"
|
pytest = "^7.1.3"
|
||||||
|
pytest-asyncio = "^0.23.0"
|
||||||
pytest-ordering = "^0.6"
|
pytest-ordering = "^0.6"
|
||||||
pytest-cov = "^3.0.0"
|
pytest-cov = "^3.0.0"
|
||||||
devtools = "^0.8.0"
|
devtools = "^0.8.0"
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ class AutomationContext:
|
|||||||
query = gql(
|
query = gql(
|
||||||
"""
|
"""
|
||||||
mutation AutomateFunctionRunStatusReport(
|
mutation AutomateFunctionRunStatusReport(
|
||||||
|
$projectId: String!
|
||||||
$functionRunId: String!
|
$functionRunId: String!
|
||||||
$status: AutomateRunStatus!
|
$status: AutomateRunStatus!
|
||||||
$statusMessage: String
|
$statusMessage: String
|
||||||
@@ -213,6 +214,7 @@ class AutomationContext:
|
|||||||
$contextView: String
|
$contextView: String
|
||||||
){
|
){
|
||||||
automateFunctionRunStatusReport(input: {
|
automateFunctionRunStatusReport(input: {
|
||||||
|
projectId: $projectId
|
||||||
functionRunId: $functionRunId
|
functionRunId: $functionRunId
|
||||||
status: $status
|
status: $status
|
||||||
statusMessage: $statusMessage
|
statusMessage: $statusMessage
|
||||||
@@ -236,6 +238,7 @@ class AutomationContext:
|
|||||||
object_results = None
|
object_results = None
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
|
"projectId": self.automation_run_data.project_id,
|
||||||
"functionRunId": self.automation_run_data.function_run_id,
|
"functionRunId": self.automation_run_data.function_run_id,
|
||||||
"status": self.run_status.value,
|
"status": self.run_status.value,
|
||||||
"statusMessage": self._automation_result.status_message,
|
"statusMessage": self._automation_result.status_message,
|
||||||
@@ -355,6 +358,24 @@ class AutomationContext:
|
|||||||
visual_overrides,
|
visual_overrides,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def attach_success_to_objects(
|
||||||
|
self,
|
||||||
|
category: str,
|
||||||
|
object_ids: Union[str, List[str]],
|
||||||
|
message: Optional[str] = None,
|
||||||
|
metadata: Optional[Dict[str, Any]] = None,
|
||||||
|
visual_overrides: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> None:
|
||||||
|
"""Add a new success case to the run results."""
|
||||||
|
self.attach_result_to_objects(
|
||||||
|
ObjectResultLevel.SUCCESS,
|
||||||
|
category,
|
||||||
|
object_ids,
|
||||||
|
message,
|
||||||
|
metadata,
|
||||||
|
visual_overrides,
|
||||||
|
)
|
||||||
|
|
||||||
def attach_info_to_objects(
|
def attach_info_to_objects(
|
||||||
self,
|
self,
|
||||||
category: str,
|
category: str,
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class AutomationStatus(str, Enum):
|
|||||||
class ObjectResultLevel(str, Enum):
|
class ObjectResultLevel(str, Enum):
|
||||||
"""Possible status message levels for object reports."""
|
"""Possible status message levels for object reports."""
|
||||||
|
|
||||||
|
SUCCESS = "SUCCESS"
|
||||||
INFO = "INFO"
|
INFO = "INFO"
|
||||||
WARNING = "WARNING"
|
WARNING = "WARNING"
|
||||||
ERROR = "ERROR"
|
ERROR = "ERROR"
|
||||||
|
|||||||
+52
-14
@@ -2,11 +2,16 @@ from deprecated import deprecated
|
|||||||
|
|
||||||
from specklepy.api.credentials import Account
|
from specklepy.api.credentials import Account
|
||||||
from specklepy.api.resources import (
|
from specklepy.api.resources import (
|
||||||
active_user,
|
ActiveUserResource,
|
||||||
|
ModelResource,
|
||||||
|
OtherUserResource,
|
||||||
|
ProjectInviteResource,
|
||||||
|
ProjectResource,
|
||||||
|
SubscriptionResource,
|
||||||
|
VersionResource,
|
||||||
branch,
|
branch,
|
||||||
commit,
|
commit,
|
||||||
object,
|
object,
|
||||||
other_user,
|
|
||||||
server,
|
server,
|
||||||
stream,
|
stream,
|
||||||
subscriptions,
|
subscriptions,
|
||||||
@@ -67,29 +72,62 @@ class SpeckleClient(CoreSpeckleClient):
|
|||||||
self.server = server.Resource(
|
self.server = server.Resource(
|
||||||
account=self.account, basepath=self.url, client=self.httpclient
|
account=self.account, basepath=self.url, client=self.httpclient
|
||||||
)
|
)
|
||||||
|
|
||||||
server_version = None
|
server_version = None
|
||||||
try:
|
try:
|
||||||
server_version = self.server.version()
|
server_version = self.server.version()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
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.version = VersionResource(
|
||||||
|
account=self.account,
|
||||||
|
basepath=self.url,
|
||||||
|
client=self.httpclient,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
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(
|
self.user = user.Resource(
|
||||||
account=self.account,
|
account=self.account,
|
||||||
basepath=self.url,
|
basepath=self.url,
|
||||||
client=self.httpclient,
|
client=self.httpclient,
|
||||||
server_version=server_version,
|
server_version=server_version,
|
||||||
)
|
)
|
||||||
self.other_user = other_user.Resource(
|
|
||||||
account=self.account,
|
|
||||||
basepath=self.url,
|
|
||||||
client=self.httpclient,
|
|
||||||
server_version=server_version,
|
|
||||||
)
|
|
||||||
self.active_user = active_user.Resource(
|
|
||||||
account=self.account,
|
|
||||||
basepath=self.url,
|
|
||||||
client=self.httpclient,
|
|
||||||
server_version=server_version,
|
|
||||||
)
|
|
||||||
self.stream = stream.Resource(
|
self.stream = stream.Resource(
|
||||||
account=self.account,
|
account=self.account,
|
||||||
basepath=self.url,
|
basepath=self.url,
|
||||||
|
|||||||
@@ -1,9 +1,41 @@
|
|||||||
import pkgutil
|
from specklepy.api.resources.current.active_user_resource import ActiveUserResource
|
||||||
import sys
|
from specklepy.api.resources.current.model_resource import ModelResource
|
||||||
from importlib import import_module
|
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__):
|
__all__ = [
|
||||||
imported_module = import_module("." + name, package=__name__)
|
"ActiveUserResource",
|
||||||
|
"ModelResource",
|
||||||
if hasattr(imported_module, "Resource"):
|
"OtherUserResource",
|
||||||
setattr(sys.modules[__name__], name, imported_module)
|
"ProjectInviteResource",
|
||||||
|
"ProjectResource",
|
||||||
|
"ServerResource",
|
||||||
|
"SubscriptionResource",
|
||||||
|
"VersionResource",
|
||||||
|
"active_user",
|
||||||
|
"branch",
|
||||||
|
"commit",
|
||||||
|
"object",
|
||||||
|
"other_user",
|
||||||
|
"server",
|
||||||
|
"stream",
|
||||||
|
"subscriptions",
|
||||||
|
"user",
|
||||||
|
]
|
||||||
|
|||||||
+66
-24
@@ -1,12 +1,25 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional, overload
|
||||||
|
|
||||||
from specklepy.api.models import PendingStreamCollaborator, User
|
from deprecated import deprecated
|
||||||
from specklepy.core.api.resources.active_user import Resource as CoreResource
|
|
||||||
|
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
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
|
||||||
class Resource(CoreResource):
|
class ActiveUserResource(CoreResource):
|
||||||
"""API Access class for users. This class provides methods to get and update
|
"""API Access class for users. This class provides methods to get and update
|
||||||
the user profile, fetch user activity, and manage pending stream invitations."""
|
the user profile, fetch user activity, and manage pending stream invitations."""
|
||||||
|
|
||||||
@@ -19,37 +32,64 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
self.schema = User
|
self.schema = User
|
||||||
|
|
||||||
def get(self) -> User:
|
def get(self) -> Optional[User]:
|
||||||
"""Gets the profile of the current authenticated user's profile
|
metrics.track(metrics.SDK, self.account, {"name": "Active User Get"})
|
||||||
(as extracted from the authorization header).
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
User -- the retrieved user
|
|
||||||
"""
|
|
||||||
metrics.track(metrics.SDK, custom_props={"name": "User Active Get"})
|
|
||||||
return super().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,
|
||||||
|
) -> User:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def update(self, *, input: UserUpdateInput) -> User:
|
||||||
|
...
|
||||||
|
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
company: Optional[str] = None,
|
company: Optional[str] = None,
|
||||||
bio: Optional[str] = None,
|
bio: Optional[str] = None,
|
||||||
avatar: Optional[str] = None,
|
avatar: Optional[str] = None,
|
||||||
):
|
*,
|
||||||
"""Updates your user profile. All arguments are optional.
|
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,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
Args:
|
def get_projects(
|
||||||
name (Optional[str]): The user's name.
|
self,
|
||||||
company (Optional[str]): The company the user works for.
|
*,
|
||||||
bio (Optional[str]): A brief user biography.
|
limit: int = 25,
|
||||||
avatar (Optional[str]): A URL to an avatar image for the user.
|
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)
|
||||||
|
|
||||||
Returns @deprecated(version=DEPRECATION_VERSION, reason=DEPRECATION_TEXT):
|
def get_project_invites(self) -> List[PendingStreamCollaborator]:
|
||||||
bool -- True if your profile was updated successfully
|
metrics.track(
|
||||||
"""
|
metrics.SDK, self.account, {"name": "Active User Get Project Invites"}
|
||||||
metrics.track(metrics.SDK, self.account, {"name": "User Active Update"})
|
)
|
||||||
return super().update(name, company, bio, avatar)
|
return super().get_project_invites()
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def activity(
|
def activity(
|
||||||
self,
|
self,
|
||||||
limit: int = 20,
|
limit: int = 20,
|
||||||
@@ -78,6 +118,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "User Active Activity"})
|
metrics.track(metrics.SDK, self.account, {"name": "User Active Activity"})
|
||||||
return super().activity(limit, action_type, before, after, cursor)
|
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]:
|
def get_all_pending_invites(self) -> List[PendingStreamCollaborator]:
|
||||||
"""Fetches all of the current user's pending stream invitations.
|
"""Fetches all of the current user's pending stream invitations.
|
||||||
|
|
||||||
@@ -89,6 +130,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
return super().get_all_pending_invites()
|
return super().get_all_pending_invites()
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get_pending_invite(
|
def get_pending_invite(
|
||||||
self, stream_id: str, token: Optional[str] = None
|
self, stream_id: str, token: Optional[str] = None
|
||||||
) -> Optional[PendingStreamCollaborator]:
|
) -> Optional[PendingStreamCollaborator]:
|
||||||
@@ -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)
|
||||||
+31
-14
@@ -1,13 +1,23 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
from specklepy.api.models import ActivityCollection, LimitedUser
|
from deprecated import deprecated
|
||||||
from specklepy.core.api.resources.other_user import Resource as CoreResource
|
|
||||||
|
from specklepy.core.api.models import (
|
||||||
|
ActivityCollection,
|
||||||
|
LimitedUser,
|
||||||
|
UserSearchResultCollection,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources import OtherUserResource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
|
|
||||||
class Resource(CoreResource):
|
class OtherUserResource(CoreResource):
|
||||||
"""
|
"""
|
||||||
Provides API access to other users' profiles and activities on the platform.
|
Provides API access to other users' profiles and activities on the platform.
|
||||||
This class enables fetching limited information about users, searching for users by name or email,
|
This class enables fetching limited information about users, searching for users by name or email,
|
||||||
@@ -19,23 +29,29 @@ class Resource(CoreResource):
|
|||||||
account=account,
|
account=account,
|
||||||
basepath=basepath,
|
basepath=basepath,
|
||||||
client=client,
|
client=client,
|
||||||
server_version=server_version,
|
server_version=(server_version,),
|
||||||
)
|
)
|
||||||
self.schema = LimitedUser
|
self.schema = LimitedUser
|
||||||
|
|
||||||
def get(self, id: str) -> LimitedUser:
|
def get(self, id: str) -> Optional[LimitedUser]:
|
||||||
"""
|
|
||||||
Retrieves the profile of a user specified by their user ID.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
id (str): The unique identifier of the user.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
LimitedUser: The profile of the user with limited information.
|
|
||||||
"""
|
|
||||||
metrics.track(metrics.SDK, self.account, {"name": "Other User Get"})
|
metrics.track(metrics.SDK, self.account, {"name": "Other User Get"})
|
||||||
return super().get(id)
|
return super().get(id)
|
||||||
|
|
||||||
|
def user_search(
|
||||||
|
self,
|
||||||
|
query: str,
|
||||||
|
*,
|
||||||
|
limit: int = 25,
|
||||||
|
cursor: Optional[str] = None,
|
||||||
|
archived: bool = False,
|
||||||
|
emailOnly: bool = False,
|
||||||
|
) -> UserSearchResultCollection:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Other User Search"})
|
||||||
|
return super().user_search(
|
||||||
|
query, limit=limit, cursor=cursor, archived=archived, emailOnly=emailOnly
|
||||||
|
)
|
||||||
|
|
||||||
|
@deprecated(reason="Use user_search instead", version=FE1_DEPRECATION_VERSION)
|
||||||
def search(
|
def search(
|
||||||
self, search_query: str, limit: int = 25
|
self, search_query: str, limit: int = 25
|
||||||
) -> Union[List[LimitedUser], SpeckleException]:
|
) -> Union[List[LimitedUser], SpeckleException]:
|
||||||
@@ -59,6 +75,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Other User Search"})
|
metrics.track(metrics.SDK, self.account, {"name": "Other User Search"})
|
||||||
return super().search(search_query, limit)
|
return super().search(search_query, limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def activity(
|
def activity(
|
||||||
self,
|
self,
|
||||||
user_id: str,
|
user_id: str,
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
from typing import Any, Optional, Tuple
|
||||||
|
|
||||||
|
from gql import Client
|
||||||
|
|
||||||
|
from specklepy.core.api.credentials import Account
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectInviteCreateInput,
|
||||||
|
ProjectInviteUseInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import PendingStreamCollaborator, ProjectWithTeam
|
||||||
|
from specklepy.core.api.resources import ProjectInviteResource as CoreResource
|
||||||
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectInviteResource(CoreResource):
|
||||||
|
"""API Access class for project invites"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
account: Account,
|
||||||
|
basepath: str,
|
||||||
|
client: Client,
|
||||||
|
server_version: Optional[Tuple[Any, ...]],
|
||||||
|
) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self, project_id: str, input: ProjectInviteCreateInput
|
||||||
|
) -> ProjectWithTeam:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Invite Create"})
|
||||||
|
return super().create(project_id, input)
|
||||||
|
|
||||||
|
def use(self, input: ProjectInviteUseInput) -> bool:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Invite Use"})
|
||||||
|
return super().use(input)
|
||||||
|
|
||||||
|
def get(
|
||||||
|
self, project_id: str, token: Optional[str]
|
||||||
|
) -> Optional[PendingStreamCollaborator]:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Invite Get"})
|
||||||
|
return super().get(project_id, token)
|
||||||
|
|
||||||
|
def cancel(
|
||||||
|
self,
|
||||||
|
project_id: str,
|
||||||
|
invite_id: str,
|
||||||
|
) -> ProjectWithTeam:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Invite Cancel"})
|
||||||
|
return super().cancel(project_id, invite_id)
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectCreateInput,
|
||||||
|
ProjectModelsFilter,
|
||||||
|
ProjectUpdateInput,
|
||||||
|
ProjectUpdateRoleInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import Project, ProjectWithModels, ProjectWithTeam
|
||||||
|
from specklepy.core.api.resources import ProjectResource as CoreResource
|
||||||
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectResource(CoreResource):
|
||||||
|
"""API Access class for projects"""
|
||||||
|
|
||||||
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get(self, project_id: str) -> Project:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Get "})
|
||||||
|
return super().get(project_id)
|
||||||
|
|
||||||
|
def get_with_models(
|
||||||
|
self,
|
||||||
|
project_id: str,
|
||||||
|
*,
|
||||||
|
models_limit: int = 25,
|
||||||
|
models_cursor: Optional[str] = None,
|
||||||
|
models_filter: Optional[ProjectModelsFilter] = None,
|
||||||
|
) -> ProjectWithModels:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Get With Models"})
|
||||||
|
return super().get_with_models(
|
||||||
|
project_id,
|
||||||
|
models_limit=models_limit,
|
||||||
|
models_cursor=models_cursor,
|
||||||
|
models_filter=models_filter,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_with_team(self, project_id: str) -> ProjectWithTeam:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Get With Team"})
|
||||||
|
return super().get_with_team(project_id)
|
||||||
|
|
||||||
|
def create(self, input: ProjectCreateInput) -> Project:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Create"})
|
||||||
|
return super().create(input)
|
||||||
|
|
||||||
|
def update(self, input: ProjectUpdateInput) -> Project:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Update"})
|
||||||
|
return super().update(input)
|
||||||
|
|
||||||
|
def delete(self, project_id: str) -> bool:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Delete"})
|
||||||
|
return super().delete(project_id)
|
||||||
|
|
||||||
|
def update_role(self, input: ProjectUpdateRoleInput) -> ProjectWithTeam:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Project Update Role"})
|
||||||
|
return super().update_role(input)
|
||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Tuple
|
||||||
|
|
||||||
from specklepy.api.models import ServerInfo
|
from specklepy.api.models import ServerInfo
|
||||||
from specklepy.core.api.resources.server import Resource as CoreResource
|
from specklepy.core.api.resources import ServerResource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
|
||||||
class Resource(CoreResource):
|
class ServerResource(CoreResource):
|
||||||
"""API Access class for the server"""
|
"""API Access class for the server"""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client) -> None:
|
def __init__(self, account, basepath, client) -> None:
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
from typing import Callable, Optional, Sequence
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing_extensions import TypeVar
|
||||||
|
|
||||||
|
from specklepy.core.api.models import (
|
||||||
|
ProjectModelsUpdatedMessage,
|
||||||
|
ProjectUpdatedMessage,
|
||||||
|
ProjectVersionsUpdatedMessage,
|
||||||
|
UserProjectsUpdatedMessage,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources import SubscriptionResource as CoreResource
|
||||||
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
TEventArgs = TypeVar("TEventArgs", bound=BaseModel)
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionResource(CoreResource):
|
||||||
|
def __init__(self, account, basepath, client) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def user_projects_updated(
|
||||||
|
self, callback: Callable[[UserProjectsUpdatedMessage], None]
|
||||||
|
) -> None:
|
||||||
|
metrics.track(
|
||||||
|
metrics.SDK, self.account, {"name": "Subscription Project Models Updated"}
|
||||||
|
)
|
||||||
|
return await super().user_projects_updated(callback)
|
||||||
|
|
||||||
|
async def project_models_updated(
|
||||||
|
self,
|
||||||
|
callback: Callable[[ProjectModelsUpdatedMessage], None],
|
||||||
|
id: str,
|
||||||
|
*,
|
||||||
|
model_ids: Optional[Sequence[str]] = None,
|
||||||
|
) -> None:
|
||||||
|
metrics.track(
|
||||||
|
metrics.SDK, self.account, {"name": "Subscription Project Models Updated"}
|
||||||
|
)
|
||||||
|
return await super().project_models_updated(callback, id, model_ids=model_ids)
|
||||||
|
|
||||||
|
async def project_updated(
|
||||||
|
self,
|
||||||
|
callback: Callable[[ProjectUpdatedMessage], None],
|
||||||
|
id: str,
|
||||||
|
) -> None:
|
||||||
|
metrics.track(
|
||||||
|
metrics.SDK, self.account, {"name": "Subscription Project Updated"}
|
||||||
|
)
|
||||||
|
return await super().project_updated(callback, id)
|
||||||
|
|
||||||
|
async def project_versions_updated(
|
||||||
|
self,
|
||||||
|
callback: Callable[[ProjectVersionsUpdatedMessage], None],
|
||||||
|
id: str,
|
||||||
|
) -> None:
|
||||||
|
metrics.track(
|
||||||
|
metrics.SDK, self.account, {"name": "Subscription Project Versions Updated"}
|
||||||
|
)
|
||||||
|
return await super().project_versions_updated(callback, id)
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from specklepy.core.api.inputs.model_inputs import ModelVersionsFilter
|
||||||
|
from specklepy.core.api.inputs.version_inputs import (
|
||||||
|
CreateVersionInput,
|
||||||
|
DeleteVersionsInput,
|
||||||
|
MarkReceivedVersionInput,
|
||||||
|
MoveVersionsInput,
|
||||||
|
UpdateVersionInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import ResourceCollection, Version
|
||||||
|
from specklepy.core.api.resources import VersionResource as CoreResource
|
||||||
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
|
||||||
|
class VersionResource(CoreResource):
|
||||||
|
"""API Access class for model versions"""
|
||||||
|
|
||||||
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get(self, version_id: str, project_id: str) -> Version:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Get"})
|
||||||
|
return super().get(version_id, project_id)
|
||||||
|
|
||||||
|
def get_versions(
|
||||||
|
self,
|
||||||
|
model_id: str,
|
||||||
|
project_id: str,
|
||||||
|
*,
|
||||||
|
limit: int = 25,
|
||||||
|
cursor: Optional[str] = None,
|
||||||
|
filter: Optional[ModelVersionsFilter] = None,
|
||||||
|
) -> ResourceCollection[Version]:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Get Versions"})
|
||||||
|
return super().get_versions(
|
||||||
|
model_id, project_id, limit=limit, cursor=cursor, filter=filter
|
||||||
|
)
|
||||||
|
|
||||||
|
def create(self, input: CreateVersionInput) -> str:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Create"})
|
||||||
|
return super().create(input)
|
||||||
|
|
||||||
|
def update(self, input: UpdateVersionInput) -> Version:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Update"})
|
||||||
|
return super().update(input)
|
||||||
|
|
||||||
|
def move_to_model(self, input: MoveVersionsInput) -> str:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Move To Model"})
|
||||||
|
return super().move_to_model(input)
|
||||||
|
|
||||||
|
def delete(self, input: DeleteVersionsInput) -> bool:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Delete"})
|
||||||
|
return super().delete(input)
|
||||||
|
|
||||||
|
def received(self, input: MarkReceivedVersionInput) -> bool:
|
||||||
|
metrics.track(metrics.SDK, self.account, {"name": "Version Received"})
|
||||||
|
return super().received(input)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.api.resources import ActiveUserResource
|
||||||
|
from specklepy.core.api.models.deprecated import FE1_DEPRECATION_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason="Renamed to ActiveUserResource", version=FE1_DEPRECATION_VERSION)
|
||||||
|
class Resource(ActiveUserResource):
|
||||||
|
"""Renamed to ActiveUserResource"""
|
||||||
+12
-1
@@ -1,7 +1,13 @@
|
|||||||
from typing import Optional, Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
from specklepy.api.models import Branch
|
from specklepy.api.models import Branch
|
||||||
from specklepy.core.api.resources.branch import Resource as CoreResource
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.deprecated.branch import Resource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
@@ -17,6 +23,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
self.schema = Branch
|
self.schema = Branch
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(
|
def create(
|
||||||
self, stream_id: str, name: str, description: str = "No description provided"
|
self, stream_id: str, name: str, description: str = "No description provided"
|
||||||
) -> str:
|
) -> str:
|
||||||
@@ -32,6 +39,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Branch Create"})
|
metrics.track(metrics.SDK, self.account, {"name": "Branch Create"})
|
||||||
return super().create(stream_id, name, description)
|
return super().create(stream_id, name, description)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(
|
def get(
|
||||||
self, stream_id: str, name: str, commits_limit: int = 10
|
self, stream_id: str, name: str, commits_limit: int = 10
|
||||||
) -> Union[Branch, None, SpeckleException]:
|
) -> Union[Branch, None, SpeckleException]:
|
||||||
@@ -48,6 +56,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Branch Get"})
|
metrics.track(metrics.SDK, self.account, {"name": "Branch Get"})
|
||||||
return super().get(stream_id, name, commits_limit)
|
return super().get(stream_id, name, commits_limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def list(self, stream_id: str, branches_limit: int = 10, commits_limit: int = 10):
|
def list(self, stream_id: str, branches_limit: int = 10, commits_limit: int = 10):
|
||||||
"""Get a list of branches from a given stream
|
"""Get a list of branches from a given stream
|
||||||
|
|
||||||
@@ -62,6 +71,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Branch List"})
|
metrics.track(metrics.SDK, self.account, {"name": "Branch List"})
|
||||||
return super().list(stream_id, branches_limit, commits_limit)
|
return super().list(stream_id, branches_limit, commits_limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -83,6 +93,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Branch Update"})
|
metrics.track(metrics.SDK, self.account, {"name": "Branch Update"})
|
||||||
return super().update(stream_id, branch_id, name, description)
|
return super().update(stream_id, branch_id, name, description)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def delete(self, stream_id: str, branch_id: str):
|
def delete(self, stream_id: str, branch_id: str):
|
||||||
"""Delete a branch
|
"""Delete a branch
|
||||||
|
|
||||||
+13
-1
@@ -1,7 +1,13 @@
|
|||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
from specklepy.api.models import Commit
|
from specklepy.api.models import Commit
|
||||||
from specklepy.core.api.resources.commit import Resource as CoreResource
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.deprecated.commit import Resource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
@@ -17,6 +23,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
self.schema = Commit
|
self.schema = Commit
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(self, stream_id: str, commit_id: str) -> Commit:
|
def get(self, stream_id: str, commit_id: str) -> Commit:
|
||||||
"""
|
"""
|
||||||
Gets a commit given a stream and the commit id
|
Gets a commit given a stream and the commit id
|
||||||
@@ -31,6 +38,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Commit Get"})
|
metrics.track(metrics.SDK, self.account, {"name": "Commit Get"})
|
||||||
return super().get(stream_id, commit_id)
|
return super().get(stream_id, commit_id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def list(self, stream_id: str, limit: int = 10) -> List[Commit]:
|
def list(self, stream_id: str, limit: int = 10) -> List[Commit]:
|
||||||
"""
|
"""
|
||||||
Get a list of commits on a given stream
|
Get a list of commits on a given stream
|
||||||
@@ -45,6 +53,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Commit List"})
|
metrics.track(metrics.SDK, self.account, {"name": "Commit List"})
|
||||||
return super().list(stream_id, limit)
|
return super().list(stream_id, limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(
|
def create(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -77,6 +86,7 @@ class Resource(CoreResource):
|
|||||||
stream_id, object_id, branch_name, message, source_application, parents
|
stream_id, object_id, branch_name, message, source_application, parents
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update(self, stream_id: str, commit_id: str, message: str) -> bool:
|
def update(self, stream_id: str, commit_id: str, message: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Update a commit
|
Update a commit
|
||||||
@@ -93,6 +103,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Commit Update"})
|
metrics.track(metrics.SDK, self.account, {"name": "Commit Update"})
|
||||||
return super().update(stream_id, commit_id, message)
|
return super().update(stream_id, commit_id, message)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def delete(self, stream_id: str, commit_id: str) -> bool:
|
def delete(self, stream_id: str, commit_id: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Delete a commit
|
Delete a commit
|
||||||
@@ -108,6 +119,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Commit Delete"})
|
metrics.track(metrics.SDK, self.account, {"name": "Commit Delete"})
|
||||||
return super().delete(stream_id, commit_id)
|
return super().delete(stream_id, commit_id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def received(
|
def received(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
+9
-1
@@ -1,6 +1,12 @@
|
|||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from specklepy.core.api.resources.object import Resource as CoreResource
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.deprecated.object import Resource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.objects.base import Base
|
from specklepy.objects.base import Base
|
||||||
|
|
||||||
@@ -16,6 +22,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
self.schema = Base
|
self.schema = Base
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(self, stream_id: str, object_id: str) -> Base:
|
def get(self, stream_id: str, object_id: str) -> Base:
|
||||||
"""
|
"""
|
||||||
Get a stream object
|
Get a stream object
|
||||||
@@ -30,6 +37,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Object Get"})
|
metrics.track(metrics.SDK, self.account, {"name": "Object Get"})
|
||||||
return super().get(stream_id, object_id)
|
return super().get(stream_id, object_id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(self, stream_id: str, objects: List[Dict]) -> str:
|
def create(self, stream_id: str, objects: List[Dict]) -> str:
|
||||||
"""
|
"""
|
||||||
Not advised - generally, you want to use `operations.send()`.
|
Not advised - generally, you want to use `operations.send()`.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.api.resources import OtherUserResource
|
||||||
|
from specklepy.core.api.models.deprecated import FE1_DEPRECATION_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason="Renamed to OtherUserResource", version=FE1_DEPRECATION_VERSION)
|
||||||
|
class Resource(OtherUserResource):
|
||||||
|
"""
|
||||||
|
Renamed to OtherUserResource
|
||||||
|
"""
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.api.resources import ServerResource
|
||||||
|
from specklepy.core.api.models.deprecated import FE1_DEPRECATION_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason="Renamed to ActiveUserResource", version=FE1_DEPRECATION_VERSION)
|
||||||
|
class Resource(ServerResource):
|
||||||
|
"""Renamed to ServerResource"""
|
||||||
+22
-1
@@ -1,8 +1,14 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
from specklepy.api.models import PendingStreamCollaborator, Stream
|
from specklepy.api.models import PendingStreamCollaborator, Stream
|
||||||
from specklepy.core.api.resources.stream import Resource as CoreResource
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.deprecated.stream import Resource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
|
|
||||||
|
|
||||||
@@ -19,6 +25,7 @@ class Resource(CoreResource):
|
|||||||
|
|
||||||
self.schema = Stream
|
self.schema = Stream
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(self, id: str, branch_limit: int = 10, commit_limit: int = 10) -> Stream:
|
def get(self, id: str, branch_limit: int = 10, commit_limit: int = 10) -> Stream:
|
||||||
"""Get the specified stream from the server
|
"""Get the specified stream from the server
|
||||||
|
|
||||||
@@ -33,6 +40,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Get"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Get"})
|
||||||
return super().get(id, branch_limit, commit_limit)
|
return super().get(id, branch_limit, commit_limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def list(self, stream_limit: int = 10) -> List[Stream]:
|
def list(self, stream_limit: int = 10) -> List[Stream]:
|
||||||
"""Get a list of the user's streams
|
"""Get a list of the user's streams
|
||||||
|
|
||||||
@@ -45,6 +53,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream List"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream List"})
|
||||||
return super().list(stream_limit)
|
return super().list(stream_limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(
|
def create(
|
||||||
self,
|
self,
|
||||||
name: str = "Anonymous Python Stream",
|
name: str = "Anonymous Python Stream",
|
||||||
@@ -65,6 +74,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Create"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Create"})
|
||||||
return super().create(name, description, is_public)
|
return super().create(name, description, is_public)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
id: str,
|
id: str,
|
||||||
@@ -87,6 +97,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Update"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Update"})
|
||||||
return super().update(id, name, description, is_public)
|
return super().update(id, name, description, is_public)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def delete(self, id: str) -> bool:
|
def delete(self, id: str) -> bool:
|
||||||
"""Delete a stream given its id
|
"""Delete a stream given its id
|
||||||
|
|
||||||
@@ -99,6 +110,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Delete"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Delete"})
|
||||||
return super().delete(id)
|
return super().delete(id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def search(
|
def search(
|
||||||
self,
|
self,
|
||||||
search_query: str,
|
search_query: str,
|
||||||
@@ -120,6 +132,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Search"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Search"})
|
||||||
return super().search(search_query, limit, branch_limit, commit_limit)
|
return super().search(search_query, limit, branch_limit, commit_limit)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def favorite(self, stream_id: str, favorited: bool = True):
|
def favorite(self, stream_id: str, favorited: bool = True):
|
||||||
"""Favorite or unfavorite the given stream.
|
"""Favorite or unfavorite the given stream.
|
||||||
|
|
||||||
@@ -134,6 +147,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Favorite"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Favorite"})
|
||||||
return super().favorite(stream_id, favorited)
|
return super().favorite(stream_id, favorited)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get_all_pending_invites(
|
def get_all_pending_invites(
|
||||||
self, stream_id: str
|
self, stream_id: str
|
||||||
) -> List[PendingStreamCollaborator]:
|
) -> List[PendingStreamCollaborator]:
|
||||||
@@ -152,6 +166,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Get"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Get"})
|
||||||
return super().get_all_pending_invites(stream_id)
|
return super().get_all_pending_invites(stream_id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite(
|
def invite(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -179,6 +194,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Create"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Create"})
|
||||||
return super().invite(stream_id, email, user_id, role, message)
|
return super().invite(stream_id, email, user_id, role, message)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite_batch(
|
def invite_batch(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -205,6 +221,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Batch Create"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Batch Create"})
|
||||||
return super().invite_batch(stream_id, emails, user_ids, message)
|
return super().invite_batch(stream_id, emails, user_ids, message)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite_cancel(self, stream_id: str, invite_id: str) -> bool:
|
def invite_cancel(self, stream_id: str, invite_id: str) -> bool:
|
||||||
"""Cancel an existing stream invite
|
"""Cancel an existing stream invite
|
||||||
|
|
||||||
@@ -220,6 +237,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Cancel"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Invite Cancel"})
|
||||||
return super().invite_cancel(stream_id, invite_id)
|
return super().invite_cancel(stream_id, invite_id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite_use(self, stream_id: str, token: str, accept: bool = True) -> bool:
|
def invite_use(self, stream_id: str, token: str, accept: bool = True) -> bool:
|
||||||
"""Accept or decline a stream invite
|
"""Accept or decline a stream invite
|
||||||
|
|
||||||
@@ -237,6 +255,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Invite Use"})
|
metrics.track(metrics.SDK, self.account, {"name": "Invite Use"})
|
||||||
return super().invite_use(stream_id, token, accept)
|
return super().invite_use(stream_id, token, accept)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update_permission(self, stream_id: str, user_id: str, role: str):
|
def update_permission(self, stream_id: str, user_id: str, role: str):
|
||||||
"""Updates permissions for a user on a given stream
|
"""Updates permissions for a user on a given stream
|
||||||
|
|
||||||
@@ -257,6 +276,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
return super().update_permission(stream_id, user_id, role)
|
return super().update_permission(stream_id, user_id, role)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def revoke_permission(self, stream_id: str, user_id: str):
|
def revoke_permission(self, stream_id: str, user_id: str):
|
||||||
"""Revoke permissions from a user on a given stream
|
"""Revoke permissions from a user on a given stream
|
||||||
|
|
||||||
@@ -270,6 +290,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Stream Permission Revoke"})
|
metrics.track(metrics.SDK, self.account, {"name": "Stream Permission Revoke"})
|
||||||
return super().revoke_permission(stream_id, user_id)
|
return super().revoke_permission(stream_id, user_id)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def activity(
|
def activity(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
+13
-16
@@ -1,24 +1,17 @@
|
|||||||
from functools import wraps
|
|
||||||
from typing import Callable, Dict, List, Optional, Union
|
from typing import Callable, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from graphql import DocumentNode
|
from graphql import DocumentNode
|
||||||
|
|
||||||
from specklepy.core.api.resources.subscriptions import Resource as CoreResource
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.current.subscription_resource import check_wsclient
|
||||||
|
from specklepy.core.api.resources.deprecated.subscriptions import (
|
||||||
|
Resource as CoreResource,
|
||||||
|
)
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
|
||||||
|
|
||||||
|
|
||||||
def check_wsclient(function):
|
|
||||||
@wraps(function)
|
|
||||||
async def check_wsclient_wrapper(self, *args, **kwargs):
|
|
||||||
if self.client is None:
|
|
||||||
raise SpeckleException(
|
|
||||||
"You must authenticate before you can subscribe to events"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return await function(self, *args, **kwargs)
|
|
||||||
|
|
||||||
return check_wsclient_wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class Resource(CoreResource):
|
class Resource(CoreResource):
|
||||||
@@ -31,6 +24,7 @@ class Resource(CoreResource):
|
|||||||
client=client,
|
client=client,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
@check_wsclient
|
@check_wsclient
|
||||||
async def stream_added(self, callback: Optional[Callable] = None):
|
async def stream_added(self, callback: Optional[Callable] = None):
|
||||||
"""Subscribes to new stream added event for your profile.
|
"""Subscribes to new stream added event for your profile.
|
||||||
@@ -46,6 +40,7 @@ class Resource(CoreResource):
|
|||||||
metrics.track(metrics.SDK, self.account, {"name": "Subscription Stream Added"})
|
metrics.track(metrics.SDK, self.account, {"name": "Subscription Stream Added"})
|
||||||
return super().stream_added(callback)
|
return super().stream_added(callback)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
@check_wsclient
|
@check_wsclient
|
||||||
async def stream_updated(self, id: str, callback: Optional[Callable] = None):
|
async def stream_updated(self, id: str, callback: Optional[Callable] = None):
|
||||||
"""
|
"""
|
||||||
@@ -66,6 +61,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
return super().stream_updated(id, callback)
|
return super().stream_updated(id, callback)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
@check_wsclient
|
@check_wsclient
|
||||||
async def stream_removed(self, callback: Optional[Callable] = None):
|
async def stream_removed(self, callback: Optional[Callable] = None):
|
||||||
"""Subscribes to stream removed event for your profile.
|
"""Subscribes to stream removed event for your profile.
|
||||||
@@ -87,6 +83,7 @@ class Resource(CoreResource):
|
|||||||
)
|
)
|
||||||
return super().stream_removed(callback)
|
return super().stream_removed(callback)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
@check_wsclient
|
@check_wsclient
|
||||||
async def subscribe(
|
async def subscribe(
|
||||||
self,
|
self,
|
||||||
+1
-1
@@ -4,7 +4,7 @@ from typing import List, Optional, Union
|
|||||||
from deprecated import deprecated
|
from deprecated import deprecated
|
||||||
|
|
||||||
from specklepy.api.models import PendingStreamCollaborator, User
|
from specklepy.api.models import PendingStreamCollaborator, User
|
||||||
from specklepy.core.api.resources.user import Resource as CoreResource
|
from specklepy.core.api.resources.deprecated.user import Resource as CoreResource
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
@@ -11,12 +11,17 @@ from gql.transport.websockets import WebsocketsTransport
|
|||||||
from specklepy.core.api import resources
|
from specklepy.core.api import resources
|
||||||
from specklepy.core.api.credentials import Account, get_account_from_token
|
from specklepy.core.api.credentials import Account, get_account_from_token
|
||||||
from specklepy.core.api.resources import (
|
from specklepy.core.api.resources import (
|
||||||
active_user,
|
ActiveUserResource,
|
||||||
|
ModelResource,
|
||||||
|
OtherUserResource,
|
||||||
|
ProjectInviteResource,
|
||||||
|
ProjectResource,
|
||||||
|
ServerResource,
|
||||||
|
SubscriptionResource,
|
||||||
|
VersionResource,
|
||||||
branch,
|
branch,
|
||||||
commit,
|
commit,
|
||||||
object,
|
object,
|
||||||
other_user,
|
|
||||||
server,
|
|
||||||
stream,
|
stream,
|
||||||
subscriptions,
|
subscriptions,
|
||||||
user,
|
user,
|
||||||
@@ -176,53 +181,81 @@ class SpeckleClient:
|
|||||||
self._init_resources()
|
self._init_resources()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_or_error = self.active_user.get()
|
_ = self.active_user.get()
|
||||||
if isinstance(user_or_error, SpeckleException):
|
except SpeckleException as ex:
|
||||||
if isinstance(user_or_error.exception, TransportServerError):
|
if isinstance(ex.exception, TransportServerError):
|
||||||
raise user_or_error.exception
|
if ex.exception.code == 403:
|
||||||
else:
|
warn(
|
||||||
raise user_or_error
|
SpeckleWarning(
|
||||||
except TransportServerError as ex:
|
"Possibly invalid token - could not authenticate Speckle Client"
|
||||||
if ex.code == 403:
|
f" for server {self.url}"
|
||||||
warn(
|
)
|
||||||
SpeckleWarning(
|
|
||||||
"Possibly invalid token - could not authenticate Speckle Client"
|
|
||||||
f" for server {self.url}"
|
|
||||||
)
|
)
|
||||||
)
|
else:
|
||||||
else:
|
raise ex
|
||||||
raise ex
|
|
||||||
|
|
||||||
def execute_query(self, query: str) -> Dict:
|
def execute_query(self, query: str) -> Dict:
|
||||||
return self.httpclient.execute(query)
|
return self.httpclient.execute(query)
|
||||||
|
|
||||||
def _init_resources(self) -> None:
|
def _init_resources(self) -> None:
|
||||||
self.server = server.Resource(
|
self.server = ServerResource(
|
||||||
account=self.account, basepath=self.url, client=self.httpclient
|
account=self.account, basepath=self.url, client=self.httpclient
|
||||||
)
|
)
|
||||||
|
|
||||||
server_version = None
|
server_version = None
|
||||||
try:
|
try:
|
||||||
server_version = self.server.version()
|
server_version = self.server.version()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
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.version = VersionResource(
|
||||||
|
account=self.account,
|
||||||
|
basepath=self.url,
|
||||||
|
client=self.httpclient,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
self.subscription = SubscriptionResource(
|
||||||
|
account=self.account,
|
||||||
|
basepath=self.ws_url,
|
||||||
|
client=self.wsclient,
|
||||||
|
)
|
||||||
|
# Deprecated Resources
|
||||||
self.user = user.Resource(
|
self.user = user.Resource(
|
||||||
account=self.account,
|
account=self.account,
|
||||||
basepath=self.url,
|
basepath=self.url,
|
||||||
client=self.httpclient,
|
client=self.httpclient,
|
||||||
server_version=server_version,
|
server_version=server_version,
|
||||||
)
|
)
|
||||||
self.other_user = other_user.Resource(
|
|
||||||
account=self.account,
|
|
||||||
basepath=self.url,
|
|
||||||
client=self.httpclient,
|
|
||||||
server_version=server_version,
|
|
||||||
)
|
|
||||||
self.active_user = active_user.Resource(
|
|
||||||
account=self.account,
|
|
||||||
basepath=self.url,
|
|
||||||
client=self.httpclient,
|
|
||||||
server_version=server_version,
|
|
||||||
)
|
|
||||||
self.stream = stream.Resource(
|
self.stream = stream.Resource(
|
||||||
account=self.account,
|
account=self.account,
|
||||||
basepath=self.url,
|
basepath=self.url,
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ from specklepy.transports.sqlite import SQLiteTransport
|
|||||||
|
|
||||||
|
|
||||||
class UserInfo(BaseModel):
|
class UserInfo(BaseModel):
|
||||||
|
id: Optional[str] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
email: Optional[str] = None
|
email: Optional[str] = None
|
||||||
company: Optional[str] = None
|
company: Optional[str] = None
|
||||||
id: Optional[str] = None
|
avatar: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
class Account(BaseModel):
|
class Account(BaseModel):
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectVisibility(str, Enum):
|
||||||
|
PRIVATE = "PRIVATE"
|
||||||
|
PUBLIC = "PUBLIC"
|
||||||
|
UNLISTEd = "UNLISTED"
|
||||||
|
|
||||||
|
|
||||||
|
class UserProjectsUpdatedMessageType(str, Enum):
|
||||||
|
ADDED = "ADDED"
|
||||||
|
REMOVED = "REMOVED"
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectModelsUpdatedMessageType(str, Enum):
|
||||||
|
CREATED = "CREATED"
|
||||||
|
DELETED = "DELETED"
|
||||||
|
UPDATED = "UPDATED"
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectUpdatedMessageType(str, Enum):
|
||||||
|
DELETED = "DELETED"
|
||||||
|
UPDATED = "UPDATED"
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectVersionsUpdatedMessageType(str, Enum):
|
||||||
|
CREATED = "CREATED"
|
||||||
|
DELETED = "DELETED"
|
||||||
|
UPDATED = "UPDATED"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
from typing import Optional, Sequence
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class CreateModelInput(BaseModel):
|
||||||
|
name: str
|
||||||
|
description: Optional[str] = None
|
||||||
|
projectId: str
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteModelInput(BaseModel):
|
||||||
|
id: str
|
||||||
|
projectId: str
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateModelInput(BaseModel):
|
||||||
|
id: str
|
||||||
|
name: Optional[str] = None
|
||||||
|
description: Optional[str] = None
|
||||||
|
projectId: str
|
||||||
|
|
||||||
|
|
||||||
|
class ModelVersionsFilter(BaseModel):
|
||||||
|
priorityIds: Sequence[str]
|
||||||
|
priorityIdsOnly: Optional[bool] = None
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
from typing import Optional, Sequence
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from specklepy.core.api.enums import ProjectVisibility
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectCreateInput(BaseModel):
|
||||||
|
name: Optional[str]
|
||||||
|
description: Optional[str]
|
||||||
|
visibility: Optional[ProjectVisibility]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectInviteCreateInput(BaseModel):
|
||||||
|
email: Optional[str]
|
||||||
|
role: Optional[str]
|
||||||
|
serverRole: Optional[str]
|
||||||
|
userId: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectInviteUseInput(BaseModel):
|
||||||
|
accept: bool
|
||||||
|
projectId: str
|
||||||
|
token: str
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectModelsFilter(BaseModel):
|
||||||
|
contributors: Optional[Sequence[str]] = None
|
||||||
|
excludeIds: Optional[Sequence[str]] = None
|
||||||
|
ids: Optional[Sequence[str]] = None
|
||||||
|
onlyWithVersions: Optional[bool] = None
|
||||||
|
search: Optional[str] = None
|
||||||
|
sourceApps: Optional[Sequence[str]] = None
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectUpdateInput(BaseModel):
|
||||||
|
id: str
|
||||||
|
name: Optional[str] = None
|
||||||
|
description: Optional[str] = None
|
||||||
|
allowPublicComments: Optional[bool] = None
|
||||||
|
visibility: Optional[ProjectVisibility] = None
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectUpdateRoleInput(BaseModel):
|
||||||
|
userId: str
|
||||||
|
projectId: str
|
||||||
|
role: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class UserProjectsFilter(BaseModel):
|
||||||
|
search: str
|
||||||
|
onlyWithRole: Optional[Sequence[str]] = None
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class UserUpdateInput(BaseModel):
|
||||||
|
avatar: Optional[str] = None
|
||||||
|
bio: Optional[str] = None
|
||||||
|
company: Optional[str] = None
|
||||||
|
name: Optional[str] = None
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
from typing import Optional, Sequence
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateVersionInput(BaseModel):
|
||||||
|
versionId: str
|
||||||
|
projectId: str
|
||||||
|
message: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class MoveVersionsInput(BaseModel):
|
||||||
|
targetModelName: str
|
||||||
|
versionIds: Sequence[str]
|
||||||
|
projectId: str
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteVersionsInput(BaseModel):
|
||||||
|
versionIds: Sequence[str]
|
||||||
|
projectId: str
|
||||||
|
|
||||||
|
|
||||||
|
class CreateVersionInput(BaseModel):
|
||||||
|
objectId: str
|
||||||
|
modelId: str
|
||||||
|
projectId: str
|
||||||
|
message: Optional[str] = None
|
||||||
|
sourceApplication: Optional[str] = "py"
|
||||||
|
totalChildrenCount: Optional[int] = None
|
||||||
|
parents: Optional[Sequence[str]] = None
|
||||||
|
|
||||||
|
|
||||||
|
class MarkReceivedVersionInput(BaseModel):
|
||||||
|
versionId: str
|
||||||
|
projectId: str
|
||||||
|
sourceApplication: str
|
||||||
|
message: Optional[str] = None
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
from specklepy.core.api.models.current import (
|
||||||
|
AuthStrategy,
|
||||||
|
LimitedUser,
|
||||||
|
Model,
|
||||||
|
ModelWithVersions,
|
||||||
|
PendingStreamCollaborator,
|
||||||
|
Project,
|
||||||
|
ProjectCollaborator,
|
||||||
|
ProjectCommentCollection,
|
||||||
|
ProjectWithModels,
|
||||||
|
ProjectWithTeam,
|
||||||
|
ResourceCollection,
|
||||||
|
ServerConfiguration,
|
||||||
|
ServerInfo,
|
||||||
|
ServerMigration,
|
||||||
|
User,
|
||||||
|
UserSearchResultCollection,
|
||||||
|
Version,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
Activity,
|
||||||
|
ActivityCollection,
|
||||||
|
Branch,
|
||||||
|
Branches,
|
||||||
|
Collaborator,
|
||||||
|
Commit,
|
||||||
|
Commits,
|
||||||
|
Object,
|
||||||
|
Stream,
|
||||||
|
Streams,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models.instances import InstanceDefinitionProxy, InstanceProxy
|
||||||
|
from specklepy.core.api.models.proxies import ColorProxy, GroupProxy
|
||||||
|
from specklepy.core.api.models.subscription_messages import (
|
||||||
|
ProjectModelsUpdatedMessage,
|
||||||
|
ProjectUpdatedMessage,
|
||||||
|
ProjectVersionsUpdatedMessage,
|
||||||
|
UserProjectsUpdatedMessage,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"User",
|
||||||
|
"ResourceCollection",
|
||||||
|
"ServerMigration",
|
||||||
|
"AuthStrategy",
|
||||||
|
"ServerConfiguration",
|
||||||
|
"ServerInfo",
|
||||||
|
"LimitedUser",
|
||||||
|
"PendingStreamCollaborator",
|
||||||
|
"ProjectCollaborator",
|
||||||
|
"Version",
|
||||||
|
"Model",
|
||||||
|
"ModelWithVersions",
|
||||||
|
"Project",
|
||||||
|
"ProjectWithModels",
|
||||||
|
"ProjectWithTeam",
|
||||||
|
"ProjectCommentCollection",
|
||||||
|
"UserSearchResultCollection",
|
||||||
|
"UserProjectsUpdatedMessage",
|
||||||
|
"ProjectModelsUpdatedMessage",
|
||||||
|
"ProjectUpdatedMessage",
|
||||||
|
"ProjectVersionsUpdatedMessage",
|
||||||
|
"Collaborator",
|
||||||
|
"Commit",
|
||||||
|
"Commits",
|
||||||
|
"Object",
|
||||||
|
"Branch",
|
||||||
|
"Branches",
|
||||||
|
"Stream",
|
||||||
|
"Streams",
|
||||||
|
"Activity",
|
||||||
|
"ActivityCollection",
|
||||||
|
"InstanceProxy",
|
||||||
|
"InstanceDefinitionProxy",
|
||||||
|
"ColorProxy",
|
||||||
|
"GroupProxy",
|
||||||
|
]
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from typing import Generic, List, Optional, TypeVar
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from specklepy.core.api.enums import ProjectVisibility
|
||||||
|
from specklepy.core.api.models.deprecated import Streams
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
class User(BaseModel):
|
||||||
|
id: str
|
||||||
|
email: Optional[str] = None
|
||||||
|
name: str
|
||||||
|
bio: Optional[str] = None
|
||||||
|
company: Optional[str] = None
|
||||||
|
avatar: Optional[str] = None
|
||||||
|
verified: Optional[bool] = None
|
||||||
|
role: Optional[str] = None
|
||||||
|
streams: Optional["Streams"] = None
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return (
|
||||||
|
f"User( id: {self.id}, name: {self.name}, email: {self.email}, company:"
|
||||||
|
f" {self.company} )"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceCollection(BaseModel, Generic[T]):
|
||||||
|
totalCount: int
|
||||||
|
items: List[T]
|
||||||
|
cursor: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
class ServerMigration(BaseModel):
|
||||||
|
movedFrom: Optional[str]
|
||||||
|
movedTo: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class AuthStrategy(BaseModel):
|
||||||
|
color: Optional[str]
|
||||||
|
icon: str
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
url: str
|
||||||
|
|
||||||
|
|
||||||
|
class ServerConfiguration(BaseModel):
|
||||||
|
blobSizeLimitBytes: int
|
||||||
|
objectMultipartUploadSizeLimitBytes: int
|
||||||
|
objectSizeLimitBytes: int
|
||||||
|
|
||||||
|
|
||||||
|
# Keeping this one all Optionals at the minute, because its used both as a deserialization model for GQL and Account Management
|
||||||
|
class ServerInfo(BaseModel):
|
||||||
|
name: Optional[str] = None
|
||||||
|
company: Optional[str] = None
|
||||||
|
url: Optional[str] = None
|
||||||
|
adminContact: Optional[str] = None
|
||||||
|
description: Optional[str] = None
|
||||||
|
canonicalUrl: Optional[str] = None
|
||||||
|
roles: Optional[List[dict]] = None
|
||||||
|
scopes: Optional[List[dict]] = None
|
||||||
|
authStrategies: Optional[List[dict]] = None
|
||||||
|
version: Optional[str] = None
|
||||||
|
frontend2: Optional[bool] = None
|
||||||
|
migration: Optional[ServerMigration] = None
|
||||||
|
|
||||||
|
# TODO separate gql model from account management model
|
||||||
|
|
||||||
|
|
||||||
|
class LimitedUser(BaseModel):
|
||||||
|
"""Limited user type, for showing public info about a user to another user."""
|
||||||
|
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
bio: Optional[str]
|
||||||
|
company: Optional[str]
|
||||||
|
avatar: Optional[str]
|
||||||
|
verified: Optional[bool]
|
||||||
|
role: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class PendingStreamCollaborator(BaseModel):
|
||||||
|
id: str
|
||||||
|
inviteId: str
|
||||||
|
streamId: Optional[str] = None
|
||||||
|
projectId: str
|
||||||
|
streamName: Optional[str] = None
|
||||||
|
projectName: str
|
||||||
|
title: str
|
||||||
|
role: str
|
||||||
|
invitedBy: LimitedUser
|
||||||
|
user: Optional[LimitedUser] = None
|
||||||
|
token: Optional[str]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return (
|
||||||
|
f"PendingStreamCollaborator( inviteId: {self.inviteId}, streamId:"
|
||||||
|
f" {self.streamId}, role: {self.role}, title: {self.title}, invitedBy:"
|
||||||
|
f" {self.user.name if self.user else None})"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectCollaborator(BaseModel):
|
||||||
|
id: str
|
||||||
|
role: str
|
||||||
|
user: LimitedUser
|
||||||
|
|
||||||
|
|
||||||
|
class Version(BaseModel):
|
||||||
|
authorUser: Optional[LimitedUser]
|
||||||
|
createdAt: datetime
|
||||||
|
id: str
|
||||||
|
message: Optional[str]
|
||||||
|
previewUrl: str
|
||||||
|
referencedObject: str
|
||||||
|
sourceApplication: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class Model(BaseModel):
|
||||||
|
author: LimitedUser
|
||||||
|
createdAt: datetime
|
||||||
|
description: Optional[str]
|
||||||
|
displayName: str
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
previewUrl: Optional[str]
|
||||||
|
updatedAt: datetime
|
||||||
|
|
||||||
|
|
||||||
|
class ModelWithVersions(Model):
|
||||||
|
versions: ResourceCollection[Version]
|
||||||
|
|
||||||
|
|
||||||
|
class Project(BaseModel):
|
||||||
|
allowPublicComments: bool
|
||||||
|
createdAt: datetime
|
||||||
|
description: Optional[str]
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
role: Optional[str]
|
||||||
|
sourceApps: List[str]
|
||||||
|
updatedAt: datetime
|
||||||
|
visibility: ProjectVisibility
|
||||||
|
workspaceId: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectWithModels(Project):
|
||||||
|
models: ResourceCollection[Model]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectWithTeam(Project):
|
||||||
|
invitedTeam: List[PendingStreamCollaborator]
|
||||||
|
team: List[ProjectCollaborator]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectCommentCollection(ResourceCollection[T], Generic[T]):
|
||||||
|
totalArchivedCount: int
|
||||||
|
|
||||||
|
|
||||||
|
class UserSearchResultCollection(BaseModel):
|
||||||
|
items: List[LimitedUser]
|
||||||
|
cursor: Optional[str] = None
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
FE1_DEPRECATION_REASON = "Stream/Branch/Commit API is now deprecated, Use the new Project/Model/Version API functions in Client}"
|
||||||
|
FE1_DEPRECATION_VERSION = "2.20"
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Collaborator(BaseModel):
|
class Collaborator(BaseModel):
|
||||||
id: Optional[str] = None
|
id: Optional[str] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
@@ -11,6 +16,7 @@ class Collaborator(BaseModel):
|
|||||||
avatar: Optional[str] = None
|
avatar: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Commit(BaseModel):
|
class Commit(BaseModel):
|
||||||
id: Optional[str] = None
|
id: Optional[str] = None
|
||||||
message: Optional[str] = None
|
message: Optional[str] = None
|
||||||
@@ -35,12 +41,14 @@ class Commit(BaseModel):
|
|||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Commits(BaseModel):
|
class Commits(BaseModel):
|
||||||
totalCount: Optional[int] = None
|
totalCount: Optional[int] = None
|
||||||
cursor: Optional[datetime] = None
|
cursor: Optional[datetime] = None
|
||||||
items: List[Commit] = []
|
items: List[Commit] = []
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Object(BaseModel):
|
class Object(BaseModel):
|
||||||
id: Optional[str] = None
|
id: Optional[str] = None
|
||||||
speckleType: Optional[str] = None
|
speckleType: Optional[str] = None
|
||||||
@@ -49,6 +57,7 @@ class Object(BaseModel):
|
|||||||
createdAt: Optional[datetime] = None
|
createdAt: Optional[datetime] = None
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Branch(BaseModel):
|
class Branch(BaseModel):
|
||||||
id: Optional[str] = None
|
id: Optional[str] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
@@ -56,12 +65,14 @@ class Branch(BaseModel):
|
|||||||
commits: Optional[Commits] = None
|
commits: Optional[Commits] = None
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Branches(BaseModel):
|
class Branches(BaseModel):
|
||||||
totalCount: Optional[int] = None
|
totalCount: Optional[int] = None
|
||||||
cursor: Optional[datetime] = None
|
cursor: Optional[datetime] = None
|
||||||
items: List[Branch] = []
|
items: List[Branch] = []
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Stream(BaseModel):
|
class Stream(BaseModel):
|
||||||
id: Optional[str] = None
|
id: Optional[str] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
@@ -88,67 +99,14 @@ class Stream(BaseModel):
|
|||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class Streams(BaseModel):
|
class Streams(BaseModel):
|
||||||
totalCount: Optional[int] = None
|
totalCount: Optional[int] = None
|
||||||
cursor: Optional[datetime] = None
|
cursor: Optional[datetime] = None
|
||||||
items: List[Stream] = []
|
items: List[Stream] = []
|
||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
id: Optional[str] = None
|
|
||||||
email: Optional[str] = None
|
|
||||||
name: Optional[str] = None
|
|
||||||
bio: Optional[str] = None
|
|
||||||
company: Optional[str] = None
|
|
||||||
avatar: Optional[str] = None
|
|
||||||
verified: Optional[bool] = None
|
|
||||||
role: Optional[str] = None
|
|
||||||
streams: Optional[Streams] = None
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return (
|
|
||||||
f"User( id: {self.id}, name: {self.name}, email: {self.email}, company:"
|
|
||||||
f" {self.company} )"
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.__repr__()
|
|
||||||
|
|
||||||
|
|
||||||
class LimitedUser(BaseModel):
|
|
||||||
"""Limited user type, for showing public info about a user to another user."""
|
|
||||||
|
|
||||||
id: str
|
|
||||||
name: Optional[str] = None
|
|
||||||
bio: Optional[str] = None
|
|
||||||
company: Optional[str] = None
|
|
||||||
avatar: Optional[str] = None
|
|
||||||
verified: Optional[bool] = None
|
|
||||||
role: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class PendingStreamCollaborator(BaseModel):
|
|
||||||
id: Optional[str] = None
|
|
||||||
inviteId: Optional[str] = None
|
|
||||||
streamId: Optional[str] = None
|
|
||||||
streamName: Optional[str] = None
|
|
||||||
title: Optional[str] = None
|
|
||||||
role: Optional[str] = None
|
|
||||||
invitedBy: Optional[User] = None
|
|
||||||
user: Optional[User] = None
|
|
||||||
token: Optional[str] = None
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return (
|
|
||||||
f"PendingStreamCollaborator( inviteId: {self.inviteId}, streamId:"
|
|
||||||
f" {self.streamId}, role: {self.role}, title: {self.title}, invitedBy:"
|
|
||||||
f" {self.user.name if self.user else None})"
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return self.__repr__()
|
|
||||||
|
|
||||||
|
|
||||||
class Activity(BaseModel):
|
class Activity(BaseModel):
|
||||||
actionType: Optional[str] = None
|
actionType: Optional[str] = None
|
||||||
info: Optional[dict] = None
|
info: Optional[dict] = None
|
||||||
@@ -169,6 +127,7 @@ class Activity(BaseModel):
|
|||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
class ActivityCollection(BaseModel):
|
class ActivityCollection(BaseModel):
|
||||||
totalCount: Optional[int] = None
|
totalCount: Optional[int] = None
|
||||||
items: Optional[List[Activity]] = None
|
items: Optional[List[Activity]] = None
|
||||||
@@ -183,23 +142,3 @@ class ActivityCollection(BaseModel):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
|
|
||||||
|
|
||||||
class ServerMigration(BaseModel):
|
|
||||||
movedTo: Optional[str] = None
|
|
||||||
movedFrom: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ServerInfo(BaseModel):
|
|
||||||
name: Optional[str] = None
|
|
||||||
company: Optional[str] = None
|
|
||||||
url: Optional[str] = None
|
|
||||||
description: Optional[str] = None
|
|
||||||
adminContact: Optional[str] = None
|
|
||||||
canonicalUrl: Optional[str] = None
|
|
||||||
roles: Optional[List[dict]] = None
|
|
||||||
scopes: Optional[List[dict]] = None
|
|
||||||
authStrategies: Optional[List[dict]] = None
|
|
||||||
version: Optional[str] = None
|
|
||||||
frontend2: Optional[bool] = None
|
|
||||||
migration: Optional[ServerMigration] = None
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
from specklepy.objects.base import Base
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceProxy(
|
||||||
|
Base,
|
||||||
|
speckle_type="Speckle.Core.Models.Instances.InstanceProxy",
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
A proxy class for an instance (e.g, a rhino block, or an autocad block reference).
|
||||||
|
"""
|
||||||
|
|
||||||
|
definitionId: str
|
||||||
|
transform: list[float]
|
||||||
|
units: str
|
||||||
|
maxDepth: int
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceDefinitionProxy(
|
||||||
|
Base,
|
||||||
|
speckle_type="Speckle.Core.Models.Instances.InstanceDefinitionProxy",
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
A proxy class for an instance definition.
|
||||||
|
"""
|
||||||
|
|
||||||
|
objects: list[str]
|
||||||
|
maxDepth: int
|
||||||
|
name: str
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
from specklepy.objects.base import Base
|
||||||
|
|
||||||
|
|
||||||
|
class ColorProxy(
|
||||||
|
Base,
|
||||||
|
speckle_type="Speckle.Core.Models.Proxies.ColorProxy",
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Represents a color that is found on objects and collections in a root collection.
|
||||||
|
"""
|
||||||
|
|
||||||
|
objects: list[str]
|
||||||
|
value: int
|
||||||
|
name: str | None # nullable but required
|
||||||
|
|
||||||
|
|
||||||
|
class GroupProxy(
|
||||||
|
Base,
|
||||||
|
speckle_type="Speckle.Core.Models.Proxies.GroupProxy",
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Grouped objects with a meaningful way for host application so use this proxy if you want to group object references for any purpose.
|
||||||
|
i.e. in rhino -> creating group make objects selectable/moveable/editable together.
|
||||||
|
"""
|
||||||
|
|
||||||
|
objects: list[str]
|
||||||
|
name: str
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from specklepy.core.api.enums import (
|
||||||
|
ProjectModelsUpdatedMessageType,
|
||||||
|
ProjectUpdatedMessageType,
|
||||||
|
ProjectVersionsUpdatedMessageType,
|
||||||
|
UserProjectsUpdatedMessageType,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models.current import Model, Project, Version
|
||||||
|
|
||||||
|
|
||||||
|
class UserProjectsUpdatedMessage(BaseModel):
|
||||||
|
id: str
|
||||||
|
type: UserProjectsUpdatedMessageType
|
||||||
|
project: Optional[Project]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectModelsUpdatedMessage(BaseModel):
|
||||||
|
id: str
|
||||||
|
type: ProjectModelsUpdatedMessageType
|
||||||
|
model: Optional[Model]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectUpdatedMessage(BaseModel):
|
||||||
|
id: str
|
||||||
|
type: ProjectUpdatedMessageType
|
||||||
|
project: Optional[Project]
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectVersionsUpdatedMessage(BaseModel):
|
||||||
|
id: str
|
||||||
|
type: ProjectVersionsUpdatedMessageType
|
||||||
|
modelId: Optional[str]
|
||||||
|
version: Optional[Version]
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
from threading import Lock
|
from threading import Lock
|
||||||
from typing import Any, Dict, List, Optional, Tuple, Type, Union
|
from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union
|
||||||
|
|
||||||
from gql.client import Client
|
from gql.client import Client
|
||||||
from gql.transport.exceptions import TransportQueryError
|
from gql.transport.exceptions import TransportQueryError
|
||||||
from graphql import DocumentNode
|
from graphql import DocumentNode
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from specklepy.core.api.credentials import Account
|
from specklepy.core.api.credentials import Account
|
||||||
from specklepy.logging.exceptions import (
|
from specklepy.logging.exceptions import (
|
||||||
@@ -14,6 +15,8 @@ from specklepy.logging.exceptions import (
|
|||||||
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
|
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
|
||||||
from specklepy.transports.sqlite import SQLiteTransport
|
from specklepy.transports.sqlite import SQLiteTransport
|
||||||
|
|
||||||
|
T = TypeVar("T", bound=BaseModel)
|
||||||
|
|
||||||
|
|
||||||
class ResourceBase(object):
|
class ResourceBase(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -43,6 +46,35 @@ class ResourceBase(object):
|
|||||||
response = response[key]
|
response = response[key]
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def make_request_and_parse_response(
|
||||||
|
self,
|
||||||
|
schema: Type[T],
|
||||||
|
query: DocumentNode,
|
||||||
|
variables: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> T:
|
||||||
|
try:
|
||||||
|
with self.__lock:
|
||||||
|
response = self.client.execute(query, variable_values=variables)
|
||||||
|
except TransportQueryError as ex:
|
||||||
|
raise GraphQLException(
|
||||||
|
message=(
|
||||||
|
f"Failed to execute the GraphQL {self.name} request. Errors:"
|
||||||
|
f" {ex.errors}"
|
||||||
|
),
|
||||||
|
errors=ex.errors,
|
||||||
|
data=ex.data,
|
||||||
|
) from ex
|
||||||
|
except Exception as ex:
|
||||||
|
raise SpeckleException(
|
||||||
|
message=(
|
||||||
|
f"Failed to execute the GraphQL {self.name} request. Inner"
|
||||||
|
f" exception: {ex}"
|
||||||
|
),
|
||||||
|
exception=ex,
|
||||||
|
) from ex
|
||||||
|
|
||||||
|
return schema.model_validate(response)
|
||||||
|
|
||||||
def _parse_response(self, response: Union[dict, list, None], schema=None):
|
def _parse_response(self, response: Union[dict, list, None], schema=None):
|
||||||
"""Try to create a class instance from the response"""
|
"""Try to create a class instance from the response"""
|
||||||
if response is None:
|
if response is None:
|
||||||
@@ -69,6 +101,8 @@ class ResourceBase(object):
|
|||||||
parse_response: bool = True,
|
parse_response: bool = True,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""Executes the GraphQL query"""
|
"""Executes the GraphQL query"""
|
||||||
|
# This method has quite complex and ambiguous typing, and counter-intuitive error handling
|
||||||
|
# We are going to phase it out in favour of `make_request_and_parse_response`
|
||||||
try:
|
try:
|
||||||
with self.__lock:
|
with self.__lock:
|
||||||
response = self.client.execute(query, variable_values=params)
|
response = self.client.execute(query, variable_values=params)
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
from specklepy.core.api.resources.current.active_user_resource import ActiveUserResource
|
||||||
|
from specklepy.core.api.resources.current.model_resource import ModelResource
|
||||||
|
from specklepy.core.api.resources.current.other_user_resource import OtherUserResource
|
||||||
|
from specklepy.core.api.resources.current.project_invite_resource import (
|
||||||
|
ProjectInviteResource,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.current.project_resource import ProjectResource
|
||||||
|
from specklepy.core.api.resources.current.server_resource import ServerResource
|
||||||
|
from specklepy.core.api.resources.current.subscription_resource import (
|
||||||
|
SubscriptionResource,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resources.current.version_resource import VersionResource
|
||||||
|
from specklepy.core.api.resources.deprecated import (
|
||||||
|
active_user,
|
||||||
|
branch,
|
||||||
|
commit,
|
||||||
|
object,
|
||||||
|
other_user,
|
||||||
|
server,
|
||||||
|
stream,
|
||||||
|
subscriptions,
|
||||||
|
user,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ActiveUserResource",
|
||||||
|
"ModelResource",
|
||||||
|
"OtherUserResource",
|
||||||
|
"ProjectInviteResource",
|
||||||
|
"ProjectResource",
|
||||||
|
"ServerResource",
|
||||||
|
"SubscriptionResource",
|
||||||
|
"VersionResource",
|
||||||
|
"active_user",
|
||||||
|
"branch",
|
||||||
|
"commit",
|
||||||
|
"object",
|
||||||
|
"other_user",
|
||||||
|
"server",
|
||||||
|
"stream",
|
||||||
|
"subscriptions",
|
||||||
|
"user",
|
||||||
|
]
|
||||||
|
|||||||
+203
-58
@@ -1,21 +1,31 @@
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import List, Optional
|
from typing import List, Optional, overload
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from gql import gql
|
from gql import gql
|
||||||
|
|
||||||
|
from specklepy.core.api.inputs.project_inputs import UserProjectsFilter
|
||||||
|
from specklepy.core.api.inputs.user_inputs import UserUpdateInput
|
||||||
from specklepy.core.api.models import (
|
from specklepy.core.api.models import (
|
||||||
ActivityCollection,
|
ActivityCollection,
|
||||||
PendingStreamCollaborator,
|
PendingStreamCollaborator,
|
||||||
|
Project,
|
||||||
|
ResourceCollection,
|
||||||
User,
|
User,
|
||||||
)
|
)
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
from specklepy.core.api.resource import ResourceBase
|
from specklepy.core.api.resource import ResourceBase
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.core.api.responses import DataResponse
|
||||||
|
from specklepy.logging.exceptions import GraphQLException
|
||||||
|
|
||||||
NAME = "active_user"
|
NAME = "active_user"
|
||||||
|
|
||||||
|
|
||||||
class Resource(ResourceBase):
|
class ActiveUserResource(ResourceBase):
|
||||||
"""API Access class for users"""
|
"""API Access class for the active user"""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client, server_version) -> None:
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -27,38 +37,75 @@ class Resource(ResourceBase):
|
|||||||
)
|
)
|
||||||
self.schema = User
|
self.schema = User
|
||||||
|
|
||||||
def get(self) -> User:
|
def get(self) -> Optional[User]:
|
||||||
"""Gets the profile of a user. If no id argument is provided,
|
"""Gets the currently active user profile (as extracted from the authorization header)
|
||||||
will return the current authenticated user's profile
|
|
||||||
(as extracted from the authorization header).
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
id {str} -- the user id
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
User -- the retrieved user
|
User -- the requested user, or none if no authentication token is provided to the Client
|
||||||
"""
|
"""
|
||||||
query = gql(
|
QUERY = gql(
|
||||||
"""
|
"""
|
||||||
query User {
|
query User {
|
||||||
activeUser {
|
data:activeUser {
|
||||||
id
|
id
|
||||||
email
|
email
|
||||||
name
|
name
|
||||||
bio
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
verified
|
verified
|
||||||
profiles
|
role
|
||||||
role
|
}
|
||||||
}
|
}
|
||||||
}
|
"""
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
params = {}
|
variables = {}
|
||||||
|
|
||||||
return self.make_request(query=query, params=params, return_type="activeUser")
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[Optional[User]], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
def _update(self, input: UserUpdateInput) -> User:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ActiveUserMutations($input: UserUpdateInput!) {
|
||||||
|
data:activeUserMutations {
|
||||||
|
data:update(user: $input) {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {"input": input.model_dump(warnings="error")}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[User]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
@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,
|
||||||
|
) -> User:
|
||||||
|
...
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def update(self, *, input: UserUpdateInput) -> User:
|
||||||
|
...
|
||||||
|
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
@@ -66,40 +113,125 @@ class Resource(ResourceBase):
|
|||||||
company: Optional[str] = None,
|
company: Optional[str] = None,
|
||||||
bio: Optional[str] = None,
|
bio: Optional[str] = None,
|
||||||
avatar: Optional[str] = None,
|
avatar: Optional[str] = None,
|
||||||
):
|
*,
|
||||||
"""Updates your user profile. All arguments are optional.
|
input: Optional[UserUpdateInput] = None,
|
||||||
|
) -> User:
|
||||||
Arguments:
|
if isinstance(input, UserUpdateInput):
|
||||||
name {str} -- your name
|
return self._update(input=input)
|
||||||
company {str} -- the company you may or may not work for
|
else:
|
||||||
bio {str} -- tell us about yourself
|
return self._update(
|
||||||
avatar {str} -- a nice photo of yourself
|
input=UserUpdateInput(
|
||||||
|
name=name,
|
||||||
Returns @deprecated(version=DEPRECATION_VERSION, reason=DEPRECATION_TEXT):
|
company=company,
|
||||||
bool -- True if your profile was updated successfully
|
bio=bio,
|
||||||
"""
|
avatar=avatar,
|
||||||
query = gql(
|
|
||||||
"""
|
|
||||||
mutation UserUpdate($user: UserUpdateInput!) {
|
|
||||||
userUpdate(user: $user)
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
params = {"name": name, "company": company, "bio": bio, "avatar": avatar}
|
|
||||||
|
|
||||||
params = {"user": {k: v for k, v in params.items() if v is not None}}
|
|
||||||
|
|
||||||
if not params["user"]:
|
|
||||||
return SpeckleException(
|
|
||||||
message=(
|
|
||||||
"You must provide at least one field to update your user profile"
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.make_request(
|
def get_projects(
|
||||||
query=query, params=params, return_type="userUpdate", parse_response=False
|
self,
|
||||||
|
*,
|
||||||
|
limit: int = 25,
|
||||||
|
cursor: Optional[str] = None,
|
||||||
|
filter: Optional[UserProjectsFilter] = None,
|
||||||
|
) -> ResourceCollection[Project]:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query User($limit : Int!, $cursor: String, $filter: UserProjectsFilter) {
|
||||||
|
data:activeUser {
|
||||||
|
data:projects(limit: $limit, cursor: $cursor, filter: $filter) {
|
||||||
|
totalCount
|
||||||
|
cursor
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"limit": limit,
|
||||||
|
"cursor": cursor,
|
||||||
|
"filter": filter.model_dump(warnings="error") if filter else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.make_request_and_parse_response(
|
||||||
|
DataResponse[Optional[DataResponse[ResourceCollection[Project]]]],
|
||||||
|
QUERY,
|
||||||
|
variables,
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.data is None:
|
||||||
|
raise GraphQLException(
|
||||||
|
"GraphQL response indicated that the ActiveUser could not be found"
|
||||||
|
)
|
||||||
|
|
||||||
|
return response.data.data
|
||||||
|
|
||||||
|
def get_project_invites(self) -> List[PendingStreamCollaborator]:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ProjectInvites {
|
||||||
|
data:activeUser {
|
||||||
|
data:projectInvites {
|
||||||
|
id
|
||||||
|
inviteId
|
||||||
|
invitedBy {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
|
role
|
||||||
|
title
|
||||||
|
token
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
verified
|
||||||
|
avatar
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {}
|
||||||
|
|
||||||
|
response = self.make_request_and_parse_response(
|
||||||
|
DataResponse[Optional[DataResponse[List[PendingStreamCollaborator]]]],
|
||||||
|
QUERY,
|
||||||
|
variables,
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.data is None:
|
||||||
|
raise GraphQLException(
|
||||||
|
"GraphQL response indicated that the ActiveUser could not be found"
|
||||||
|
)
|
||||||
|
|
||||||
|
return response.data.data
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def activity(
|
def activity(
|
||||||
self,
|
self,
|
||||||
limit: int = 20,
|
limit: int = 20,
|
||||||
@@ -107,7 +239,7 @@ class Resource(ResourceBase):
|
|||||||
before: Optional[datetime] = None,
|
before: Optional[datetime] = None,
|
||||||
after: Optional[datetime] = None,
|
after: Optional[datetime] = None,
|
||||||
cursor: Optional[datetime] = None,
|
cursor: Optional[datetime] = None,
|
||||||
):
|
) -> ActivityCollection:
|
||||||
"""
|
"""
|
||||||
Get the activity from a given stream in an Activity collection.
|
Get the activity from a given stream in an Activity collection.
|
||||||
Step into the activity `items` for the list of activity.
|
Step into the activity `items` for the list of activity.
|
||||||
@@ -178,6 +310,7 @@ class Resource(ResourceBase):
|
|||||||
schema=ActivityCollection,
|
schema=ActivityCollection,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get_all_pending_invites(self) -> List[PendingStreamCollaborator]:
|
def get_all_pending_invites(self) -> List[PendingStreamCollaborator]:
|
||||||
"""Get all of the active user's pending stream invites
|
"""Get all of the active user's pending stream invites
|
||||||
|
|
||||||
@@ -198,13 +331,18 @@ class Resource(ResourceBase):
|
|||||||
inviteId
|
inviteId
|
||||||
streamId
|
streamId
|
||||||
streamName
|
streamName
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
title
|
title
|
||||||
role
|
role
|
||||||
invitedBy {
|
invitedBy {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,6 +355,7 @@ class Resource(ResourceBase):
|
|||||||
schema=PendingStreamCollaborator,
|
schema=PendingStreamCollaborator,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get_pending_invite(
|
def get_pending_invite(
|
||||||
self, stream_id: str, token: Optional[str] = None
|
self, stream_id: str, token: Optional[str] = None
|
||||||
) -> Optional[PendingStreamCollaborator]:
|
) -> Optional[PendingStreamCollaborator]:
|
||||||
@@ -241,15 +380,21 @@ class Resource(ResourceBase):
|
|||||||
streamInvite(streamId: $streamId, token: $token) {
|
streamInvite(streamId: $streamId, token: $token) {
|
||||||
id
|
id
|
||||||
token
|
token
|
||||||
|
inviteId
|
||||||
streamId
|
streamId
|
||||||
streamName
|
streamName
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
title
|
title
|
||||||
role
|
role
|
||||||
invitedBy {
|
invitedBy {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from gql import gql
|
||||||
|
|
||||||
|
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.resource import ResourceBase
|
||||||
|
from specklepy.core.api.responses import DataResponse
|
||||||
|
|
||||||
|
NAME = "model"
|
||||||
|
|
||||||
|
|
||||||
|
class ModelResource(ResourceBase):
|
||||||
|
"""API Access class for models"""
|
||||||
|
|
||||||
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
name=NAME,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get(self, model_id: str, project_id: str) -> Model:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ModelGet($modelId: String!, $projectId: String!) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
data:model(id: $modelId) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
previewUrl
|
||||||
|
updatedAt
|
||||||
|
description
|
||||||
|
displayName
|
||||||
|
createdAt
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"modelId": model_id,
|
||||||
|
"projectId": project_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Model]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
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:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ModelGetWithVersions($modelId: String!, $projectId: String!, $versionsLimit: Int!, $versionsCursor: String, $versionsFilter: ModelVersionsFilter) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
data:model(id: $modelId) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
previewUrl
|
||||||
|
updatedAt
|
||||||
|
versions(limit: $versionsLimit, cursor: $versionsCursor, filter: $versionsFilter) {
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
referencedObject
|
||||||
|
message
|
||||||
|
sourceApplication
|
||||||
|
createdAt
|
||||||
|
previewUrl
|
||||||
|
authorUser {
|
||||||
|
avatar
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalCount
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
description
|
||||||
|
displayName
|
||||||
|
createdAt
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"modelId": model_id,
|
||||||
|
"versionsLimit": versions_limit,
|
||||||
|
"versionsCursor": versions_cursor,
|
||||||
|
"versionsFilter": versions_filter.model_dump(warnings="error")
|
||||||
|
if versions_filter
|
||||||
|
else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[ModelWithVersions]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def get_models(
|
||||||
|
self,
|
||||||
|
project_id: str,
|
||||||
|
*,
|
||||||
|
models_limit: int = 25,
|
||||||
|
models_cursor: Optional[str] = None,
|
||||||
|
models_filter: Optional[ProjectModelsFilter] = None,
|
||||||
|
) -> ResourceCollection[Model]:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ProjectGetWithModels($projectId: String!, $modelsLimit: Int!, $modelsCursor: String, $modelsFilter: ProjectModelsFilter) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
data:models(limit: $modelsLimit, cursor: $modelsCursor, filter: $modelsFilter) {
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
previewUrl
|
||||||
|
updatedAt
|
||||||
|
displayName
|
||||||
|
description
|
||||||
|
createdAt
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalCount
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"modelsLimit": models_limit,
|
||||||
|
"modelsCursor": models_cursor,
|
||||||
|
"modelsFilter": models_filter.model_dump(warnings="error")
|
||||||
|
if models_filter
|
||||||
|
else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[ResourceCollection[Model]]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def create(self, input: CreateModelInput) -> Model:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ModelCreate($input: CreateModelInput!) {
|
||||||
|
data:modelMutations {
|
||||||
|
data:create(input: $input) {
|
||||||
|
id
|
||||||
|
displayName
|
||||||
|
name
|
||||||
|
description
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
previewUrl
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Model]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def delete(self, input: DeleteModelInput) -> bool:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ModelDelete($input: DeleteModelInput!) {
|
||||||
|
data:modelMutations {
|
||||||
|
data:delete(input: $input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {"input": input.model_dump(warnings="error")}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[bool]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def update(self, input: UpdateModelInput) -> Model:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ModelUpdate($input: UpdateModelInput!) {
|
||||||
|
data:modelMutations {
|
||||||
|
data:update(input: $input) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
displayName
|
||||||
|
description
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
previewUrl
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Model]], QUERY, variables
|
||||||
|
).data.data
|
||||||
+89
-22
@@ -1,16 +1,26 @@
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from gql import gql
|
from gql import gql
|
||||||
|
|
||||||
from specklepy.core.api.models import ActivityCollection, LimitedUser
|
from specklepy.core.api.models import (
|
||||||
|
ActivityCollection,
|
||||||
|
LimitedUser,
|
||||||
|
UserSearchResultCollection,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
from specklepy.core.api.resource import ResourceBase
|
from specklepy.core.api.resource import ResourceBase
|
||||||
|
from specklepy.core.api.responses import DataResponse
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
NAME = "other_user"
|
NAME = "other_user"
|
||||||
|
|
||||||
|
|
||||||
class Resource(ResourceBase):
|
class OtherUserResource(ResourceBase):
|
||||||
"""API Access class for other users, that are not the currently active user."""
|
"""API Access class for other users, that are not the currently active user."""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client, server_version) -> None:
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
@@ -23,7 +33,7 @@ class Resource(ResourceBase):
|
|||||||
)
|
)
|
||||||
self.schema = LimitedUser
|
self.schema = LimitedUser
|
||||||
|
|
||||||
def get(self, id: str) -> LimitedUser:
|
def get(self, id: str) -> Optional[LimitedUser]:
|
||||||
"""
|
"""
|
||||||
Gets the profile of another user.
|
Gets the profile of another user.
|
||||||
|
|
||||||
@@ -33,26 +43,81 @@ class Resource(ResourceBase):
|
|||||||
Returns:
|
Returns:
|
||||||
LimitedUser -- the retrieved profile of another user
|
LimitedUser -- the retrieved profile of another user
|
||||||
"""
|
"""
|
||||||
query = gql(
|
QUERY = gql(
|
||||||
"""
|
"""
|
||||||
query OtherUser($id: String!) {
|
query LimitedUser($id: String!) {
|
||||||
otherUser(id: $id) {
|
data:otherUser(id: $id){
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
bio
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
verified
|
verified
|
||||||
role
|
role
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
params = {"id": id}
|
variables = {"id": id}
|
||||||
|
|
||||||
return self.make_request(query=query, params=params, return_type="otherUser")
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[Optional[LimitedUser]], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
def user_search(
|
||||||
|
self,
|
||||||
|
query: str,
|
||||||
|
*,
|
||||||
|
limit: int = 25,
|
||||||
|
cursor: Optional[str] = None,
|
||||||
|
archived: bool = False,
|
||||||
|
emailOnly: bool = False,
|
||||||
|
) -> UserSearchResultCollection:
|
||||||
|
"""Searches for a user on the server, by name or email. The search query must be at least
|
||||||
|
3 characters long
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
search_query {str} -- a string to search for
|
||||||
|
limit {int} -- the maximum number of results to return
|
||||||
|
cursor {Optional[str]} --
|
||||||
|
archived {bool} --
|
||||||
|
emailOnly {bool} --
|
||||||
|
Returns:
|
||||||
|
ResourceCollection[LimitedUser] -- User objects that match the search query
|
||||||
|
"""
|
||||||
|
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query UserSearch($query: String!, $limit: Int!, $cursor: String, $archived: Boolean, $emailOnly: Boolean) {
|
||||||
|
data:userSearch(query: $query, limit: $limit, cursor: $cursor, archived: $archived, emailOnly: $emailOnly) {
|
||||||
|
cursor
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
variables = {
|
||||||
|
"query": query,
|
||||||
|
"limit": limit,
|
||||||
|
"cursor": cursor,
|
||||||
|
"archived": archived,
|
||||||
|
"emailOnly": emailOnly,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[UserSearchResultCollection], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
@deprecated(reason="Use user_search instead", version=FE1_DEPRECATION_VERSION)
|
||||||
def search(
|
def search(
|
||||||
self, search_query: str, limit: int = 25
|
self, search_query: str, limit: int = 25
|
||||||
) -> Union[List[LimitedUser], SpeckleException]:
|
) -> Union[List[LimitedUser], SpeckleException]:
|
||||||
@@ -75,12 +140,13 @@ class Resource(ResourceBase):
|
|||||||
query UserSearch($search_query: String!, $limit: Int!) {
|
query UserSearch($search_query: String!, $limit: Int!) {
|
||||||
userSearch(query: $search_query, limit: $limit) {
|
userSearch(query: $search_query, limit: $limit) {
|
||||||
items {
|
items {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
bio
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
verified
|
verified
|
||||||
|
role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,6 +158,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["userSearch", "items"]
|
query=query, params=params, return_type=["userSearch", "items"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def activity(
|
def activity(
|
||||||
self,
|
self,
|
||||||
user_id: str,
|
user_id: str,
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
from typing import Any, Optional, Tuple
|
||||||
|
|
||||||
|
from gql import Client, gql
|
||||||
|
|
||||||
|
from specklepy.core.api.credentials import Account
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectInviteCreateInput,
|
||||||
|
ProjectInviteUseInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import PendingStreamCollaborator, ProjectWithTeam
|
||||||
|
from specklepy.core.api.resource import ResourceBase
|
||||||
|
from specklepy.core.api.responses import DataResponse
|
||||||
|
|
||||||
|
NAME = "project_invite"
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectInviteResource(ResourceBase):
|
||||||
|
"""API Access class for project invites"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
account: Account,
|
||||||
|
basepath: str,
|
||||||
|
client: Client,
|
||||||
|
server_version: Optional[Tuple[Any, ...]],
|
||||||
|
) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
name=NAME,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self, project_id: str, input: ProjectInviteCreateInput
|
||||||
|
) -> ProjectWithTeam:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectInviteCreate($projectId: ID!, $input: ProjectInviteCreateInput!) {
|
||||||
|
data:projectMutations {
|
||||||
|
data:invites {
|
||||||
|
data:create(projectId: $projectId, input: $input) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
workspaceId
|
||||||
|
sourceApps
|
||||||
|
team {
|
||||||
|
id
|
||||||
|
role
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invitedTeam {
|
||||||
|
id
|
||||||
|
inviteId
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
|
title
|
||||||
|
role
|
||||||
|
token
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
invitedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[DataResponse[ProjectWithTeam]]], QUERY, variables
|
||||||
|
).data.data.data
|
||||||
|
|
||||||
|
def use(self, input: ProjectInviteUseInput) -> bool:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectInviteUse($input: ProjectInviteUseInput!) {
|
||||||
|
data:projectMutations {
|
||||||
|
data:invites {
|
||||||
|
data:use(input: $input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[DataResponse[bool]]], QUERY, variables
|
||||||
|
).data.data.data
|
||||||
|
|
||||||
|
def get(
|
||||||
|
self, project_id: str, token: Optional[str]
|
||||||
|
) -> Optional[PendingStreamCollaborator]:
|
||||||
|
"""Returns: The invite, or None if no invite exists"""
|
||||||
|
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ProjectInvite($projectId: String!, $token: String) {
|
||||||
|
data:projectInvite(projectId: $projectId, token: $token) {
|
||||||
|
id
|
||||||
|
inviteId
|
||||||
|
invitedBy {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
|
role
|
||||||
|
title
|
||||||
|
token
|
||||||
|
user {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"token": token,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[Optional[PendingStreamCollaborator]], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
def cancel(
|
||||||
|
self,
|
||||||
|
project_id: str,
|
||||||
|
invite_id: str,
|
||||||
|
) -> ProjectWithTeam:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectInviteCancel($projectId: ID!, $inviteId: String!) {
|
||||||
|
data:projectMutations {
|
||||||
|
data:invites {
|
||||||
|
data:cancel(projectId: $projectId, inviteId: $inviteId) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
team {
|
||||||
|
id
|
||||||
|
role
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invitedTeam {
|
||||||
|
id
|
||||||
|
inviteId
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
|
title
|
||||||
|
role
|
||||||
|
token
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
invitedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"inviteId": invite_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[DataResponse[ProjectWithTeam]]], QUERY, variables
|
||||||
|
).data.data.data
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from gql import gql
|
||||||
|
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectCreateInput,
|
||||||
|
ProjectModelsFilter,
|
||||||
|
ProjectUpdateInput,
|
||||||
|
ProjectUpdateRoleInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import Project, ProjectWithModels, ProjectWithTeam
|
||||||
|
from specklepy.core.api.resource import ResourceBase
|
||||||
|
from specklepy.core.api.responses import DataResponse
|
||||||
|
|
||||||
|
NAME = "project"
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectResource(ResourceBase):
|
||||||
|
"""API Access class for projects"""
|
||||||
|
|
||||||
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
name=NAME,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get(self, project_id: str) -> Project:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query Project($projectId: String!) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
allowPublicComments
|
||||||
|
createdAt
|
||||||
|
description
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
sourceApps
|
||||||
|
updatedAt
|
||||||
|
visibility
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[Project], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
def get_with_models(
|
||||||
|
self,
|
||||||
|
project_id: str,
|
||||||
|
*,
|
||||||
|
models_limit: int = 25,
|
||||||
|
models_cursor: Optional[str] = None,
|
||||||
|
models_filter: Optional[ProjectModelsFilter] = None,
|
||||||
|
) -> ProjectWithModels:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ProjectGetWithModels($projectId: String!, $modelsLimit: Int!, $modelsCursor: String, $modelsFilter: ProjectModelsFilter) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
models(limit: $modelsLimit, cursor: $modelsCursor, filter: $modelsFilter) {
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
previewUrl
|
||||||
|
updatedAt
|
||||||
|
displayName
|
||||||
|
description
|
||||||
|
createdAt
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"modelsLimit": models_limit,
|
||||||
|
"modelsCursor": models_cursor,
|
||||||
|
"modelsFilter": models_filter.model_dump(warnings="error")
|
||||||
|
if models_filter
|
||||||
|
else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[ProjectWithModels], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
def get_with_team(self, project_id: str) -> ProjectWithTeam:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query ProjectGetWithTeam($projectId: String!) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
workspaceId
|
||||||
|
sourceApps
|
||||||
|
team {
|
||||||
|
id
|
||||||
|
role
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invitedTeam {
|
||||||
|
id
|
||||||
|
inviteId
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
|
title
|
||||||
|
role
|
||||||
|
token
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
invitedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[ProjectWithTeam], QUERY, variables
|
||||||
|
).data
|
||||||
|
|
||||||
|
def create(self, input: ProjectCreateInput) -> Project:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectCreate($input: ProjectCreateInput) {
|
||||||
|
data:projectMutations {
|
||||||
|
data:create(input: $input) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Project]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def update(self, input: ProjectUpdateInput) -> Project:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectUpdate($input: ProjectUpdateInput!) {
|
||||||
|
data:projectMutations{
|
||||||
|
data:update(update: $input) {
|
||||||
|
allowPublicComments
|
||||||
|
createdAt
|
||||||
|
description
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
sourceApps
|
||||||
|
updatedAt
|
||||||
|
visibility
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Project]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def delete(self, project_id: str) -> bool:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectDelete($projectId: String!) {
|
||||||
|
data:projectMutations {
|
||||||
|
data:delete(id: $projectId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[bool]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def update_role(self, input: ProjectUpdateRoleInput) -> ProjectWithTeam:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation ProjectUpdateRole($input: ProjectUpdateRoleInput!) {
|
||||||
|
data:projectMutations {
|
||||||
|
data:updateRole(input: $input) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
team {
|
||||||
|
id
|
||||||
|
role
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invitedTeam {
|
||||||
|
id
|
||||||
|
inviteId
|
||||||
|
projectId
|
||||||
|
projectName
|
||||||
|
title
|
||||||
|
role
|
||||||
|
token
|
||||||
|
user {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
invitedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[ProjectWithTeam]], QUERY, variables
|
||||||
|
).data.data
|
||||||
+1
-1
@@ -11,7 +11,7 @@ from specklepy.logging.exceptions import GraphQLException
|
|||||||
NAME = "server"
|
NAME = "server"
|
||||||
|
|
||||||
|
|
||||||
class Resource(ResourceBase):
|
class ServerResource(ResourceBase):
|
||||||
"""API Access class for the server"""
|
"""API Access class for the server"""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client) -> None:
|
def __init__(self, account, basepath, client) -> None:
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
from functools import wraps
|
||||||
|
from typing import Any, Callable, Dict, Optional, Sequence, Type
|
||||||
|
|
||||||
|
from gql import gql
|
||||||
|
from graphql import DocumentNode
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing_extensions import TypeVar
|
||||||
|
|
||||||
|
from specklepy.core.api.models import (
|
||||||
|
ProjectModelsUpdatedMessage,
|
||||||
|
ProjectUpdatedMessage,
|
||||||
|
ProjectVersionsUpdatedMessage,
|
||||||
|
UserProjectsUpdatedMessage,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.resource import ResourceBase
|
||||||
|
from specklepy.core.api.responses import DataResponse
|
||||||
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
|
NAME = "subscribe"
|
||||||
|
|
||||||
|
TEventArgs = TypeVar("TEventArgs", bound=BaseModel)
|
||||||
|
|
||||||
|
|
||||||
|
def check_wsclient(function):
|
||||||
|
@wraps(function)
|
||||||
|
async def check_wsclient_wrapper(self, *args, **kwargs):
|
||||||
|
if self.client is None:
|
||||||
|
raise SpeckleException(
|
||||||
|
"You must authenticate before you can subscribe to events"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return await function(self, *args, **kwargs)
|
||||||
|
|
||||||
|
return check_wsclient_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
class SubscriptionResource(ResourceBase):
|
||||||
|
"""API Access class for subscriptions"""
|
||||||
|
|
||||||
|
def __init__(self, account, basepath, client) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
name=NAME,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def user_projects_updated(
|
||||||
|
self, callback: Callable[[UserProjectsUpdatedMessage], None]
|
||||||
|
) -> None:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
subscription UserProjectsUpdated {
|
||||||
|
data:userProjectsUpdated {
|
||||||
|
id
|
||||||
|
project {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
await self.subscribe_2(
|
||||||
|
DataResponse[UserProjectsUpdatedMessage],
|
||||||
|
QUERY,
|
||||||
|
None,
|
||||||
|
callback=lambda d: callback(d.data),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def project_models_updated(
|
||||||
|
self,
|
||||||
|
callback: Callable[[ProjectModelsUpdatedMessage], None],
|
||||||
|
id: str,
|
||||||
|
model_ids: Optional[Sequence[str]] = None,
|
||||||
|
) -> None:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
subscription ProjectModelsUpdated($id: String!, $modelIds: [String!]) {
|
||||||
|
data:projectModelsUpdated(id: $id, modelIds: $modelIds) {
|
||||||
|
id
|
||||||
|
model {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
previewUrl
|
||||||
|
updatedAt
|
||||||
|
description
|
||||||
|
displayName
|
||||||
|
createdAt
|
||||||
|
author {
|
||||||
|
avatar
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
verified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {"id": id, "modelIds": model_ids}
|
||||||
|
|
||||||
|
await self.subscribe_2(
|
||||||
|
DataResponse[ProjectModelsUpdatedMessage],
|
||||||
|
QUERY,
|
||||||
|
variables,
|
||||||
|
callback=lambda d: callback(d.data),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def project_updated(
|
||||||
|
self,
|
||||||
|
callback: Callable[[ProjectUpdatedMessage], None],
|
||||||
|
id: str,
|
||||||
|
) -> None:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
subscription ProjectUpdated($id: String!) {
|
||||||
|
data:projectUpdated(id: $id) {
|
||||||
|
id
|
||||||
|
project {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
visibility
|
||||||
|
allowPublicComments
|
||||||
|
role
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
sourceApps
|
||||||
|
workspaceId
|
||||||
|
}
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {"id": id}
|
||||||
|
|
||||||
|
await self.subscribe_2(
|
||||||
|
DataResponse[ProjectUpdatedMessage],
|
||||||
|
QUERY,
|
||||||
|
variables,
|
||||||
|
callback=lambda d: callback(d.data),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def project_versions_updated(
|
||||||
|
self,
|
||||||
|
callback: Callable[[ProjectVersionsUpdatedMessage], None],
|
||||||
|
id: str,
|
||||||
|
) -> None:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
subscription ProjectVersionsUpdated($id: String!) {
|
||||||
|
data:projectVersionsUpdated(id: $id) {
|
||||||
|
id
|
||||||
|
modelId
|
||||||
|
type
|
||||||
|
version {
|
||||||
|
id
|
||||||
|
referencedObject
|
||||||
|
message
|
||||||
|
sourceApplication
|
||||||
|
createdAt
|
||||||
|
previewUrl
|
||||||
|
authorUser {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {"id": id}
|
||||||
|
|
||||||
|
await self.subscribe_2(
|
||||||
|
DataResponse[ProjectVersionsUpdatedMessage],
|
||||||
|
QUERY,
|
||||||
|
variables,
|
||||||
|
callback=lambda d: callback(d.data),
|
||||||
|
)
|
||||||
|
|
||||||
|
@check_wsclient
|
||||||
|
async def subscribe_2(
|
||||||
|
self,
|
||||||
|
response_type: Type[TEventArgs],
|
||||||
|
query: DocumentNode,
|
||||||
|
variables: Optional[Dict[str, Any]],
|
||||||
|
callback: Callable[[TEventArgs], None],
|
||||||
|
) -> None:
|
||||||
|
async with self.client as session:
|
||||||
|
self.session = session
|
||||||
|
gen = session.subscribe(query, variable_values=variables)
|
||||||
|
async for res in gen:
|
||||||
|
event_arg = response_type.model_validate(res)
|
||||||
|
callback(event_arg)
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from gql import gql
|
||||||
|
|
||||||
|
from specklepy.core.api.inputs.model_inputs import ModelVersionsFilter
|
||||||
|
from specklepy.core.api.inputs.version_inputs import (
|
||||||
|
CreateVersionInput,
|
||||||
|
DeleteVersionsInput,
|
||||||
|
MarkReceivedVersionInput,
|
||||||
|
MoveVersionsInput,
|
||||||
|
UpdateVersionInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import ResourceCollection, Version
|
||||||
|
from specklepy.core.api.resource import ResourceBase
|
||||||
|
from specklepy.core.api.responses import DataResponse
|
||||||
|
|
||||||
|
NAME = "model"
|
||||||
|
|
||||||
|
|
||||||
|
class VersionResource(ResourceBase):
|
||||||
|
"""API Access class for model versions"""
|
||||||
|
|
||||||
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
|
super().__init__(
|
||||||
|
account=account,
|
||||||
|
basepath=basepath,
|
||||||
|
client=client,
|
||||||
|
name=NAME,
|
||||||
|
server_version=server_version,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get(self, version_id: str, project_id: str) -> Version:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query VersionGet($projectId: String!, $versionId: String!) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
data:version(id: $versionId) {
|
||||||
|
id
|
||||||
|
referencedObject
|
||||||
|
message
|
||||||
|
sourceApplication
|
||||||
|
createdAt
|
||||||
|
previewUrl
|
||||||
|
authorUser {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"versionId": version_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Version]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def get_versions(
|
||||||
|
self,
|
||||||
|
model_id: str,
|
||||||
|
project_id: str,
|
||||||
|
*,
|
||||||
|
limit: int = 25,
|
||||||
|
cursor: Optional[str] = None,
|
||||||
|
filter: Optional[ModelVersionsFilter] = None,
|
||||||
|
) -> ResourceCollection[Version]:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
query VersionGetVersions($projectId: String!, $modelId: String!, $limit: Int!, $cursor: String, $filter: ModelVersionsFilter) {
|
||||||
|
data:project(id: $projectId) {
|
||||||
|
data:model(id: $modelId) {
|
||||||
|
data:versions(limit: $limit, cursor: $cursor, filter: $filter) {
|
||||||
|
items {
|
||||||
|
id
|
||||||
|
referencedObject
|
||||||
|
message
|
||||||
|
sourceApplication
|
||||||
|
createdAt
|
||||||
|
previewUrl
|
||||||
|
authorUser {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"projectId": project_id,
|
||||||
|
"modelId": model_id,
|
||||||
|
"limit": limit,
|
||||||
|
"cursor": cursor,
|
||||||
|
"filter": filter.model_dump(warnings="error") if filter else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[DataResponse[ResourceCollection[Version]]]],
|
||||||
|
QUERY,
|
||||||
|
variables,
|
||||||
|
).data.data.data
|
||||||
|
|
||||||
|
def create(self, input: CreateVersionInput) -> str:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation Create($input: CreateVersionInput!) {
|
||||||
|
data:versionMutations {
|
||||||
|
data:create(input: $input) {
|
||||||
|
data:id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[DataResponse[str]]], QUERY, variables
|
||||||
|
).data.data.data
|
||||||
|
|
||||||
|
def update(self, input: UpdateVersionInput) -> Version:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation VersionUpdate($input: UpdateVersionInput!) {
|
||||||
|
data:versionMutations {
|
||||||
|
data:update(input: $input) {
|
||||||
|
id
|
||||||
|
referencedObject
|
||||||
|
message
|
||||||
|
sourceApplication
|
||||||
|
createdAt
|
||||||
|
previewUrl
|
||||||
|
authorUser {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
company
|
||||||
|
verified
|
||||||
|
role
|
||||||
|
avatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {"input": input.model_dump(warnings="error")}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[Version]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def move_to_model(self, input: MoveVersionsInput) -> str:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation VersionMoveToModel($input: MoveVersionsInput!) {
|
||||||
|
data:versionMutations {
|
||||||
|
data:moveToModel(input: $input) {
|
||||||
|
data:id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[DataResponse[str]]], QUERY, variables
|
||||||
|
).data.data.data
|
||||||
|
|
||||||
|
def delete(self, input: DeleteVersionsInput) -> bool:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation VersionDelete($input: DeleteVersionsInput!) {
|
||||||
|
data:versionMutations {
|
||||||
|
data:delete(input: $input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[bool]], QUERY, variables
|
||||||
|
).data.data
|
||||||
|
|
||||||
|
def received(self, input: MarkReceivedVersionInput) -> bool:
|
||||||
|
QUERY = gql(
|
||||||
|
"""
|
||||||
|
mutation MarkReceived($input: MarkReceivedVersionInput!) {
|
||||||
|
data:versionMutations {
|
||||||
|
data:markReceived(input: $input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
variables = {
|
||||||
|
"input": input.model_dump(warnings="error"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.make_request_and_parse_response(
|
||||||
|
DataResponse[DataResponse[bool]], QUERY, variables
|
||||||
|
).data.data
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.core.api.models.deprecated import FE1_DEPRECATION_VERSION
|
||||||
|
from specklepy.core.api.resources import ActiveUserResource
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(
|
||||||
|
reason="Class renamed to ActiveUserResource", version=FE1_DEPRECATION_VERSION
|
||||||
|
)
|
||||||
|
class Resource(ActiveUserResource):
|
||||||
|
"""
|
||||||
|
Class renamed to ActiveUserResource
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
+15
-2
@@ -1,8 +1,13 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from gql import gql
|
from gql import gql
|
||||||
|
|
||||||
from specklepy.core.api.models import Branch
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
Branch,
|
||||||
|
)
|
||||||
from specklepy.core.api.resource import ResourceBase
|
from specklepy.core.api.resource import ResourceBase
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
@@ -10,7 +15,10 @@ NAME = "branch"
|
|||||||
|
|
||||||
|
|
||||||
class Resource(ResourceBase):
|
class Resource(ResourceBase):
|
||||||
"""API Access class for branches"""
|
"""
|
||||||
|
API Access class for branches
|
||||||
|
Branch resource is deprecated, please use model resource instead
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client) -> None:
|
def __init__(self, account, basepath, client) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -21,6 +29,7 @@ class Resource(ResourceBase):
|
|||||||
)
|
)
|
||||||
self.schema = Branch
|
self.schema = Branch
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(
|
def create(
|
||||||
self, stream_id: str, name: str, description: str = "No description provided"
|
self, stream_id: str, name: str, description: str = "No description provided"
|
||||||
) -> str:
|
) -> str:
|
||||||
@@ -54,6 +63,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="branchCreate", parse_response=False
|
query=query, params=params, return_type="branchCreate", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(self, stream_id: str, name: str, commits_limit: int = 10):
|
def get(self, stream_id: str, name: str, commits_limit: int = 10):
|
||||||
"""Get a branch by name from a stream
|
"""Get a branch by name from a stream
|
||||||
|
|
||||||
@@ -101,6 +111,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["stream", "branch"]
|
query=query, params=params, return_type=["stream", "branch"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def list(self, stream_id: str, branches_limit: int = 10, commits_limit: int = 10):
|
def list(self, stream_id: str, branches_limit: int = 10, commits_limit: int = 10):
|
||||||
"""Get a list of branches from a given stream
|
"""Get a list of branches from a given stream
|
||||||
|
|
||||||
@@ -156,6 +167,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["stream", "branches", "items"]
|
query=query, params=params, return_type=["stream", "branches", "items"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -197,6 +209,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="branchUpdate", parse_response=False
|
query=query, params=params, return_type="branchUpdate", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def delete(self, stream_id: str, branch_id: str):
|
def delete(self, stream_id: str, branch_id: str):
|
||||||
"""Delete a branch
|
"""Delete a branch
|
||||||
|
|
||||||
+16
-2
@@ -1,8 +1,13 @@
|
|||||||
from typing import List, Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from gql import gql
|
from gql import gql
|
||||||
|
|
||||||
from specklepy.core.api.models import Commit
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
Commit,
|
||||||
|
)
|
||||||
from specklepy.core.api.resource import ResourceBase
|
from specklepy.core.api.resource import ResourceBase
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
@@ -10,7 +15,10 @@ NAME = "commit"
|
|||||||
|
|
||||||
|
|
||||||
class Resource(ResourceBase):
|
class Resource(ResourceBase):
|
||||||
"""API Access class for commits"""
|
"""
|
||||||
|
API Access class for commits
|
||||||
|
Commit resource is deprecated, please use version resource instead
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client) -> None:
|
def __init__(self, account, basepath, client) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -21,6 +29,7 @@ class Resource(ResourceBase):
|
|||||||
)
|
)
|
||||||
self.schema = Commit
|
self.schema = Commit
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(self, stream_id: str, commit_id: str) -> Commit:
|
def get(self, stream_id: str, commit_id: str) -> Commit:
|
||||||
"""
|
"""
|
||||||
Gets a commit given a stream and the commit id
|
Gets a commit given a stream and the commit id
|
||||||
@@ -59,6 +68,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["stream", "commit"]
|
query=query, params=params, return_type=["stream", "commit"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def list(self, stream_id: str, limit: int = 10) -> List[Commit]:
|
def list(self, stream_id: str, limit: int = 10) -> List[Commit]:
|
||||||
"""
|
"""
|
||||||
Get a list of commits on a given stream
|
Get a list of commits on a given stream
|
||||||
@@ -100,6 +110,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["stream", "commits", "items"]
|
query=query, params=params, return_type=["stream", "commits", "items"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(
|
def create(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -149,6 +160,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="commitCreate", parse_response=False
|
query=query, params=params, return_type="commitCreate", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update(self, stream_id: str, commit_id: str, message: str) -> bool:
|
def update(self, stream_id: str, commit_id: str, message: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Update a commit
|
Update a commit
|
||||||
@@ -176,6 +188,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="commitUpdate", parse_response=False
|
query=query, params=params, return_type="commitUpdate", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def delete(self, stream_id: str, commit_id: str) -> bool:
|
def delete(self, stream_id: str, commit_id: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Delete a commit
|
Delete a commit
|
||||||
@@ -200,6 +213,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="commitDelete", parse_response=False
|
query=query, params=params, return_type="commitDelete", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def received(
|
def received(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.core.api.models.deprecated import FE1_DEPRECATION_VERSION
|
||||||
|
from specklepy.core.api.resources import OtherUserResource
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(
|
||||||
|
reason="Class renamed to OtherUserResource", version=FE1_DEPRECATION_VERSION
|
||||||
|
)
|
||||||
|
class Resource(OtherUserResource):
|
||||||
|
"""
|
||||||
|
Class renamed to OtherUserResource
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
from specklepy.core.api.models.deprecated import FE1_DEPRECATION_VERSION
|
||||||
|
from specklepy.core.api.resources import ServerResource
|
||||||
|
|
||||||
|
NAME = "server"
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason="Renamed to ServerResource", version=FE1_DEPRECATION_VERSION)
|
||||||
|
class Resource(ServerResource):
|
||||||
|
"""API Access class for the server"""
|
||||||
+32
-1
@@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from gql import gql
|
from gql import gql
|
||||||
|
|
||||||
from specklepy.core.api.models import (
|
from specklepy.core.api.models import (
|
||||||
@@ -8,6 +9,10 @@ from specklepy.core.api.models import (
|
|||||||
PendingStreamCollaborator,
|
PendingStreamCollaborator,
|
||||||
Stream,
|
Stream,
|
||||||
)
|
)
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
)
|
||||||
from specklepy.core.api.resource import ResourceBase
|
from specklepy.core.api.resource import ResourceBase
|
||||||
from specklepy.logging.exceptions import SpeckleException, UnsupportedException
|
from specklepy.logging.exceptions import SpeckleException, UnsupportedException
|
||||||
|
|
||||||
@@ -15,7 +20,10 @@ NAME = "stream"
|
|||||||
|
|
||||||
|
|
||||||
class Resource(ResourceBase):
|
class Resource(ResourceBase):
|
||||||
"""API Access class for streams"""
|
"""
|
||||||
|
API Access class for streams
|
||||||
|
Stream resource is deprecated, please use project resource instead
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, account, basepath, client, server_version) -> None:
|
def __init__(self, account, basepath, client, server_version) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
@@ -28,6 +36,7 @@ class Resource(ResourceBase):
|
|||||||
|
|
||||||
self.schema = Stream
|
self.schema = Stream
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get(self, id: str, branch_limit: int = 10, commit_limit: int = 10) -> Stream:
|
def get(self, id: str, branch_limit: int = 10, commit_limit: int = 10) -> Stream:
|
||||||
"""Get the specified stream from the server
|
"""Get the specified stream from the server
|
||||||
|
|
||||||
@@ -89,6 +98,7 @@ class Resource(ResourceBase):
|
|||||||
|
|
||||||
return self.make_request(query=query, params=params, return_type="stream")
|
return self.make_request(query=query, params=params, return_type="stream")
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def list(self, stream_limit: int = 10) -> List[Stream]:
|
def list(self, stream_limit: int = 10) -> List[Stream]:
|
||||||
"""Get a list of the user's streams
|
"""Get a list of the user's streams
|
||||||
|
|
||||||
@@ -142,6 +152,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["user", "streams", "items"]
|
query=query, params=params, return_type=["user", "streams", "items"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def create(
|
def create(
|
||||||
self,
|
self,
|
||||||
name: str = "Anonymous Python Stream",
|
name: str = "Anonymous Python Stream",
|
||||||
@@ -176,6 +187,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="streamCreate", parse_response=False
|
query=query, params=params, return_type="streamCreate", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update(
|
def update(
|
||||||
self,
|
self,
|
||||||
id: str,
|
id: str,
|
||||||
@@ -216,6 +228,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="streamUpdate", parse_response=False
|
query=query, params=params, return_type="streamUpdate", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def delete(self, id: str) -> bool:
|
def delete(self, id: str) -> bool:
|
||||||
"""Delete a stream given its id
|
"""Delete a stream given its id
|
||||||
|
|
||||||
@@ -239,6 +252,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type="streamDelete", parse_response=False
|
query=query, params=params, return_type="streamDelete", parse_response=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def search(
|
def search(
|
||||||
self,
|
self,
|
||||||
search_query: str,
|
search_query: str,
|
||||||
@@ -318,6 +332,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["streams", "items"]
|
query=query, params=params, return_type=["streams", "items"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def favorite(self, stream_id: str, favorited: bool = True):
|
def favorite(self, stream_id: str, favorited: bool = True):
|
||||||
"""Favorite or unfavorite the given stream.
|
"""Favorite or unfavorite the given stream.
|
||||||
|
|
||||||
@@ -351,6 +366,7 @@ class Resource(ResourceBase):
|
|||||||
query=query, params=params, return_type=["streamFavorite"]
|
query=query, params=params, return_type=["streamFavorite"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def get_all_pending_invites(
|
def get_all_pending_invites(
|
||||||
self, stream_id: str
|
self, stream_id: str
|
||||||
) -> List[PendingStreamCollaborator]:
|
) -> List[PendingStreamCollaborator]:
|
||||||
@@ -378,19 +394,27 @@ class Resource(ResourceBase):
|
|||||||
inviteId
|
inviteId
|
||||||
streamId
|
streamId
|
||||||
streamName
|
streamName
|
||||||
|
projectName
|
||||||
|
projectId
|
||||||
title
|
title
|
||||||
role
|
role
|
||||||
invitedBy{
|
invitedBy{
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
bio
|
||||||
company
|
company
|
||||||
avatar
|
avatar
|
||||||
|
verified
|
||||||
|
role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,6 +430,7 @@ class Resource(ResourceBase):
|
|||||||
schema=PendingStreamCollaborator,
|
schema=PendingStreamCollaborator,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite(
|
def invite(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -462,6 +487,7 @@ class Resource(ResourceBase):
|
|||||||
parse_response=False,
|
parse_response=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite_batch(
|
def invite_batch(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
@@ -521,6 +547,7 @@ class Resource(ResourceBase):
|
|||||||
parse_response=False,
|
parse_response=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite_cancel(self, stream_id: str, invite_id: str) -> bool:
|
def invite_cancel(self, stream_id: str, invite_id: str) -> bool:
|
||||||
"""Cancel an existing stream invite
|
"""Cancel an existing stream invite
|
||||||
|
|
||||||
@@ -552,6 +579,7 @@ class Resource(ResourceBase):
|
|||||||
parse_response=False,
|
parse_response=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def invite_use(self, stream_id: str, token: str, accept: bool = True) -> bool:
|
def invite_use(self, stream_id: str, token: str, accept: bool = True) -> bool:
|
||||||
"""Accept or decline a stream invite
|
"""Accept or decline a stream invite
|
||||||
|
|
||||||
@@ -589,6 +617,7 @@ class Resource(ResourceBase):
|
|||||||
parse_response=False,
|
parse_response=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def update_permission(self, stream_id: str, user_id: str, role: str):
|
def update_permission(self, stream_id: str, user_id: str, role: str):
|
||||||
"""Updates permissions for a user on a given stream
|
"""Updates permissions for a user on a given stream
|
||||||
|
|
||||||
@@ -635,6 +664,7 @@ class Resource(ResourceBase):
|
|||||||
parse_response=False,
|
parse_response=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def revoke_permission(self, stream_id: str, user_id: str):
|
def revoke_permission(self, stream_id: str, user_id: str):
|
||||||
"""Revoke permissions from a user on a given stream
|
"""Revoke permissions from a user on a given stream
|
||||||
|
|
||||||
@@ -664,6 +694,7 @@ class Resource(ResourceBase):
|
|||||||
parse_response=False,
|
parse_response=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
def activity(
|
def activity(
|
||||||
self,
|
self,
|
||||||
stream_id: str,
|
stream_id: str,
|
||||||
+7
-1
@@ -1,11 +1,16 @@
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import Callable, Dict, List, Optional, Union
|
from typing import Callable, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
from deprecated import deprecated
|
||||||
from gql import gql
|
from gql import gql
|
||||||
from graphql import DocumentNode
|
from graphql import DocumentNode
|
||||||
|
|
||||||
|
from specklepy.core.api.models.deprecated import (
|
||||||
|
FE1_DEPRECATION_REASON,
|
||||||
|
FE1_DEPRECATION_VERSION,
|
||||||
|
Stream,
|
||||||
|
)
|
||||||
from specklepy.core.api.resource import ResourceBase
|
from specklepy.core.api.resource import ResourceBase
|
||||||
from specklepy.core.api.resources.stream import Stream
|
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import SpeckleException
|
||||||
|
|
||||||
NAME = "subscribe"
|
NAME = "subscribe"
|
||||||
@@ -35,6 +40,7 @@ class Resource(ResourceBase):
|
|||||||
name=NAME,
|
name=NAME,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated(reason=FE1_DEPRECATION_REASON, version=FE1_DEPRECATION_VERSION)
|
||||||
@check_wsclient
|
@check_wsclient
|
||||||
async def stream_added(self, callback: Optional[Callable] = None):
|
async def stream_added(self, callback: Optional[Callable] = None):
|
||||||
"""Subscribes to new stream added event for your profile.
|
"""Subscribes to new stream added event for your profile.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
schema: https://app.speckle.systems/graphql
|
||||||
|
documents: '**/*.graphql'
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
class DataResponse(BaseModel, Generic[T]):
|
||||||
|
data: T
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
from typing import Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
|
|
||||||
|
|
||||||
class CRS(Base, speckle_type="Objects.GIS.CRS"):
|
|
||||||
"""A Coordinate Reference System stored in wkt format"""
|
|
||||||
|
|
||||||
name: Optional[str] = None
|
|
||||||
authority_id: Optional[str] = None
|
|
||||||
wkt: Optional[str] = None
|
|
||||||
units_native: Optional[str] = None
|
|
||||||
offset_x: Optional[float] = None
|
|
||||||
offset_y: Optional[float] = None
|
|
||||||
rotation: Optional[float] = None
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
"""Builtin Speckle object kit."""
|
|
||||||
|
|
||||||
from specklepy.objects.GIS.CRS import CRS
|
|
||||||
from specklepy.objects.GIS.geometry import (
|
|
||||||
GisLineElement,
|
|
||||||
GisPointElement,
|
|
||||||
GisPolygonElement,
|
|
||||||
GisPolygonGeometry,
|
|
||||||
GisRasterElement,
|
|
||||||
)
|
|
||||||
from specklepy.objects.GIS.layers import RasterLayer, VectorLayer
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"VectorLayer",
|
|
||||||
"RasterLayer",
|
|
||||||
"GisPolygonGeometry",
|
|
||||||
"GisPolygonElement",
|
|
||||||
"GisLineElement",
|
|
||||||
"GisPointElement",
|
|
||||||
"GisRasterElement",
|
|
||||||
"CRS",
|
|
||||||
]
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
from typing import List, Optional, Union
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.geometry import (
|
|
||||||
Arc,
|
|
||||||
Circle,
|
|
||||||
Line,
|
|
||||||
Mesh,
|
|
||||||
Point,
|
|
||||||
Polycurve,
|
|
||||||
Polyline,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class GisPolygonGeometry(
|
|
||||||
Base, speckle_type="Objects.GIS.PolygonGeometry", detachable={"displayValue"}
|
|
||||||
):
|
|
||||||
"""GIS Polygon Geometry"""
|
|
||||||
|
|
||||||
boundary: Optional[Union[Polyline, Arc, Line, Circle, Polycurve]] = None
|
|
||||||
voids: Optional[List[Union[Polyline, Arc, Line, Circle, Polycurve]]] = None
|
|
||||||
displayValue: Optional[List[Mesh]] = None
|
|
||||||
|
|
||||||
|
|
||||||
class GisPolygonElement(Base, speckle_type="Objects.GIS.PolygonElement"):
|
|
||||||
"""GIS Polygon element"""
|
|
||||||
|
|
||||||
geometry: Optional[List[GisPolygonGeometry]] = None
|
|
||||||
attributes: Optional[Base] = None
|
|
||||||
|
|
||||||
|
|
||||||
class GisLineElement(Base, speckle_type="Objects.GIS.LineElement"):
|
|
||||||
"""GIS Polyline element"""
|
|
||||||
|
|
||||||
geometry: Optional[List[Union[Polyline, Arc, Line, Circle, Polycurve]]] = None
|
|
||||||
attributes: Optional[Base] = None
|
|
||||||
|
|
||||||
|
|
||||||
class GisPointElement(Base, speckle_type="Objects.GIS.PointElement"):
|
|
||||||
"""GIS Point element"""
|
|
||||||
|
|
||||||
geometry: Optional[List[Point]] = None
|
|
||||||
attributes: Optional[Base] = None
|
|
||||||
|
|
||||||
|
|
||||||
class GisRasterElement(
|
|
||||||
Base, speckle_type="Objects.GIS.RasterElement", detachable={"displayValue"}
|
|
||||||
):
|
|
||||||
"""GIS Raster element"""
|
|
||||||
|
|
||||||
band_count: Optional[int] = None
|
|
||||||
band_names: Optional[List[str]] = None
|
|
||||||
x_origin: Optional[float] = None
|
|
||||||
y_origin: Optional[float] = None
|
|
||||||
x_size: Optional[int] = None
|
|
||||||
y_size: Optional[int] = None
|
|
||||||
x_resolution: Optional[float] = None
|
|
||||||
y_resolution: Optional[float] = None
|
|
||||||
noDataValue: Optional[List[float]] = None
|
|
||||||
displayValue: Optional[List[Mesh]] = None
|
|
||||||
|
|
||||||
|
|
||||||
class GisTopography(
|
|
||||||
GisRasterElement,
|
|
||||||
speckle_type="Objects.GIS.GisTopography",
|
|
||||||
detachable={"displayValue"},
|
|
||||||
):
|
|
||||||
"""GIS Raster element with 3d Topography representation"""
|
|
||||||
|
|
||||||
|
|
||||||
class GisNonGeometryElement(Base, speckle_type="Objects.GIS.NonGeometryElement"):
|
|
||||||
"""GIS Table feature"""
|
|
||||||
|
|
||||||
attributes: Optional[Base] = None
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
from typing import Any, Dict, List, Optional, Union
|
|
||||||
|
|
||||||
from deprecated import deprecated
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.GIS.CRS import CRS
|
|
||||||
from specklepy.objects.other import Collection
|
|
||||||
|
|
||||||
|
|
||||||
@deprecated(version="2.15", reason="Use VectorLayer or RasterLayer instead")
|
|
||||||
class Layer(Base, detachable={"features"}):
|
|
||||||
"""A GIS Layer"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: Optional[str] = None,
|
|
||||||
crs: Optional[CRS] = None,
|
|
||||||
units: str = "m",
|
|
||||||
features: Optional[List[Base]] = None,
|
|
||||||
layerType: str = "None",
|
|
||||||
geomType: str = "None",
|
|
||||||
renderer: Optional[Dict[str, Any]] = None,
|
|
||||||
**kwargs,
|
|
||||||
) -> None:
|
|
||||||
super().__init__(**kwargs)
|
|
||||||
self.name = name
|
|
||||||
self.crs = crs
|
|
||||||
self.units = units
|
|
||||||
self.type = layerType
|
|
||||||
self.features = features or []
|
|
||||||
self.geomType = geomType
|
|
||||||
self.renderer = renderer or {}
|
|
||||||
|
|
||||||
|
|
||||||
@deprecated(version="2.16", reason="Use VectorLayer or RasterLayer instead")
|
|
||||||
class VectorLayer(
|
|
||||||
Collection,
|
|
||||||
detachable={"elements"},
|
|
||||||
speckle_type="VectorLayer",
|
|
||||||
serialize_ignore={"features"},
|
|
||||||
):
|
|
||||||
"""GIS Vector Layer"""
|
|
||||||
|
|
||||||
name: Optional[str] = None
|
|
||||||
crs: Optional[Union[CRS, Base]] = None
|
|
||||||
units: Optional[str] = None
|
|
||||||
elements: Optional[List[Base]] = None
|
|
||||||
attributes: Optional[Base] = None
|
|
||||||
geomType: Optional[str] = "None"
|
|
||||||
renderer: Optional[Dict[str, Any]] = None
|
|
||||||
collectionType = "VectorLayer"
|
|
||||||
|
|
||||||
@property
|
|
||||||
@deprecated(version="2.14", reason="Use elements")
|
|
||||||
def features(self) -> Optional[List[Base]]:
|
|
||||||
return self.elements
|
|
||||||
|
|
||||||
@features.setter
|
|
||||||
def features(self, value: Optional[List[Base]]) -> None:
|
|
||||||
self.elements = value
|
|
||||||
|
|
||||||
|
|
||||||
@deprecated(version="2.16", reason="Use VectorLayer or RasterLayer instead")
|
|
||||||
class RasterLayer(
|
|
||||||
Collection,
|
|
||||||
detachable={"elements"},
|
|
||||||
speckle_type="RasterLayer",
|
|
||||||
serialize_ignore={"features"},
|
|
||||||
):
|
|
||||||
"""GIS Raster Layer"""
|
|
||||||
|
|
||||||
name: Optional[str] = None
|
|
||||||
crs: Optional[Union[CRS, Base]] = None
|
|
||||||
units: Optional[str] = None
|
|
||||||
rasterCrs: Optional[Union[CRS, Base]] = None
|
|
||||||
elements: Optional[List[Base]] = None
|
|
||||||
geomType: Optional[str] = "None"
|
|
||||||
renderer: Optional[Dict[str, Any]] = None
|
|
||||||
collectionType = "RasterLayer"
|
|
||||||
|
|
||||||
@property
|
|
||||||
@deprecated(version="2.14", reason="Use elements")
|
|
||||||
def features(self) -> Optional[List[Base]]:
|
|
||||||
return self.elements
|
|
||||||
|
|
||||||
@features.setter
|
|
||||||
def features(self, value: Optional[List[Base]]) -> None:
|
|
||||||
self.elements = value
|
|
||||||
|
|
||||||
|
|
||||||
class VectorLayer( # noqa: F811
|
|
||||||
Collection,
|
|
||||||
detachable={"elements"},
|
|
||||||
speckle_type="Objects.GIS.VectorLayer",
|
|
||||||
serialize_ignore={"features"},
|
|
||||||
):
|
|
||||||
"""GIS Vector Layer"""
|
|
||||||
|
|
||||||
name: Optional[str] = None
|
|
||||||
crs: Optional[Union[CRS, Base]] = None
|
|
||||||
units: Optional[str] = None
|
|
||||||
elements: Optional[List[Base]] = None
|
|
||||||
attributes: Optional[Base] = None
|
|
||||||
geomType: Optional[str] = "None"
|
|
||||||
renderer: Optional[Dict[str, Any]] = None
|
|
||||||
collectionType = "VectorLayer"
|
|
||||||
|
|
||||||
@property
|
|
||||||
@deprecated(version="2.14", reason="Use elements")
|
|
||||||
def features(self) -> Optional[List[Base]]:
|
|
||||||
return self.elements
|
|
||||||
|
|
||||||
@features.setter
|
|
||||||
def features(self, value: Optional[List[Base]]) -> None:
|
|
||||||
self.elements = value
|
|
||||||
|
|
||||||
|
|
||||||
class RasterLayer( # noqa: F811
|
|
||||||
Collection,
|
|
||||||
detachable={"elements"},
|
|
||||||
speckle_type="Objects.GIS.RasterLayer",
|
|
||||||
serialize_ignore={"features"},
|
|
||||||
):
|
|
||||||
"""GIS Raster Layer"""
|
|
||||||
|
|
||||||
name: Optional[str] = None
|
|
||||||
crs: Optional[Union[CRS, Base]] = None
|
|
||||||
units: Optional[str] = None
|
|
||||||
rasterCrs: Optional[Union[CRS, Base]] = None
|
|
||||||
elements: Optional[List[Base]] = None
|
|
||||||
geomType: Optional[str] = "None"
|
|
||||||
renderer: Optional[Dict[str, Any]] = None
|
|
||||||
collectionType = "RasterLayer"
|
|
||||||
|
|
||||||
@property
|
|
||||||
@deprecated(version="2.14", reason="Use elements")
|
|
||||||
def features(self) -> Optional[List[Base]]:
|
|
||||||
return self.elements
|
|
||||||
|
|
||||||
@features.setter
|
|
||||||
def features(self, value: Optional[List[Base]]) -> None:
|
|
||||||
self.elements = value
|
|
||||||
@@ -1,14 +1,6 @@
|
|||||||
"""Builtin Speckle object kit."""
|
"""Builtin Speckle object kit."""
|
||||||
|
|
||||||
from specklepy.objects import (
|
from specklepy.objects import encoding, geometry, other, primitive, units
|
||||||
GIS,
|
|
||||||
encoding,
|
|
||||||
geometry,
|
|
||||||
other,
|
|
||||||
primitive,
|
|
||||||
structural,
|
|
||||||
units,
|
|
||||||
)
|
|
||||||
from specklepy.objects.base import Base
|
from specklepy.objects.base import Base
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@@ -17,7 +9,5 @@ __all__ = [
|
|||||||
"geometry",
|
"geometry",
|
||||||
"other",
|
"other",
|
||||||
"units",
|
"units",
|
||||||
"structural",
|
|
||||||
"primitive",
|
"primitive",
|
||||||
"GIS",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
from typing import Any, List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from deprecated import deprecated
|
from deprecated import deprecated
|
||||||
|
|
||||||
from specklepy.objects.geometry import Plane, Point, Polyline, Vector
|
from specklepy.objects.geometry import Point, Vector
|
||||||
|
|
||||||
from .base import Base
|
from .base import Base
|
||||||
|
|
||||||
OTHER = "Objects.Other."
|
OTHER = "Objects.Other."
|
||||||
OTHER_REVIT = OTHER + "Revit."
|
|
||||||
|
|
||||||
IDENTITY_TRANSFORM = [
|
IDENTITY_TRANSFORM = [
|
||||||
1.0,
|
1.0,
|
||||||
@@ -29,21 +28,6 @@ IDENTITY_TRANSFORM = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class Material(Base, speckle_type=OTHER + "Material"):
|
|
||||||
"""Generic class for materials containing generic parameters."""
|
|
||||||
|
|
||||||
name: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class RevitMaterial(Material, speckle_type="Objects.Other.Revit." + "RevitMaterial"):
|
|
||||||
materialCategory: Optional[str] = None
|
|
||||||
materialClass: Optional[str] = None
|
|
||||||
shininess: Optional[int] = None
|
|
||||||
smoothness: Optional[int] = None
|
|
||||||
transparency: Optional[int] = None
|
|
||||||
parameters: Optional[Base] = None
|
|
||||||
|
|
||||||
|
|
||||||
class RenderMaterial(Base, speckle_type=OTHER + "RenderMaterial"):
|
class RenderMaterial(Base, speckle_type=OTHER + "RenderMaterial"):
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
opacity: float = 1
|
opacity: float = 1
|
||||||
@@ -53,36 +37,16 @@ class RenderMaterial(Base, speckle_type=OTHER + "RenderMaterial"):
|
|||||||
emissive: int = -16777216 # black arbg
|
emissive: int = -16777216 # black arbg
|
||||||
|
|
||||||
|
|
||||||
class MaterialQuantity(Base, speckle_type=OTHER + "MaterialQuantity"):
|
class RenderMaterialProxy(
|
||||||
material: Optional[Material] = None
|
Base,
|
||||||
volume: Optional[float] = None
|
speckle_type="Speckle.Core.Models.Proxies.RenderMaterialProxy",
|
||||||
area: Optional[float] = None
|
):
|
||||||
|
|
||||||
|
|
||||||
class DisplayStyle(Base, speckle_type=OTHER + "DisplayStyle"):
|
|
||||||
"""
|
"""
|
||||||
Minimal display style class.
|
Used to store render material to object relationships in root collections.
|
||||||
Developed primarily for display styles in Rhino and AutoCAD.
|
|
||||||
Rhino object attributes uses OpenNURBS definition for linetypes and lineweights.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: Optional[str] = None
|
objects: list[str]
|
||||||
color: int = -2894893 # light gray arbg
|
value: RenderMaterial
|
||||||
linetype: Optional[str] = None
|
|
||||||
lineweight: float = 0
|
|
||||||
|
|
||||||
|
|
||||||
class Text(Base, speckle_type=OTHER + "Text"):
|
|
||||||
"""
|
|
||||||
Text object to render it on viewer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
plane: Plane
|
|
||||||
value: str
|
|
||||||
height: float
|
|
||||||
rotation: float
|
|
||||||
displayValue: Optional[List[Polyline]] = None
|
|
||||||
richText: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Transform(
|
class Transform(
|
||||||
@@ -253,59 +217,10 @@ class Transform(
|
|||||||
return cls(value=value)
|
return cls(value=value)
|
||||||
|
|
||||||
|
|
||||||
class BlockDefinition(
|
|
||||||
Base, speckle_type=OTHER + "BlockDefinition", detachable={"geometry"}
|
|
||||||
):
|
|
||||||
name: Optional[str] = None
|
|
||||||
basePoint: Optional[Point] = None
|
|
||||||
geometry: Optional[List[Base]] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Instance(Base, speckle_type=OTHER + "Instance", detachable={"definition"}):
|
|
||||||
transform: Optional[Transform] = None
|
|
||||||
definition: Optional[Base] = None
|
|
||||||
|
|
||||||
|
|
||||||
class BlockInstance(
|
|
||||||
Instance, speckle_type=OTHER + "BlockInstance", serialize_ignore={"blockDefinition"}
|
|
||||||
):
|
|
||||||
@property
|
|
||||||
@deprecated(version="2.13", reason="Use definition")
|
|
||||||
def blockDefinition(self) -> Optional[BlockDefinition]:
|
|
||||||
if isinstance(self.definition, BlockDefinition):
|
|
||||||
return self.definition
|
|
||||||
return None
|
|
||||||
|
|
||||||
@blockDefinition.setter
|
|
||||||
def blockDefinition(self, value: Optional[BlockDefinition]) -> None:
|
|
||||||
self.definition = value
|
|
||||||
|
|
||||||
|
|
||||||
class RevitInstance(Instance, speckle_type=OTHER_REVIT + "RevitInstance"):
|
|
||||||
level: Optional[Base] = None
|
|
||||||
facingFlipped: bool
|
|
||||||
handFlipped: bool
|
|
||||||
parameters: Optional[Base] = None
|
|
||||||
elementId: Optional[str]
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: prob move this into a built elements module, but just trialling this for now
|
|
||||||
class RevitParameter(Base, speckle_type="Objects.BuiltElements.Revit.Parameter"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
value: Any = None
|
|
||||||
applicationUnitType: Optional[str] = None # eg UnitType UT_Length
|
|
||||||
applicationUnit: Optional[str] = None # DisplayUnitType eg DUT_MILLIMITERS
|
|
||||||
applicationInternalName: Optional[
|
|
||||||
str
|
|
||||||
] = None # BuiltInParameterName or GUID for shared parameter
|
|
||||||
isShared: bool = False
|
|
||||||
isReadOnly: bool = False
|
|
||||||
isTypeParameter: bool = False
|
|
||||||
|
|
||||||
|
|
||||||
class Collection(
|
class Collection(
|
||||||
Base, speckle_type="Speckle.Core.Models.Collection", detachable={"elements"}
|
Base,
|
||||||
|
speckle_type="Speckle.Core.Models.Collections.Collection",
|
||||||
|
detachable={"elements"},
|
||||||
):
|
):
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None
|
||||||
collectionType: Optional[str] = None
|
|
||||||
elements: Optional[List[Base]] = None
|
elements: Optional[List[Base]] = None
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
"""Builtin Speckle object kit."""
|
|
||||||
|
|
||||||
from specklepy.objects.structural.analysis import (
|
|
||||||
Model,
|
|
||||||
ModelInfo,
|
|
||||||
ModelSettings,
|
|
||||||
ModelUnits,
|
|
||||||
)
|
|
||||||
from specklepy.objects.structural.axis import Axis, AxisType
|
|
||||||
from specklepy.objects.structural.geometry import (
|
|
||||||
Element1D,
|
|
||||||
Element2D,
|
|
||||||
Element3D,
|
|
||||||
ElementType1D,
|
|
||||||
ElementType2D,
|
|
||||||
ElementType3D,
|
|
||||||
Node,
|
|
||||||
Restraint,
|
|
||||||
)
|
|
||||||
from specklepy.objects.structural.loading import (
|
|
||||||
ActionType,
|
|
||||||
BeamLoadType,
|
|
||||||
CombinationType,
|
|
||||||
FaceLoadType,
|
|
||||||
Load,
|
|
||||||
LoadAxisType,
|
|
||||||
LoadBeam,
|
|
||||||
LoadCase,
|
|
||||||
LoadCombinations,
|
|
||||||
LoadDirection,
|
|
||||||
LoadDirection2D,
|
|
||||||
LoadFace,
|
|
||||||
LoadGravity,
|
|
||||||
LoadNode,
|
|
||||||
LoadType,
|
|
||||||
)
|
|
||||||
from specklepy.objects.structural.materials import (
|
|
||||||
Concrete,
|
|
||||||
MaterialType,
|
|
||||||
Steel,
|
|
||||||
StructuralMaterial,
|
|
||||||
Timber,
|
|
||||||
)
|
|
||||||
from specklepy.objects.structural.properties import (
|
|
||||||
BaseReferencePoint,
|
|
||||||
MemberType,
|
|
||||||
Property,
|
|
||||||
Property1D,
|
|
||||||
Property2D,
|
|
||||||
Property3D,
|
|
||||||
PropertyDamper,
|
|
||||||
PropertyMass,
|
|
||||||
PropertySpring,
|
|
||||||
PropertyType2D,
|
|
||||||
PropertyType3D,
|
|
||||||
PropertyTypeDamper,
|
|
||||||
PropertyTypeSpring,
|
|
||||||
ReferenceSurface,
|
|
||||||
ReferenceSurfaceEnum,
|
|
||||||
SectionProfile,
|
|
||||||
ShapeType,
|
|
||||||
shapeType,
|
|
||||||
)
|
|
||||||
from specklepy.objects.structural.results import (
|
|
||||||
Result,
|
|
||||||
Result1D,
|
|
||||||
Result2D,
|
|
||||||
Result3D,
|
|
||||||
ResultGlobal,
|
|
||||||
ResultNode,
|
|
||||||
ResultSet1D,
|
|
||||||
ResultSet2D,
|
|
||||||
ResultSet3D,
|
|
||||||
ResultSetAll,
|
|
||||||
ResultSetNode,
|
|
||||||
)
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"Element1D",
|
|
||||||
"Element2D",
|
|
||||||
"Element3D",
|
|
||||||
"ElementType1D",
|
|
||||||
"ElementType2D",
|
|
||||||
"ElementType3D",
|
|
||||||
"AxisType",
|
|
||||||
"Axis",
|
|
||||||
"Node",
|
|
||||||
"Restraint",
|
|
||||||
"Load",
|
|
||||||
"LoadType",
|
|
||||||
"ActionType",
|
|
||||||
"BeamLoadType",
|
|
||||||
"FaceLoadType",
|
|
||||||
"LoadDirection",
|
|
||||||
"LoadDirection2D",
|
|
||||||
"LoadAxisType",
|
|
||||||
"CombinationType",
|
|
||||||
"LoadBeam",
|
|
||||||
"LoadCase",
|
|
||||||
"LoadCombinations",
|
|
||||||
"LoadFace",
|
|
||||||
"LoadGravity",
|
|
||||||
"LoadNode",
|
|
||||||
"Model",
|
|
||||||
"ModelInfo",
|
|
||||||
"ModelSettings",
|
|
||||||
"ModelUnits",
|
|
||||||
"MaterialType",
|
|
||||||
"Concrete",
|
|
||||||
"StructuralMaterial",
|
|
||||||
"Steel",
|
|
||||||
"Timber",
|
|
||||||
"Property",
|
|
||||||
"Property1D",
|
|
||||||
"Property2D",
|
|
||||||
"Property3D",
|
|
||||||
"PropertyDamper",
|
|
||||||
"PropertyMass",
|
|
||||||
"PropertySpring",
|
|
||||||
"SectionProfile",
|
|
||||||
"MemberType",
|
|
||||||
"BaseReferencePoint",
|
|
||||||
"ReferenceSurface",
|
|
||||||
"PropertyType2D",
|
|
||||||
"PropertyType3D",
|
|
||||||
"ShapeType",
|
|
||||||
"PropertyTypeSpring",
|
|
||||||
"PropertyTypeDamper",
|
|
||||||
"ReferenceSurfaceEnum",
|
|
||||||
"shapeType",
|
|
||||||
"Result",
|
|
||||||
"Result1D",
|
|
||||||
"ResultSet1D",
|
|
||||||
"Result2D",
|
|
||||||
"ResultSet2D",
|
|
||||||
"Result3D",
|
|
||||||
"ResultSet3D",
|
|
||||||
"ResultGlobal",
|
|
||||||
"ResultSetNode",
|
|
||||||
"ResultNode",
|
|
||||||
"ResultSetAll",
|
|
||||||
]
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
|
|
||||||
STRUCTURAL_ANALYSIS = "Objects.Structural.Analysis."
|
|
||||||
|
|
||||||
|
|
||||||
class ModelUnits(Base, speckle_type=STRUCTURAL_ANALYSIS + "ModelUnits"):
|
|
||||||
length: Optional[str] = None
|
|
||||||
sections: Optional[str] = None
|
|
||||||
displacements: Optional[str] = None
|
|
||||||
stress: Optional[str] = None
|
|
||||||
force: Optional[str] = None
|
|
||||||
mass: Optional[str] = None
|
|
||||||
time: Optional[str] = None
|
|
||||||
temperature: Optional[str] = None
|
|
||||||
velocity: Optional[str] = None
|
|
||||||
acceleration: Optional[str] = None
|
|
||||||
energy: Optional[str] = None
|
|
||||||
angle: Optional[str] = None
|
|
||||||
strain: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ModelSettings(Base, speckle_type=STRUCTURAL_ANALYSIS + "ModelSettings"):
|
|
||||||
modelUnits: Optional[ModelUnits] = None
|
|
||||||
steelCode: Optional[str] = None
|
|
||||||
concreteCode: Optional[str] = None
|
|
||||||
coincidenceTolerance: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class ModelInfo(Base, speckle_type=STRUCTURAL_ANALYSIS + "ModelInfo"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
description: Optional[str] = None
|
|
||||||
projectNumber: Optional[str] = None
|
|
||||||
projectName: Optional[str] = None
|
|
||||||
settings: Optional[ModelSettings] = None
|
|
||||||
initials: Optional[str] = None
|
|
||||||
application: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Model(Base, speckle_type=STRUCTURAL_ANALYSIS + "Model"):
|
|
||||||
specs: Optional[ModelInfo] = None
|
|
||||||
nodes: Optional[List] = None
|
|
||||||
elements: Optional[List] = None
|
|
||||||
loads: Optional[List] = None
|
|
||||||
restraints: Optional[List] = None
|
|
||||||
properties: Optional[List] = None
|
|
||||||
materials: Optional[List] = None
|
|
||||||
layerDescription: Optional[str] = None
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.geometry import Plane
|
|
||||||
|
|
||||||
|
|
||||||
class AxisType(int, Enum):
|
|
||||||
Cartesian = 0
|
|
||||||
Cylindrical = 1
|
|
||||||
Spherical = 2
|
|
||||||
|
|
||||||
|
|
||||||
class Axis(Base, speckle_type="Objects.Structural.Geometry.Axis"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
axisType: Optional[AxisType] = None
|
|
||||||
plane: Optional[Plane] = None
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.geometry import Line, Mesh, Plane, Point, Vector
|
|
||||||
from specklepy.objects.structural.axis import Axis
|
|
||||||
from specklepy.objects.structural.properties import (
|
|
||||||
Property1D,
|
|
||||||
Property2D,
|
|
||||||
Property3D,
|
|
||||||
PropertyDamper,
|
|
||||||
PropertyMass,
|
|
||||||
PropertySpring,
|
|
||||||
)
|
|
||||||
|
|
||||||
STRUCTURAL_GEOMETRY = "Objects.Structural.Geometry"
|
|
||||||
|
|
||||||
|
|
||||||
class ElementType1D(int, Enum):
|
|
||||||
Beam = 0
|
|
||||||
Brace = 1
|
|
||||||
Bar = 2
|
|
||||||
Column = 3
|
|
||||||
Rod = 4
|
|
||||||
Spring = 5
|
|
||||||
Tie = 6
|
|
||||||
Strut = 7
|
|
||||||
Link = 8
|
|
||||||
Damper = 9
|
|
||||||
Cable = 10
|
|
||||||
Spacer = 11
|
|
||||||
Other = 12
|
|
||||||
Null = 13
|
|
||||||
|
|
||||||
|
|
||||||
class ElementType2D(int, Enum):
|
|
||||||
Quad4 = 0
|
|
||||||
Quad8 = 1
|
|
||||||
Triangle3 = 2
|
|
||||||
Triangle6 = 3
|
|
||||||
|
|
||||||
|
|
||||||
class ElementType3D(int, Enum):
|
|
||||||
Brick8 = 0
|
|
||||||
Wedge6 = 1
|
|
||||||
Pyramid5 = 2
|
|
||||||
Tetra4 = 3
|
|
||||||
|
|
||||||
|
|
||||||
class Restraint(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Restraint"):
|
|
||||||
code: Optional[str] = None
|
|
||||||
stiffnessX: float = 0.0
|
|
||||||
stiffnessY: float = 0.0
|
|
||||||
stiffnessZ: float = 0.0
|
|
||||||
stiffnessXX: float = 0.0
|
|
||||||
stiffnessYY: float = 0.0
|
|
||||||
stiffnessZZ: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class Node(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Node"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
basePoint: Optional[Point] = None
|
|
||||||
constraintAxis: Optional[Axis] = None
|
|
||||||
restraint: Optional[Restraint] = None
|
|
||||||
springProperty: Optional[PropertySpring] = None
|
|
||||||
massProperty: Optional[PropertyMass] = None
|
|
||||||
damperProperty: Optional[PropertyDamper] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Element1D(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Element1D"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
baseLine: Optional[Line] = None
|
|
||||||
property: Optional[Property1D] = None
|
|
||||||
type: Optional[ElementType1D] = None
|
|
||||||
end1Releases: Optional[Restraint] = None
|
|
||||||
end2Releases: Optional[Restraint] = None
|
|
||||||
end1Offset: Optional[Vector] = None
|
|
||||||
end2Offset: Optional[Vector] = None
|
|
||||||
orientationNode: Optional[Node] = None
|
|
||||||
orinetationAngle: float = 0.0
|
|
||||||
localAxis: Optional[Plane] = None
|
|
||||||
parent: Optional[Base] = None
|
|
||||||
end1Node: Optional[Node] = None
|
|
||||||
end2Node: Optional[Node] = None
|
|
||||||
topology: Optional[List] = None
|
|
||||||
displayMesh: Optional[Mesh] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Element2D(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Element2D"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
property: Optional[Property2D] = None
|
|
||||||
type: Optional[ElementType2D] = None
|
|
||||||
offset: float = 0.0
|
|
||||||
orientationAngle: float = 0.0
|
|
||||||
parent: Optional[Base] = None
|
|
||||||
topology: Optional[List] = None
|
|
||||||
displayMesh: Optional[Mesh] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Element3D(Base, speckle_type=STRUCTURAL_GEOMETRY + ".Element3D"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
baseMesh: Optional[Mesh] = None
|
|
||||||
property: Optional[Property3D] = None
|
|
||||||
type: Optional[ElementType3D] = None
|
|
||||||
orientationAngle: float = 0.0
|
|
||||||
parent: Optional[Base] = None
|
|
||||||
topology: List
|
|
||||||
|
|
||||||
|
|
||||||
# class Storey needs ependency on built elements first
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.geometry import Vector
|
|
||||||
from specklepy.objects.structural.axis import Axis
|
|
||||||
|
|
||||||
STRUCTURAL_LOADING = "Objects.Structural.Loading."
|
|
||||||
|
|
||||||
|
|
||||||
class LoadType(int, Enum):
|
|
||||||
none = 0
|
|
||||||
Dead = 1
|
|
||||||
SuperDead = 2
|
|
||||||
Soil = 3
|
|
||||||
Live = 4
|
|
||||||
LiveRoof = 5
|
|
||||||
ReducibleLive = 6
|
|
||||||
Wind = 7
|
|
||||||
Snow = 8
|
|
||||||
Rain = 9
|
|
||||||
Thermal = 10
|
|
||||||
Notional = 11
|
|
||||||
Prestress = 12
|
|
||||||
Equivalent = 13
|
|
||||||
Accidental = 14
|
|
||||||
SeismicRSA = 15
|
|
||||||
SeismicAccTorsion = 16
|
|
||||||
SeismicStatic = 17
|
|
||||||
Other = 18
|
|
||||||
|
|
||||||
|
|
||||||
class ActionType(int, Enum):
|
|
||||||
none = 0
|
|
||||||
Permanent = 1
|
|
||||||
Variable = 2
|
|
||||||
Accidental = 3
|
|
||||||
|
|
||||||
|
|
||||||
class BeamLoadType(int, Enum):
|
|
||||||
Point = 0
|
|
||||||
Uniform = 1
|
|
||||||
Linear = 2
|
|
||||||
Patch = 3
|
|
||||||
TriLinear = 4
|
|
||||||
|
|
||||||
|
|
||||||
class FaceLoadType(int, Enum):
|
|
||||||
Constant = 0
|
|
||||||
Variable = 1
|
|
||||||
Point = 2
|
|
||||||
|
|
||||||
|
|
||||||
class LoadDirection2D(int, Enum):
|
|
||||||
X = 0
|
|
||||||
Y = 1
|
|
||||||
Z = 2
|
|
||||||
|
|
||||||
|
|
||||||
class LoadDirection(int, Enum):
|
|
||||||
X = 0
|
|
||||||
Y = 1
|
|
||||||
Z = 2
|
|
||||||
XX = 3
|
|
||||||
YY = 4
|
|
||||||
ZZ = 5
|
|
||||||
|
|
||||||
|
|
||||||
class LoadAxisType(int, Enum):
|
|
||||||
Global = 0
|
|
||||||
Local = 1 # local element axes
|
|
||||||
DeformedLocal = (
|
|
||||||
2 # element local axis that is embedded in the element as it deforms
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CombinationType(int, Enum):
|
|
||||||
LinearAdd = 0
|
|
||||||
Envelope = 1
|
|
||||||
AbsoluteAdd = 2
|
|
||||||
SRSS = 3
|
|
||||||
RangeAdd = 4
|
|
||||||
|
|
||||||
|
|
||||||
class LoadCase(Base, speckle_type=STRUCTURAL_LOADING + "LoadCase"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
loadType: Optional[LoadType] = None
|
|
||||||
group: Optional[str] = None
|
|
||||||
actionType: Optional[ActionType] = None
|
|
||||||
description: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Load(Base, speckle_type=STRUCTURAL_LOADING + "Load"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
loadCase: Optional[LoadCase] = None
|
|
||||||
|
|
||||||
|
|
||||||
class LoadBeam(Load, speckle_type=STRUCTURAL_LOADING + "LoadBeam"):
|
|
||||||
elements: Optional[List] = None
|
|
||||||
loadType: Optional[BeamLoadType] = None
|
|
||||||
direction: Optional[LoadDirection] = None
|
|
||||||
loadAxis: Optional[Axis] = None
|
|
||||||
loadAxisType: Optional[LoadAxisType] = None
|
|
||||||
isProjected: Optional[bool] = None
|
|
||||||
values: Optional[List] = None
|
|
||||||
positions: Optional[List] = None
|
|
||||||
|
|
||||||
|
|
||||||
class LoadCombinations(Base, speckle_type=STRUCTURAL_LOADING + "LoadCombination"):
|
|
||||||
name: Optional[str] = None
|
|
||||||
loadCases: List
|
|
||||||
loadFactors: List
|
|
||||||
combinationType: CombinationType
|
|
||||||
|
|
||||||
|
|
||||||
class LoadFace(Load, speckle_type=STRUCTURAL_LOADING + "LoadFace"):
|
|
||||||
elements: Optional[List] = None
|
|
||||||
loadType: Optional[FaceLoadType] = None
|
|
||||||
direction: Optional[LoadDirection2D] = None
|
|
||||||
loadAxis: Optional[Axis] = None
|
|
||||||
loadAxisType: Optional[LoadAxisType] = None
|
|
||||||
isProjected: Optional[bool] = None
|
|
||||||
values: Optional[List] = None
|
|
||||||
positions: Optional[List] = None
|
|
||||||
|
|
||||||
|
|
||||||
class LoadGravity(Load, speckle_type=STRUCTURAL_LOADING + "LoadGravity"):
|
|
||||||
elements: Optional[List] = None
|
|
||||||
nodes: Optional[List] = None
|
|
||||||
gravityFactors: Optional[Vector] = None
|
|
||||||
|
|
||||||
|
|
||||||
class LoadNode(Load, speckle_type=STRUCTURAL_LOADING + "LoadNode"):
|
|
||||||
nodes: Optional[List] = None
|
|
||||||
loadAxis: Optional[Axis] = None
|
|
||||||
direction: Optional[LoadDirection] = None
|
|
||||||
value: float = 0.0
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
|
|
||||||
STRUCTURAL_MATERIALS = "Objects.Structural.Materials"
|
|
||||||
|
|
||||||
|
|
||||||
class MaterialType(int, Enum):
|
|
||||||
Concrete = 0
|
|
||||||
Steel = 1
|
|
||||||
Timber = 2
|
|
||||||
Aluminium = 3
|
|
||||||
Masonry = 4
|
|
||||||
FRP = 5
|
|
||||||
Glass = 6
|
|
||||||
Fabric = 7
|
|
||||||
Rebar = 8
|
|
||||||
Tendon = 9
|
|
||||||
ColdFormed = 10
|
|
||||||
Other = 11
|
|
||||||
|
|
||||||
|
|
||||||
class StructuralMaterial(
|
|
||||||
Base, speckle_type=STRUCTURAL_MATERIALS + ".StructuralMaterial"
|
|
||||||
):
|
|
||||||
name: Optional[str] = None
|
|
||||||
grade: Optional[str] = None
|
|
||||||
materialType: Optional[MaterialType] = None
|
|
||||||
designCode: Optional[str] = None
|
|
||||||
codeYear: Optional[str] = None
|
|
||||||
strength: float = 0.0
|
|
||||||
elasticModulus: float = 0.0
|
|
||||||
poissonsRatio: float = 0.0
|
|
||||||
shearModulus: float = 0.0
|
|
||||||
density: float = 0.0
|
|
||||||
thermalExpansivity: float = 0.0
|
|
||||||
dampingRatio: float = 0.0
|
|
||||||
cost: float = 0.0
|
|
||||||
materialSafetyFactor: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class Concrete(StructuralMaterial):
|
|
||||||
compressiveStrength: float = 0.0
|
|
||||||
tensileStrength: float = 0.0
|
|
||||||
flexuralStrength: float = 0.0
|
|
||||||
maxCompressiveStrain: float = 0.0
|
|
||||||
maxTensileStrain: float = 0.0
|
|
||||||
maxAggregateSize: float = 0.0
|
|
||||||
lightweight: Optional[bool] = None
|
|
||||||
|
|
||||||
|
|
||||||
class Steel(StructuralMaterial, speckle_type=STRUCTURAL_MATERIALS + ".Steel"):
|
|
||||||
yieldStrength: float = 0.0
|
|
||||||
ultimateStrength: float = 0.0
|
|
||||||
maxStrain: float = 0.0
|
|
||||||
strainHardeningModulus: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class Timber(StructuralMaterial, speckle_type=STRUCTURAL_MATERIALS + ".Timber"):
|
|
||||||
species: Optional[str] = None
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.structural.axis import Axis
|
|
||||||
from specklepy.objects.structural.materials import StructuralMaterial
|
|
||||||
|
|
||||||
STRUCTURAL_PROPERTY = "Objects.Structural.Properties"
|
|
||||||
|
|
||||||
|
|
||||||
class MemberType(int, Enum):
|
|
||||||
Beam = 0
|
|
||||||
Column = 1
|
|
||||||
Generic1D = 2
|
|
||||||
Slab = 3
|
|
||||||
Wall = 4
|
|
||||||
Generic2D = 5
|
|
||||||
VoidCutter1D = 6
|
|
||||||
VoidCutter2D = 7
|
|
||||||
|
|
||||||
|
|
||||||
class BaseReferencePoint(int, Enum):
|
|
||||||
Centroid = 0
|
|
||||||
TopLeft = 1
|
|
||||||
TopCentre = 2
|
|
||||||
TopRight = 3
|
|
||||||
MidLeft = 4
|
|
||||||
MidRight = 5
|
|
||||||
BotLeft = 6
|
|
||||||
BotCentre = 7
|
|
||||||
BotRight = 8
|
|
||||||
|
|
||||||
|
|
||||||
class ReferenceSurface(int, Enum):
|
|
||||||
Top = 0
|
|
||||||
Middle = 1
|
|
||||||
Bottom = 2
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyType2D(int, Enum):
|
|
||||||
Stress = 0
|
|
||||||
Fabric = 1
|
|
||||||
Plate = 2
|
|
||||||
Shell = 3
|
|
||||||
Curved = 4
|
|
||||||
Wall = 5
|
|
||||||
Strain = 6
|
|
||||||
Axi = 7
|
|
||||||
Load = 8
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyType3D(int, Enum):
|
|
||||||
Solid = 0
|
|
||||||
Infinite = 1
|
|
||||||
|
|
||||||
|
|
||||||
class ShapeType(int, Enum):
|
|
||||||
Rectangular = 0
|
|
||||||
Circular = 1
|
|
||||||
I = 2 # noqa: E741
|
|
||||||
Tee = 3
|
|
||||||
Angle = 4
|
|
||||||
Channel = 5
|
|
||||||
Perimeter = 6
|
|
||||||
Box = 7
|
|
||||||
Catalogue = 8
|
|
||||||
Explicit = 9
|
|
||||||
Undefined = 10
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyTypeSpring(int, Enum):
|
|
||||||
Axial = 0
|
|
||||||
Torsional = 1
|
|
||||||
General = 2
|
|
||||||
Matrix = 3
|
|
||||||
TensionOnly = 4
|
|
||||||
CompressionOnly = 5
|
|
||||||
Connector = 6
|
|
||||||
LockUp = 7
|
|
||||||
Gap = 8
|
|
||||||
Friction = 9
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyTypeDamper(int, Enum):
|
|
||||||
Axial = 0
|
|
||||||
Torsional = 1
|
|
||||||
General = 2
|
|
||||||
|
|
||||||
|
|
||||||
class Property(Base, speckle_type=STRUCTURAL_PROPERTY):
|
|
||||||
name: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class SectionProfile(
|
|
||||||
Base, speckle_type=STRUCTURAL_PROPERTY + ".Profiles.SectionProfile"
|
|
||||||
):
|
|
||||||
name: Optional[str] = None
|
|
||||||
shapeType: Optional[ShapeType] = None
|
|
||||||
area: float = 0.0
|
|
||||||
Iyy: float = 0.0
|
|
||||||
Izz: float = 0.0
|
|
||||||
J: float = 0.0
|
|
||||||
Ky: float = 0.0
|
|
||||||
weight: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class Property1D(Property, speckle_type=STRUCTURAL_PROPERTY + ".Property1D"):
|
|
||||||
memberType: Optional[MemberType] = None
|
|
||||||
material: Optional[StructuralMaterial] = None
|
|
||||||
profile: Optional[SectionProfile] = None
|
|
||||||
referencePoint: Optional[BaseReferencePoint] = None
|
|
||||||
offsetY: float = 0.0
|
|
||||||
offsetZ: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class Property2D(Property, speckle_type=STRUCTURAL_PROPERTY + ".Property2D"):
|
|
||||||
type: Optional[PropertyType2D] = None
|
|
||||||
thickness: float = 0.0
|
|
||||||
material: Optional[StructuralMaterial] = None
|
|
||||||
orientationAxis: Optional[Axis] = None
|
|
||||||
refSurface: Optional[ReferenceSurface] = None
|
|
||||||
zOffset: float = 0.0
|
|
||||||
modifierInPlane: float = 0.0
|
|
||||||
modifierBending: float = 0.0
|
|
||||||
modifierShear: float = 0.0
|
|
||||||
modifierVolume: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class Property3D(Property, speckle_type=STRUCTURAL_PROPERTY + ".Property3D"):
|
|
||||||
type: Optional[PropertyType3D] = None
|
|
||||||
material: Optional[StructuralMaterial] = None
|
|
||||||
orientationAxis: Optional[Axis] = None
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyDamper(Property, speckle_type=STRUCTURAL_PROPERTY + ".PropertyDamper"):
|
|
||||||
damperType: Optional[PropertyTypeDamper] = None
|
|
||||||
dampingX: float = 0.0
|
|
||||||
dampingY: float = 0.0
|
|
||||||
dampingZ: float = 0.0
|
|
||||||
dampingXX: float = 0.0
|
|
||||||
dampingYY: float = 0.0
|
|
||||||
dampingZZ: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyMass(Property, speckle_type=STRUCTURAL_PROPERTY + ".PropertyMass"):
|
|
||||||
mass: float = 0.0
|
|
||||||
inertiaXX: float = 0.0
|
|
||||||
inertiaYY: float = 0.0
|
|
||||||
inertiaZZ: float = 0.0
|
|
||||||
inertiaXY: float = 0.0
|
|
||||||
inertiaYZ: float = 0.0
|
|
||||||
inertiaZX: float = 0.0
|
|
||||||
massModified: Optional[bool] = None
|
|
||||||
massModifierX: float = 0.0
|
|
||||||
massModifierY: float = 0.0
|
|
||||||
massModifierZ: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class PropertySpring(Property, speckle_type=STRUCTURAL_PROPERTY + ".PropertySpring"):
|
|
||||||
springType: Optional[PropertyTypeSpring] = None
|
|
||||||
springCurveX: float = 0.0
|
|
||||||
stiffnessX: float = 0.0
|
|
||||||
springCurveY: float = 0.0
|
|
||||||
stiffnessY: float = 0.0
|
|
||||||
springCurveZ: float = 0.0
|
|
||||||
stiffnessZ: float = 0.0
|
|
||||||
springCurveXX: float = 0.0
|
|
||||||
stiffnessXX: float = 0.0
|
|
||||||
springCurveYY: float = 0.0
|
|
||||||
stiffnessYY: float = 0.0
|
|
||||||
springCurveZZ: float = 0.0
|
|
||||||
stiffnessZZ: float = 0.0
|
|
||||||
dampingRatio: float = 0.0
|
|
||||||
dampingX: float = 0.0
|
|
||||||
dampingY: float = 0.0
|
|
||||||
dampingZ: float = 0.0
|
|
||||||
dampingXX: float = 0.0
|
|
||||||
dampingYY: float = 0.0
|
|
||||||
dampingZZ: float = 0.0
|
|
||||||
matrix: float = 0.0
|
|
||||||
postiveLockup: float = 0.0
|
|
||||||
frictionCoefficient: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
class ReferenceSurfaceEnum(int, Enum):
|
|
||||||
Concrete = 0
|
|
||||||
Steel = 1
|
|
||||||
Timber = 2
|
|
||||||
Aluminium = 3
|
|
||||||
Masonry = 4
|
|
||||||
FRP = 5
|
|
||||||
Glass = 6
|
|
||||||
Fabric = 7
|
|
||||||
Rebar = 8
|
|
||||||
Tendon = 9
|
|
||||||
ColdFormed = 10
|
|
||||||
Other = 11
|
|
||||||
|
|
||||||
|
|
||||||
class shapeType(int, Enum):
|
|
||||||
Concrete = 0
|
|
||||||
Steel = 1
|
|
||||||
Timber = 2
|
|
||||||
Aluminium = 3
|
|
||||||
Masonry = 4
|
|
||||||
FRP = 5
|
|
||||||
Glass = 6
|
|
||||||
Fabric = 7
|
|
||||||
Rebar = 8
|
|
||||||
Tendon = 9
|
|
||||||
ColdFormed = 10
|
|
||||||
Other = 11
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
from typing import List, Optional
|
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
|
||||||
from specklepy.objects.structural.analysis import Model
|
|
||||||
from specklepy.objects.structural.geometry import Element1D, Element2D, Element3D, Node
|
|
||||||
|
|
||||||
STRUCTURAL_RESULTS = "Objects.Structural.Results."
|
|
||||||
|
|
||||||
|
|
||||||
class Result(Base, speckle_type=STRUCTURAL_RESULTS + "Result"):
|
|
||||||
resultCase: Optional[Base] = None
|
|
||||||
permutation: Optional[str] = None
|
|
||||||
description: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ResultSet1D(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSet1D"):
|
|
||||||
results1D: List
|
|
||||||
|
|
||||||
|
|
||||||
class Result1D(Result, speckle_type=STRUCTURAL_RESULTS + "Result1D"):
|
|
||||||
element: Optional[Element1D] = None
|
|
||||||
position: Optional[float] = None
|
|
||||||
dispX: Optional[float] = None
|
|
||||||
dispY: Optional[float] = None
|
|
||||||
dispZ: Optional[float] = None
|
|
||||||
rotXX: Optional[float] = None
|
|
||||||
rotYY: Optional[float] = None
|
|
||||||
rotZZ: Optional[float] = None
|
|
||||||
forceX: Optional[float] = None
|
|
||||||
forceY: Optional[float] = None
|
|
||||||
forceZ: Optional[float] = None
|
|
||||||
momentXX: Optional[float] = None
|
|
||||||
momentYY: Optional[float] = None
|
|
||||||
momentZZ: Optional[float] = None
|
|
||||||
axialStress: Optional[float] = None
|
|
||||||
shearStressY: Optional[float] = None
|
|
||||||
shearStressZ: Optional[float] = None
|
|
||||||
bendingStressYPos: Optional[float] = None
|
|
||||||
bendingStressYNeg: Optional[float] = None
|
|
||||||
bendingStressZPos: Optional[float] = None
|
|
||||||
bendingStressZNeg: Optional[float] = None
|
|
||||||
combinedStressMax: Optional[float] = None
|
|
||||||
combinedStressMin: Optional[float] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ResultSet2D(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSet2D"):
|
|
||||||
results2D: List
|
|
||||||
|
|
||||||
|
|
||||||
class Result2D(Result, speckle_type=STRUCTURAL_RESULTS + "Result2D"):
|
|
||||||
element: Optional[Element2D] = None
|
|
||||||
position: List
|
|
||||||
dispX: Optional[float] = None
|
|
||||||
dispY: Optional[float] = None
|
|
||||||
dispZ: Optional[float] = None
|
|
||||||
forceXX: Optional[float] = None
|
|
||||||
forceYY: Optional[float] = None
|
|
||||||
forceXY: Optional[float] = None
|
|
||||||
momentXX: Optional[float] = None
|
|
||||||
momentYY: Optional[float] = None
|
|
||||||
momentXY: Optional[float] = None
|
|
||||||
shearX: Optional[float] = None
|
|
||||||
shearY: Optional[float] = None
|
|
||||||
stressTopXX: Optional[float] = None
|
|
||||||
stressTopYY: Optional[float] = None
|
|
||||||
stressTopZZ: Optional[float] = None
|
|
||||||
stressTopXY: Optional[float] = None
|
|
||||||
stressTopYZ: Optional[float] = None
|
|
||||||
stressTopZX: Optional[float] = None
|
|
||||||
stressMidXX: Optional[float] = None
|
|
||||||
stressMidYY: Optional[float] = None
|
|
||||||
stressMidZZ: Optional[float] = None
|
|
||||||
stressMidXY: Optional[float] = None
|
|
||||||
stressMidYZ: Optional[float] = None
|
|
||||||
stressMidZX: Optional[float] = None
|
|
||||||
stressBotXX: Optional[float] = None
|
|
||||||
stressBotYY: Optional[float] = None
|
|
||||||
stressBotZZ: Optional[float] = None
|
|
||||||
stressBotXY: Optional[float] = None
|
|
||||||
stressBotYZ: Optional[float] = None
|
|
||||||
stressBotZX: Optional[float] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ResultSet3D(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSet3D"):
|
|
||||||
results3D: List
|
|
||||||
|
|
||||||
|
|
||||||
class Result3D(Result, speckle_type=STRUCTURAL_RESULTS + "Result3D"):
|
|
||||||
element: Optional[Element3D] = None
|
|
||||||
position: List
|
|
||||||
dispX: Optional[float] = None
|
|
||||||
dispY: Optional[float] = None
|
|
||||||
dispZ: Optional[float] = None
|
|
||||||
stressXX: Optional[float] = None
|
|
||||||
stressYY: Optional[float] = None
|
|
||||||
stressZZ: Optional[float] = None
|
|
||||||
stressXY: Optional[float] = None
|
|
||||||
stressYZ: Optional[float] = None
|
|
||||||
stressZX: Optional[float] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ResultGlobal(Result, speckle_type=STRUCTURAL_RESULTS + "ResultGlobal"):
|
|
||||||
model: Optional[Model] = None
|
|
||||||
loadX: Optional[float] = None
|
|
||||||
loadY: Optional[float] = None
|
|
||||||
loadZ: Optional[float] = None
|
|
||||||
loadXX: Optional[float] = None
|
|
||||||
loadYY: Optional[float] = None
|
|
||||||
loadZZ: Optional[float] = None
|
|
||||||
reactionX: Optional[float] = None
|
|
||||||
reactionY: Optional[float] = None
|
|
||||||
reactionZ: Optional[float] = None
|
|
||||||
reactionXX: Optional[float] = None
|
|
||||||
reactionYY: Optional[float] = None
|
|
||||||
reactionZZ: Optional[float] = None
|
|
||||||
mode: Optional[float] = None
|
|
||||||
frequency: Optional[float] = None
|
|
||||||
loadFactor: Optional[float] = None
|
|
||||||
modalStiffness: Optional[float] = None
|
|
||||||
modalGeoStiffness: Optional[float] = None
|
|
||||||
effMassX: Optional[float] = None
|
|
||||||
effMassY: Optional[float] = None
|
|
||||||
effMassZ: Optional[float] = None
|
|
||||||
effMassXX: Optional[float] = None
|
|
||||||
effMassYY: Optional[float] = None
|
|
||||||
effMassZZ: Optional[float] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ResultSetNode(Result, speckle_type=STRUCTURAL_RESULTS + "ResultSetNode"):
|
|
||||||
resultsNode: List
|
|
||||||
|
|
||||||
|
|
||||||
class ResultNode(Result, speckle_type=STRUCTURAL_RESULTS + " ResultNode"):
|
|
||||||
node: Optional[Node] = None
|
|
||||||
dispX: Optional[float] = None
|
|
||||||
dispY: Optional[float] = None
|
|
||||||
dispZ: Optional[float] = None
|
|
||||||
rotXX: Optional[float] = None
|
|
||||||
rotYY: Optional[float] = None
|
|
||||||
rotZZ: Optional[float] = None
|
|
||||||
reactionX: Optional[float] = None
|
|
||||||
reactionY: Optional[float] = None
|
|
||||||
reactionZ: Optional[float] = None
|
|
||||||
reactionXX: Optional[float] = None
|
|
||||||
reactionYY: Optional[float] = None
|
|
||||||
reactionZZ: Optional[float] = None
|
|
||||||
constraintX: Optional[float] = None
|
|
||||||
constraintY: Optional[float] = None
|
|
||||||
constraintZ: Optional[float] = None
|
|
||||||
constraintXX: Optional[float] = None
|
|
||||||
constraintYY: Optional[float] = None
|
|
||||||
constraintZZ: Optional[float] = None
|
|
||||||
velX: Optional[float] = None
|
|
||||||
velY: Optional[float] = None
|
|
||||||
velZ: Optional[float] = None
|
|
||||||
velXX: Optional[float] = None
|
|
||||||
velYY: Optional[float] = None
|
|
||||||
velZZ: Optional[float] = None
|
|
||||||
accX: Optional[float] = None
|
|
||||||
accY: Optional[float] = None
|
|
||||||
accZ: Optional[float] = None
|
|
||||||
accXX: Optional[float] = None
|
|
||||||
accYY: Optional[float] = None
|
|
||||||
accZZ: Optional[float] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ResultSetAll(Base, speckle_type=None):
|
|
||||||
resultSet1D: Optional[ResultSet1D] = None
|
|
||||||
resultSet2D: Optional[ResultSet2D] = None
|
|
||||||
resultSet3D: Optional[ResultSet3D] = None
|
|
||||||
resultsGlobal: Optional[ResultGlobal] = None
|
|
||||||
resultsNode: Optional[ResultSetNode] = None
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
|
||||||
|
from specklepy.core.api.inputs.user_inputs import UserUpdateInput
|
||||||
|
from specklepy.core.api.models import ResourceCollection, User
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestActiveUserResource:
|
||||||
|
def test_active_user_get(self, client: SpeckleClient):
|
||||||
|
res = client.active_user.get()
|
||||||
|
|
||||||
|
assert isinstance(res, User)
|
||||||
|
|
||||||
|
def test_active_user_update(self, client: SpeckleClient):
|
||||||
|
NEW_NAME = "Ron"
|
||||||
|
NEW_BIO = "Now I have a bio, isn't that nice!"
|
||||||
|
NEW_COMPANY = "Limited Cooperation Organization Inc"
|
||||||
|
|
||||||
|
input = UserUpdateInput(name=NEW_NAME, bio=NEW_BIO, company=NEW_COMPANY)
|
||||||
|
res = client.active_user.update(input=input)
|
||||||
|
|
||||||
|
assert isinstance(res, User)
|
||||||
|
assert res.name == NEW_NAME
|
||||||
|
assert res.bio == NEW_BIO
|
||||||
|
assert res.company == NEW_COMPANY
|
||||||
|
|
||||||
|
def test_active_user_get_projects(self, client: SpeckleClient):
|
||||||
|
existing = client.active_user.get_projects()
|
||||||
|
|
||||||
|
p1 = client.project.create(
|
||||||
|
ProjectCreateInput(name="Project 1", description=None, visibility=None)
|
||||||
|
)
|
||||||
|
p2 = client.project.create(
|
||||||
|
ProjectCreateInput(name="Project 2", description=None, visibility=None)
|
||||||
|
)
|
||||||
|
|
||||||
|
res = client.active_user.get_projects()
|
||||||
|
|
||||||
|
assert isinstance(res, ResourceCollection)
|
||||||
|
assert len(res.items) == len(existing.items) + 2
|
||||||
|
assert any(project.id == p1.id for project in res.items)
|
||||||
|
assert any(project.id == p2.id for project in res.items)
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.inputs.model_inputs import (
|
||||||
|
CreateModelInput,
|
||||||
|
DeleteModelInput,
|
||||||
|
UpdateModelInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
|
||||||
|
from specklepy.core.api.models.current import (
|
||||||
|
Model,
|
||||||
|
Project,
|
||||||
|
ProjectWithModels,
|
||||||
|
ResourceCollection,
|
||||||
|
)
|
||||||
|
from specklepy.logging.exceptions import GraphQLException
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestModelResource:
|
||||||
|
@pytest.fixture()
|
||||||
|
def test_project(self, client: SpeckleClient) -> Project:
|
||||||
|
project = client.project.create(
|
||||||
|
ProjectCreateInput(name="Test project", description="", visibility=None)
|
||||||
|
)
|
||||||
|
return project
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def test_model(self, client: SpeckleClient, test_project: Project) -> Model:
|
||||||
|
model = client.model.create(
|
||||||
|
CreateModelInput(
|
||||||
|
name="Test Model", description="", projectId=test_project.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return model
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"name, description",
|
||||||
|
[
|
||||||
|
("My Model", "My model description"),
|
||||||
|
("my/nested/model", None),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_model_create(
|
||||||
|
self, client: SpeckleClient, test_project: Project, name: str, description: str
|
||||||
|
):
|
||||||
|
input = CreateModelInput(
|
||||||
|
name=name, description=description, projectId=test_project.id
|
||||||
|
)
|
||||||
|
result = client.model.create(input)
|
||||||
|
|
||||||
|
assert isinstance(result, Model)
|
||||||
|
assert result.name.lower() == name.lower()
|
||||||
|
assert result.description == description
|
||||||
|
|
||||||
|
def test_model_get(
|
||||||
|
self, client: SpeckleClient, test_model: Model, test_project: Project
|
||||||
|
):
|
||||||
|
result = client.model.get(test_model.id, test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, Model)
|
||||||
|
assert result.id == test_model.id
|
||||||
|
assert result.name == test_model.name
|
||||||
|
assert result.description == test_model.description
|
||||||
|
assert result.createdAt == test_model.createdAt
|
||||||
|
assert result.updatedAt == test_model.updatedAt
|
||||||
|
|
||||||
|
def test_get_models(
|
||||||
|
self, client: SpeckleClient, test_project: Project, test_model: Model
|
||||||
|
):
|
||||||
|
result = client.model.get_models(test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, ResourceCollection)
|
||||||
|
assert len(result.items) == 1
|
||||||
|
assert result.totalCount == 1
|
||||||
|
assert result.items[0].id == test_model.id
|
||||||
|
|
||||||
|
def test_project_get_models(
|
||||||
|
self, client: SpeckleClient, test_project: Project, test_model: Model
|
||||||
|
):
|
||||||
|
result = client.project.get_with_models(test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, ProjectWithModels)
|
||||||
|
assert result.id == test_project.id
|
||||||
|
assert len(result.models.items) == 1
|
||||||
|
assert result.models.totalCount == 1
|
||||||
|
assert result.models.items[0].id == test_model.id
|
||||||
|
|
||||||
|
def test_model_update(
|
||||||
|
self, client: SpeckleClient, test_model: Model, test_project: Project
|
||||||
|
):
|
||||||
|
new_name = "MY new name"
|
||||||
|
new_description = "MY new desc"
|
||||||
|
|
||||||
|
update_data = UpdateModelInput(
|
||||||
|
id=test_model.id,
|
||||||
|
name=new_name,
|
||||||
|
description=new_description,
|
||||||
|
projectId=test_project.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
updated_model = client.model.update(update_data)
|
||||||
|
|
||||||
|
assert isinstance(updated_model, Model)
|
||||||
|
assert updated_model.id == test_model.id
|
||||||
|
assert updated_model.name.lower() == new_name.lower()
|
||||||
|
assert updated_model.description == new_description
|
||||||
|
assert updated_model.updatedAt >= test_model.updatedAt
|
||||||
|
|
||||||
|
def test_model_delete(
|
||||||
|
self, client: SpeckleClient, test_model: Model, test_project: Project
|
||||||
|
):
|
||||||
|
delete_data = DeleteModelInput(id=test_model.id, projectId=test_project.id)
|
||||||
|
|
||||||
|
response = client.model.delete(delete_data)
|
||||||
|
assert response is True
|
||||||
|
|
||||||
|
with pytest.raises(GraphQLException):
|
||||||
|
client.model.get(test_model.id, test_project.id)
|
||||||
|
|
||||||
|
with pytest.raises(GraphQLException):
|
||||||
|
client.model.delete(delete_data)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.models import User
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestOtherUserResource:
|
||||||
|
@pytest.fixture(scope="class")
|
||||||
|
def test_data(self, second_client: SpeckleClient) -> User:
|
||||||
|
user_info = second_client.active_user.get()
|
||||||
|
assert user_info
|
||||||
|
return user_info
|
||||||
|
|
||||||
|
def test_other_user_get(self, client: SpeckleClient, test_data: User):
|
||||||
|
res = client.other_user.get(test_data.id)
|
||||||
|
assert res is not None
|
||||||
|
assert res.name == test_data.name
|
||||||
|
|
||||||
|
def test_other_user_get_non_existent_user(self, client: SpeckleClient):
|
||||||
|
result = client.other_user.get("AnIdThatDoesntExist")
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
def test_user_search(self, client: SpeckleClient, test_data: User):
|
||||||
|
assert test_data.email
|
||||||
|
res = client.other_user.user_search(test_data.email, limit=25)
|
||||||
|
assert len(res.items) == 1
|
||||||
|
assert res.items[0].id == test_data.id
|
||||||
|
|
||||||
|
def test_user_search_non_existent_user(self, client: SpeckleClient):
|
||||||
|
res = client.other_user.user_search("idontexist@example.com", limit=25)
|
||||||
|
assert len(res.items) == 0
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectCreateInput,
|
||||||
|
ProjectInviteCreateInput,
|
||||||
|
ProjectInviteUseInput,
|
||||||
|
ProjectUpdateRoleInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import (
|
||||||
|
LimitedUser,
|
||||||
|
PendingStreamCollaborator,
|
||||||
|
Project,
|
||||||
|
ProjectWithTeam,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestProjectInviteResource:
|
||||||
|
@pytest.fixture
|
||||||
|
def project(self, client: SpeckleClient):
|
||||||
|
return client.project.create(
|
||||||
|
ProjectCreateInput(name="test", description=None, visibility=None)
|
||||||
|
)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def created_invite(
|
||||||
|
self, client: SpeckleClient, second_client: SpeckleClient, project: Project
|
||||||
|
):
|
||||||
|
input = ProjectInviteCreateInput(
|
||||||
|
email=second_client.account.userInfo.email,
|
||||||
|
role=None,
|
||||||
|
serverRole=None,
|
||||||
|
userId=None,
|
||||||
|
)
|
||||||
|
res = client.project_invite.create(project.id, input)
|
||||||
|
invites = second_client.active_user.get_project_invites()
|
||||||
|
return next(i for i in invites if i.projectId == res.id)
|
||||||
|
|
||||||
|
def test_project_invite_create_by_email(
|
||||||
|
self, client: SpeckleClient, second_client: SpeckleClient, project: Project
|
||||||
|
):
|
||||||
|
input = ProjectInviteCreateInput(
|
||||||
|
email=second_client.account.userInfo.email,
|
||||||
|
role=None,
|
||||||
|
serverRole=None,
|
||||||
|
userId=None,
|
||||||
|
)
|
||||||
|
res = client.project_invite.create(project.id, input)
|
||||||
|
|
||||||
|
invites = second_client.active_user.get_project_invites()
|
||||||
|
invite = next(i for i in invites if i.projectId == res.id)
|
||||||
|
|
||||||
|
assert isinstance(res, ProjectWithTeam)
|
||||||
|
assert res.id == project.id
|
||||||
|
assert len(res.invitedTeam) == 1
|
||||||
|
|
||||||
|
assert isinstance(invite.user, LimitedUser)
|
||||||
|
assert invite.user.id == second_client.account.userInfo.id
|
||||||
|
assert invite.token
|
||||||
|
|
||||||
|
def test_project_invite_create_by_user_id(
|
||||||
|
self, client: SpeckleClient, second_client: SpeckleClient, project: Project
|
||||||
|
):
|
||||||
|
input = ProjectInviteCreateInput(
|
||||||
|
email=None,
|
||||||
|
role=None,
|
||||||
|
serverRole=None,
|
||||||
|
userId=second_client.account.userInfo.id,
|
||||||
|
)
|
||||||
|
res = client.project_invite.create(project.id, input)
|
||||||
|
|
||||||
|
assert isinstance(res, ProjectWithTeam)
|
||||||
|
assert res.id == project.id
|
||||||
|
assert len(res.invitedTeam) == 1
|
||||||
|
invited_team_member = res.invitedTeam[0].user
|
||||||
|
assert isinstance(invited_team_member, LimitedUser)
|
||||||
|
assert invited_team_member.id == second_client.account.userInfo.id
|
||||||
|
|
||||||
|
def test_project_invite_get(
|
||||||
|
self,
|
||||||
|
second_client: SpeckleClient,
|
||||||
|
project: Project,
|
||||||
|
created_invite: PendingStreamCollaborator,
|
||||||
|
):
|
||||||
|
collaborator = second_client.project_invite.get(
|
||||||
|
project.id, created_invite.token
|
||||||
|
)
|
||||||
|
assert isinstance(collaborator, PendingStreamCollaborator)
|
||||||
|
assert collaborator.inviteId == created_invite.inviteId
|
||||||
|
|
||||||
|
assert isinstance(collaborator.user, LimitedUser)
|
||||||
|
assert isinstance(created_invite.user, LimitedUser)
|
||||||
|
|
||||||
|
assert collaborator.user.id == created_invite.user.id
|
||||||
|
|
||||||
|
def test_project_invite_get_non_existing(
|
||||||
|
self, second_client: SpeckleClient, project: Project
|
||||||
|
):
|
||||||
|
collaborator = second_client.project_invite.get(
|
||||||
|
project.id, "this is not a real token"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert collaborator is None
|
||||||
|
|
||||||
|
def test_project_invite_use_member_added(
|
||||||
|
self,
|
||||||
|
client: SpeckleClient,
|
||||||
|
second_client: SpeckleClient,
|
||||||
|
project: Project,
|
||||||
|
created_invite: PendingStreamCollaborator,
|
||||||
|
):
|
||||||
|
assert created_invite.token
|
||||||
|
|
||||||
|
input = ProjectInviteUseInput(
|
||||||
|
accept=True, projectId=created_invite.projectId, token=created_invite.token
|
||||||
|
)
|
||||||
|
res = second_client.project_invite.use(input)
|
||||||
|
|
||||||
|
assert res is True
|
||||||
|
|
||||||
|
project = client.project.get_with_team(project.id)
|
||||||
|
assert isinstance(project, ProjectWithTeam)
|
||||||
|
|
||||||
|
team_members = [c.user.id for c in project.team]
|
||||||
|
expected_team_members = [
|
||||||
|
client.account.userInfo.id,
|
||||||
|
second_client.account.userInfo.id,
|
||||||
|
]
|
||||||
|
|
||||||
|
assert set(team_members) == set(expected_team_members)
|
||||||
|
|
||||||
|
def test_project_invite_cancel_member_not_added(
|
||||||
|
self, client: SpeckleClient, created_invite: PendingStreamCollaborator
|
||||||
|
):
|
||||||
|
res = client.project_invite.cancel(
|
||||||
|
created_invite.projectId, created_invite.inviteId
|
||||||
|
)
|
||||||
|
|
||||||
|
assert isinstance(res, ProjectWithTeam)
|
||||||
|
assert len(res.invitedTeam) == 0
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"new_role", ["stream:owner", "stream:contributor", "stream:reviewer", None]
|
||||||
|
)
|
||||||
|
def test_project_update_role(
|
||||||
|
self,
|
||||||
|
client: SpeckleClient,
|
||||||
|
second_client: SpeckleClient,
|
||||||
|
project: Project,
|
||||||
|
new_role: Optional[str],
|
||||||
|
created_invite: PendingStreamCollaborator,
|
||||||
|
):
|
||||||
|
assert created_invite.token
|
||||||
|
|
||||||
|
input = ProjectInviteUseInput(
|
||||||
|
accept=True, projectId=created_invite.projectId, token=created_invite.token
|
||||||
|
)
|
||||||
|
res = second_client.project_invite.use(input)
|
||||||
|
|
||||||
|
invitee_id = second_client.account.userInfo.id
|
||||||
|
assert invitee_id
|
||||||
|
input = ProjectUpdateRoleInput(
|
||||||
|
userId=invitee_id,
|
||||||
|
projectId=project.id,
|
||||||
|
role=new_role,
|
||||||
|
)
|
||||||
|
res = client.project.update_role(input)
|
||||||
|
|
||||||
|
assert isinstance(res, ProjectWithTeam)
|
||||||
|
final_project = second_client.project.get(project.id)
|
||||||
|
|
||||||
|
assert isinstance(res, Project)
|
||||||
|
assert final_project.role == new_role
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.enums import ProjectVisibility
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectCreateInput,
|
||||||
|
ProjectUpdateInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import Project
|
||||||
|
from specklepy.logging.exceptions import GraphQLException
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestProjectResource:
|
||||||
|
@pytest.fixture()
|
||||||
|
def test_project(self, client: SpeckleClient) -> Project:
|
||||||
|
project = client.project.create(
|
||||||
|
ProjectCreateInput(
|
||||||
|
name="test project123",
|
||||||
|
description="desc",
|
||||||
|
visibility=ProjectVisibility.PRIVATE,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return project
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"name, description, visibility",
|
||||||
|
[
|
||||||
|
("Very private project", "My secret project", ProjectVisibility.PRIVATE),
|
||||||
|
("Very public project", None, ProjectVisibility.PUBLIC),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_project_create(
|
||||||
|
self,
|
||||||
|
client: SpeckleClient,
|
||||||
|
name: str,
|
||||||
|
description: str,
|
||||||
|
visibility: ProjectVisibility,
|
||||||
|
):
|
||||||
|
input = ProjectCreateInput(
|
||||||
|
name=name,
|
||||||
|
description=description,
|
||||||
|
visibility=visibility,
|
||||||
|
)
|
||||||
|
result = client.project.create(input)
|
||||||
|
|
||||||
|
assert isinstance(result, Project)
|
||||||
|
assert result.id is not None
|
||||||
|
assert result.name == name
|
||||||
|
assert result.description == (description or "")
|
||||||
|
assert result.visibility == visibility
|
||||||
|
|
||||||
|
def test_project_get(self, client: SpeckleClient, test_project: Project):
|
||||||
|
result = client.project.get(test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, Project)
|
||||||
|
assert result.id == test_project.id
|
||||||
|
assert result.name == test_project.name
|
||||||
|
assert result.description == test_project.description
|
||||||
|
assert result.visibility == test_project.visibility
|
||||||
|
assert result.createdAt == test_project.createdAt
|
||||||
|
|
||||||
|
def test_project_update(self, client: SpeckleClient, test_project: Project):
|
||||||
|
new_name = "MY new name"
|
||||||
|
new_description = "MY new desc"
|
||||||
|
new_visibility = ProjectVisibility.PUBLIC
|
||||||
|
|
||||||
|
update_data = ProjectUpdateInput(
|
||||||
|
id=test_project.id,
|
||||||
|
name=new_name,
|
||||||
|
description=new_description,
|
||||||
|
visibility=new_visibility,
|
||||||
|
)
|
||||||
|
|
||||||
|
updated_project = client.project.update(update_data)
|
||||||
|
|
||||||
|
assert isinstance(updated_project, Project)
|
||||||
|
assert updated_project.id == test_project.id
|
||||||
|
assert updated_project.name == new_name
|
||||||
|
assert updated_project.description == new_description
|
||||||
|
assert updated_project.visibility == new_visibility
|
||||||
|
|
||||||
|
def test_project_delete(self, client: SpeckleClient):
|
||||||
|
"""Test deleting a project."""
|
||||||
|
project_to_delete = client.project.create(
|
||||||
|
ProjectCreateInput(name="Delete me", description=None, visibility=None)
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.project.delete(project_to_delete.id)
|
||||||
|
assert response is True
|
||||||
|
|
||||||
|
with pytest.raises(GraphQLException):
|
||||||
|
client.project.get(project_to_delete.id)
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
import asyncio
|
||||||
|
from typing import Dict, Optional
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.enums import (
|
||||||
|
ProjectModelsUpdatedMessageType,
|
||||||
|
ProjectUpdatedMessageType,
|
||||||
|
ProjectVersionsUpdatedMessageType,
|
||||||
|
UserProjectsUpdatedMessageType,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.inputs.model_inputs import CreateModelInput
|
||||||
|
from specklepy.core.api.inputs.project_inputs import (
|
||||||
|
ProjectCreateInput,
|
||||||
|
ProjectUpdateInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import (
|
||||||
|
Model,
|
||||||
|
Project,
|
||||||
|
ProjectModelsUpdatedMessage,
|
||||||
|
ProjectUpdatedMessage,
|
||||||
|
ProjectVersionsUpdatedMessage,
|
||||||
|
UserProjectsUpdatedMessage,
|
||||||
|
Version,
|
||||||
|
)
|
||||||
|
from tests.integration.conftest import create_client, create_version
|
||||||
|
|
||||||
|
WAIT_PERIOD = 0.4 # time in seconds
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestSubscriptionResource:
|
||||||
|
@pytest.fixture
|
||||||
|
def subscription_client(
|
||||||
|
self, host: str, user_dict: Dict[str, str]
|
||||||
|
) -> SpeckleClient:
|
||||||
|
return create_client(host, user_dict["token"])
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_project(self, subscription_client: SpeckleClient) -> Project:
|
||||||
|
project = subscription_client.project.create(
|
||||||
|
ProjectCreateInput(name="Test project", description="", visibility=None)
|
||||||
|
)
|
||||||
|
return project
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_model(
|
||||||
|
self, subscription_client: SpeckleClient, test_project: Project
|
||||||
|
) -> Model:
|
||||||
|
model1 = subscription_client.model.create(
|
||||||
|
CreateModelInput(
|
||||||
|
name="Test Model 1", description="", projectId=test_project.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return model1
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_user_projects_updated(
|
||||||
|
self,
|
||||||
|
subscription_client: SpeckleClient,
|
||||||
|
) -> None:
|
||||||
|
message: Optional[UserProjectsUpdatedMessage] = None
|
||||||
|
|
||||||
|
task = None
|
||||||
|
|
||||||
|
def callback(d: UserProjectsUpdatedMessage):
|
||||||
|
nonlocal message
|
||||||
|
message = d
|
||||||
|
|
||||||
|
task = asyncio.create_task(
|
||||||
|
subscription_client.subscription.user_projects_updated(callback)
|
||||||
|
)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time to subscription to be setup
|
||||||
|
|
||||||
|
input = ProjectCreateInput(name=None, description=None, visibility=None)
|
||||||
|
created = subscription_client.project.create(input)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time for subscription to be triggered
|
||||||
|
|
||||||
|
assert isinstance(message, UserProjectsUpdatedMessage)
|
||||||
|
assert message.id == created.id
|
||||||
|
assert message.type == UserProjectsUpdatedMessageType.ADDED
|
||||||
|
assert isinstance(message.project, Project)
|
||||||
|
task.cancel()
|
||||||
|
await task
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_project_models_updated(
|
||||||
|
self, subscription_client: SpeckleClient, test_project: Project
|
||||||
|
) -> None:
|
||||||
|
message: Optional[ProjectModelsUpdatedMessage] = None
|
||||||
|
|
||||||
|
task = None
|
||||||
|
|
||||||
|
def callback(d: ProjectModelsUpdatedMessage):
|
||||||
|
nonlocal message
|
||||||
|
message = d
|
||||||
|
|
||||||
|
task = asyncio.create_task(
|
||||||
|
subscription_client.subscription.project_models_updated(
|
||||||
|
callback, test_project.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time to subscription to be setup
|
||||||
|
|
||||||
|
input = CreateModelInput(
|
||||||
|
name="my model", description="myDescription", projectId=test_project.id
|
||||||
|
)
|
||||||
|
created = subscription_client.model.create(input)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time for subscription to be triggered
|
||||||
|
|
||||||
|
assert isinstance(message, ProjectModelsUpdatedMessage)
|
||||||
|
assert message.id == created.id
|
||||||
|
assert message.type == ProjectModelsUpdatedMessageType.CREATED
|
||||||
|
assert isinstance(message.model, Model)
|
||||||
|
task.cancel()
|
||||||
|
await task
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_project_updated(
|
||||||
|
self, subscription_client: SpeckleClient, test_project: Project
|
||||||
|
) -> None:
|
||||||
|
message: Optional[ProjectUpdatedMessage] = None
|
||||||
|
|
||||||
|
task = None
|
||||||
|
|
||||||
|
def callback(d: ProjectUpdatedMessage):
|
||||||
|
nonlocal message
|
||||||
|
message = d
|
||||||
|
|
||||||
|
task = asyncio.create_task(
|
||||||
|
subscription_client.subscription.project_updated(callback, test_project.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time to subscription to be setup
|
||||||
|
|
||||||
|
input = ProjectUpdateInput(id=test_project.id, name="This is my new name")
|
||||||
|
created = subscription_client.project.update(input)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time for subscription to be triggered
|
||||||
|
|
||||||
|
assert isinstance(message, ProjectUpdatedMessage)
|
||||||
|
assert message.id == created.id
|
||||||
|
assert message.type == ProjectUpdatedMessageType.UPDATED
|
||||||
|
assert isinstance(message.project, Project)
|
||||||
|
task.cancel()
|
||||||
|
await task
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_project_versions_updated(
|
||||||
|
self,
|
||||||
|
subscription_client: SpeckleClient,
|
||||||
|
test_project: Project,
|
||||||
|
test_model: Model,
|
||||||
|
) -> None:
|
||||||
|
message: Optional[ProjectVersionsUpdatedMessage] = None
|
||||||
|
|
||||||
|
task = None
|
||||||
|
|
||||||
|
def callback(d: ProjectVersionsUpdatedMessage):
|
||||||
|
nonlocal message
|
||||||
|
message = d
|
||||||
|
|
||||||
|
task = asyncio.create_task(
|
||||||
|
subscription_client.subscription.project_versions_updated(
|
||||||
|
callback, test_project.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time to subscription to be setup
|
||||||
|
|
||||||
|
created = create_version(subscription_client, test_project.id, test_model.id)
|
||||||
|
|
||||||
|
await asyncio.sleep(WAIT_PERIOD) # Give time for subscription to be triggered
|
||||||
|
|
||||||
|
assert isinstance(message, ProjectVersionsUpdatedMessage)
|
||||||
|
assert message.id == created.id
|
||||||
|
assert message.type == ProjectVersionsUpdatedMessageType.CREATED
|
||||||
|
assert isinstance(message.version, Version)
|
||||||
|
task.cancel()
|
||||||
|
await task
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.api.client import SpeckleClient
|
||||||
|
from specklepy.core.api.inputs.model_inputs import CreateModelInput
|
||||||
|
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
|
||||||
|
from specklepy.core.api.inputs.version_inputs import (
|
||||||
|
DeleteVersionsInput,
|
||||||
|
MarkReceivedVersionInput,
|
||||||
|
MoveVersionsInput,
|
||||||
|
UpdateVersionInput,
|
||||||
|
)
|
||||||
|
from specklepy.core.api.models import (
|
||||||
|
Model,
|
||||||
|
ModelWithVersions,
|
||||||
|
Project,
|
||||||
|
ResourceCollection,
|
||||||
|
Version,
|
||||||
|
)
|
||||||
|
from specklepy.logging.exceptions import GraphQLException
|
||||||
|
from tests.integration.conftest import create_version
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.run()
|
||||||
|
class TestVersionResource:
|
||||||
|
@pytest.fixture
|
||||||
|
def test_project(self, client: SpeckleClient) -> Project:
|
||||||
|
project = client.project.create(
|
||||||
|
ProjectCreateInput(name="Test project", description="", visibility=None)
|
||||||
|
)
|
||||||
|
return project
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_model_1(self, client: SpeckleClient, test_project: Project) -> Model:
|
||||||
|
model1 = client.model.create(
|
||||||
|
CreateModelInput(
|
||||||
|
name="Test Model 1", description="", projectId=test_project.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return model1
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_model_2(self, client: SpeckleClient, test_project: Project) -> Model:
|
||||||
|
model2 = client.model.create(
|
||||||
|
CreateModelInput(
|
||||||
|
name="Test Model 2", description="", projectId=test_project.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return model2
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_version(
|
||||||
|
self, client: SpeckleClient, test_project: Project, test_model_1: Model
|
||||||
|
) -> Version:
|
||||||
|
return create_version(client, test_project.id, test_model_1.id)
|
||||||
|
|
||||||
|
def test_version_get(
|
||||||
|
self, client: SpeckleClient, test_version: Version, test_project: Project
|
||||||
|
):
|
||||||
|
result = client.version.get(test_version.id, test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, Version)
|
||||||
|
assert result.id == test_version.id
|
||||||
|
assert result.message == test_version.message
|
||||||
|
|
||||||
|
def test_versions_get(
|
||||||
|
self,
|
||||||
|
client: SpeckleClient,
|
||||||
|
test_model_1: Model,
|
||||||
|
test_project: Project,
|
||||||
|
test_version: Version,
|
||||||
|
):
|
||||||
|
result = client.version.get_versions(test_model_1.id, test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, ResourceCollection)
|
||||||
|
assert len(result.items) == 1
|
||||||
|
assert result.totalCount == 1
|
||||||
|
assert result.items[0].id == test_version.id
|
||||||
|
|
||||||
|
def test_version_received(
|
||||||
|
self, client: SpeckleClient, test_version: Version, test_project: Project
|
||||||
|
):
|
||||||
|
input = MarkReceivedVersionInput(
|
||||||
|
versionId=test_version.id,
|
||||||
|
projectId=test_project.id,
|
||||||
|
sourceApplication="Integration test",
|
||||||
|
)
|
||||||
|
result = client.version.received(input)
|
||||||
|
|
||||||
|
assert result is True
|
||||||
|
|
||||||
|
def test_model_get_with_versions(
|
||||||
|
self,
|
||||||
|
client: SpeckleClient,
|
||||||
|
test_model_1: Model,
|
||||||
|
test_project: Project,
|
||||||
|
test_version: Version,
|
||||||
|
):
|
||||||
|
result = client.model.get_with_versions(test_model_1.id, test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(result, ModelWithVersions)
|
||||||
|
assert result.id == test_model_1.id
|
||||||
|
assert len(result.versions.items) == 1
|
||||||
|
assert result.versions.totalCount == 1
|
||||||
|
assert result.versions.items[0].id == test_version.id
|
||||||
|
|
||||||
|
def test_version_update(
|
||||||
|
self, client: SpeckleClient, test_version: Version, test_project: Project
|
||||||
|
):
|
||||||
|
new_message = "MY new version message"
|
||||||
|
input = UpdateVersionInput(
|
||||||
|
versionId=test_version.id, projectId=test_project.id, message=new_message
|
||||||
|
)
|
||||||
|
updated_version = client.version.update(input)
|
||||||
|
|
||||||
|
assert isinstance(updated_version, Version)
|
||||||
|
assert updated_version.id == test_version.id
|
||||||
|
assert updated_version.message == new_message
|
||||||
|
assert updated_version.previewUrl == test_version.previewUrl
|
||||||
|
|
||||||
|
def test_version_move_to_model(
|
||||||
|
self,
|
||||||
|
client: SpeckleClient,
|
||||||
|
test_project: Project,
|
||||||
|
test_version: Version,
|
||||||
|
test_model_2: Model,
|
||||||
|
):
|
||||||
|
input = MoveVersionsInput(
|
||||||
|
targetModelName=test_model_2.name,
|
||||||
|
versionIds=[test_version.id],
|
||||||
|
projectId=test_project.id,
|
||||||
|
)
|
||||||
|
moved_model_id = client.version.move_to_model(input)
|
||||||
|
|
||||||
|
assert isinstance(moved_model_id, str)
|
||||||
|
assert moved_model_id == test_model_2.id
|
||||||
|
moved_version = client.version.get(test_version.id, test_project.id)
|
||||||
|
|
||||||
|
assert isinstance(moved_version, Version)
|
||||||
|
assert moved_version.id == test_version.id
|
||||||
|
assert moved_version.message == test_version.message
|
||||||
|
assert moved_version.previewUrl == test_version.previewUrl
|
||||||
|
|
||||||
|
def test_version_delete(
|
||||||
|
self, client: SpeckleClient, test_version: Version, test_project: Project
|
||||||
|
):
|
||||||
|
input = DeleteVersionsInput(
|
||||||
|
versionIds=[test_version.id], projectId=test_project.id
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.version.delete(input)
|
||||||
|
assert response is True
|
||||||
|
|
||||||
|
with pytest.raises(GraphQLException):
|
||||||
|
client.version.get(test_version.id, test_project.id)
|
||||||
|
|
||||||
|
with pytest.raises(GraphQLException):
|
||||||
|
client.version.delete(input)
|
||||||
+6
-7
@@ -2,7 +2,7 @@ import pytest
|
|||||||
|
|
||||||
from specklepy.api.client import SpeckleClient
|
from specklepy.api.client import SpeckleClient
|
||||||
from specklepy.api.models import Activity, ActivityCollection, User
|
from specklepy.api.models import Activity, ActivityCollection, User
|
||||||
from specklepy.logging.exceptions import SpeckleException
|
from specklepy.logging.exceptions import GraphQLException
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.run(order=2)
|
@pytest.mark.run(order=2)
|
||||||
@@ -19,15 +19,14 @@ class TestUser:
|
|||||||
def test_user_update(self, client: SpeckleClient):
|
def test_user_update(self, client: SpeckleClient):
|
||||||
bio = "i am a ghost in the machine"
|
bio = "i am a ghost in the machine"
|
||||||
|
|
||||||
failed_update = client.active_user.update()
|
with pytest.raises(GraphQLException):
|
||||||
assert isinstance(failed_update, SpeckleException)
|
client.active_user.update(bio=None)
|
||||||
|
|
||||||
updated = client.active_user.update(bio=bio)
|
updated = client.active_user.update(bio=bio)
|
||||||
|
|
||||||
me = client.active_user.get()
|
assert isinstance(updated, User)
|
||||||
|
assert isinstance(updated, User)
|
||||||
assert updated is True
|
assert updated.bio == bio
|
||||||
assert me.bio == bio
|
|
||||||
|
|
||||||
def test_user_activity(self, client: SpeckleClient, second_user_dict):
|
def test_user_activity(self, client: SpeckleClient, second_user_dict):
|
||||||
my_activity = client.active_user.activity(limit=10)
|
my_activity = client.active_user.activity(limit=10)
|
||||||
+2
-2
@@ -13,7 +13,7 @@ class TestOtherUser:
|
|||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
client.other_user.get()
|
client.other_user.get()
|
||||||
|
|
||||||
def test_user_search(self, client, second_user_dict):
|
def test_user_search(self, client: SpeckleClient, second_user_dict):
|
||||||
search_results = client.other_user.search(
|
search_results = client.other_user.search(
|
||||||
search_query=second_user_dict["name"][:5]
|
search_query=second_user_dict["name"][:5]
|
||||||
)
|
)
|
||||||
@@ -27,7 +27,7 @@ class TestOtherUser:
|
|||||||
second_user_dict["id"] = result_user.id
|
second_user_dict["id"] = result_user.id
|
||||||
assert getattr(result_user, "email", None) is None
|
assert getattr(result_user, "email", None) is None
|
||||||
|
|
||||||
def test_user_get(self, client, second_user_dict):
|
def test_user_get(self, client: SpeckleClient, second_user_dict):
|
||||||
fetched_user = client.other_user.get(id=second_user_dict["id"])
|
fetched_user = client.other_user.get(id=second_user_dict["id"])
|
||||||
|
|
||||||
assert isinstance(fetched_user, LimitedUser)
|
assert isinstance(fetched_user, LimitedUser)
|
||||||
@@ -1,26 +1,30 @@
|
|||||||
import random
|
import random
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Dict
|
||||||
from urllib.parse import parse_qs, urlparse
|
from urllib.parse import parse_qs, urlparse
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from specklepy.api.client import SpeckleClient
|
from specklepy.api.client import SpeckleClient
|
||||||
from specklepy.api.models import Stream
|
from specklepy.core.api import operations
|
||||||
|
from specklepy.core.api.inputs.version_inputs import CreateVersionInput
|
||||||
|
from specklepy.core.api.models import Stream, Version
|
||||||
from specklepy.logging import metrics
|
from specklepy.logging import metrics
|
||||||
from specklepy.objects.base import Base
|
from specklepy.objects.base import Base
|
||||||
from specklepy.objects.fakemesh import FakeDirection, FakeMesh
|
from specklepy.objects.fakemesh import FakeDirection, FakeMesh
|
||||||
from specklepy.objects.geometry import Point
|
from specklepy.objects.geometry import Point
|
||||||
|
from specklepy.transports.server.server import ServerTransport
|
||||||
|
|
||||||
metrics.disable()
|
metrics.disable()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def host():
|
def host() -> str:
|
||||||
return "localhost:3000"
|
return "localhost:3000"
|
||||||
|
|
||||||
|
|
||||||
def seed_user(host):
|
def seed_user(host: str) -> Dict[str, str]:
|
||||||
seed = uuid.uuid4().hex
|
seed = uuid.uuid4().hex
|
||||||
user_dict = {
|
user_dict = {
|
||||||
"email": f"{seed[0:7]}@example.org",
|
"email": f"{seed[0:7]}@example.org",
|
||||||
@@ -57,32 +61,53 @@ def seed_user(host):
|
|||||||
return user_dict
|
return user_dict
|
||||||
|
|
||||||
|
|
||||||
|
def create_version(client: SpeckleClient, project_id: str, model_id: str) -> Version:
|
||||||
|
remote = ServerTransport(project_id, client)
|
||||||
|
objectId = operations.send(
|
||||||
|
Base(applicationId="ASDF"), [remote], use_default_cache=False
|
||||||
|
)
|
||||||
|
input = CreateVersionInput(
|
||||||
|
objectId=objectId, modelId=model_id, projectId=project_id
|
||||||
|
)
|
||||||
|
version_id = client.version.create(input)
|
||||||
|
return client.version.get(version_id, project_id)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def user_dict(host):
|
def user_dict(host: str) -> Dict[str, str]:
|
||||||
return seed_user(host)
|
return seed_user(host)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def second_user_dict(host):
|
def second_user_dict(host: str) -> Dict[str, str]:
|
||||||
return seed_user(host)
|
return seed_user(host)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
def create_client(host: str, token: str) -> SpeckleClient:
|
||||||
def client(host, user_dict):
|
|
||||||
client = SpeckleClient(host=host, use_ssl=False)
|
client = SpeckleClient(host=host, use_ssl=False)
|
||||||
client.authenticate_with_token(user_dict["token"])
|
client.authenticate_with_token(token)
|
||||||
|
user = client.active_user.get()
|
||||||
|
assert user
|
||||||
|
client.account.userInfo.id = user.id
|
||||||
|
client.account.userInfo.email = user.email
|
||||||
|
client.account.userInfo.name = user.name
|
||||||
|
client.account.userInfo.company = user.company
|
||||||
|
client.account.userInfo.avatar = user.avatar
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def second_client(host, second_user_dict):
|
def client(host: str, user_dict: Dict[str, str]) -> SpeckleClient:
|
||||||
client = SpeckleClient(host=host, use_ssl=False)
|
return create_client(host, user_dict["token"])
|
||||||
client.authenticate_with_token(second_user_dict["token"])
|
|
||||||
return client
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def sample_stream(client):
|
def second_client(host: str, second_user_dict: Dict[str, str]):
|
||||||
|
return create_client(host, second_user_dict["token"])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def sample_stream(client: SpeckleClient) -> Stream:
|
||||||
stream = Stream(
|
stream = Stream(
|
||||||
name="a sample stream for testing",
|
name="a sample stream for testing",
|
||||||
description="a stream created for testing",
|
description="a stream created for testing",
|
||||||
@@ -93,7 +118,7 @@ def sample_stream(client):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def mesh():
|
def mesh() -> FakeMesh:
|
||||||
mesh = FakeMesh()
|
mesh = FakeMesh()
|
||||||
mesh.name = "my_mesh"
|
mesh.name = "my_mesh"
|
||||||
mesh.vertices = [random.uniform(0, 10) for _ in range(1, 210)]
|
mesh.vertices = [random.uniform(0, 10) for _ in range(1, 210)]
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# pylint: disable=redefined-outer-name
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.core.api.models.instances import InstanceDefinitionProxy, InstanceProxy
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def instance_proxy():
|
||||||
|
return InstanceProxy(
|
||||||
|
definitionId="definitionId", transform=[1, 23.5], units="unit", maxDepth=3
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def instance_definition_proxy():
|
||||||
|
return InstanceDefinitionProxy(
|
||||||
|
objects=["app_id_1", "app_id_2"], maxDepth=2, name="group_proxy_name"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_instance_proxy():
|
||||||
|
try:
|
||||||
|
InstanceProxy(definitionId="", transform="", units="", maxDepth=1) # wrong type
|
||||||
|
assert False
|
||||||
|
except TypeError:
|
||||||
|
assert True
|
||||||
|
except:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_instance_definition_proxy():
|
||||||
|
try:
|
||||||
|
InstanceDefinitionProxy(objects="", maxDepth=1, name="") # wrong type
|
||||||
|
assert False
|
||||||
|
except TypeError:
|
||||||
|
assert True
|
||||||
|
except:
|
||||||
|
assert False
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# pylint: disable=redefined-outer-name
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from specklepy.core.api.models.proxies import ColorProxy, GroupProxy
|
||||||
|
from specklepy.objects.other import RenderMaterial, RenderMaterialProxy
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def color_proxy():
|
||||||
|
return ColorProxy(
|
||||||
|
objects=["app_id_1", "app_id_2"], value=11111, name="color_proxy_name"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def group_proxy():
|
||||||
|
return GroupProxy(objects=["app_id_1", "app_id_2"], name="group_proxy_name")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def material():
|
||||||
|
return RenderMaterial(
|
||||||
|
name="name", opacity=0.3, metalness=0, roughness=0, diffuse=1, emissive=1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def material_proxy():
|
||||||
|
return RenderMaterialProxy(objects=["app_id_1", "app_id_2"], value=material())
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_color_proxy():
|
||||||
|
try:
|
||||||
|
ColorProxy(objects="", value=2, name="") # wrong type
|
||||||
|
assert False
|
||||||
|
except TypeError:
|
||||||
|
assert True
|
||||||
|
except:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_group_proxy():
|
||||||
|
try:
|
||||||
|
GroupProxy(objects="", name="") # wrong type
|
||||||
|
assert False
|
||||||
|
except TypeError:
|
||||||
|
assert True
|
||||||
|
except:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_material_proxy():
|
||||||
|
try:
|
||||||
|
RenderMaterialProxy(objects="", name="") # wrong type
|
||||||
|
assert False
|
||||||
|
except TypeError:
|
||||||
|
assert True
|
||||||
|
except:
|
||||||
|
assert False
|
||||||
@@ -3,7 +3,7 @@ from typing import Type
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from specklepy.objects.base import Base
|
from specklepy.objects.base import Base
|
||||||
from specklepy.objects.structural import Concrete
|
from specklepy.objects.geometry import Line
|
||||||
|
|
||||||
|
|
||||||
class Foo(Base):
|
class Foo(Base):
|
||||||
@@ -29,8 +29,8 @@ class Baz(Bar):
|
|||||||
"Tests.Unit.TestRegisteringBase.Foo:Custom.Bar:Tests.Unit.TestRegisteringBase.Baz",
|
"Tests.Unit.TestRegisteringBase.Foo:Custom.Bar:Tests.Unit.TestRegisteringBase.Baz",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Concrete,
|
Line,
|
||||||
"Objects.Structural.Materials.StructuralMaterial:Objects.Structural.Materials.Concrete",
|
"Objects.Geometry.Line",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -43,7 +43,7 @@ def test_determine_speckle_type(klass: Type[Base], speckle_type: str):
|
|||||||
[
|
[
|
||||||
(Base, "Base"),
|
(Base, "Base"),
|
||||||
(Foo, "Tests.Unit.TestRegisteringBase.Foo"),
|
(Foo, "Tests.Unit.TestRegisteringBase.Foo"),
|
||||||
(Concrete, "Objects.Structural.Materials.Concrete"),
|
(Line, "Objects.Geometry.Line"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_full_name(klass: Type[Base], fully_qualified_name: str):
|
def test_full_name(klass: Type[Base], fully_qualified_name: str):
|
||||||
|
|||||||
@@ -1,143 +0,0 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from specklepy.objects.geometry import Line, Mesh, Point, Vector
|
|
||||||
from specklepy.objects.structural.analysis import Model
|
|
||||||
from specklepy.objects.structural.geometry import (
|
|
||||||
Element1D,
|
|
||||||
Element2D,
|
|
||||||
ElementType1D,
|
|
||||||
ElementType2D,
|
|
||||||
Node,
|
|
||||||
Restraint,
|
|
||||||
)
|
|
||||||
from specklepy.objects.structural.loading import LoadGravity
|
|
||||||
from specklepy.objects.structural.materials import StructuralMaterial
|
|
||||||
from specklepy.objects.structural.properties import (
|
|
||||||
MemberType,
|
|
||||||
Property1D,
|
|
||||||
Property2D,
|
|
||||||
SectionProfile,
|
|
||||||
ShapeType,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def point():
|
|
||||||
return Point(x=1, y=10, z=0)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def vector():
|
|
||||||
return Vector(x=0, y=0, z=-1)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def line(point, interval):
|
|
||||||
return Line(
|
|
||||||
start=point,
|
|
||||||
end=point,
|
|
||||||
domain=interval,
|
|
||||||
# These attributes are not handled in C#
|
|
||||||
# bbox=None,
|
|
||||||
# length=None
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def mesh(box):
|
|
||||||
return Mesh(
|
|
||||||
vertices=[2, 1, 2, 4, 77.3, 5, 33, 4, 2],
|
|
||||||
faces=[1, 2, 3, 4, 5, 6, 7],
|
|
||||||
colors=[111, 222, 333, 444, 555, 666, 777],
|
|
||||||
bbox=box,
|
|
||||||
area=233,
|
|
||||||
volume=232.2,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def restraint():
|
|
||||||
return Restraint(code="FFFFFF")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def node(restraint, point):
|
|
||||||
return Node(basePoint=point, restraint=restraint, name="node1")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def material():
|
|
||||||
return StructuralMaterial(name="TestMaterial")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def memberType():
|
|
||||||
return MemberType(0)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def shapeType():
|
|
||||||
return ShapeType(8)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def sectionProfile(shapeType):
|
|
||||||
return SectionProfile(name="Test", shapeType=shapeType)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def property1D(memberType, sectionProfile, material):
|
|
||||||
return Property1D(
|
|
||||||
Material=material,
|
|
||||||
SectionProfile=sectionProfile,
|
|
||||||
memberType=memberType,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def elementType1D():
|
|
||||||
return ElementType1D(0)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def element1D(line, restraint, elementType1D, property1D):
|
|
||||||
return Element1D(
|
|
||||||
baseLine=line,
|
|
||||||
end1Releases=restraint,
|
|
||||||
end2Releases=restraint,
|
|
||||||
type=elementType1D,
|
|
||||||
property=property1D,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def property2D(material):
|
|
||||||
return Property2D(Material=material)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def elementType2D():
|
|
||||||
return ElementType2D(0)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def element2D(point, elementType2D):
|
|
||||||
return Element2D(
|
|
||||||
topology=[point],
|
|
||||||
type=elementType2D,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def loadGravity(element1D, element2D, vector):
|
|
||||||
return LoadGravity(elements=[element1D, element2D], gravityFactors=vector)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def model(loadGravity, element1D, element2D, material, property1D, property2D):
|
|
||||||
return Model(
|
|
||||||
loads=[loadGravity],
|
|
||||||
elements=[element1D, element2D],
|
|
||||||
materials=[material],
|
|
||||||
properties=[property1D, property2D],
|
|
||||||
)
|
|
||||||
Reference in New Issue
Block a user