33from .auth import BaseOAuthClient , Scope , TokenProviderInterface , SimpleTokenProvider , OAuthTokenProvider
44
55BASE_URL = 'https://developer.api.autodesk.com/modelderivative/v2'
6+ READ_SCOPES = [Scope .DataRead , Scope .ViewablesRead ]
67WRITE_SCOPES = [Scope .DataCreate , Scope .DataWrite , Scope .DataRead ]
78
89def urnify (text ):
910 """
10- Convert input string into base64-encoded string (without padding '=' characters) that can be used as Model Derivative service URN.
11+ Convert input string into base64-encoded string (without padding '=' characters) that can be used
12+ as Model Derivative service URN.
1113
1214 Args:
1315 text (str): Input text.
@@ -104,8 +106,9 @@ def submit_job(self, urn: str, output_formats: list[dict], output_region: str, r
104106 ```
105107 FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
106108 FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
109+ URN = urnify("some-object-id")
107110 client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
108- job = client.submit_job(urn , [{ "type": "svf", views: ["2d", "3d"] }], "US")
111+ job = client.submit_job(URN , [{ "type": "svf", views: ["2d", "3d"] }], "US")
109112 print(job)
110113 ```
111114 """
@@ -131,4 +134,173 @@ def submit_job(self, urn: str, output_formats: list[dict], output_region: str, r
131134 if force :
132135 headers ['x-ads-force' ] = 'true'
133136 # TODO: what about the EMEA endpoint?
134- return self ._post ('/designdata/job' , WRITE_SCOPES , json = json , headers = headers ).json ()
137+ return self ._post ('/designdata/job' , WRITE_SCOPES , json = json , headers = headers ).json ()
138+
139+ def get_thumbnail (self , urn : str , width : int = None , height : int = None ) -> bytes :
140+ """
141+ Download thumbnail for a source file.
142+
143+ **Documentation**: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-thumbnail-GET
144+
145+ Args:
146+ urn (str): Base64-encoded ID of the source file.
147+ width (int, optional): Width of thumbnail. Possible values: 100, 200, 400.
148+
149+ If width is omitted, but height is specified, the implicit value for width will match height. If both
150+ width and height are omitted, the server will return a thumbnail closest to a width of 200, if available.
151+ height (int, optional): Height of thumbnail. Possible values: 100, 200, 400.
152+
153+ If height is omitted, but width is specified, the implicit value for height will match width. If both
154+ width and height are omitted, the server will return a thumbnail closest to a width of 200, if available.
155+
156+ Returns:
157+ bytes: buffer containing the thumbnail PNG image.
158+
159+ Examples:
160+ ```
161+ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
162+ FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
163+ URN = urnify("some-object-id")
164+ client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
165+ png = client.get_thumbnail(URN)
166+ with open("thumbnail.png", "wb") as output:
167+ output.write(png)
168+ ```
169+ """
170+ params = {}
171+ if width :
172+ params ['width' ] = width
173+ if height :
174+ params ['height' ] = height
175+ # TODO: what about the EMEA endpoint?
176+ resp = self ._get ('/designdata/{}/thumbnail' .format (urn ), READ_SCOPES , params = params )
177+ return resp .content
178+
179+ def get_manifest (self , urn : str ) -> dict :
180+ """
181+ Retrieve the manifest for the source design specified by the urn URI parameter.
182+ The manifest is a list containing information about the derivatives generated while translating a source file.
183+ The manifest contains information such as the URNs of the derivatives, the translation status of each derivative,
184+ and much more.
185+
186+ **Documentation**: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-manifest-GET
187+
188+ Args:
189+ urn (str): Base64-encoded ID of the source file.
190+
191+ Returns:
192+ dict: Parsed manifest JSON.
193+
194+ Examples:
195+ ```
196+ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
197+ FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
198+ URN = urnify("some-object-id")
199+ client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
200+ manifest = client.get_manifest(URN)
201+ print(manifest)
202+ ```
203+ """
204+ # TODO: what about the EMEA endpoint?
205+ return self ._get ('/designdata/{}/manifest' .format (urn ), READ_SCOPES ).json ()
206+
207+ def delete_manifest (self , urn : str ):
208+ """
209+ Delete the manifest and all its translated output files (derivatives). However, it does not delete
210+ the design source file.
211+
212+ **Documentation**: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-manifest-DELETE
213+
214+ Args:
215+ urn (str): Base64-encoded ID of the source file.
216+
217+ Examples:
218+ ```
219+ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
220+ FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
221+ URN = urnify("some-object-id")
222+ client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
223+ client.delete_manifest(URN)
224+ ```
225+ """
226+ # TODO: what about the EMEA endpoint?
227+ self ._delete ('/designdata/{}/manifest' .format (urn ), WRITE_SCOPES )
228+
229+ def get_metadata (self , urn : str ) -> dict :
230+ """
231+ Returns a list of model view (metadata) IDs for a design model. The metadata ID enables end users
232+ to select an object tree and properties for a specific model view.
233+
234+ **Documentation**: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-GET
235+
236+ Args:
237+ urn (str): Base64-encoded ID of the source file.
238+
239+ Returns:
240+ dict: Parsed response JSON.
241+
242+ Examples:
243+ ```
244+ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
245+ FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
246+ URN = urnify("some-object-id")
247+ client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
248+ metadata = client.get_metadata(URN)
249+ print(metadata)
250+ ```
251+ """
252+ # TODO: what about the EMEA endpoint?
253+ return self ._get ('/designdata/{}/metadata' .format (urn ), READ_SCOPES ).json ()
254+
255+ def get_viewable_tree (self , urn : str , guid : str ) -> dict :
256+ """
257+ Return an object tree, i.e., a hierarchical list of objects for a model view.
258+
259+ **Documentation**: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-guid-GET
260+
261+ Args:
262+ urn (str): Base64-encoded ID of the source file.
263+ guid (str): ID of one of the viewables extracted from the source file.
264+
265+ Returns:
266+ dict: Parsed response JSON.
267+
268+ Examples:
269+ ```
270+ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
271+ FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
272+ URN = urnify("some-object-id")
273+ client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
274+ tree = client.get_viewable_tree(URN, "some-viewable-guid")
275+ print(tree)
276+ ```
277+ """
278+ # TODO: what about the EMEA endpoint?
279+ return self ._get ('/designdata/{}/metadata/{}' .format (urn , guid ), READ_SCOPES ).json ()
280+
281+ def get_viewable_properties (self , urn : str , guid : str ) -> dict :
282+ """
283+ Return a list of properties for each object in an object tree. Properties are returned according to object ID
284+ and do not follow a hierarchical structure.
285+
286+ **Documentation**: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-guid-properties-GET
287+
288+ Args:
289+ urn (str): Base64-encoded ID of the source file.
290+ guid (str): ID of one of the viewables extracted from the source file.
291+
292+ Returns:
293+ dict: Parsed response JSON.
294+
295+ Examples:
296+ ```
297+ FORGE_CLIENT_ID = os.environ["FORGE_CLIENT_ID"]
298+ FORGE_CLIENT_SECRET = os.environ["FORGE_CLIENT_SECRET"]
299+ URN = urnify("some-object-id")
300+ client = ModelDerivativeClient(OAuthTokenProvider(FORGE_CLIENT_ID, FORGE_CLIENT_SECRET))
301+ props = client.get_viewable_properties(URN, "some-viewable-guid")
302+ print(props)
303+ ```
304+ """
305+ # TODO: what about the EMEA endpoint?
306+ return self ._get ('/designdata/{}/metadata/{}/properties' .format (urn , guid ), READ_SCOPES ).json ()
0 commit comments