Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a419664461 | |||
| 4a0c07009b | |||
| 682bcbfa9f | |||
| ccf284e8fa | |||
| 23102a28ff | |||
| 5475edb253 | |||
| c52f80c1ef | |||
| 21eecfa24c | |||
| 5dde1bfcf1 | |||
| 82c9d874c9 | |||
| 9acf2c8a92 | |||
| 95012e60c1 | |||
| 19b6500bbd | |||
| 47a06e4630 | |||
| e5a8b40bb2 | |||
| 219456f5f8 | |||
| d1544ae89f | |||
| 8f7d4b2ca7 | |||
| a7d31d4983 | |||
| a89b12a02c | |||
| 15ae68f5d7 | |||
| 0709cd99b5 | |||
| faf06f7141 | |||
| b54e09f811 | |||
| 55b7e0d732 | |||
| 45c922679b |
+13
-4
@@ -2,14 +2,15 @@ version: 2.1
|
||||
|
||||
orbs:
|
||||
python: circleci/python@1.3.2
|
||||
codecov: codecov/codecov@3.2.2
|
||||
|
||||
jobs:
|
||||
test:
|
||||
docker:
|
||||
- image: "cimg/python:<<parameters.tag>>"
|
||||
- image: "circleci/node:12"
|
||||
- image: "circleci/redis:6"
|
||||
- image: "circleci/postgres:12"
|
||||
- image: 'cimg/node:14.18'
|
||||
- image: 'circleci/redis:6'
|
||||
- image: 'cimg/postgres:12.8'
|
||||
environment:
|
||||
POSTGRES_DB: speckle2_test
|
||||
POSTGRES_PASSWORD: speckle
|
||||
@@ -38,7 +39,15 @@ jobs:
|
||||
name: upgrade pip
|
||||
- python/install-packages:
|
||||
pkg-manager: poetry
|
||||
- run: poetry run pytest
|
||||
- run: poetry run pytest --cov --cov-report xml:reports/coverage.xml --junitxml=reports/test-results.xml
|
||||
|
||||
- store_test_results:
|
||||
path: reports
|
||||
|
||||
- store_artifacts:
|
||||
path: reports
|
||||
|
||||
- codecov/upload
|
||||
|
||||
deploy:
|
||||
docker:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.tool-versions
|
||||
.envrc
|
||||
reports/
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<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> </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
|
||||
|
||||
|
||||
Generated
+531
-281
File diff suppressed because it is too large
Load Diff
+5
-4
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "specklepy"
|
||||
version = "2.1.0"
|
||||
version = "2.4.0"
|
||||
description = "The Python SDK for Speckle 2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Speckle Systems <devops@speckle.systems>"]
|
||||
@@ -12,16 +12,17 @@ homepage = "https://speckle.systems/"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.6.5"
|
||||
pydantic = "^1.7.3"
|
||||
pydantic = "^1.8.2"
|
||||
appdirs = "^1.4.4"
|
||||
gql = {version = ">=3.0.0a6", extras = ["all"], allow-prereleases = true}
|
||||
ujson = "^4.1.0"
|
||||
gql = {version = ">=3.0.0b1", extras = ["all"], allow-prereleases = true}
|
||||
ujson = "^4.3.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
black = "^20.8b1"
|
||||
isort = "^5.7.0"
|
||||
pytest = "^6.2.2"
|
||||
pytest-ordering = "^0.6"
|
||||
pytest-cov = "^3.0.0"
|
||||
|
||||
|
||||
[tool.black]
|
||||
|
||||
@@ -89,6 +89,28 @@ def get_default_account(base_path: str = None) -> Account:
|
||||
|
||||
|
||||
class StreamWrapper:
|
||||
"""
|
||||
The `StreamWrapper` gives you some handy helpers to deal with urls and get authenticated clients and transports.
|
||||
|
||||
Construct a `StreamWrapper` with a stream, branch, commit, or object URL. The corresponding ids will be stored
|
||||
in the wrapper. If you have local accounts on the machine, you can use the `get_account` and `get_client` methods
|
||||
to get a local account for the server. You can also pass a token into `get_client` if you don't have a corresponding
|
||||
local account for the server.
|
||||
|
||||
```py
|
||||
from specklepy.api.credentials import StreamWrapper
|
||||
|
||||
# provide any stream, branch, commit, object, or globals url
|
||||
wrapper = StreamWrapper("https://speckle.xyz/streams/3073b96e86/commits/604bea8cc6")
|
||||
|
||||
# get an authenticated SpeckleClient if you have a local account for the server
|
||||
client = wrapper.get_client()
|
||||
|
||||
# get an authenticated ServerTransport if you have a local account for the server
|
||||
transport = wrapper.get_transport()
|
||||
```
|
||||
"""
|
||||
|
||||
stream_url: str = None
|
||||
use_ssl: bool = True
|
||||
host: str = None
|
||||
@@ -122,9 +144,9 @@ class StreamWrapper:
|
||||
parsed = urlparse(url)
|
||||
self.host = parsed.netloc
|
||||
self.use_ssl = parsed.scheme == "https"
|
||||
segments = parsed.path.strip("/").split("/")
|
||||
segments = parsed.path.strip("/").split("/", 3)
|
||||
|
||||
if not segments or len(segments) > 4 or len(segments) < 2:
|
||||
if not segments or len(segments) < 2:
|
||||
raise SpeckleException(
|
||||
f"Cannot parse {url} into a stream wrapper class - invalid URL provided."
|
||||
)
|
||||
@@ -154,6 +176,9 @@ class StreamWrapper:
|
||||
)
|
||||
|
||||
def get_account(self) -> Account:
|
||||
"""
|
||||
Gets an account object for this server from the local accounts db (added via Speckle Manager or a json file)
|
||||
"""
|
||||
if self.account:
|
||||
return self.account
|
||||
|
||||
@@ -164,23 +189,42 @@ class StreamWrapper:
|
||||
|
||||
return self.account
|
||||
|
||||
def get_client(self) -> SpeckleClient:
|
||||
if self.client:
|
||||
def get_client(self, token: str = None) -> SpeckleClient:
|
||||
"""
|
||||
Gets an authenticated client for this server. You may provide a token if there aren't any local accounts on this
|
||||
machine. If no account is found and no token is provided, an unauthenticated client is returned.
|
||||
|
||||
Arguments:
|
||||
token {str} -- optional token if no local account is available (defaults to None)
|
||||
|
||||
Returns:
|
||||
SpeckleClient -- authenticated with a corresponding local account or the provided token
|
||||
"""
|
||||
if self.client and token is None:
|
||||
return self.client
|
||||
|
||||
if not self.account:
|
||||
self.get_account()
|
||||
|
||||
self.client = SpeckleClient(host=self.host, use_ssl=self.use_ssl)
|
||||
if not self.client:
|
||||
self.client = SpeckleClient(host=self.host, use_ssl=self.use_ssl)
|
||||
|
||||
if self.account is None:
|
||||
if self.account is None and token is None:
|
||||
warn(f"No local account found for server {self.host}", SpeckleWarning)
|
||||
return self.client
|
||||
|
||||
self.client.authenticate(self.account.token)
|
||||
self.client.authenticate(self.account.token if self.account else token)
|
||||
|
||||
return self.client
|
||||
|
||||
def get_transport(self) -> ServerTransport:
|
||||
if not self.client:
|
||||
self.get_client()
|
||||
return ServerTransport(self.client, self.stream_id)
|
||||
def get_transport(self, token: str = None) -> ServerTransport:
|
||||
"""
|
||||
Gets a server transport for this stream using an authenticated client. If there is no local account for this
|
||||
server and the client was not authenticated with a token, this will throw an exception.
|
||||
|
||||
Returns:
|
||||
ServerTransport -- constructed for this stream with a pre-authenticated client
|
||||
"""
|
||||
if not self.client or not self.client.me:
|
||||
self.get_client(token)
|
||||
return ServerTransport(self.stream_id, self.client)
|
||||
|
||||
@@ -185,3 +185,40 @@ class Resource(ResourceBase):
|
||||
return self.make_request(
|
||||
query=query, params=params, return_type="commitDelete", parse_response=False
|
||||
)
|
||||
|
||||
def received(
|
||||
self,
|
||||
stream_id: str,
|
||||
commit_id: str,
|
||||
source_application: str = "python",
|
||||
message: Optional[str] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Mark a commit object a received by the source application.
|
||||
"""
|
||||
query = gql(
|
||||
"""
|
||||
mutation CommitReceive($receivedInput:CommitReceivedInput!){
|
||||
commitReceive(input:$receivedInput)
|
||||
}
|
||||
"""
|
||||
)
|
||||
params = {
|
||||
"receivedInput": {
|
||||
"sourceApplication": source_application,
|
||||
"streamId": stream_id,
|
||||
"commitId": commit_id,
|
||||
"message": "message",
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
return self.make_request(
|
||||
query=query,
|
||||
params=params,
|
||||
return_type="commitReceive",
|
||||
parse_response=False,
|
||||
)
|
||||
except Exception as ex:
|
||||
print(ex.with_traceback)
|
||||
return False
|
||||
|
||||
@@ -32,4 +32,4 @@ class GraphQLException(SpeckleException):
|
||||
|
||||
class SpeckleWarning(Warning):
|
||||
def __init__(self, *args: object) -> None:
|
||||
super().__init__(*args)
|
||||
super().__init__(*args)
|
||||
|
||||
@@ -122,4 +122,4 @@ class MetricsTracker(metaclass=Singleton):
|
||||
except Exception as ex:
|
||||
LOG.error("Error sending metrics request: " + str(ex))
|
||||
|
||||
self.queue.task_done()
|
||||
self.queue.task_done()
|
||||
|
||||
@@ -13,21 +13,68 @@ from .batch_sender import BatchSender
|
||||
|
||||
|
||||
class ServerTransport(AbstractTransport):
|
||||
"""
|
||||
The `ServerTransport` is the vehicle through which you transport objects to and from a Speckle Server. Provide it to
|
||||
`operations.send()` or `operations.receive()`.
|
||||
|
||||
The `ServerTransport` can be authenticted two different ways:
|
||||
1. by providing a `SpeckleClient`
|
||||
2. by providing a `token` and `url`
|
||||
|
||||
```py
|
||||
from specklepy.api import operations
|
||||
from specklepy.transports.server import ServerTransport
|
||||
|
||||
# here's the data you want to send
|
||||
block = Block(length=2, height=4)
|
||||
|
||||
# next create the server transport - this is the vehicle through which you will send and receive
|
||||
transport = ServerTransport(stream_id=new_stream_id, client=client)
|
||||
|
||||
# this serialises the block and sends it to the transport
|
||||
hash = operations.send(base=block, transports=[transport])
|
||||
|
||||
# you can now create a commit on your stream with this object
|
||||
commid_id = client.commit.create(
|
||||
stream_id=new_stream_id,
|
||||
obj_id=hash,
|
||||
message="this is a block I made in speckle-py",
|
||||
)
|
||||
```
|
||||
"""
|
||||
|
||||
_name = "RemoteTransport"
|
||||
url: str = None
|
||||
stream_id: str = None
|
||||
saved_obj_count: int = 0
|
||||
session: requests.Session = None
|
||||
|
||||
def __init__(self, client: SpeckleClient, stream_id: str, **data: Any) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
stream_id: str,
|
||||
client: SpeckleClient = None,
|
||||
token: str = None,
|
||||
url: str = None,
|
||||
**data: Any,
|
||||
) -> None:
|
||||
super().__init__(**data)
|
||||
# TODO: replace client with account or some other auth avenue
|
||||
if not client.me:
|
||||
raise SpeckleException("The provided SpeckleClient was not authenticated.")
|
||||
self.url = client.url
|
||||
self.stream_id = stream_id
|
||||
if client is None and token is None and url is None:
|
||||
raise SpeckleException(
|
||||
"You must provide either a client or a token and url to construct a ServerTransport."
|
||||
)
|
||||
|
||||
if client:
|
||||
if not client.me:
|
||||
raise SpeckleException(
|
||||
"The provided SpeckleClient was not authenticated."
|
||||
)
|
||||
token = client.me["token"]
|
||||
url = client.url
|
||||
|
||||
self.stream_id = stream_id
|
||||
self.url = url
|
||||
|
||||
token = client.me["token"]
|
||||
self._batch_sender = BatchSender(
|
||||
self.url, self.stream_id, token, max_batch_size_mb=1
|
||||
)
|
||||
|
||||
@@ -58,7 +58,7 @@ class TestBranch:
|
||||
assert isinstance(branches, list)
|
||||
assert len(branches) == 2
|
||||
assert isinstance(branches[0], Branch)
|
||||
assert branches[0].name == branch.name
|
||||
assert branches[1].name == branch.name
|
||||
|
||||
def test_branch_update(self, client, stream, branch, updated_branch):
|
||||
updated = client.branch.update(
|
||||
|
||||
@@ -68,3 +68,20 @@ class TestCommit:
|
||||
deleted = client.commit.delete(stream_id=stream.id, commit_id=commit_id)
|
||||
|
||||
assert deleted is True
|
||||
|
||||
def test_commit_marked_as_received(self, client, stream, mesh) -> None:
|
||||
commit = Commit(message="this commit should be received")
|
||||
commit.id = client.commit.create(
|
||||
stream_id=stream.id,
|
||||
object_id=mesh.id,
|
||||
message=commit.message,
|
||||
)
|
||||
|
||||
commit_marked_received = client.commit.received(
|
||||
stream.id,
|
||||
commit.id,
|
||||
source_application="pytest",
|
||||
message="testing received",
|
||||
)
|
||||
|
||||
assert commit_marked_received == True
|
||||
|
||||
+113
-50
@@ -5,11 +5,28 @@ import pytest
|
||||
from specklepy.api import operations
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.encoding import CurveArray, ObjectArray
|
||||
from specklepy.objects.geometry import (Arc, Box, Brep, BrepEdge, BrepFace,
|
||||
BrepLoop, BrepTrim, BrepTrimTypeEnum,
|
||||
Circle, Curve, Ellipse, Interval, Line,
|
||||
Mesh, Plane, Point, Polycurve,
|
||||
Polyline, Surface, Vector)
|
||||
from specklepy.objects.geometry import (
|
||||
Arc,
|
||||
Box,
|
||||
Brep,
|
||||
BrepEdge,
|
||||
BrepFace,
|
||||
BrepLoop,
|
||||
BrepTrim,
|
||||
BrepTrimTypeEnum,
|
||||
Circle,
|
||||
Curve,
|
||||
Ellipse,
|
||||
Interval,
|
||||
Line,
|
||||
Mesh,
|
||||
Plane,
|
||||
Point,
|
||||
Polycurve,
|
||||
Polyline,
|
||||
Surface,
|
||||
Vector,
|
||||
)
|
||||
from specklepy.transports.memory import MemoryTransport
|
||||
|
||||
|
||||
@@ -71,7 +88,7 @@ def arc(plane, interval):
|
||||
angleRadians=33,
|
||||
plane=plane,
|
||||
domain=interval,
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# bbox=None,
|
||||
# area=None,
|
||||
@@ -88,7 +105,7 @@ def circle(plane, interval):
|
||||
radius=22,
|
||||
plane=plane,
|
||||
domain=interval,
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# bbox=None,
|
||||
# area=None,
|
||||
@@ -103,7 +120,7 @@ def ellipse(plane, interval):
|
||||
secondRadius=22,
|
||||
plane=plane,
|
||||
domain=interval,
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# trimDomain=None,
|
||||
# bbox=None,
|
||||
@@ -118,7 +135,7 @@ def polyline(interval):
|
||||
value=[22, 44, 54.3, 99, 232, 21],
|
||||
closed=True,
|
||||
domain=interval,
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# bbox=None,
|
||||
# area=None,
|
||||
@@ -137,7 +154,7 @@ def curve(interval):
|
||||
points=[23, 21, 44, 43, 56, 76, 1, 3, 2],
|
||||
weights=[23, 11, 23],
|
||||
knots=[22, 45, 76, 11],
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# displayValue=None,
|
||||
# bbox=None,
|
||||
@@ -152,7 +169,7 @@ def polycurve(interval, curve, polyline):
|
||||
segments=[curve, polyline],
|
||||
domain=interval,
|
||||
closed=True,
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# bbox=None,
|
||||
# area=None,
|
||||
@@ -187,7 +204,7 @@ def surface(interval):
|
||||
domainV=interval,
|
||||
knotsU=[1.1, 2.2, 3.3, 4.4],
|
||||
knotsV=[9, 8, 7, 6, 5, 4.4],
|
||||
units='m',
|
||||
units="m",
|
||||
# These attributes are not handled in C#
|
||||
# bbox=None,
|
||||
# area=None,
|
||||
@@ -218,11 +235,7 @@ def brep_edge(interval):
|
||||
|
||||
@pytest.fixture()
|
||||
def brep_loop():
|
||||
return BrepLoop(
|
||||
FaceIndex=5,
|
||||
TrimIndices=[3, 4, 5],
|
||||
Type='unknown'
|
||||
)
|
||||
return BrepLoop(FaceIndex=5, TrimIndices=[3, 4, 5], Type="unknown")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@@ -235,7 +248,7 @@ def brep_trim():
|
||||
LoopIndex=4,
|
||||
CurveIndex=7,
|
||||
IsoStatus=6,
|
||||
TrimType='Mated',
|
||||
TrimType="Mated",
|
||||
IsReversed=False,
|
||||
# These attributes are not handled in C#
|
||||
# Domain=None,
|
||||
@@ -243,10 +256,21 @@ def brep_trim():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def brep(mesh, box, surface, curve, polyline, circle, point,
|
||||
brep_edge, brep_loop, brep_trim, brep_face):
|
||||
def brep(
|
||||
mesh,
|
||||
box,
|
||||
surface,
|
||||
curve,
|
||||
polyline,
|
||||
circle,
|
||||
point,
|
||||
brep_edge,
|
||||
brep_loop,
|
||||
brep_trim,
|
||||
brep_face,
|
||||
):
|
||||
return Brep(
|
||||
provenance='pytest',
|
||||
provenance="pytest",
|
||||
bbox=box,
|
||||
area=32,
|
||||
volume=54,
|
||||
@@ -265,33 +289,57 @@ def brep(mesh, box, surface, curve, polyline, circle, point,
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def geometry_objects_dict(point, vector, plane, line, arc,
|
||||
circle, ellipse, polyline, curve,
|
||||
polycurve, surface, brep_trim):
|
||||
def geometry_objects_dict(
|
||||
point,
|
||||
vector,
|
||||
plane,
|
||||
line,
|
||||
arc,
|
||||
circle,
|
||||
ellipse,
|
||||
polyline,
|
||||
curve,
|
||||
polycurve,
|
||||
surface,
|
||||
brep_trim,
|
||||
):
|
||||
return {
|
||||
'point': point,
|
||||
'vector': vector,
|
||||
'plane': plane,
|
||||
'line': line,
|
||||
'arc': arc,
|
||||
'circle': circle,
|
||||
'ellipse': ellipse,
|
||||
'polyline': polyline,
|
||||
'curve': curve,
|
||||
'polycurve': polycurve,
|
||||
'surface': surface,
|
||||
'brep_trim': brep_trim
|
||||
"point": point,
|
||||
"vector": vector,
|
||||
"plane": plane,
|
||||
"line": line,
|
||||
"arc": arc,
|
||||
"circle": circle,
|
||||
"ellipse": ellipse,
|
||||
"polyline": polyline,
|
||||
"curve": curve,
|
||||
"polycurve": polycurve,
|
||||
"surface": surface,
|
||||
"brep_trim": brep_trim,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('object_name', [
|
||||
'point', 'vector', 'plane', 'line', 'arc', 'circle',
|
||||
'ellipse', 'polyline', 'curve', 'polycurve', 'surface', 'brep_trim'
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"object_name",
|
||||
[
|
||||
"point",
|
||||
"vector",
|
||||
"plane",
|
||||
"line",
|
||||
"arc",
|
||||
"circle",
|
||||
"ellipse",
|
||||
"polyline",
|
||||
"curve",
|
||||
"polycurve",
|
||||
"surface",
|
||||
"brep_trim",
|
||||
],
|
||||
)
|
||||
def test_to_and_from_list(object_name: str, geometry_objects_dict):
|
||||
object = geometry_objects_dict[object_name]
|
||||
assert hasattr(object, 'to_list')
|
||||
assert hasattr(object, 'from_list')
|
||||
assert hasattr(object, "to_list")
|
||||
assert hasattr(object, "from_list")
|
||||
|
||||
chunks = object.to_list()
|
||||
assert isinstance(chunks, list)
|
||||
@@ -306,8 +354,7 @@ def test_brep_surfaces_value_serialization(surface):
|
||||
assert brep.Surfaces == None
|
||||
assert brep.SurfacesValue == None
|
||||
brep.Surfaces = [surface, surface]
|
||||
assert brep.SurfacesValue == ObjectArray.from_objects(
|
||||
[surface, surface]).data
|
||||
assert brep.SurfacesValue == ObjectArray.from_objects([surface, surface]).data
|
||||
|
||||
brep.SurfacesValue = ObjectArray.from_objects([surface]).data
|
||||
assert len(brep.Surfaces) == 1
|
||||
@@ -341,16 +388,32 @@ def test_brep_curve3d_values_serialization(curve, polyline, circle):
|
||||
def test_brep_vertices_values_serialization():
|
||||
brep = Brep()
|
||||
brep.VerticesValue = [1, 1, 1, 1, 2, 2, 2, 3, 3, 3]
|
||||
brep.Vertices[0].get_id() == Point(x=1, y=1, z=1, _units='mm').get_id()
|
||||
brep.Vertices[1].get_id() == Point(x=2, y=2, z=2, _units='mm').get_id()
|
||||
brep.Vertices[2].get_id() == Point(x=3, y=3, z=3, _units='mm').get_id()
|
||||
brep.Vertices[0].get_id() == Point(x=1, y=1, z=1, _units="mm").get_id()
|
||||
brep.Vertices[1].get_id() == Point(x=2, y=2, z=2, _units="mm").get_id()
|
||||
brep.Vertices[2].get_id() == Point(x=3, y=3, z=3, _units="mm").get_id()
|
||||
|
||||
|
||||
def test_trims_value_serialization():
|
||||
brep = Brep()
|
||||
brep.TrimsValue = [
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1,
|
||||
1, 0, 0, 0, 0, 1, 2, 1, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
]
|
||||
|
||||
brep.Trims[0].get_id() == BrepTrim(
|
||||
@@ -383,7 +446,7 @@ def test_serialized_brep_attributes(brep: Brep):
|
||||
serialized = operations.serialize(brep, [transport])
|
||||
serialized_dict = json.loads(serialized)
|
||||
|
||||
removed_keys = ['Surfaces', 'Curve3D', 'Curve2D', 'Vertices', 'Trims']
|
||||
removed_keys = ["Surfaces", "Curve3D", "Curve2D", "Vertices", "Trims"]
|
||||
|
||||
for k in removed_keys:
|
||||
assert k not in serialized_dict.keys()
|
||||
|
||||
+3
-11
@@ -21,11 +21,9 @@ class TestObject:
|
||||
|
||||
def test_object_create(self, client, stream, base):
|
||||
transport = SQLiteTransport()
|
||||
s = BaseObjectSerializer(
|
||||
write_transports=[transport], read_transport=transport)
|
||||
s = BaseObjectSerializer(write_transports=[transport], read_transport=transport)
|
||||
_, base_dict = s.traverse_base(base)
|
||||
obj_id = client.object.create(
|
||||
stream_id=stream.id, objects=[base_dict])[0]
|
||||
obj_id = client.object.create(stream_id=stream.id, objects=[base_dict])[0]
|
||||
|
||||
assert isinstance(obj_id, str)
|
||||
assert base_dict["@detach"]["speckle_type"] == "reference"
|
||||
@@ -43,12 +41,6 @@ class TestObject:
|
||||
|
||||
def test_object_array_decoder(self):
|
||||
array = ObjectArray()
|
||||
array.data = [
|
||||
5, 1, 1, 1, 1, 1,
|
||||
4, 1, 1, 1, 1,
|
||||
3, 1, 1, 1,
|
||||
2, 1, 1,
|
||||
1, 1
|
||||
]
|
||||
array.data = [5, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1, 1]
|
||||
|
||||
assert array.decode(decoder=sum) == [5, 4, 3, 2, 1]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import json
|
||||
from attr import has
|
||||
import pytest
|
||||
from specklepy.api import operations
|
||||
from specklepy.transports.server import ServerTransport
|
||||
@@ -53,6 +52,11 @@ class TestSerialization:
|
||||
def test_send_and_receive(self, client, sample_stream, mesh):
|
||||
transport = ServerTransport(client=client, stream_id=sample_stream.id)
|
||||
hash = operations.send(mesh, transports=[transport])
|
||||
|
||||
# also try constructing server transport with token and url
|
||||
transport = ServerTransport(
|
||||
stream_id=sample_stream.id, token=client.me["token"], url=client.url
|
||||
)
|
||||
# use a fresh memory transport to force receiving from remote
|
||||
received = operations.receive(
|
||||
hash, remote_transport=transport, local_transport=MemoryTransport()
|
||||
@@ -84,4 +88,4 @@ class TestSerialization:
|
||||
untyped = '{"foo": "bar"}'
|
||||
deserialised = operations.deserialize(untyped)
|
||||
|
||||
assert deserialised == {"foo": "bar"}
|
||||
assert deserialised == {"foo": "bar"}
|
||||
|
||||
@@ -18,6 +18,14 @@ class TestWrapper:
|
||||
assert wacky_wrap.branch_name == "🍕⬅🌟 you wat?"
|
||||
assert wrap.type == "branch"
|
||||
|
||||
def test_parse_nested_branch(self):
|
||||
wrap = StreamWrapper(
|
||||
"https://testing.speckle.dev/streams/4c3ce1459c/branches/izzy/dev"
|
||||
)
|
||||
|
||||
assert wrap.branch_name == "izzy/dev"
|
||||
assert wrap.type == "branch"
|
||||
|
||||
def test_parse_commit(self):
|
||||
wrap = StreamWrapper(
|
||||
"https://testing.speckle.dev/streams/4c3ce1459c/commits/8b9b831792"
|
||||
@@ -39,3 +47,33 @@ class TestWrapper:
|
||||
"https://testing.speckle.dev/streams/0c6ad366c4/globals/abd3787893"
|
||||
)
|
||||
assert wrap.type == "commit"
|
||||
|
||||
#! NOTE: the following three tests may not pass locally if you have a `speckle.xyz` account in manager
|
||||
def test_get_client_without_auth(self):
|
||||
wrap = StreamWrapper(
|
||||
"https://speckle.xyz/streams/4c3ce1459c/commits/8b9b831792"
|
||||
)
|
||||
client = wrap.get_client()
|
||||
|
||||
assert client is not None
|
||||
|
||||
def test_get_new_client_with_token(self):
|
||||
wrap = StreamWrapper(
|
||||
"https://speckle.xyz/streams/4c3ce1459c/commits/8b9b831792"
|
||||
)
|
||||
client = wrap.get_client()
|
||||
client = wrap.get_client(token="super-secret-token")
|
||||
|
||||
assert client.me["token"] == "super-secret-token"
|
||||
|
||||
def test_get_transport_with_token(self):
|
||||
wrap = StreamWrapper(
|
||||
"https://speckle.xyz/streams/4c3ce1459c/commits/8b9b831792"
|
||||
)
|
||||
client = wrap.get_client()
|
||||
assert not client.me # unauthenticated bc no local accounts
|
||||
|
||||
transport = wrap.get_transport(token="super-secret-token")
|
||||
|
||||
assert transport is not None
|
||||
assert client.me["token"] == "super-secret-token"
|
||||
|
||||
Reference in New Issue
Block a user