Unity Cloud BuildのAPIをPythonから利用してみました。他のシステムと連携してビルドしたファイルをアップロードする際に利用できるかなーと思います。
Unity Cloud Buildを利用してみた
BitBucket(旧:Stash)のソースコードからビルドできる点もポイントが高かったです。初期ビルドの設定はボタンぽちぽちで5分くらいだったので説明省略しています。
初回は手動でビルドして2回目以降をAPI経由で利用するといった用途を想定しています。今回利用するAPIの詳細は全て公式ドキュメントに記載されています。
1. ビルド実行
ビルドに失敗するとHTTPStatus:202が返ってきます。ビルド完了したファイルのURLは別ファイル
u.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import requests
API_TOKEN = "****"
ORGID = "****"
PROJECTS = "****"
BUILD_TARGETS = "****"
def get_url(func_name, extend=None):
auth_base = "orgs/{orgid}/projects/{projectid}/buildtargets/{buildtargetid}".format(orgid=ORGID,
projectid=PROJECTS,
buildtargetid=BUILD_TARGETS)
if extend:
url_base = "https://build-api.cloud.unity3d.com/api/v1/{auth}/{func}{extend}"
return url_base.format(auth=auth_base, func=func_name, extend=extend)
url_base = "https://build-api.cloud.unity3d.com/api/v1/{auth}/{func}"
return url_base.format(auth=auth_base, func=func_name)
def get_headers():
return {
"Content-Type": "application/json",
"Authorization": "Basic {token}".format(token=API_TOKEN),
}
def execute_build():
"""
ビルド実行
# 準正常系 既にビルド中
[{"buildtargetid":"****","buildTargetName":"****","error":"Cannot start build - already a build pending."}] 202
"""
response = requests.post(get_url("builds"), headers=get_headers(), data={})
print(response.text), response.status_code
return
# ビルド実行
execute_build()
2. ビルドステータス取得
ビルドステータスは次の通り { queued , sentToBuilder , started , restarted , success , failure , canceled , unknown }
無課金だとqueuedの時間が長いです。ビルド成功したらsuccessとなります
u.py
def get_builds():
"""
最新の25件のビルド情報が取得できる。
それより古いデータ取得したい時はper_pageとpageパラメータを修正すること
"""
response = requests.get(get_url("builds"), headers=get_headers())
print(response.text), response.status_code
return
def get_build(number):
"""
指定したビルド情報が取得できる
# 準正常系
存在しない場合は404 : {"error":"The requested object was not found."}
:param number: int
"""
response = requests.get(get_url("builds", extend="/" + str(number)), headers=get_headers())
print(response.text), response.status_code
return
def get_latest_build():
"""
最新1件のビルドが取得できる
"""
build_start_result = requests.get(get_url("builds", extend="?per_page=1&page=1"), headers=get_headers())
print(build_start_result.text), build_start_result.status_code
return
# 特定ビルド取得
get_build(6)
# 最新ビルド取得
get_latest_build()
# ビルド一括取得
get_build_status()
3. ビルドキャンセル
実装してから、APIからキャンセルしたいことなんて、あるのだろうか? と思いました。
HTMLのDELETEクエリーでキャンセルする仕様です。DELETEクエリーは今年初の利用。REST原則に忠実でAPI作ったエンジニアの性格が、なんとなく伝わりました。
u.py
def cancel_all():
"""
全てのビルドをキャンセルする
"""
response = requests.delete(get_url("builds"), headers=get_headers())
print(response.text), response.status_code
def cancel(number):
"""
特定ビルドをキャンセルする
# 正常系 キャンセル成功
204
# 準正常系 存在しない
{"error":"The requested object was not found."} 404
# 準正常系 ビルド完了済みのビルドを指定したとき
204
:param number: int
"""
response = requests.delete(get_url("builds", extend="/" + str(number)), headers=get_headers())
print(response.text), response.status_code
# 特定ビルドキャンセル
cancel(7)
# 全ビルドキャンセル
cancel_all()
4. ダウンロードURL取得
ビルド成功したらS3にファイルがアップロードされます。ダウンロードするためのURLを取得するための関数です。
u.py
def get_latest_build_download_urls():
"""
最新の成功したビルドのダウンロードURL
:return: str
"""
response = requests.get(get_url("builds", extend="?buildStatus=success&per_page=1&page=1"),
headers=get_headers())
data = ujson.loads(response.text)
assert len(data) > 0
return data[0].get('links').get('download_primary').get('href')
# 最新の成功したビルドのダウンロードURL
print get_latest_build_download_urls()
全部まとめた完成品のソース
u.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import requests
import ujson
API_TOKEN = "****"
ORGID = "****"
PROJECTS = "****"
BUILD_TARGETS = "****"
def get_url(func_name, extend=None):
auth_base = "orgs/{orgid}/projects/{projectid}/buildtargets/{buildtargetid}".format(orgid=ORGID,
projectid=PROJECTS,
buildtargetid=BUILD_TARGETS)
if extend:
url_base = "https://build-api.cloud.unity3d.com/api/v1/{auth}/{func}{extend}"
return url_base.format(auth=auth_base, func=func_name, extend=extend)
url_base = "https://build-api.cloud.unity3d.com/api/v1/{auth}/{func}"
return url_base.format(auth=auth_base, func=func_name)
def get_headers():
return {
"Content-Type": "application/json",
"Authorization": "Basic {token}".format(token=API_TOKEN),
}
def execute_build():
"""
ビルド実行
# 準正常系 既にビルド中
[{"buildtargetid":"****","buildTargetName":"****","error":"Cannot start build - already a build pending."}] 202
"""
response = requests.post(get_url("builds"), headers=get_headers(), data={})
print(response.text), response.status_code
return
def get_builds():
"""
最新の25件のビルド情報が取得できる。
それより古いデータ取得したい時はper_pageとpageパラメータを修正すること
"""
response = requests.get(get_url("builds"), headers=get_headers())
print(response.text), response.status_code
return
def get_build(number):
"""
指定したビルド情報が取得できる
# 準正常系
存在しない場合は404 : {"error":"The requested object was not found."}
:param number: int
"""
response = requests.get(get_url("builds", extend="/" + str(number)), headers=get_headers())
print(response.text), response.status_code
return
def get_latest_build():
"""
最新1件のビルドが取得できる
"""
build_start_result = requests.get(get_url("builds", extend="?per_page=1&page=1"), headers=get_headers())
print(build_start_result.text), build_start_result.status_code
return
def get_latest_build_download_urls():
"""
最新の成功したビルドのダウンロードURL
:return: str
"""
response = requests.get(get_url("builds", extend="?buildStatus=success&per_page=1&page=1"),
headers=get_headers())
data = ujson.loads(response.text)
assert len(data) > 0
return data[0].get('links').get('download_primary').get('href')
def cancel_all():
"""
全てのビルドをキャンセルする
"""
response = requests.delete(get_url("builds"), headers=get_headers())
print(response.text), response.status_code
def cancel(number):
"""
特定ビルドをキャンセルする
# 正常系 キャンセル成功
204
# 準正常系 存在しない
{"error":"The requested object was not found."} 404
# 準正常系 ビルド完了済みのビルドを指定したとき
204
:param number: int
"""
response = requests.delete(get_url("builds", extend="/" + str(number)), headers=get_headers())
print(response.text), response.status_code
# 特定ビルドキャンセル
# cancel(7)
# 全ビルドキャンセル
# cancel_all()
# 特定ビルド取得
# get_build(6)
# 最新ビルド取得
# get_latest_build()
# ビルド一括取得
# get_build_status()
# ビルド実行
# execute_build()
# 最新の成功したビルドのダウンロードURL
print get_latest_build_download_urls()