美文网首页DeadlineHoudini
Deadline WebAPI 适配 Houdini18.5 p

Deadline WebAPI 适配 Houdini18.5 p

作者: MasterZhang | 来源:发表于2021-01-10 16:59 被阅读0次

Deadline本身机制是通过各DCC软件自身的后台命令去执行渲染或者解算。如果要从外部提交任务到Deadline需要通过Deadline提供的Web Sevice进行数据交互。但是官方只提供了Python2版本的API并没有提供Python3版的。为了能在Houdini18.5 python3版里直接提交任务到Deadline,这里对其接口API稍微改了一下。(当然,如果熟悉Deadline的job数据,直接使用 GET,POST,DELETE,PUT这四种方式与Web Service进行数据交互也是可以的,这样不仅能无视python版本还能支持其他语言)

启动WebService

任意一台安装Deadline Client的机器上,在安装目录里可以找到deadlinewebservice.exe。以管理员身份运行后可以在该机器上开启一个Deadline Web Service。该Serivce的作用其实就是一个中间数据转发小服务,它能接收从其他机器传来的命令数据,之后对Deadline仓库与数据进行交互,最后将操作结果返回。为了统一管理,一般我们会将Deadline Web Serivce放在仓库统一的服务器里。

然后其他机器上要连接到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()函数里.添加version版本执行文件返回值。

我这里使用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.最好把这个文件夹复制到你Houdini中心管理的地方统一载入。

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函数主要处理GET,DELETE请求,psend函数主要处理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()

#设置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数据内容

job信息本身是一个大json. Deadline对Job数据的具体值进行对应的操作。

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 : 状态
       值为int,在使用api的时候可以传入字符串,其中对于的int值如下
       Unknown:0 
       Active:1
       Suspended:2
       Completed:3 
       Failed :4   
       Pending :6
_id : job id

其中最重要的是Props属性,它的内容有:

['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: 任务名称
 User: 电脑账户名称 比如 Administrator,laozhang
 Frames: 帧数范围 结构'1-2'
 Chunk: 1 ,每台机器载入一次工程的执行长度。如果设置为1,那么每次载入工程后,渲染一帧然后关闭工程,下次继续载入。机器少建议开大。
 Tasks: 执行的任务数量,就是点击一个job后,右边显示任务数。
 Grp: 机器组
 Pool: 机器池
 Pri: 优先级 
 Dep: 依赖关系
        [{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有个不严谨的地方就是,从Deadline API返回的job数据属性名其与传入的属性名称不一致。

建议在User-Manual-> Manual Job Submission下可查看job传入属性名称

这里说2个常用的。

Frames Per Tasks: 每任务长度

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

而需要传入的是ChunkSize

调用的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

所谓依赖关系,就是当A依赖B时,只有B渲染或解算完后才会执行A。

在返回的job中属性是Dep:[] 一个列表

而需要传入的名称是JobDependencies,值为父依赖的job id

props['JobDependencies']= dependent_job_id

相关文章

网友评论

    本文标题:Deadline WebAPI 适配 Houdini18.5 p

    本文链接:https://www.haomeiwen.com/subject/ywvcaktx.html