def get_client(self): """Start the client if the client isn't already started.""" try: client = Client.get_client(create_if_needed=False) except Exception as e: if self.stack == "STAGE": base_url = "https://staging.dev.onshape.com" token_uri = "https://staging-oauth.dev.onshape.com/oauth/token" authorization_uri = "https://staging-oauth.dev.onshape.com/oauth/authorize" elif self.stack == "DEMOC": base_url = "https://demo-c.dev.onshape.com" token_uri = "https://demo-c-oauth.dev.onshape.com/oauth/token" authorization_uri = "https://demo-c-oauth.dev.onshape.com/oauth/authorize" # PROD stack is default. else: base_url = "https://cad.onshape.com" token_uri = "https://oauth.onshape.com/oauth/token" authorization_uri = "https://oauth.onshape.com/oauth/authorize" client = Client( configuration={ "client_id": self.client_id, "client_secret": self.client_secret, "base_url": base_url, "token_uri": token_uri, "authorization_uri": authorization_uri, "oauth_authorization_method": OAuthAuthorizationMethods.MANUAL_FLOW, "scope": ["OAuth2Read"], "redirect_uri": self.redirect_uri, "access_token": self.access_token, "refresh_token": self.refresh_token }) return client
def client() -> Client: """Client needed to make API calls.""" try: client = Client.get_client() except Exception as e: client = Client(stack_key="onshape_client_test") return client
def import_item(self, import_item): did = self.onshape_element.did wid = self.onshape_element.wvmid path = write_to_file(import_item["file"]) eid = import_file(path, did, wid) onshape_element = self.onshape_element onshape_element.eid = eid url = onshape_element.get_url() mass_properties = Client.get_client().part_studios_api.get_mass_properties(did, 'w', wid, eid) # type: BTMassPropResponse volume = mass_properties.bodies["-all-"].volume[0]*1000000000 bounding_box = Client.get_client().part_studios_api.get_bounding_boxes2(did, 'w', wid, eid, _preload_content=False) data = bounding_box.data if six.PY3: data = data.decode('utf-8') bounding_box = json.loads(data) x_span = (bounding_box["highX"]-bounding_box["lowX"])*1000 y_span = (bounding_box["highY"]-bounding_box["lowY"])*1000 z_span = (bounding_box["highZ"]-bounding_box["lowZ"])*1000 bounding_box = "L = {x_span}, W = {y_span}, H = {z_span}".format(x_span=x_span, y_span=y_span, z_span=z_span) if "part_metadata" in import_item or "element_metadata" in import_item: meta_data_to_be_set = MetaDataBody(OnshapeElement.create_from_ids(did, "w", wid, eid)) if "part_metadata" in import_item: part_metadata = import_item["part_metadata"] # Add the volume part volume property from the API: meta_data_to_be_set.add_to_part_metadata("Part Volume", volume) meta_data_to_be_set.add_to_part_metadata("Bounding Box", bounding_box) for k, v in part_metadata.items(): # For the fixed field items, set for the first part if k != "additionalItems": meta_data_to_be_set.add_to_part_metadata(k, v) else: for custom_metadata_item in v: meta_data_to_be_set.add_to_part_metadata(custom_metadata_item["part_id"], custom_metadata_item["property_name"], custom_metadata_item["new_value"]) if "element_metadata" in import_item: element_metadata = import_item["element_metadata"] for k, v in element_metadata.items(): if k != "additionalItems": meta_data_to_be_set.add_to_element_metadata(k,v) else: for custom_metadata_item in v: meta_data_to_be_set.add_to_element_metadata(custom_metadata_item["property_name"], custom_metadata_item["new_value"], eid=eid) meta_data_to_be_set.send() if "bounding_box" in import_item and import_item["bounding_box"]: feature_path = "bound_all_set_metadata.json" # feature_path = "bound_all_feature.json" # feature_path = "make_cube_feature.json" with open(os.path.dirname(__file__) + "/assets/" + feature_path, "r") as f: body = {"feature": json.loads(f.read())} Client.get_client().part_studios_api.add_feature1(did, "w", wid, eid, body=body)
def test_specify_client_config_in_code(): client = Client( configuration={ "base_url": "https://cad.onshape.com", "access_key": "USER_ACCESS_KEY", "secret_key": "USER_SECRET_KEY", }) assert client.configuration.api_key["SECRET_KEY"] == "USER_SECRET_KEY" assert client.configuration.api_key["ACCESS_KEY"] == "USER_ACCESS_KEY" # Reset client: client = Client() assert client.configuration.api_key["SECRET_KEY"] != "USER_SECRET_KEY" assert client.configuration.api_key["ACCESS_KEY"] != "USER_ACCESS_KEY"
def make_version(name, did): return json.loads(Client.get_client().documents_api.create_version( did, bt_version_or_workspace_params=BTVersionOrWorkspaceParams( name=name + "-" + str(datetime.now()), document_id=did), _preload_content=False, ).data)["id"]
def do_POST(self): content_length = int(self.headers['Content-Length']) body = self.rfile.read(content_length) unquoted_s = "" if six.PY2: import urllib unquoted_s = urllib.unquote(body) elif six.PY3: unquoted_s = body.decode('utf-8') data = json.loads(unquoted_s) from onshape_client.oas.models import BTDocumentParams bt_document_params = BTDocumentParams(name=data["doc_name"]) new_doc_response = Client.get_client().documents_api.create11( bt_document_params, _preload_content=False) did = get_field(new_doc_response, "id") wid = get_field(new_doc_response, "defaultWorkspace")["id"] # Use a fake eid because it isn't used later. eid = "00000000000000" self.onshape_element = OnshapeElement.create_from_ids( did, "w", wid, eid) if "import_items" in data: for import_item in data["import_items"]: self.import_item(import_item) self.send_response(200) self.send_header('Content-type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.end_headers() content = { "document_href": self.onshape_element.get_url(url_type="document") } self.wfile.write(sendable(json.dumps(content)))
def test_import_file(assets, new_document): """Import a file from the local file system. Returns the URL of the resulting element if translated.""" client = Client() cube_path = assets / 'Cube.x_t' file = open(cube_path, 'rb').read() r = client.blob_elements_api.upload_file_create_element( new_document.did, new_document.wvmid, _preload_content=False) # file=file, translate=True, encodedFilename=cube_path.name, media_type="application/stl", translation_id = get_field(r, 'translationId') print("The translationId is: {}.".format(translation_id)) state = 'ACTIVE' while state == 'ACTIVE': time.sleep(2) r = client.translation_api.get_translation(translation_id, _preload_content=False) state = get_field(r, "requestState") element_id = get_field(r, 'resultElementIds')[0] # Make the actual download when the translation is done, otherwise report the error if state == "DONE": print( "Translated document available at {host}/documents/{did}/w/{wid}/e/{eid}" .format(host=client.configuration.host, did=get_field(r, 'documentId'), wid=get_field(r, 'workspaceId'), eid=element_id)) else: print("An error ocurred on the server! Here is the response: \n") return element_id
def create_drawing(self, drawing_name="My Drawing"): """Create a four view drawing of the current element""" if self.wvm != "w": raise UserWarning( "Can only create a drawing in a workspace - not a version." ) drawing = Client.get_client().drawings_api.create_drawing_app_element( bt_drawing_params=BTDrawingParams( document_id=self.did, workspace_id=self.wvmid, drawing_name=drawing_name, element_id=self.eid, views="four", template_document_id="cbe6e776694549b5ba1a3e88", template_workspace_id="24d08acf10234dbc8d3ab585", template_element_id="17eef7862b224f6fb12cbc46", projection="third", hidden_lines="EXCLUDED", is_surface=False, element_configuration="default", is_flattened_part=False, reference_type=1, ) ) drawing = OnshapeElement.create_from_ids(eid=drawing.id, sibling=self) return drawing
def _get_configuration_encoding_response(self): res = Client.get_client().elements_api.encode_configuration_map( self.did, self.eid, self._get_bt_configuration_params_for_current_configuration(), _preload_content=False) return json.loads(res.data.decode("utf-8"))
def export_file( self, file_path: Path, bt_translate_format_params: BTTranslateFormatParams ): """Exports the element this class is pointing to""" bt_translate_format_params.element_id = self.eid kwargs = {} kwargs.update( dict( did=self.did, wv=self.wvm, wvid=self.wvmid, eid=self.eid, bt_translate_format_params=bt_translate_format_params, ) ) if self._get_element_info().data_type == OnshapeElement.DRAWING_DATA_TYPE: func = Client.get_client().drawings_api.create_drawing_translation elif self.element_type == "Assembly": func = Client.get_client().assemblies_api.translate_format elif self.element_type == "Part Studio": func = Client.get_client().part_studios_api.create_part_studio_translation else: raise NotImplemented( f"Export for {self.element_type} through the OnshapeElement isn't supported yet." ) result = func(**kwargs) if ( "store_in_document" in bt_translate_format_params.to_dict() and bt_translate_format_params.store_in_document ): return translation_id = result.id result = OnshapeElement.poll_translation_result(translation_id) if result.result_external_data_ids: count = 0 for download_id in result.result_external_data_ids: file_path.write_bytes( Client.get_client() .documents_api.download_external_data( did=self.did, fid=download_id, _preload_content=False ) .data ) count = count+1 file_path.with_name(f"{file_path.name}-{count}")
def create(name="New Document"): """Returns a blank new document.""" client = Client.get_client() doc_params = BTDocumentParams(name=name, is_public=True) doc = client.documents_api.create_document(doc_params) doc = OnshapeElement.create_from_ids( did=doc.id, wvm="w", wvmid=doc.default_workspace.id ) return doc
def element_type(self): """ :return:String "APPLICATION" (for a drawing or 3rd party application), "PARTSTUDIO" or "ASSEMBLY" """ elements = Client.get_client().documents_api.get_elements_in_document( self.did, self.wvm, self.wvmid ) for element in elements: if element.id == self.eid: return element.type
def get_microversion_url(self): """Determine the microversion from the current version/workspace and return the path to that microversion. This will call the API to get the current microversion if the microversion is not already specified.""" if self.optional_microversion: return self.get_url() else: res = Client.get_client().documents_api.get_current_microversion( self.did, self.wvm, self.wvmid, _preload_content=False) microversion = json.loads(res.data.decode("UTF-8"))["microversion"] self.optional_microversion = microversion return self.get_url()
def make_version(self, name, **kwargs): result = Client.get_client().documents_api.create_version( self.did, bt_version_or_workspace_params=BTVersionOrWorkspaceParams( name=name, document_id=self.did, **kwargs ), _preload_content=False, ) return self.create_from_ids( wvmid=json.loads(result.data)["id"], wvm="v", sibling=self )
def new_assembly(self, name="Assembly"): asm = Client.get_client().assemblies_api.create_assembly( self.did, self.wvmid, BTModelElementParams(name=name), _preload_content=False) asm = json.loads(asm.data.decode('utf-8')) return OnshapeElement.create_from_ids(did=self.did, wvm='w', wvmid=self.wvmid, eid=asm["id"])
def make_sub_assembly_definition(self, sa_occurrence_path): """Get the AssemblyDefinition representing the subassembly.""" sa = self.get_instance(sa_occurrence_path) result = Client.get_client().assemblies_api.get_assembly_definition( sa["documentId"], 'v', sa["documentVersion"], sa["elementId"], configuration=sa["configuration"], _preload_content=False) return AssemblyDefinition(json.loads(result.data.decode("UTF-8")))
def test_specify_client_config_in_code(): # Clear the current instance if there is one Client.__instance = None client = Client(configuration={ "base_url": "https://cad.onshape.com", "access_key": "USER_ACCESS_KEY", "secret_key": "USER_SECRET_KEY" }) assert client.configuration.api_key["SECRET_KEY"] == "USER_SECRET_KEY" assert client.configuration.api_key["ACCESS_KEY"] == "USER_ACCESS_KEY"
def poll_translation_result(translation_id): def is_polling_done(response): if response.request_state == "DONE": return True elif response.request_state == "ACTIVE": return False raise UserWarning(f"Translation failed") polling_function = lambda: Client.get_client().translation_api.get_translation( translation_id ) return OnshapeElement.poll(polling_function, is_polling_done)
def create_from_ids(did=None, wvm=None, wvmid=None, eid=None, partid=None, configuration=None): client = Client.get_client() url = client.configuration.host + "/documents/" + did + "/" + wvm + "/" + wvmid url = url + "/e/" + eid if eid else url url = url + "?configuration=" + configuration if configuration else url result = OnshapeElement(url) result.partid = partid return result
def get_element_property_name_to_property_id_map(self): """Get the element metadata for the workspace/version and build the map""" client = Client.get_client() property_map = {} response = client.metadata_api.get_wv_es_metadata(self.onshape_element.did, self.onshape_element.wvm, self.onshape_element.wvmid, _preload_content=False) data = json.loads(response.data) for element in data['items']: eid = element['elementId'] property_map[eid] = {} props_to_be_added = property_map[eid] for property in element['properties']: props_to_be_added[property['name']] = property['propertyId'] return property_map
def connectToClient(verbose=False): # Setting up the client args["client"] = Client( configuration={ "base_url": args["base"], "access_key": args["key"], "secret_key": args["secret"] }) args["headers"] = { 'Accept': 'application/vnd.onshape.v1+json; charset=UTF-8;qs=0.1', 'Content-Type': 'application/json' } if (verbose): print("Connected to Onshape Client!", end="\n\n")
def get_part_property_name_to_property_id_map(self): """Get the part property map for the element in the particular version and build out the property map""" client = Client.get_client() property_map = {} part_index_to_part_id = [] el = self.onshape_element response = client.metadata_api.get_wmve_ps_metadata(el.did, el.wvm, el.wvmid, el.eid, _preload_content=False) data = load_json(response) for i, part in enumerate(data['items']): partId = part['partId'] part_index_to_part_id.append(partId) property_map[partId] = {} props_to_be_added = property_map[partId] for property in part['properties']: props_to_be_added[property['name']] = property['propertyId'] return property_map, part_index_to_part_id
def import_file(self, file_path, translate=True, **kwargs): """Import a file from the local file system. Returns the URL of the resulting element if translated.""" client = Client.get_client() result = client.blob_elements_api.upload_file_create_element( self.did, self.wvmid, file=open(file_path, "rb"), encoded_filename=file_path.name, **kwargs, ) if translate: translation_id = result.translation_id result = OnshapeElement.poll_translation_result(translation_id) element_id = result.result_element_ids[0] else: element_id = result.id return OnshapeElement.create_from_ids(eid=element_id, sibling=self)
def __init__(self, url, *args, client=None, **kwargs): self.client = client if client else Client() self.original_url = url parsed_vals = urlparse(url) self.base_url = parsed_vals.scheme + "://" + parsed_vals.netloc path_list = parsed_vals.path.split('/') self.did = path_list[2] self.wvmid = path_list[4] self.wvm = path_list[3] if len(path_list) > 7: eid = path_list[8] optional_microversion = path_list[6] else: eid = path_list[6] # This is the microversion retrieved from get_microversion_path() and represents a part that is pointing towards # both a version/workspace and a microversion. optional_microversion = None self.eid = eid self.optional_microversion = optional_microversion
def initializeClient(self): """ Initializes all of the onshape info for API communication """ self.key = "" self.secret = "" with open("api-key", "r") as f: self.key = f.readline().rstrip() self.secret = f.readline().rstrip() self.base_url = 'https://cad.onshape.com' self.headers = { 'Accept': 'application/vnd.onshape.v1+json', 'Content-Type': 'application/json' } self.currentCourse = 'ME134' self.query_params = {} self.sharedQ = {'filter': 2, 'q': self.currentCourse} self.client = Client( configuration={ "base__url": self.base_url, "access_key": self.key, "secret_key": self.secret })
def __init__(self, name=None, max_points=1, onshape_element=None): """Initialize the definition of the check""" self.max_points = max_points # The points scored for this check self.points = 0 self.name = name if name else self.__name__ # Start client on the fly if need be. self.client = Client.get_client() # A key value map for template substitutions self.template_context = {"a_test_variable_name": "a test variable value"} self.onshape_element = onshape_element if isinstance(onshape_element, OnshapeElement) or not onshape_element \ else OnshapeElement(onshape_element) self.did = self.onshape_element.did self.wvm = self.onshape_element.wvm self.wvmid = self.onshape_element.wvmid self.eid = self.onshape_element.eid # Whether or not the check passed self.passed = False
def imageToOnshape(api_path, image_path, feature_title, ids=["", "", ""], scale=100, thresh=100): key = "" secret = "" with open(api_path, "r") as f: key = f.readline().rstrip() secret = f.readline().rstrip() did, wid, eid = ids base_url = 'https://rogers.onshape.com' client = Client(configuration={ "base_url": base_url, "access_key": key, "secret_key": secret }) get_string = "/api/featurestudios/d/" + did + "/w/" + wid + "/e/" + eid update_string = get_string post_api_call = base_url + update_string get_api_call = base_url + get_string # read the image img = cv2.imread(image_path) width = int(img.shape[1] * scale / 100) height = int(img.shape[0] * scale / 100) dim = (width, height) image = cv2.resize(img, dim, interpolation=cv2.INTER_NEAREST) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) _, binary = cv2.threshold(gray, thresh, thresh, cv2.THRESH_BINARY_INV) # GRAB EXTERNAL CONTOUR contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) data = np.vstack(contours).squeeze() # np.savetxt("test-test.txt", data, fmt="%d") x = [sub[0] / scale for sub in data] y = [sub[1] / scale for sub in data] formatter_x = [] formatter_y = [] for i, pixel in enumerate(x): formatter_x.append("%.6f" % (pixel)) formatter_y.append("%.6f" % (y[i])) formatter_y = formatter_y[:-1] formatter_x = formatter_x[:-1] formatter_x.append("%.6f" % (x[0])) formatter_y.append("%.6f" % (y[0])) test_string = "vector( 2.000000, 1.000000) * mm" overall_string = "" for i in range(len(formatter_x)): if i == len(formatter_x) - 1: overall_string += ("vector(%s, %s) * inch" % (formatter_x[i], formatter_y[i])) else: overall_string += ("vector(%s, %s) * inch, " % (formatter_x[i], formatter_y[i])) if i % 5 == 0: overall_string += "\n" start_string = """FeatureScript 1301; import(path : "onshape/std/geometry.fs", version : "1301.0"); annotation { "Feature Type Name" : "Python3 Feature" } export const myFeature = defineFeature(function(context is Context, id is Id, definition is map) precondition { // Define the parameters of the feature type } { var sketch1 = newSketch(context, id + "sketch1", { "sketchPlane" : qCreatedBy(makeId("Top"), EntityType.FACE) }); skPolyline(sketch1, "polyline1", { "points" : [""" start_string = start_string.replace("Python3 Feature", feature_title) end_string = """]}); skSolve(sketch1); // Define the function's action });""" full_fs = (start_string + overall_string + end_string) # Make API Calls headers = { 'Accept': 'application/vnd.onshape.v1+json', 'Content-Type': 'application/json' } r = client.api_client.request('GET', url=get_api_call, query_params={}, headers=headers) result = json.loads(r.data) #Find rejectMicroversionSkew, serializationVersion, sourceMicroversion serializationVersion = result["serializationVersion"] sourceMicroversion = result["sourceMicroversion"] rejectMicroversionSkew = result["rejectMicroversionSkew"] body = { "contents": full_fs, "serializationVersion": str(serializationVersion), "sourceMicroversion": str(sourceMicroversion), "rejectMicroversionSkew": str(rejectMicroversionSkew) } r = client.api_client.request("POST", url=post_api_call, query_params={}, headers=headers, body=body) result2 = json.loads(r.data)
def _get_raw_configuration_params(self): response = Client.get_client().elements_api.get_configuration( self.did, self.wvm, self.wvmid, self.eid, _preload_content=False) return json.loads(response.data.decode("utf-8"))
def create_from_ids(did, wvm, wvmid, eid): client = Client.get_client() return OnshapeElement(client.configuration.host + "/documents/" + did + "/" + wvm + "/" + wvmid + "/e/" + eid)
def _get_element_infos(self): return Client.get_client().documents_api.get_elements_in_document( self.did, self.wvm, self.wvmid)