Files
specklepy/speckle/api/client.py
T
2021-02-22 18:23:30 +00:00

107 lines
3.4 KiB
Python

import re
from gql.client import SyncClientSession
from speckle.logging.exceptions import SpeckleException
from typing import Dict
from speckle.api import resources
from speckle.api.resources import (
branch,
commit,
stream,
object,
server,
user,
subscriptions,
)
from gql import Client, gql
from gql.transport.requests import RequestsHTTPTransport
from gql.transport.aiohttp import AIOHTTPTransport
from gql.transport.websockets import WebsocketsTransport
class SpeckleClient:
DEFAULT_HOST = "staging.speckle.dev"
USE_SSL = True
def __init__(self, host: str = DEFAULT_HOST, use_ssl: bool = USE_SSL) -> None:
ws_protocol = "ws"
http_protocol = "http"
if use_ssl:
ws_protocol = "wss"
http_protocol = "https"
# sanitise host input by removing protocol and trailing slash
host = re.sub(r"((^\w+:|^)\/\/)|(\/$)", "", host)
self.url = f"{http_protocol}://{host}"
self.graphql = self.url + "/graphql"
self.ws_url = f"{ws_protocol}://{host}/graphql"
self.me = None
self.httpclient = Client(
transport=RequestsHTTPTransport(url=self.graphql, verify=True, retries=3)
)
self.wsclient = None
self._init_resources()
def authenticate(self, token: str) -> None:
"""Authenticate the client using a personal access token
The token is saved in the client object and a synchronous GraphQL entrypoint is created
Arguments:
token {str} -- an api token
"""
self.me = {"token": token}
headers = {
"Authorization": f"Bearer {self.me['token']}",
"Content-Type": "application/json",
}
httptransport = RequestsHTTPTransport(
url=self.graphql, headers=headers, verify=True, retries=3
)
wstransport = WebsocketsTransport(
url=self.ws_url,
init_payload={"Authorization": f"Bearer {self.me['token']}"},
)
self.httpclient = Client(transport=httptransport)
self.wsclient = Client(transport=wstransport)
self._init_resources()
def execute_query(self, query: str) -> Dict:
return self.httpclient.execute(query)
def _init_resources(self) -> None:
self.stream = stream.Resource(
me=self.me, basepath=self.url, client=self.httpclient
)
self.commit = commit.Resource(
me=self.me, basepath=self.url, client=self.httpclient
)
self.branch = branch.Resource(
me=self.me, basepath=self.url, client=self.httpclient
)
self.object = object.Resource(
me=self.me, basepath=self.url, client=self.httpclient
)
self.server = server.Resource(
me=self.me, basepath=self.url, client=self.httpclient
)
self.user = user.Resource(me=self.me, basepath=self.url, client=self.httpclient)
self.subscribe = subscriptions.Resource(
me=self.me,
basepath=self.ws_url,
client=self.wsclient,
)
def __getattr__(self, name):
try:
attr = getattr(resources, name)
return attr.Resource(me=self.me, basepath=self.url, client=self.httpclient)
except:
raise SpeckleException(
f"Method {name} is not supported by the SpeckleClient class"
)