6
6
import secrets
7
7
import string
8
8
from enum import Enum
9
- from typing import BinaryIO
9
+ from typing import Any , BinaryIO , Optional , Union
10
10
from urllib .parse import parse_qs , urlencode , urlparse
11
11
12
12
import requests
@@ -32,7 +32,7 @@ class HTTP(str, Enum):
32
32
DELETE = "delete"
33
33
34
34
35
- def load_env_variables (env ) :
35
+ def load_env_variables (env : str ) -> tuple [ str , str ] :
36
36
"""
37
37
Load environment variables from the specified .env file.
38
38
@@ -61,7 +61,7 @@ def load_env_variables(env):
61
61
return access_key , secret_key
62
62
63
63
64
- def make_nonce ():
64
+ def make_nonce () -> str :
65
65
"""
66
66
Generate a unique ID for the request, 25 chars in length
67
67
@@ -85,7 +85,7 @@ class Client:
85
85
- logging (bool, default=True): Turn logging on or off
86
86
"""
87
87
88
- def __init__ (self , env = "./.env" , log_file = "./onshape.log" , log_level = 1 ) :
88
+ def __init__ (self , env : str = "./.env" , log_file : str = "./onshape.log" , log_level : int = 1 ) -> None :
89
89
"""
90
90
Instantiates an instance of the Onshape class. Reads credentials from a .env file.
91
91
@@ -96,13 +96,13 @@ def __init__(self, env="./.env", log_file="./onshape.log", log_level=1):
96
96
- env (str, default='./.env'): Environment file location
97
97
"""
98
98
99
- self ._url = BASE_URL
99
+ self ._url : str = BASE_URL
100
100
self ._access_key , self ._secret_key = load_env_variables (env )
101
101
LOGGER .set_file_name (log_file )
102
102
LOGGER .set_stream_level (LOG_LEVEL [log_level ])
103
103
LOGGER .info (f"Onshape API initialized with env file: { env } " )
104
104
105
- def get_document (self , did ) :
105
+ def get_document (self , did : str ) -> DocumentMetaData :
106
106
"""
107
107
Get details for a specified document.
108
108
@@ -116,7 +116,7 @@ def get_document(self, did):
116
116
117
117
return DocumentMetaData .model_validate (_request_json )
118
118
119
- def get_elements (self , did , wtype , wid ) :
119
+ def get_elements (self , did : str , wtype : str , wid : str ) -> dict [ str , Element ] :
120
120
"""
121
121
Get list of elements in a document.
122
122
@@ -138,7 +138,7 @@ def get_elements(self, did, wtype, wid):
138
138
139
139
return {element ["name" ]: Element .model_validate (element ) for element in _elements_json }
140
140
141
- def get_features_from_partstudio (self , did , wid , eid ) :
141
+ def get_features_from_partstudio (self , did : str , wid : str , eid : str ) -> requests . Response :
142
142
"""
143
143
Gets the feature list for specified document / workspace / part studio.
144
144
@@ -156,7 +156,7 @@ def get_features_from_partstudio(self, did, wid, eid):
156
156
"/api/partstudios/d/" + did + "/w/" + wid + "/e/" + eid + "/features" ,
157
157
)
158
158
159
- def get_features_from_assembly (self , did , wtype , wid , eid ) :
159
+ def get_features_from_assembly (self , did : str , wtype : str , wid : str , eid : str ) -> dict [ str , Any ] :
160
160
"""
161
161
Gets the feature list for specified document / workspace / part studio.
162
162
@@ -173,7 +173,7 @@ def get_features_from_assembly(self, did, wtype, wid, eid):
173
173
"get" , "/api/assemblies/d/" + did + "/" + wtype + "/" + wid + "/e/" + eid + "/features"
174
174
).json ()
175
175
176
- def get_variables (self , did , wid , eid ) :
176
+ def get_variables (self , did : str , wid : str , eid : str ) -> dict [ str , Variable ] :
177
177
"""
178
178
Get list of variables in a variable studio.
179
179
@@ -194,7 +194,7 @@ def get_variables(self, did, wid, eid):
194
194
195
195
return {variable ["name" ]: Variable .model_validate (variable ) for variable in _variables_json [0 ]["variables" ]}
196
196
197
- def set_variables (self , did , wid , eid , variables ) :
197
+ def set_variables (self , did : str , wid : str , eid : str , variables : dict [ str , Variable ]) -> requests . Response :
198
198
"""
199
199
Set variables in a variable studio.
200
200
@@ -219,7 +219,7 @@ def set_variables(self, did, wid, eid, variables):
219
219
body = payload ,
220
220
)
221
221
222
- def create_assembly (self , did , wid , name = "My Assembly" ):
222
+ def create_assembly (self , did : str , wid : str , name : str = "My Assembly" ) -> requests . Response :
223
223
"""
224
224
Creates a new assembly element in the specified document / workspace.
225
225
@@ -236,7 +236,9 @@ def create_assembly(self, did, wid, name="My Assembly"):
236
236
237
237
return self .request (HTTP .POST , "/api/assemblies/d/" + did + "/w/" + wid , body = payload )
238
238
239
- def get_assembly (self , did , wtype , wid , eid , configuration = "default" ):
239
+ def get_assembly (
240
+ self , did : str , wtype : str , wid : str , eid : str , configuration : str = "default"
241
+ ) -> tuple [Assembly , dict [str , Any ]]:
240
242
_request_path = "/api/assemblies/d/" + did + "/" + wtype + "/" + wid + "/e/" + eid
241
243
_assembly_json = self .request (
242
244
HTTP .GET ,
@@ -251,10 +253,10 @@ def get_assembly(self, did, wtype, wid, eid, configuration="default"):
251
253
252
254
return Assembly .model_validate (_assembly_json ), _assembly_json
253
255
254
- def get_parts (self , did , wid , eid ) :
256
+ def get_parts (self , did : str , wid : str , eid : str ) -> None :
255
257
pass
256
258
257
- def download_stl (self , did , wid , eid , partID , buffer : BinaryIO ):
259
+ def download_stl (self , did : str , wid : str , eid : str , partID : str , buffer : BinaryIO ) -> None :
258
260
"""
259
261
Exports STL export from a part studio and saves it to a file.
260
262
@@ -288,7 +290,7 @@ def download_stl(self, did, wid, eid, partID, buffer: BinaryIO):
288
290
else :
289
291
LOGGER .info (f"Failed to download STL file: { response .status_code } - { response .text } " )
290
292
291
- def get_mass_properties (self , did , wid , eid , partID ) :
293
+ def get_mass_properties (self , did : str , wid : str , eid : str , partID : str ) -> MassModel :
292
294
"""
293
295
Get mass properties for a part in a part studio.
294
296
@@ -306,7 +308,16 @@ def get_mass_properties(self, did, wid, eid, partID):
306
308
307
309
return MassModel .model_validate (_resonse_json ["bodies" ][partID ])
308
310
309
- def request (self , method , path , query = None , headers = None , body = None , base_url = None , log_response = True ):
311
+ def request (
312
+ self ,
313
+ method : Union [HTTP , str ],
314
+ path : str ,
315
+ query : Optional [dict [str , Any ]] = None ,
316
+ headers : Optional [dict [str , str ]] = None ,
317
+ body : Optional [dict [str , Any ]] = None ,
318
+ base_url : Optional [str ] = None ,
319
+ log_response : bool = True ,
320
+ ) -> requests .Response :
310
321
"""
311
322
Issues a request to Onshape
312
323
@@ -347,10 +358,12 @@ def request(self, method, path, query=None, headers=None, body=None, base_url=No
347
358
348
359
return res
349
360
350
- def _build_url (self , base_url , path , query ) :
361
+ def _build_url (self , base_url : str , path : str , query : dict [ str , Any ]) -> str :
351
362
return base_url + path + "?" + urlencode (query )
352
363
353
- def _send_request (self , method , url , headers , body ):
364
+ def _send_request (
365
+ self , method : Union [HTTP , str ], url : str , headers : dict [str , str ], body : Optional [dict [str , Any ]]
366
+ ) -> requests .Response :
354
367
return requests .request (
355
368
method ,
356
369
url ,
@@ -361,7 +374,9 @@ def _send_request(self, method, url, headers, body):
361
374
timeout = 10 , # Specify an appropriate timeout value in seconds
362
375
)
363
376
364
- def _handle_redirect (self , res , method , headers , log_response = True ):
377
+ def _handle_redirect (
378
+ self , res : requests .Response , method : Union [HTTP , str ], headers : dict [str , str ], log_response : bool = True
379
+ ) -> requests .Response :
365
380
location = urlparse (res .headers ["Location" ])
366
381
querystring = parse_qs (location .query )
367
382
@@ -374,13 +389,21 @@ def _handle_redirect(self, res, method, headers, log_response=True):
374
389
method , location .path , query = new_query , headers = headers , base_url = new_base_url , log_response = log_response
375
390
)
376
391
377
- def _log_response (self , res ) :
392
+ def _log_response (self , res : requests . Response ) -> None :
378
393
if not 200 <= res .status_code <= 206 :
379
394
LOGGER .debug (f"Request failed, details: { res .text } " )
380
395
else :
381
396
LOGGER .debug (f"Request succeeded, details: { res .text } " )
382
397
383
- def _make_auth (self , method , date , nonce , path , query = None , ctype = "application/json" ):
398
+ def _make_auth (
399
+ self ,
400
+ method : Union [HTTP , str ],
401
+ date : str ,
402
+ nonce : str ,
403
+ path : str ,
404
+ query : Optional [dict [str , Any ]] = None ,
405
+ ctype : str = "application/json" ,
406
+ ) -> str :
384
407
"""
385
408
Create the request signature to authenticate
386
409
@@ -412,7 +435,13 @@ def _make_auth(self, method, date, nonce, path, query=None, ctype="application/j
412
435
413
436
return auth
414
437
415
- def _make_headers (self , method , path , query = None , headers = None ):
438
+ def _make_headers (
439
+ self ,
440
+ method : Union [HTTP , str ],
441
+ path : str ,
442
+ query : Optional [dict [str , Any ]] = None ,
443
+ headers : Optional [dict [str , str ]] = None ,
444
+ ) -> dict [str , str ]:
416
445
"""
417
446
Creates a headers object to sign the request
418
447
0 commit comments