Примеры скриптов по базовому рабочему процессу модели преобразования в Python
Когда я исследовал один случай перевода модели в SVF (формат Forge Viewer), я нашел старый скрипт Python, который не был перенесен. Поэтому я потратил время на то, чтобы работать с последней версией слежб Forge. Скрипт показывает весь рабочий процесс от получения токена, создания bucket, загрузки объекта для запроса преобразования объекта. Я думаю, что это было бы полезно для некоторых программистов Python, поэтому я выложил его на мой Github:
https://github.com/xiaodongliang/forge.workflow-python-sample
Код также прилагается сюда, чтобы его можно было найти в Интернете.
- #!/usr/bin/env python
- # pyadva.py - продемонстрировать авторизацию Autodesk View и Data API и процесс преобразования на Python
- #
- # Copyright (C) 2017 by Forge Partnership, Autodesk Inc.
- #
- import base64, json, md5, os.path, requests, shutil, time
- from optparse import OptionParser
- _version = '2.0'
- BASE_URL = 'https://developer.api.autodesk.com/'
- BUCKET_KEY = '<your bucket name>'
- _file_missing_prompt = "Error: specified %s file '%s' does not exist.\n"
- def parse_credentials(filename):
- "Разобрать учетные данные из заданного текстового файла."
- f = open( filename )
- lines = f.readlines()
- f.close()
- credentials = []
- for line in lines:
- i = line.find('#')
- if -1 < i: line = line[0:i]
- i = line.find(':')
- if -1 < i: line = line[i+1:]
- line = line.strip()
- if 0 < len(line):
- print line
- line = line.strip("\"'")
- credentials.append(line)
- if 2 != len(credentials):
- raise "Недопустимые учетные данные: ожидается две записи, ключ пользователя и секрет;\nпрочитано %s строк, %s после снятия комментариев." % (len(lines),len(credentials))
- credentials = null
- return credentials
- def main():
- "Управление авторизацией Autodesk 3D процессом преобразования."
- global BUCKET_KEY
- progname = 'pylmv'
- use = 'используется: %s [options]'% progname
- parser = OptionParser( usage, version = progname + ' ' + _version )
- parser.add_option( '-b', '--bucketskip', action='store_true', dest='bucketskip', help = 'skip bucket creation' )
- parser.add_option( '-c', '--credentials', dest='credentials_filename', help = 'credentials filename', metavar="FILE", default='credentials.txt' )
- parser.add_option( '-m', '--model', dest='model_filename', help = 'model filename', metavar="FILE", default='samples/mytestmodel.rvt' )
- parser.add_option( '-q', '--quiet', dest='quiet', action='store_true', default=False, help = 'reduce verbosity' )
- parser.add_option( '-u', '--urn', dest='urn', help = 'specify urn of already uploaded model file', default='' )
- (options, args) = parser.parse_args()
- print options
- print args
- verbose = not options.quiet
- if 1 < len( args ):
- raise SystemExit(parser.print_help() or 1)
- model_filepath = options.model_filename
- if not model_filepath:
- print 'Пожалуйста, укажите файл модели для обработки.'
- raise SystemExit(parser.print_help() or 2)
- if not os.path.exists( model_filepath ):
- print _file_missing_prompt % ('model', model_filepath)
- raise SystemExit(parser.print_help() or 3)
- # Шаг 1: зарегистрируйте и создайте приложение, извлеките учетные данные
- if not os.path.exists( options.credentials_filename ):
- print _file_missing_prompt % ('credentials', options.credentials_filename)
- raise SystemExit(parser.print_help() or 4)
- credentials = parse_credentials(options.credentials_filename)
- if not credentials:
- print "Неверные учетные данные, указанные в '%s'." % options.credentials_filename
- raise SystemExit(parser.print_help() or 5)
- consumer_key = credentials[0]
- consumer_secret = credentials[1]
- BUCKET_KEY =(BUCKET_KEY + '-' + consumer_key).lower ()
- # Шаг 2: Получите ваш токен доступа
- # curl -k \
- # --data "client_id=<ваш идентификатор клиента>&client_secret = <ваш секрет клиента>&grant_type=client_credentials&scope=data:read data:write bucket:create bucket:read" \
- # https://developer.api.autodesk.com/authentication/v1/authenticate \
- # --header "Content-Type: application/x-www-form-urlencoded"
- url = BASE_URL + 'authentication/v1/authenticate'
- data = {
- 'client_id' : consumer_key,
- 'client_secret' : consumer_secret,
- 'grant_type' : 'client_credentials',
- 'scope': 'data:read data:write bucket:create bucket:read'
- }
- headers = {
- 'Content-Type' : 'application/x-www-form-urlencoded'
- }
- r = requests.post(url, data=data, headers=headers)
- content = eval(r.content)
- if verbose or 200 != r.status_code:
- print r.status_code
- print r.headers['content-type']
- print type(r.content)
- print content
- # -- пример результатов --
- # 200
- # application/json
- # {"token_type":"Bearer","expires_in":1799,"access_token":"ESzsFt7OZ90tSUBGh6JrPoBjpdEp"}
- if 200 != r.status_code:
- print "Код аутентификации, возвращаемый статусом %s." % r.status_code
- raise SystemExit(6)
- access_token = content['access_token']
- print 'Шаг 2 возвращает токен доступа', access_token
- # Шаг 3: Создайте контейнер
- if not options.bucketskip:
- # Проверка первичного существования:
- # curl -k -X GET \
- # -H "Authorization: Bearer lEaixuJ5wXby7Trk6Tb77g6Mi8IL" \
- # https://developer.api.autodesk.com/oss/v2/buckets/<название вашего контейнера>/details
- url = BASE_URL + 'oss/v2/buckets/' + BUCKET_KEY + '/details'
- headers = {
- 'Authorization' : 'Bearer ' + access_token
- }
- print 'Шаг 3: проверьте, существует ли контейнер'
- print 'curl -k -X GET -H "Authorization: Bearer %s" %s' % (access_token, url)
- print url
- print headers
- r = requests.get(url, headers=headers)
- if verbose:
- print r.status_code
- print r.headers['content-type']
- print r.content
- # -- пример результатов --
- # 200
- # application/json; charset=utf-8
- # {
- # "key":"jtbucket",
- # "owner":"NjEasFuPL6WAsNctq3VCgXDnTUBGa858",
- # "createDate":1404399358062,
- # "permissions":[{"serviceId":"NjEasFuPL6WAsNctq3VCgXDnTUBGa858","access":"full"}],
- # "policyKey":"transient"
- # }
- if 200 != r.status_code:
- # Создать новый контейнер:
- # curl -k \
- # --header "Content-Type: application/json" --header "Authorization: Bearer fDqpZKYM7ExcC2694eQ1pwe8nwnW" \
- # --data '{\"bucketKey\":\"<your bucket name>\",\"policyKey\":\"transient\"}' \
- # https://developer.api.autodesk.com/oss/v2/buckets
- url = BASE_URL + 'oss/v2/buckets'
- data = {
- 'bucketKey' : BUCKET_KEY,
- 'policyKey' : 'transient'
- }
- headers = {
- 'Content-Type' : 'application/json',
- 'Authorization' : 'Bearer ' + access_token
- }
- print 'Шаг 3: Создайте контейнер'
- print 'curl -k -H "Authorization: Bearer %s" -H "Content-Type:application/json" --data "{\\"bucketKey\\":\\"%s\\",\\"policyKey\\":\\"transient\\"}" %s' % (access_token, BUCKET_KEY, url)
- print url
- print json.dumps(data)
- print headers
- r = requests.post(url, data=json.dumps(data), headers=headers)
- if verbose or 200 != r.status_code:
- print r.status_code
- print r.headers['content-type']
- print r.content
- # -- пример результатов --
- # Запрос Python завершился ошибкой, но сгенерированная команда curl
- # отработала, и предоставила
- # следующий результат:
- #
- # {
- # "key":"jtbucket",
- # "owner":"NjEasFuPL6WAsNctq3VCgXDnTUBGa858",
- # "createDate":1404399358062,
- # "permissions":[{"serviceId":"NjEasFuPL6WAsNctq3VCgXDnTUBGa858","access":"full"}],
- # "policyKey":"transient"
- # }
- if 200 != r.status_code:
- print "Создание ведра возвращает код состояния %s." % r.status_code
- raise SystemExit(7)
- # Шаг 4: Загрузите файл
- if options.urn:
- urn = options.urn
- else:
- # curl -k \
- # --header "Authorization: Bearer K16B98iaYNElzVheldlUAUqOoMRC" \
- # -H "Content-Type:application/octet-stream" \
- # --upload-file "<имя вашего объекта>"
- # -X PUT https://developer.api.autodesk.com/oss/v2/buckets/<your bucket name>/objects/<имя вашего объекта>
- filesize = os.path.getsize( model_filepath )
- model_filename = os.path.basename( model_filepath ).replace(' ', '+')
- #model_filename = model_filename.replace('.','_')
- url = 'https://developer.api.autodesk.com/oss/v2/buckets/' + BUCKET_KEY + '/objects/' + model_filename
- headers = {
- 'Content-Type' : 'application/octet-stream',
- #'Content-Length' : str(filesize),
- 'Authorization' : 'Bearer ' + access_token,
- #'Expect' : ''
- }
- print "Шаг 4: начало загрузки файла модели '%s', %s байт..."% (model_filename,filesize)
- print 'curl -k -H "Authorization: Bearer %s" -H "Content-Type:application/octet-stream" -T "%s" -X PUT %s' % (access_token, model_filepath, url)
- with open(model_filepath, 'rb') as f:
- #files = { model_filename : f }
- #r = requests.put(url, headers=headers, files=files)
- # выгрузка не принимает объекты, состоящие из нескольких частей
- # смотрите http://docs.python-requests.org/en/latest/api/
- # files: Словарь 'name': file-like-objects (or {'name': ('filename', fileobj)}) для выгрузки, состоящей из нескольких частей.
- # data: Словарь, байты или файл-подобный объект для отправки в тело запроса.
- r = requests.put(url, headers=headers, data=f)
- #with open(model_filepath, 'rb') as f:
- # request = requests.put(url, headers=headers, data=f)
- if verbose:
- print r.status_code
- print r.headers['content-type']
- print r.content
- # -- пример результатов --
- # Запрос Python завершился ошибкой, но curl
- # отработала, и предоставила
- # следующий результат:
- #
- # {
- # "bucket-key": "<ваше имя контейнера>",
- # "objects" : [ {
- # "location" : "https://developer.api.autodesk.com/oss/v1/buckets/jtbucket/objects/two_columns_rvt",
- # "size" : 4165632,
- # "key" : "two_columns_rvt",
- # "id" : "urn:adsk.objects:os.object:jtbucket/two_columns_rvt",
- # "sha-1" : "cb15374248562743c5a99e0bdb0535f508a19848",
- # "content-type" : "application/octet-stream"
- # } ]
- # }
- content = eval(r.content)
- #urn = content['objects'][0]['id']
- urn = content['objectId']
- print 'id:', urn
- # import base64
- # base64.b64encode("urn:adsk.objects:os.object:<имя вашего контейнера>/имя вашего объекта")
- # 'dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6anRidWNrZXQvdHdvX2NvbHVtbnNfcnZ0'
- urn = base64.b64encode(urn)
- print 'urn:', urn
- # Шаг 6: Регистрация данных с помощью служб просмотра
- # curl -k \
- # -H "Content-Type: application/json" \
- # -H "Authorization:Bearer 1f4bEhzvxJ9CMvMPSHD4gXO4SYEr" \
- # -i -d "{\"urn\":\"dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXQvc2t5c2NwcjEuM2Rz\"}" \
- # https://developer.api.autodesk.com/modelderivative/v2/designdata/job
- url = BASE_URL + 'modelderivative/v2/designdata/job'
- data = {
- "input": {
- "urn": urn
- },
- "output": {
- "destination": {
- "region": "us"
- },
- "formats": [
- {
- "type": "svf",
- "views":["2d", "3d"]
- }]
- }
- }
- headers = {
- 'Content-Type' : 'application/json',
- 'Authorization' : 'Bearer ' + access_token
- }
- print 'Шаг 6: запрос на преобразование объекта'
- print 'curl -k -H "Authorization: Bearer %s" -H "Content-Type:application/json" -i -d "{\\"urn\\":\\"%s\\"}" %s' % (access_token, urn, url)
- print url
- print json.dumps(data)
- print headers
- r = requests.post(url, data=json.dumps(data), headers=headers)
- if verbose or 200 != r.status_code:
- print r.status_code
- print r.headers['content-type']
- print r.content
- # -- пример результатов --
- # Запрос Python завершился ошибкой, но curl
- # отработала, и предоставила
- # следующий результат:
- #
- if 200 != r.status_code:
- print "Регистрировать данные, возвращаемые кодом состояния %s." % r.status_code
- raise SystemExit(9)
- if __name__ == '__main__':
- main()
Оригинальным автором этого образца является мой коллега Джереми Таммик. Недавно он также выпустил еще один блог по скриптам Python.
https://forge.autodesk.com/cloud_and_mobile/2016/12/forge-formats-python-scripts.html
Источник: https://forge.autodesk.com/blog/sample-scripts-basic-workflow-translating-model-python
Обсуждение: http://adn-cis.org/forum/index.php?topic=8121
Опубликовано 31.10.2017