Deadline WebAPI 適配 Houdini18.5 py3

Deadline本身機制是通過各DCC軟件自身的后臺命令去執(zhí)行渲染或者解算。如果要從外部提交任務(wù)到Deadline需要通過Deadline提供的Web Sevice進行數(shù)據(jù)交互。但是官方只提供了Python2版本的API并沒有提供Python3版的。為了能在Houdini18.5 python3版里直接提交任務(wù)到Deadline,這里對其接口API稍微改了一下。(當然,如果熟悉Deadline的job數(shù)據(jù),直接使用 GET,POST,DELETE,PUT這四種方式與Web Service進行數(shù)據(jù)交互也是可以的,這樣不僅能無視python版本還能支持其他語言)

啟動WebService

任意一臺安裝Deadline Client的機器上,在安裝目錄里可以找到deadlinewebservice.exe。以管理員身份運行后可以在該機器上開啟一個Deadline Web Service。該Serivce的作用其實就是一個中間數(shù)據(jù)轉(zhuǎn)發(fā)小服務(wù),它能接收從其他機器傳來的命令數(shù)據(jù),之后對Deadline倉庫與數(shù)據(jù)進行交互,最后將操作結(jié)果返回。為了統(tǒng)一管理,一般我們會將Deadline Web Serivce放在倉庫統(tǒng)一的服務(wù)器里。

然后其他機器上要連接到Web Service就需要連接它所在的IP與端口。

<meta name="source" content="lake">
image.png

幾處腳本修改

Repository中腳本修改

找到Deadline倉庫安裝目錄下的Houdini插件,比如:xxx/DeadlineRepository10/plugins/Houdini

1.Houdini.param添加Houdini18.5的配置

如果要使用HQueue,需要同樣配置[Houdini18_5_SimTracker]

[Houdini18_5_Hython_Executable]
Label=Houdini 18.5 Hython Executable
Category=Render Executables
CategoryOrder=0
Type=multilinemultifilename
Index=3
Default=C:\Program Files\Side Effects Software\Houdini 18.5.448\bin\Hython.exe;/Applications/Houdini/Houdini18.5.448/Frameworks/Houdini.framework/Versions/18.5.448/Resources/bin/hython;/opt/hfs18.5/bin/hython
Description=The path to the hython executable. It can be found in the Houdini bin folder.
Description=The path to the hython executable. It can be found in the Houdini bin folder.

2.Houdini.py的RenderExecutable()函數(shù)里.添加version版本執(zhí)行文件返回值。

我這里使用self.GetConfigEntry返回報錯,所以直接返回houdiniExeList,其實就是Exe的配置路徑

    def RenderExecutable( self ):

        version = self.GetPluginInfoEntryWithDefault( "Version", "16.0" ).replace( ".", "_" ) 
        build = self.GetPluginInfoEntryWithDefault( "Build", "none" ).lower()

        if version.startswith('18_5'):
            houdiniExeList=r'C:\Program Files\Side Effects Software\Houdini 18.5.449\bin\Hython.exe;/Applications/Houdini/Houdini18.5.449/Frameworks/Houdini.framework/Versions/18.5.449/Resources/bin/hython;/opt/hfs18.5/bin/hython'
        else:
            houdiniExeList = self.GetConfigEntry( "Houdini" + version + "_Hython_Executable" )

         ...

Deadline API腳本更改

也就是Deadline提供的Standalone Web Service接口python包。在倉庫安裝目錄的api/python文件夾下的Deadline,比如: xxx/DeadlineRepository10/api/python/Deadline.最好把這個文件夾復(fù)制到你Houdini中心管理的地方統(tǒng)一載入。

1.找到DeadlineUtility.py將 basestring 替換為 str

def ArrayToCommaSeparatedString( iterable ):
    # if isinstance( iterable, basestring ):
    if isinstance( iterable, str ):
        return iterable

    if iterable is None:
        return ""

    return ",".join( str(x) for x in iterable )

2.找到DeadlineSend.py 注銷掉所以python2的url請求方式,改為python3的requests方式。

從這里可以看出,與Web Serive交互其實就是Http請求機制。其中send函數(shù)主要處理GET,DELETE請求,psend函數(shù)主要處理PUT,POST請求。

import socket
# import httplib
import json
# import urllib2
import traceback
import requests

def send(address, message, requestType, useAuth=False, username="", password=""):
    """
        Used for sending requests that do not require message body, like GET and DELETE.
        Params: address of the webservice (string).
                message to the webservice (string).
                request type for the message (string, GET or DELETE).
    """
    try:
        if not address.startswith("http://"):
            address = "http://" + address
        url = address + message
         response =requests.request(requestType,url)
        data = response.text

        data = data.replace('\n', ' ')

    # except urllib2.HTTPError as err:
    except Exception as err:
        data = traceback.format_exc()
        if response == 401:
            data = "Error: HTTP Status Code 401\. Authentication with the Web Service failed. Please ensure that the authentication credentials are set, are correct, and that authentication mode is enabled."
        # else:
        #     data = err.read()
    try:
        data = json.loads(data)
    except:
        pass

    return data

def pSend(address, message, requestType, body, useAuth=False, username="", password=""):
    """
        Used for sending requests that require a message body, like PUT and POST.
        Params: address of the webservice (string).
                message to the webservice (string).
                request type for the message (string, PUT or POST).
                message body for the request (string, JSON object).
    """
    response = ""
    try:
        if not address.startswith("http://"):
            address = "http://"+address
        url = address + message
    except Exception as err:
        data = traceback.format_exc()
        if response == 401:
            data = "Error: HTTP Status Code 401\. Authentication with the Web Service failed. Please ensure that the authentication credentials are set, are correct, and that authentication mode is enabled."
        # else:
        #     data = err.read()

     try:
        data = json.loads(data)
    except:
        pass

    return data

Houdini18.5 py3版提交案例

import os
import hou
import getpass
import DeadlineConnect as Connect

connectionObject = Connect.DeadlineCon('192.168.1.xx',8082)
file_path = hou.hipFile.name()
version =hou.applicationVersionString()
hip_name=os.path.sliptext(hou.hipFile.basename())[0]
user_name = getpass.getuser()
pool ='none'
pri=100
chunk=10

node=hou.node('obj/geo1/filecache1')
node_name=node.name()
f1=node.parm('f1').eval()
f2=node.parm('f2').eval()

#設(shè)置job屬性
props={}
props['Name']=hip_name+'_'+node_name
props['UserName']= user_name
props['Frames']='{}-{}'.format(f1,f2)
props['Plugin']='Houdini'
props['Pool']=pool
props['Pri']=pri
props['ChunkSize']=chunk    

#插件屬性
plug = {"OutputDriver": node.path()+'/render',
          "SceneFile": file_path ,
          "Version": version
         }

job = connectionObject.Jobs.SubmitJob(props, plug)

JOB數(shù)據(jù)內(nèi)容

job信息本身是一個大json. Deadline對Job數(shù)據(jù)的具體值進行對應(yīng)的操作。

job的keys有:

['Props', 'ComFra', 'IsSub', 'Purged', 'Mach', 'Date', 'DateStart', 'DateComp', 'Plug', 'OutDir', 'OutFile', 'TileFile', 'Main', 
 'MainStart', 'MainEnd', 'Tile', 'TileFrame', 'TileCount', 'TileX', 'TileY', 'Stat', 'Aux', 'Bad', 'CompletedChunks', 'QueuedChunks', 'SuspendedChunks', 'RenderingChunks', 'FailedChunks', 'PendingChunks', 'SnglTskPrg', 'Errs', 'DataSize', '_id', 'ExtraElements']

常用屬性說明:

Props : 屬性
Stat : 狀態(tài)
       值為int,在使用api的時候可以傳入字符串,其中對于的int值如下
       Unknown:0 
       Active:1
       Suspended:2
       Completed:3 
       Failed :4   
       Pending :6
_id : job id

其中最重要的是Props屬性,它的內(nèi)容有:

['Name', 'Batch', 'User', 'Region', 'Cmmt', 'Dept', 'Frames', 'Chunk', 'Tasks', 'Grp', 'Pool', 'SecPool', 'Pri', 'ReqAss', 'ScrDep', 'Conc', 'ConcLimt', 'AuxSync', 'Int', 'IntPer', 'RemTmT', 'Seq', 'Reload', 'NoEvnt', 'OnComp', 'Protect', 'PathMap', 'AutoTime', 'TimeScrpt', 'MinTime', 'MaxTime', 'Timeout', 'FrameTimeout', 'StartTime', 'InitializePluginTime', 'Dep', 'DepFrame', 'DepFrameStart', 'DepFrameEnd', 'DepComp', 'DepDel', 'DepFail', 'DepPer', 'NoBad', 'OverAutoClean', 'OverClean', 'OverCleanDays', 'OverCleanType', 'JobFailOvr', 'JobFailErr', 'TskFailOvr', 'TskFailErr', 'SndWarn', 'NotOvr', 'SndEmail', 'SndPopup', 'NotEmail', 'NotUser', 'NotNote', 'Limits', 'ListedSlaves', 'White', 'MachLmt', 'MachLmtProg', 'PrJobScrp', 'PoJobScrp', 'PrTskScrp', 'PoTskScrp', 'Schd', 'SchdDays', 'SchdDate', 'SchdStop', 'MonStart','MonStop', 'TueStart', 'TueStop', 'WedStart', 'WedStop', 'ThuStart', 'ThuStop', 'FriStart', 'FriStop', 'SatStart', 'SatStop', 'SunStart', 'SunStop', 'PlugInfo', 'Env', 'EnvOnly', 'PlugDir', 'EventDir', 'OptIns', 'EventOI', 'AWSPortalAssets', 'AWSPortalAssetFileWhitelist', 'Ex0','Ex1', 'Ex2', 'Ex3', 'Ex4', 'Ex5', 'Ex6', 'Ex7', 'Ex8', 'Ex9', 'ExDic', 'OvrTaskEINames', 'TaskEx0', 'TaskEx1', 'TaskEx2', 'TaskEx3', 'TaskEx4', 'TaskEx5', 'TaskEx6', 'TaskEx7', 'TaskEx8', 'TaskEx9']

常見屬性說明:    
 Name: 任務(wù)名稱
 User: 電腦賬戶名稱 比如 Administrator,laozhang
 Frames: 幀數(shù)范圍 結(jié)構(gòu)'1-2'
 Chunk: 1 ,每臺機器載入一次工程的執(zhí)行長度。如果設(shè)置為1,那么每次載入工程后,渲染一幀然后關(guān)閉工程,下次繼續(xù)載入。機器少建議開大。
 Tasks: 執(zhí)行的任務(wù)數(shù)量,就是點擊一個job后,右邊顯示任務(wù)數(shù)。
 Grp: 機器組
 Pool: 機器池
 Pri: 優(yōu)先級 
 Dep: 依賴關(guān)系
        [{u'ResumeOnPercentageValue': 0.0, u'OverrideFrameOffsets': False, u'EndOffset': 0, u'OverrideResumeOn': False,
       u'ResumeOnFailed': False, u'JobID': u'5ff7c49d14a13a26f4b9f893', u'IgnoreFrameOffsets': False,
       u'ResumeOnDeleted': False, u'StartOffset': 0, u'ResumeOnComplete': True, u'ResumeOnPercentageCompleted': False, u'Notes': u''}]

一些真正被Deadline輸入識別的屬性

Deadline有個不嚴謹?shù)牡胤骄褪?,從Deadline API返回的job數(shù)據(jù)屬性名其與傳入的屬性名稱不一致。

建議在User-Manual-> Manual Job Submission下可查看job傳入屬性名稱

這里說2個常用的。

Frames Per Tasks: 每任務(wù)長度

在返回的job屬性里是Chunk字段

而需要傳入的是ChunkSize

調(diào)用的API是Jobs.SetJobFrameRange(self, id, frameList, chunkSize):

body = json.dumps({"Command":"setjobframerange","JobID":id, "FrameList":frameList, "ChunkSize":chunkSize})

return self.connectionProperties.__put__("/api/jobs", body)

JobDependencies: 依賴job

所謂依賴關(guān)系,就是當A依賴B時,只有B渲染或解算完后才會執(zhí)行A。

在返回的job中屬性是Dep:[] 一個列表

而需要傳入的名稱是JobDependencies,值為父依賴的job id

props['JobDependencies']= dependent_job_id
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容