The SpeckleClient is your main entry point for interacting with Speckle Server. It handles authentication and provides access to resource APIs (projects, models, versions, users, etc.).
Copy
from specklepy.api.client import SpeckleClientclient = SpeckleClient(host="https://app.speckle.systems")client.authenticate_with_token("your_token_here")project = client.project.get("project_id")
The client provides access to various resource APIs through these properties. Each resource has its own detailed documentation page.
Listing Projects: Workspace vs Non-Workspace ServersThe method for listing projects differs depending on your server deployment:
Workspace-enabled servers (e.g., app.speckle.systems): Use client.workspace.get_projects(workspace_id) to list projects within a workspace, or client.active_user.get_projects(filter=UserProjectsFilter(personalOnly=True)) for personal projects.
Non-workspace servers (self-hosted/open-source): Use client.active_user.get_projects() to list all projects you have access to. The workspace resource is not available.
For cross-server compatibility, check workspace support first:
Copy
info = client.server.get()if info.workspaces and info.workspaces.workspacesEnabled: # Use workspace.get_projects() workspaces = client.active_user.get_workspaces() for ws in workspaces.items: projects = client.workspace.get_projects(ws.id)else: # Use active_user.get_projects() projects = client.active_user.get_projects()
Note: In earlier versions of specklepy, projects were accessed via the stream resource with a list() method. This has been replaced by the resource-based approach described above.
Workspace Resource AvailabilityThe workspace resource is available on the hosted Speckle server at app.speckle.systems and other workspace-enabled deployments.Self-hosted/open-source server deployments do not include workspace features and this resource will not be available. Attempting to use workspace methods on non-workspace servers will raise an error.Check your server capabilities before using workspace operations, or wrap calls in try/except blocks for cross-server compatibility.
try: workspace = client.workspace.get("workspace_id") print(f"Workspace: {workspace.name}")except Exception as e: print("Workspace features not available on this server")
Perform complex queries with specific field selections
Use new API features before SDK support is added
Optimize queries by requesting only needed fields
Example - Custom Fields:
Copy
# Query custom or new fields not in SDKquery = gql(""" query ProjectWithCustomFields($projectId: String!) { project(id: $projectId) { id name customField newFeature { data } } }""")# Execute with variablesresult = client.execute_query(query)
Example - Mutations:
Copy
# Custom mutation not yet in SDKmutation = gql(""" mutation CustomOperation($input: CustomInput!) { customOperation(input: $input) { success data { id result } } }""")result = client.execute_query(mutation)
GraphQL Schema DocumentationTo explore available queries, mutations, and fields, visit your Speckle server’s GraphQL playground:
Never hardcode tokens in your source code. Use environment variables instead:
Copy
import osfrom specklepy.api.client import SpeckleClienttoken = os.environ.get("SPECKLE_TOKEN")if not token: raise ValueError("SPECKLE_TOKEN environment variable not set")client = SpeckleClient(host="https://app.speckle.systems")client.authenticate_with_token(token)
Should I create a new client for each operation?
No. Create one client per server and reuse it for all operations:
Copy
# ✓ Good - create once, reuseclient = SpeckleClient(host="https://app.speckle.systems")client.authenticate_with_token(token)project1 = client.project.get(id1)project2 = client.project.get(id2)# ✗ Bad - don't create a new client each time# client = SpeckleClient(...) # inside a loop
How do I verify authentication succeeded?
Access the account property after authentication:
Copy
from specklepy.api.client import SpeckleClientclient = SpeckleClient(host="https://app.speckle.systems")try: client.authenticate_with_token(token) print(f"✓ Authenticated as {client.account.userInfo.name}")except Exception as e: print(f"✗ Authentication failed: {e}") exit(1)
How do I check if a server has workspace features?
Workspace features are only available on specific deployments. Check before using:
Copy
from specklepy.api.client import SpeckleClientclient = SpeckleClient(host="https://app.speckle.systems")client.authenticate_with_token(token)try: workspaces = client.active_user.get_workspaces() print(f"Workspace features available")except Exception: print("Server does not support workspace features")
How do I handle different server versions?
Check the server version and adapt your code accordingly:
Copy
from specklepy.api.client import SpeckleClientclient = SpeckleClient(host="https://app.speckle.systems")client.authenticate_with_token(token)version_tuple = client.server.version()major_version = version_tuple[0] if version_tuple else Noneif major_version and major_version >= 3: print("Using v3+ features")elif major_version == 2: print("Using v2 features")
What exceptions should I handle?
Common exceptions to handle:
Copy
from specklepy.api.client import SpeckleClienttry: client = SpeckleClient(host="https://app.speckle.systems") client.authenticate_with_token(token) project = client.project.get("project_id")except ConnectionError: print("Cannot connect to server")except PermissionError: print("Authentication failed or insufficient permissions")except ValueError: print("Invalid input (e.g., malformed ID)")except Exception as e: print(f"Unexpected error: {e}")
How do I list projects on different server types?
The method for listing projects depends on whether the server has workspace features:
Copy
# Check server capabilities firstinfo = client.server.get()has_workspaces = info.workspaces and info.workspaces.workspacesEnabledif has_workspaces: # Workspace-enabled server (e.g., https://app.speckle.systems) # List workspace projects workspaces = client.active_user.get_workspaces() for ws in workspaces.items: projects = client.workspace.get_projects(ws.id) print(f"Workspace {ws.name}: {projects.totalCount} projects") # List personal projects from specklepy.core.api.inputs.user_inputs import UserProjectsFilter personal = client.active_user.get_projects( filter=UserProjectsFilter(personalOnly=True) )else: # Non-workspace server (self-hosted/open-source) # List all accessible projects projects = client.active_user.get_projects() print(f"Total projects: {projects.totalCount}")
Note: Earlier versions of specklepy used stream.list() - this has been replaced by the resource-based approach above.