This guide provides a brief introduction on setting up and using the Onshape REST API in Python. Specifically, resources detailed in this guide are written in Jupyter notebooks through Google Colab. It is recommended to use the same programming environment for practice and learning.
- 1. General resources
- 2. Generating your Onshape API keys
- 3. Getting started with Onshape REST API
- 4. Other methods
Before getting started, you should have a working background knowledge on the Python programming language and preferrably some experience with Jupyter notebooks in Google Colab. Working in the same development environment gives better efficiency on the integration to Onshape.
Below are some useful resources and links that will be referred to in this guide, please feel free to save these resources for future referrence:
- All Onshape API endpoints are documented on Glassworks.
- The source code of the
onshape_client
library can be found in this GitHub repository and the code for all API calls can be found in this directory. - The PTC-API-Playground GitHub repository provides various sample projects through making Onshape API calls.
- A libary of ready-to-use Python snippets of Onshape API calls can be found here, which can be easily imported to your own Jupyter notebook on Google Colab. A quick guide to import can be found in the
README.md
file of its home repository. - A few more introduction videos on Digital Twins with the Onshape REST API can be found here.
To gain access to your Onshape document through making API calls, we need to first generate and obtain a set of API keys for your account:
-
Go to https://dev-portal.onshape.com and log in with your Onshape account.
-
Under "API keys" of the left panel, click "Create new API key" in the top right corner of the page.
-
Choose the company and permissions that you would like this key to have access to (recommend at least permissions to read and write, then be careful with the rest before you gain sufficient experience).
-
Once the API key is created, a pop-up box should show an access key and a secret key.
-
You are free to record and save your API keys in any ways. However, we recommend opening up a text file locally in your computer and saving these two keys in the following format, replacing the
{...}
with your actual keys. Then, save the file as a.py
file.access = '{access_key}' secret = '{secret_key}'
CAUTION:
- You should NEVER share your API keys with other people, nor upload this publicly through the Internet. Having access to your API keys is equivalent to gaining access to your Onshape account through password login with the permissions you specified in step 3 above.
- You should also periodically delete your API keys and create a new set of keys on the developer portal, so that even you accidentally uploaded your keys to any public platform, the leaked keys can be deactivated.
Note that this section only describes the most basic structure of a typical Onshape API call, more advanced applications can be found in the Onshape API Snippets and other sample projects in the PTC-API-Playground.
For every Onshape document, its URL can be broken down in a few structured segments.For example, here is a URL of an Onshape document: https://cad.onshape.com/documents/263517311c2ad139d4eb57ca/w/b45057ae06777e0c28bca6c5/e/d316bcbc694c9dbb6555f340
https://cad.onshape.com/
is called the "base URL". Default base URL will becad.onshape.com
for standard Onshape accounts. For enterprise accounts, it will be a different URL for every different enterprise (e.g.,ptc.onshape.com
).documents/
ord/
provides the unique ID of the "document" that is loaded in the browser, orDID
. A document contains all the content related to the design project, including Part Studios, Assemblies, Drawings, etc.w/
provides the unique ID of the "workspace" that is currently being worked on, orWID
. By default, you always start with the "Main" workspace when you first create an Onshape document. Meanwhile, additional workspace can be created in the document through branching. However, this part of the URL can also be replaced with:v/
followed by aVID
: a "version" or "release" of the Onshape document that is created at a specific point of time of the design process.m/
followed by anMID
: a "micro-version" of the document at a specific point of time of the design process. Every change made to an Onshape document automatically generates a micro-version for the document.- Note that versions are specifically created and defined by the users, but micro-versions are automatically logged by the system.
e/
provides the unique ID of the "element" that is currently opened in the workspace, orEID
. An element is essentially a tab in an Onshape document, which can be a Part Studio, an Assembly, a Drawing, etc.
There is also an efficient way of separating the URL into its components:
from onshape_client.onshape_url import OnshapeElement
url = 'https://cad.onshape.com/documents/263517311c2ad139d4eb57ca/w/b45057ae06777e0c28bca6c5/e/d316bcbc694c9dbb6555f340'
element = OnshapeElement(url)
base = element.base_url
# Assume we would like to replace "did", "wid", and "eid" of the "fixed_url" with IDs from the main "url" above
fixed_url = '/api/partstudios/d/did/w/wid/e/eid/massproperties'
fixed_url = fixed_url.replace('did', element.did)
fixed_url = fixed_url.replace('wid', element.wvmid)
fixed_url = fixed_url.replace('eid', element.eid)
Note: you may need to install the onshape_client
library through the following command line in your terminal if you have never done so before:
$ pip install onshape-client
On Glassworks Explorer, every Onshape API endpoint is labelled with its respective API call type. For every REST API call in Onshape, it should fall under one of the three types:
GET
: retrieve information from the server (e.g., retrieve the parameters of a specific feature in the Onshape document).POST
: update the server with new information (e.g., change the parameter values of a specific feature in the Onshape document).DELETE
: delete information from the server (e.g., delete a specific part from a Part Studio in the Onshape document).
Note: you may not be able to use any API call labelled with DELETE
if you did not allow deleting permission in step 3 of section 2 above.
Before making any API call to Onshape, you need to first set up and configure an "Onshape client" with your API keys. In other words, you need to log in to your Onshape account before you can make changes to your documents, but through an API approach. In general, the set-up process is in the following format:
from onshape_client.client import Client
client = Client(configuration={"base_url": base,
"access_key": access,
"secret_key": secret})
Alternatively, Section 00.1 of the Onshape API Snippets already provides two methods of configuring your API client: manually typing in your API keys, or uploading the .py
file that you may have created and saved in Step 5 of section 2 above. Both of these methods provide efficient and safe configuration approach; your API keys will be deleted from the script right after you successfully configure your account.
After you successfully configure your API keys, you can start making REST API calls with the permissions you provided as you created the keys. A typical Onshape API call has the following format:
response = client.api_client.request(method, url, query_params, headers, body)
method
is one of the three API call types listed in section 3.2 above. This should be entered as a string with all letters capitalized (e.g.,"GET"
). The API call type for every endpoint is also labelled on Glassworks.url
is the URL address to this API call, found as the title for each REST API call on Glassworks. Note that this may NOT be the same URL that you use to access the Onshape document from the browser. For example, to retrieve a list of all the part features in a Part Studio:url='{base_url}/api/partstudios/d/{did}/{wvm}/{wvmid}/e/{eid}/features'
. Notice the addedapi/partstudios/
at the beginning and/features
at the end of the URL.query_params
is a dictionary of parameters that you would like your CAD model to possess. For every endpoint on Glassworks, the "parameters" labelled with(query)
along with their data type are what can be optionally included in thequery_params
dictionary. Common components ofquery_params
include:- The "configuration" of the Onshape document, see further details in section 3.3.1.
- The
partId
of the part that you would like to look specifically into in a Part Studio. You can get all the parts in a Part Studio with this Glassworks endpoint, or snippet 02.1 in the Onshape API Snippets. - Note that the variety of
query_params
are not limited to the two presented here. More advanced applications can be found in the PTC-API-Playground.
headers
is a dictionary that generally consists of only two components:"Accept"
and"Content_Type"
. On Glassworks, the"Accept
header can be found in "Media type" under "Responses" of the API call that you are making. For most cases, we would like"Content_Type"
to be"application/json
, so that we can deal with API response data in JSON format. As an example,headers = {'Accept': 'application/vnd.onshape.v2+json; charset=UTF-8;qs=0.2', 'Content-Type': 'application/json'}
.- Note that if you are making multiple related API calls (e.g., the workflow of making a
POST
call as shown in section 3.3.2), make sure the"Accept"
components of allheaders
across API calls have the same version. Otherwise, the server cannot deal with data of different format in different versions.
- Note that if you are making multiple related API calls (e.g., the workflow of making a
body
is a dictionary of additional request payload that the API call carries with. It is generally only used when making aPOST
call, and it should be written in the same JSON format, the format that is defined for theGET
call; see further details in section 3.3.2.
Putting everything together, here is an example of a complete API call to get the mass properties of a part from the Part Studio:
url = 'https://cad.onshape.com/documents/263517311c2ad139d4eb57ca/w/b45057ae06777e0c28bca6c5/e/d316bcbc694c9dbb6555f340'
element = OnshapeElement(url)
base = element.base_url
fixed_url = '/api/partstudios/d/did/w/wid/e/eid/massproperties'
fixed_url = fixed_url.replace('did', element.did)
fixed_url = fixed_url.replace('wid', element.wvmid)
fixed_url = fixed_url.replace('eid', element.eid)
method = 'GET'
params = {'partID': 'JZH',
'configuration': 'configVariable%3D0.01%2Bmeter'}
headers = {'Accept': 'application/vnd.onshape.v2+json;charset=UTF-8;qs=0.2',
'Content-Type': 'application/json'}
payload = {}
response = client.api_client.request(method, url=base + fixed_url, query_params=params, headers=headers, body=payload)
With the procedure detailed above, the response
from such API calls will be stored in JSON format, and a good way of making the output data more readable and accessbile will be the following:
import json
parsed = json.loads(response.data)
print(json.dumps(parsed, indent=4, sort_keys=True))
Then, parsed
can be accessed in the same way as a Python dictionary, and the print
statement will print out parsed
in a more readable structure with indentation.
When modelling in an Onshape document, building "configurations" of the design provides an efficient method to change the design to different states, both within the Onshape user interface and through making REST API calls. With configurations created for an Onshape document, one can easily change the model in Onshape through multiple API calls with different configuration
input for query_params
in the request. In general, there are two types of configuration that one can create in Onshape:
- Configuration input: various user-defined states of the model that the model can be varied to, where each state may change multiple parameters and/or dimensions of the design.
- Configuration variable: similar to an ordinary variable in Onshape, but with more efficient access and control through API calls.
When accessing the Onshape document with certain configurations through the URL, simply adds ?configuration={config}
to the end of the URL of the document. To build {config}
with the configurations of the document, the following rules applied:
%3D
after a configuration input/variable means=
.%2B
after the numerical value of a configuration variable means the unit of the variable to be followed.%3B
is used asand
when more than one configuration input and/or variable are used.
For example, if I have an Onshape document with configurations size
and base_dimension
, where:
size
is a configuration input with states:"Default"
,"Large"
, and"Small"
;base_dimension
is a configuration variable that defines the base length of the model.
Then, a possible configuration of this model can be specified through an API call in the following format:
# Setting "size" to be "Large" and the "base_dimension" to be 0.5 meter
config = "size%3DLarge%3Bbase_dimension%3D0.5%2Bmeter"
params["configuration"] = config
Note: however, if you do not specify the "configuration"
in your query_params
for the API calls, Onshape will always use the default value of all the configurations, despite any changes in the actual Onshape document. Also, changes to the configuration through API calls are not saved in your actual Onshape document. Hence, you should plan the usage of your CAD model beforehand when deciding whether you should build the model with "configurations" or "variables" (which is essentially a part "feature").
When making a POST
API call to update information of the Onshape model, most procedures and API call components are similar to a GET
call. The major difference comes from specifying the payload body
of the request.
As an example, let's take a look at snippet 01.4 in the Onshape API Snippets. For this example, we would like to update the geometry of a part feature in the Part Studio. In general, the overall pathway of achieving this will be:
- Get the information about this feature through this endpoint, which is a
GET
API call. Making this call can follow the procedure described above in section 3.3. - Explore the returned JSON
response
from theGET
request and locate the specific feature that you would like to modify. Update the information of that feature in-place in the requestresponse
in its original JSON format. - Send the updated information back to your Onshape document and update the feature through this endpoint, which is a
POST
API call.
Note that when you open a POST
endpoint on Glassworks, there should be a section named "Request body" under the "Parameters" that are required for the call. You should define the body
for your API call request to include the required information as specified.
For example, the example above tries to make changes to a feature in the document, and the endpoint of the POST
call in step 3 requires the information of the "feature"
that is to be changed. Hence, the required information for that specific feature is what you will need to locate, retrieve, and modify in step 2.
Instead of building API calls from scratch, there are two other methods that may provide more efficient access to API calls. Note: these are methods are still under testing, some API calls may not function properly. Hence, it is still important to learn how to build an API call from scratch with the steps outlined above.
Installing and importing the onshape_client
library also allow you to make these API calls directly. However, the documentation that automatically shows up when filling the arguments of these calls is not yet fully comprehensive, which may require further referrence to Glassworks. The source code for this library can be found in this GitHub repository, and the code for all API calls can be found in this directory.
With a client
set up as shown in section 3.3, here is an example of getting the mass properties of a part studio in Onshape through making API calls (corresponds to this Glassworks endpoint):
response = client.part_studios_api.get_part_studio_mass_properties(did="263517311c2ad139d4eb57ca",
wvm='w',
wvmid='b45057ae06777e0c28bca6c5',
eid='d316bcbc694c9dbb6555f340')
print(response)
Note a few things from this example:
- After you type out
client.
, you should be able to see a list of different APIs, which corresponds to the API categories on Glassworks. - After specifying the API category (e.g.,
client.part_studios_api.
in this case), you should be able to see a list of different API calls, which are all the API calls that can be made through theonshape_client
library. Note that the function names may be slightly different from the titles shown on Glassworks. - The arguments of the function should align with the field names on Glassworks. In the example above, the arguments included are all the required parameters for the call, and you can definitely also enter other optional parameters as well.
- The returned output of the function (i.e.,
response
in this case) is already well formatted; a simpleprint
statement is capable of printing it in a human-readable format. - If you run into any errors when executing the API call, you may want to check out the source code of the function here.
All API calls have been automatically generated with the method stored in this repository. The API calls are structured in the form of code snippets in Jupyter notebook, which provides greater flexibility with documentation. However, the generator may not be routinely updated with the most current version of the API specification. Also, it should be noted that this repository is only tested with some of the more popular API endpoints, and it may run into errors for edge cases.