Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f20fc7edb3 | |||
| 0cd0c3a1f6 | |||
| 2594ce0382 | |||
| ec67f5ba48 | |||
| db61d2e99c |
@@ -1,6 +1,6 @@
|
||||
import multiprocessing
|
||||
|
||||
from ifcopenshell import file, ifcopenshell_wrapper, open, sqlite
|
||||
from ifcopenshell import SchemaError, file, ifcopenshell_wrapper, open, sqlite
|
||||
from ifcopenshell.geom import iterator, settings
|
||||
|
||||
from specklepy.logging.exceptions import SpeckleException
|
||||
@@ -33,7 +33,14 @@ def _create_iterator_settings() -> settings:
|
||||
|
||||
|
||||
def open_ifc(file_path: str) -> file:
|
||||
ifc_file = open(file_path)
|
||||
try:
|
||||
ifc_file = open(file_path)
|
||||
except SchemaError:
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
raise
|
||||
except Exception as ex:
|
||||
raise SpeckleException("File could not be opened as an IFC file") from ex
|
||||
|
||||
if isinstance(ifc_file, file):
|
||||
return ifc_file
|
||||
|
||||
@@ -34,6 +34,16 @@ class ImportJob:
|
||||
_current_storey_data_object: DataObject | None = field(default=None, init=False)
|
||||
|
||||
def convert_element(self, step_element: entity_instance) -> Base:
|
||||
try:
|
||||
return self._convert_element(step_element)
|
||||
except SpeckleException:
|
||||
raise
|
||||
except Exception as ex:
|
||||
raise SpeckleException(
|
||||
f"Failed to convert {step_element.is_a()} #{step_element.id()}"
|
||||
) from ex
|
||||
|
||||
def _convert_element(self, step_element: entity_instance) -> Base:
|
||||
# Track current storey context and store for level proxies
|
||||
previous_storey_data_object = self._current_storey_data_object
|
||||
if step_element.is_a("IfcBuildingStorey"):
|
||||
@@ -110,18 +120,22 @@ class ImportJob:
|
||||
def pre_process_geometry(self) -> None:
|
||||
iterator = create_geometry_iterator(self.ifc_file)
|
||||
if not iterator.initialize():
|
||||
raise SpeckleException(
|
||||
"geometry iterator failed to initialize for the given file"
|
||||
)
|
||||
raise SpeckleException("Failed to find any geometry in file")
|
||||
self.geometries_count = 0
|
||||
while True:
|
||||
shape = cast(TriangulationElement, iterator.get())
|
||||
self.geometries_count += 1
|
||||
id = cast(int, shape.id)
|
||||
|
||||
display_value = geometry_to_speckle(shape, self._render_material_manager)
|
||||
self.cached_display_values[id] = display_value
|
||||
|
||||
try:
|
||||
display_value = geometry_to_speckle(
|
||||
shape, self._render_material_manager
|
||||
)
|
||||
self.cached_display_values[id] = display_value
|
||||
except Exception as ex:
|
||||
raise SpeckleException(
|
||||
f"Failed to convert geometry with id: {id}"
|
||||
) from ex
|
||||
if not iterator.next():
|
||||
break
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ def open_and_convert_file(
|
||||
remote_transport = ServerTransport(project.id, account=account)
|
||||
|
||||
ifc_file = open_ifc(file_path) # pyright: ignore[reportUnknownVariableType]
|
||||
|
||||
import_job = ImportJob(ifc_file) # pyright: ignore[reportUnknownArgumentType]
|
||||
data = import_job.convert()
|
||||
|
||||
|
||||
@@ -131,6 +131,19 @@ class SpeckleClient:
|
||||
self.account = Account.from_token(token, self.url)
|
||||
self._set_up_client()
|
||||
|
||||
userData = self.active_user.get()
|
||||
|
||||
# None if the token lacked the profile:read scope or if it was None
|
||||
if userData:
|
||||
self.account.userInfo.id = userData.id
|
||||
self.account.userInfo.email = userData.email
|
||||
self.account.userInfo.name = userData.name
|
||||
self.account.userInfo.company = userData.company
|
||||
self.account.userInfo.avatar = userData.avatar
|
||||
|
||||
self.account.serverInfo = self.server.get()
|
||||
self.account.serverInfo.url = self.url
|
||||
|
||||
def authenticate_with_account(self, account: Account) -> None:
|
||||
"""Authenticate the client using an Account object
|
||||
The account is saved in the client object and a synchronous GraphQL
|
||||
@@ -143,6 +156,21 @@ class SpeckleClient:
|
||||
self.account = account
|
||||
self._set_up_client()
|
||||
|
||||
try:
|
||||
_ = self.active_user.get()
|
||||
except SpeckleException as ex:
|
||||
if isinstance(ex.exception, TransportServerError):
|
||||
if ex.exception.code == 403:
|
||||
warn(
|
||||
SpeckleWarning(
|
||||
"Possibly invalid token - could not authenticate "
|
||||
f"Speckle Client for server {self.url}"
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
else:
|
||||
raise ex
|
||||
|
||||
def _set_up_client(self) -> None:
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.account.token}",
|
||||
@@ -162,21 +190,6 @@ class SpeckleClient:
|
||||
|
||||
self._init_resources()
|
||||
|
||||
try:
|
||||
_ = self.active_user.get()
|
||||
except SpeckleException as ex:
|
||||
if isinstance(ex.exception, TransportServerError):
|
||||
if ex.exception.code == 403:
|
||||
warn(
|
||||
SpeckleWarning(
|
||||
"Possibly invalid token - could not authenticate "
|
||||
f"Speckle Client for server {self.url}"
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
else:
|
||||
raise ex
|
||||
|
||||
def execute_query(self, query: str) -> Dict:
|
||||
return self.httpclient.execute(query)
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class Account(BaseModel):
|
||||
return self.__repr__()
|
||||
|
||||
@classmethod
|
||||
def from_token(cls, token: str, server_url: str = None):
|
||||
def from_token(cls, token: str, server_url: str | None = None):
|
||||
acct = cls(token=token)
|
||||
acct.serverInfo.url = server_url
|
||||
return acct
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from urllib.parse import quote, unquote, urlparse
|
||||
from warnings import warn
|
||||
|
||||
from gql import gql
|
||||
|
||||
from specklepy.core.api.client import SpeckleClient
|
||||
from specklepy.core.api.credentials import (
|
||||
Account,
|
||||
@@ -139,27 +137,11 @@ class StreamWrapper:
|
||||
|
||||
if use_fe2 is True and self.branch_name is not None:
|
||||
self.model_id = self.branch_name
|
||||
# get branch name
|
||||
query = gql(
|
||||
"""
|
||||
query Project($project_id: String!, $model_id: String!) {
|
||||
project(id: $project_id) {
|
||||
id
|
||||
model(id: $model_id) {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
)
|
||||
self._client = self.get_client()
|
||||
params = {"project_id": self.stream_id, "model_id": self.model_id}
|
||||
project = self._client.httpclient.execute(query, params)
|
||||
|
||||
try:
|
||||
self.branch_name = project["project"]["model"]["name"]
|
||||
except KeyError as ke:
|
||||
raise SpeckleException("Project model name is not found", ke) from ke
|
||||
self._client = self.get_client()
|
||||
model = self._client.model.get(self.model_id, self.stream_id)
|
||||
|
||||
self.branch_name = model.name
|
||||
|
||||
if not self.stream_id:
|
||||
raise SpeckleException(
|
||||
@@ -175,6 +157,10 @@ class StreamWrapper:
|
||||
"""
|
||||
Gets an account object for this server from the local accounts db
|
||||
(added via Speckle Manager or a json file)
|
||||
|
||||
WARNING: this function will return ANY account for the server,
|
||||
just because you pass a token in doesn't guarantee it will be used.
|
||||
This whole class could do with a re-design...
|
||||
"""
|
||||
if self._account and self._account.token:
|
||||
return self._account
|
||||
|
||||
@@ -88,6 +88,8 @@ def user_application_data_path() -> Path:
|
||||
message="Cannot get appdata path from environment."
|
||||
)
|
||||
return Path(app_data_path)
|
||||
if sys.platform.startswith("darwin"): # macOS
|
||||
return _ensure_folder_exists(Path.home() / "Library", "Application Support")
|
||||
else:
|
||||
# try getting the standard XDG_DATA_HOME value
|
||||
# as that is used as an override
|
||||
@@ -98,7 +100,7 @@ def user_application_data_path() -> Path:
|
||||
return _ensure_folder_exists(Path.home(), ".config")
|
||||
except Exception as ex:
|
||||
raise SpeckleException(
|
||||
message="Failed to initialize user application data path.", exception=ex
|
||||
message="Failed to initialize user application data path."
|
||||
) from ex
|
||||
|
||||
|
||||
|
||||
@@ -97,10 +97,11 @@ def initialise_tracker(account: Account | None = None):
|
||||
if not METRICS_TRACKER:
|
||||
METRICS_TRACKER = MetricsTracker()
|
||||
|
||||
if account and account.userInfo.email:
|
||||
METRICS_TRACKER.set_last_user(account.userInfo.email)
|
||||
if account and account.serverInfo.url:
|
||||
METRICS_TRACKER.set_last_server(account.serverInfo.url)
|
||||
if not account:
|
||||
return
|
||||
|
||||
METRICS_TRACKER.set_last_user(account.userInfo.email)
|
||||
METRICS_TRACKER.set_last_server(account.serverInfo.url)
|
||||
|
||||
|
||||
class Singleton(type):
|
||||
@@ -132,12 +133,12 @@ class MetricsTracker(metaclass=Singleton):
|
||||
if node and user:
|
||||
self.last_user = f"@{self.hash(f'{node}-{user}')}"
|
||||
|
||||
def set_last_user(self, email: str):
|
||||
def set_last_user(self, email: str | None):
|
||||
if not email:
|
||||
return
|
||||
self.last_user = f"@{self.hash(email)}"
|
||||
|
||||
def set_last_server(self, server: str):
|
||||
def set_last_server(self, server: str | None):
|
||||
if not server:
|
||||
return
|
||||
self.last_server = self.hash(server)
|
||||
|
||||
@@ -6,7 +6,7 @@ from specklepy.api import operations
|
||||
from specklepy.api.client import SpeckleClient
|
||||
from specklepy.api.credentials import Account, get_account_from_token
|
||||
from specklepy.core.helpers import speckle_path_provider
|
||||
from specklepy.logging.exceptions import SpeckleException, SpeckleWarning
|
||||
from specklepy.logging.exceptions import SpeckleException
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.transports.server import ServerTransport
|
||||
|
||||
@@ -17,7 +17,7 @@ def test_invalid_authentication():
|
||||
speckle_path_provider.override_application_data_path(gettempdir())
|
||||
client = SpeckleClient()
|
||||
|
||||
with pytest.warns(SpeckleWarning):
|
||||
with pytest.raises(SpeckleException):
|
||||
client.authenticate_with_token("fake token")
|
||||
|
||||
# remove path override
|
||||
|
||||
@@ -8,11 +8,12 @@ import requests
|
||||
|
||||
from specklepy.api.client import SpeckleClient
|
||||
from specklepy.core.api import operations
|
||||
from specklepy.core.api.credentials import Account, UserInfo
|
||||
from specklepy.core.api.enums import ProjectVisibility
|
||||
from specklepy.core.api.inputs.project_inputs import ProjectCreateInput
|
||||
from specklepy.core.api.inputs.version_inputs import CreateVersionInput
|
||||
from specklepy.core.api.models import Version
|
||||
from specklepy.core.api.models.current import Project
|
||||
from specklepy.core.api.models.current import Project, ServerInfo
|
||||
from specklepy.logging import metrics
|
||||
from specklepy.objects.base import Base
|
||||
from specklepy.objects.geometry import Point
|
||||
@@ -89,13 +90,15 @@ def second_user_dict(host: str) -> Dict[str, str]:
|
||||
def create_client(host: str, token: str) -> SpeckleClient:
|
||||
client = SpeckleClient(host=host, use_ssl=False)
|
||||
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
|
||||
|
||||
assert isinstance(client.account, Account)
|
||||
assert isinstance(client.account.userInfo, UserInfo)
|
||||
assert client.account.userInfo.id
|
||||
assert client.account.userInfo.name
|
||||
assert isinstance(client.account.serverInfo, ServerInfo)
|
||||
assert client.account.serverInfo.url
|
||||
assert client.account.serverInfo.name
|
||||
|
||||
return client
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user