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)
Ejemplo n.º 2
0
 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_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
Ejemplo n.º 4
0
 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"))
Ejemplo n.º 5
0
 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"]
Ejemplo n.º 6
0
def import_file(file_path, did, wid):
    """Import a file from the local file system. Returns the URL of the resulting element if translated."""
    client = Client.get_client()
    file = open(file_path, 'rb').read()
    r = client.blob_elements_api.upload_file_create_element(
        did,
        wid,
        media_type="application/stl",
        file=file,
        translate=True,
        encodedFilename=file_path.split('/')[-1],
        _preload_content=False)
    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
Ejemplo n.º 7
0
    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)))
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
 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}")
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
 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
Ejemplo n.º 12
0
 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
     )
Ejemplo n.º 13
0
 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")))
Ejemplo n.º 14
0
 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"])
Ejemplo n.º 15
0
 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()
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
 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
Ejemplo n.º 18
0
 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
Ejemplo n.º 19
0
 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
Ejemplo n.º 20
0
 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)
Ejemplo n.º 21
0
    def __init__(self, url, *args, **kwargs):

        self.client = Client.get_client()

        self.original_url = url
        parsed_vals = parse(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
Ejemplo n.º 22
0
    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
Ejemplo n.º 23
0
 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"))
Ejemplo n.º 24
0
 def create_from_ids(did, wvm, wvmid, eid):
     client = Client.get_client()
     return OnshapeElement(client.configuration.host + "/documents/" + did +
                           "/" + wvm + "/" + wvmid + "/e/" + eid)
Ejemplo n.º 25
0
 def _get_element_infos(self):
     return Client.get_client().documents_api.get_elements_in_document(
         self.did, self.wvm, self.wvmid)
Ejemplo n.º 26
0
 def _get_document_info(self):
     return Client.get_client().documents_api.get_document(self.did)
Ejemplo n.º 27
0
 def delete(self):
     Client.get_client().documents_api.delete_document(self.did)
Ejemplo n.º 28
0
 def microversion(self):
     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"]
     return microversion
Ejemplo n.º 29
0
 def element_type(self):
     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
Ejemplo n.º 30
0
    def request(self,
                method,
                url,
                query_params=None,
                headers=None,
                body=None,
                post_params=None,
                _preload_content=True,
                _request_timeout=None):
        """Perform requests.

        :param method: http request method
        :param url: http request url
        :param query_params: query parameters in the url
        :param headers: http request headers
        :param body: request json body, for `application/json`
        :param post_params: request post parameters,
                            `application/x-www-form-urlencoded`
                            and `multipart/form-data`
        :param _preload_content: if False, the urllib3.HTTPResponse object will
                                 be returned without reading/decoding response
                                 data. Default is True.
        :param _request_timeout: timeout setting for this request. If one
                                 number provided, it will be total request
                                 timeout. It can also be a pair (tuple) of
                                 (connection, read) timeouts.
        """
        method = method.upper()
        assert method in [
            'GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS'
        ]

        if post_params and body:
            raise ApiValueError(
                "body parameter cannot be used with post_params parameter.")

        post_params = post_params or {}
        headers = headers or {}

        timeout = None
        if _request_timeout:
            if isinstance(_request_timeout, (int, ) if six.PY3 else
                          (int, long)):  # noqa: E501,F821
                timeout = urllib3.Timeout(total=_request_timeout)
            elif (isinstance(_request_timeout, tuple)
                  and len(_request_timeout) == 2):
                timeout = urllib3.Timeout(connect=_request_timeout[0],
                                          read=_request_timeout[1])

        if 'Content-Type' not in headers:
            headers['Content-Type'] = 'application/json'

        # Ethan added:
        add_onshape_specific_headers(method,
                                     url,
                                     self.configuration,
                                     query_params=query_params,
                                     headers=headers)

        try:
            # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
            if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
                if query_params:
                    url += '?' + urlencode(query_params)
                if re.search('json', headers['Content-Type'], re.IGNORECASE):
                    request_body = None
                    if body is not None:
                        request_body = json.dumps(body)
                    r = self.pool_manager.request(
                        method,
                        url,
                        body=request_body,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                elif headers[
                        'Content-Type'] == 'application/x-www-form-urlencoded':  # noqa: E501
                    r = self.pool_manager.request(
                        method,
                        url,
                        fields=post_params,
                        encode_multipart=False,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                elif headers['Content-Type'] == 'multipart/form-data':
                    # must del headers['Content-Type'], or the correct
                    # Content-Type which generated by urllib3 will be
                    # overwritten.
                    del headers['Content-Type']
                    r = self.pool_manager.request(
                        method,
                        url,
                        fields=post_params,
                        encode_multipart=True,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                # Pass a `string` parameter directly in the body to support
                # other content types than Json when `body` argument is
                # provided in serialized form
                elif isinstance(body, str) or isinstance(body, bytes):
                    request_body = body
                    r = self.pool_manager.request(
                        method,
                        url,
                        body=request_body,
                        preload_content=_preload_content,
                        timeout=timeout,
                        headers=headers)
                else:
                    # Cannot generate the request from given parameters
                    msg = """Cannot prepare a request message for provided
                             arguments. Please check that your arguments match
                             declared content type."""
                    raise ApiException(status=0, reason=msg)
            # For `GET`, `HEAD`
            else:
                r = self.pool_manager.request(method,
                                              url,
                                              fields=query_params,
                                              preload_content=_preload_content,
                                              timeout=timeout,
                                              headers=headers,
                                              redirect=False)
        except urllib3.exceptions.SSLError as e:
            msg = "{0}\n{1}".format(type(e).__name__, str(e))
            raise ApiException(status=0, reason=msg)

        if _preload_content:
            r = RESTResponse(r)

        # TODO: Handle redirections
        # Ethan added the below clause to handle redirects correctly:
        if 300 <= r.status <= 399:
            # parse location
            location_string = r.getheaders()["Location"]
            location = urlparse(location_string)
            new_url = location.scheme + '://' + location.netloc + location.path
            logger.debug('request redirected to: ' + location_string)
            parsed_qs = parse_qs(location.query)
            for q in parsed_qs:
                parsed_qs[q] = parsed_qs[q][0]
            return self.request(method,
                                new_url,
                                headers=headers,
                                query_params=parsed_qs,
                                body=body,
                                post_params=post_params,
                                _preload_content=_preload_content,
                                _request_timeout=_request_timeout)

        if r.status == 403 or r.status == 401:
            from onshape_client.client import Client
            client = Client.get_client()
            if client.get_authentication_method() == "oauth":
                client.do_oauth_flow()
                headers['Authorization'] = "Bearer {}".format(
                    client.configuration.access_token)
                return self.request(method,
                                    url,
                                    query_params=query_params,
                                    headers=headers,
                                    body=body,
                                    post_params=post_params,
                                    _preload_content=_preload_content,
                                    _request_timeout=_request_timeout)

        if not 200 <= r.status <= 299:
            raise ApiException(http_resp=r)

        return r