diff --git a/src/autodesk_forge_sdk/md.py b/src/autodesk_forge_sdk/md.py index 9242598..b015fd2 100644 --- a/src/autodesk_forge_sdk/md.py +++ b/src/autodesk_forge_sdk/md.py @@ -146,10 +146,12 @@ def submit_job(self, urn: str, output_formats: List[Dict], **kwargs) -> Dict: headers = {} if "force" in kwargs: headers["x-ads-force"] = "true" - # TODO: what about the EMEA endpoint? + if "output_region" in kwargs: + if kwargs["output_region"] == "EMEA": + return self._post("/regions/eu/designdata/job", scopes=WRITE_SCOPES, json=json, headers=headers).json() return self._post("/designdata/job", scopes=WRITE_SCOPES, json=json, headers=headers).json() - def get_thumbnail(self, urn: str, width: int = None, height: int = None) -> bytes: + def get_thumbnail(self, urn: str, width: int = None, height: int = None, region: str = "US") -> bytes: """ Download thumbnail for a source file. @@ -168,6 +170,8 @@ def get_thumbnail(self, urn: str, width: int = None, height: int = None) -> byte If height is omitted, but width is specified, the implicit value for height will match width. If both width and height are omitted, the server will return a thumbnail closest to a width of 200, if available. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Returns: bytes: buffer containing the thumbnail PNG image. @@ -189,11 +193,13 @@ def get_thumbnail(self, urn: str, width: int = None, height: int = None) -> byte params["width"] = width if height: params["height"] = height - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/thumbnail".format(urn) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/thumbnail".format(urn) + else: + endpoint = "/designdata/{}/thumbnail".format(urn) return self._get(endpoint, scopes=READ_SCOPES, params=params).content - def get_manifest(self, urn: str) -> Dict: + def get_manifest(self, urn: str, region: str = "US") -> Dict: """ Retrieve the manifest for the source design specified by the urn URI parameter. The manifest is a list containing information about the derivatives generated @@ -205,6 +211,8 @@ def get_manifest(self, urn: str) -> Dict: Args: urn (str): Base64-encoded ID of the source file. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Returns: Dict: Parsed manifest JSON. @@ -219,11 +227,13 @@ def get_manifest(self, urn: str) -> Dict: print(manifest) ``` """ - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/manifest".format(urn) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/manifest".format(urn) + else: + endpoint = "/designdata/{}/manifest".format(urn) return self._get(endpoint, scopes=READ_SCOPES).json() - def delete_manifest(self, urn: str): + def delete_manifest(self, urn: str, region: str = "US"): """ Delete the manifest and all its translated output files (derivatives). However, it does not delete the design source file. @@ -233,6 +243,8 @@ def delete_manifest(self, urn: str): Args: urn (str): Base64-encoded ID of the source file. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Examples: ``` @@ -244,11 +256,13 @@ def delete_manifest(self, urn: str): client.delete_manifest(URN) ``` """ - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/manifest".format(urn) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/manifest".format(urn) + else: + endpoint = "/designdata/{}/manifest".format(urn) self._delete(endpoint, scopes=WRITE_SCOPES) - def get_metadata(self, urn: str) -> Dict: + def get_metadata(self, urn: str, region: str = "US") -> Dict: """ Returns a list of model view (metadata) IDs for a design model. The metadata ID enables end users to select an object tree and properties for a specific model view. @@ -258,6 +272,8 @@ def get_metadata(self, urn: str) -> Dict: Args: urn (str): Base64-encoded ID of the source file. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Returns: Dict: Parsed response JSON. @@ -273,11 +289,13 @@ def get_metadata(self, urn: str) -> Dict: print(metadata) ``` """ - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/metadata".format(urn) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/metadata".format(urn) + else: + endpoint = "/designdata/{}/metadata".format(urn) return self._get(endpoint, scopes=READ_SCOPES).json() - def get_viewable_tree(self, urn: str, guid: str) -> Dict: + def get_viewable_tree(self, urn: str, guid: str, region: str = "US") -> Dict: """ Return an object tree, i.e., a hierarchical list of objects for a model view. @@ -287,6 +305,8 @@ def get_viewable_tree(self, urn: str, guid: str) -> Dict: Args: urn (str): Base64-encoded ID of the source file. guid (str): ID of one of the viewables extracted from the source file. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Returns: Dict: Parsed response JSON. @@ -302,11 +322,13 @@ def get_viewable_tree(self, urn: str, guid: str) -> Dict: print(tree) ``` """ - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/metadata/{}".format(urn, guid) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/metadata/{}".format(urn, guid) + else: + endpoint = "/designdata/{}/metadata/{}".format(urn, guid) return self._get(endpoint, scopes=READ_SCOPES).json() - def get_viewable_properties(self, urn: str, guid: str) -> Dict: + def get_viewable_properties(self, urn: str, guid: str, region: str = "US") -> Dict: """ Return a list of properties for each object in an object tree. Properties are returned according to object ID and do not follow a hierarchical structure. @@ -317,6 +339,8 @@ def get_viewable_properties(self, urn: str, guid: str) -> Dict: Args: urn (str): Base64-encoded ID of the source file. guid (str): ID of one of the viewables extracted from the source file. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Returns: Dict: Parsed response JSON. @@ -331,11 +355,13 @@ def get_viewable_properties(self, urn: str, guid: str) -> Dict: print(props) ``` """ - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/metadata/{}/properties".format(urn, guid) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/metadata/{}/properties".format(urn, guid) + else: + endpoint = "/designdata/{}/metadata/{}/properties".format(urn, guid) return self._get(endpoint, scopes=READ_SCOPES).json() - def get_derivative_info(self, urn: str, deriv_urn: str) -> Dict: + def get_derivative_info(self, urn: str, deriv_urn: str, region: str = "US") -> Dict: """ Return information about the specified derivative. @@ -345,17 +371,21 @@ def get_derivative_info(self, urn: str, deriv_urn: str) -> Dict: Args: urn (str): Base64-encoded ID of the source file. deriv_urn (str): ID of one of the derivatives generated from the source file. + region (str, optional): Region where the bucket resides. + Acceptable values: US, EMEA. Default: US. Returns: Dict: Derivative information, currently with just a single property, "size", indicating the size of the derivative in bytes. """ - # TODO: what about the EMEA endpoint? - endpoint = "/designdata/{}/manifest/{}".format(urn, deriv_urn) + if region == "EMEA": + endpoint = "/regions/eu/designdata/{}/manifest/{}".format(urn, deriv_urn) + else: + endpoint = "/designdata/{}/manifest/{}".format(urn, deriv_urn) resp = self._head(endpoint, scopes=READ_SCOPES) return { "size": int(resp.headers["Content-Length"]) } - def get_derivative(self, urn: str, deriv_urn: str, byte_range: tuple=None) -> bytes: + def get_derivative(self, urn: str, deriv_urn: str, byte_range: tuple = None) -> bytes: """ Download a derivative generated from a specific source model. To download the derivative, you need to specify its URN which can be retrieved from the Model Derivative manifest. diff --git a/tests/context.py b/tests/context.py index 9d2ef76..38d9f67 100644 --- a/tests/context.py +++ b/tests/context.py @@ -14,3 +14,4 @@ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"] FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"] FORGE_BUCKET = os.environ["FORGE_BUCKET"] + diff --git a/tests/test_md.py b/tests/test_md.py index 8cab5db..bdb8868 100644 --- a/tests/test_md.py +++ b/tests/test_md.py @@ -1,5 +1,6 @@ import unittest -from .context import ModelDerivativeClient, urnify, OAuthTokenProvider, FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, FORGE_BUCKET +from context import ModelDerivativeClient, urnify, OAuthTokenProvider, FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, FORGE_BUCKET + class ModelDerivativeClientTestSuite(unittest.TestCase): """Forge Model Derivative client test cases.""" @@ -22,8 +23,12 @@ def test_urnify(self): # output.write(png) # def test_get_manifest(self): - # manifest = self.client.get_manifest('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6cGV0cmJyb3otc2FtcGxlcy9ybWVfYmFzaWNfc2FtcGxlX3Byb2plY3QucnZ0') + # manifest = self.client.get_manifest("dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6aGVubi1tYWluLWJ1Y2tldC9yYWNiYXNpY3NhbXBsZXByb2plY3QucnZ0", "EMEA") # assert manifest + # def test_get_metadata(self): + # metadata = self.client.get_metadata("dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6aGVubi1tYWluLWJ1Y2tldC9yYWNiYXNpY3NhbXBsZXByb2plY3QucnZ0", "EMEA") + # assert metadata + if __name__ == "__main__": unittest.main() \ No newline at end of file