Package: pyhorn
pyhornpyhorn is a python client for accessing the RESTful API of theOpencast Matterhornvideo capture system. It provides a client interface,MHClient, that exposes methods
for accessing both raw and ‘objectified’ response data from the various Matterhorn
REST API endpoints.This software should be considered Alpha, therefore likely to change/break in the
near future.InstallpipinstallpyhornOverviewData available from the REST endpoints is accessible through methods of the MHClient
object. In many cases the response data is encapsulated in additional classes to make
accessing various attributes of the data possible using object notation. For instance,
data about Matterhorn workflows can be accessed using theclient.workflows()method. The return value will be a list ofendpoints.workflow.Workflowobjects.
Theoperationsattribute of those objects will get you a list ofendpoints.workflow.WorkflowOperationobjects. And so forth.Currently there are only a handfull of endpoints wrapped in this way, and only a
few convenience classes and methods defined for each one. The idea is to continue
adding more as I (or you) need them. Pull requests welcome!MHClient Method ListIn the case of methods that accept a set of keyword arguments, the list of expected
kwargs is mapped directly from the Matterhorn endpoint. In other words, if you
want to know what kwargs to use forMHClient.workflows(), check the corresponding
entry in the REST API docs athttp://matterhorn.example.edu/docs.html?path=/workflow.endpoints()- /info/components.jsonme()- /info/me.jsonworkflows(**kwargs)- /workflow/instances.jsonworkflow(instance_id)- /workflow/instance/{id}.jsonepisodes(**kwargs)- /episode/episode.jsonepisode(episode_id)- /episode/episode.jsonuser_actions(**kwargs)- /usertracking/actions.jsonagents()- /capture-admin/agents.jsonagent(agent_name)- /capture-admin/agents/{agent_name}.jsonhosts()- /services/hosts.jsonjob(job_id)- /services/job/{job_id}.jsonsearch_episodes(**kwargs)- /search/episode.jsonsearch_episode(episode_id)- /search/episode.jsonstatistics()- /services/statistics.jsonExample UsageCreate the client interface…>>>frompyhornimportMHClient>>>client=MHClient('http://matterhorn.example.edu','user','passwd')User/pass combo should be for your REST API user, typically the
“matterhorn_system_account” user. It is possible to create and use a client
object without a user/pass combo (omit the constructor args), but requests
will only work for endpoints that do not require auth (e.g., episode search)The default request timeout is 5 seconds. Passtimeout=nto the MHClient
constructor to use something else.Get a list of available endpoints…>>>client.endpoints()[{u'description':u'Capture Agent Admin REST Endpoint',u'docs':u'http://matterhorn.example.edu80/capture-admin/docs',u'path':u'/capture-admin',u'type':u'org.opencastproject.capture.admin',u'version':u'1.4.4',u'wadl':u'http://matterhorn.example.edu80/capture-admin/?_wadl&_type=xml'},{u'description':u'EpisodeService REST Endpoint',u'docs':u'http://matterhorn.example.edu80/episode/docs',u'path':u'/episode',u'type':u'org.opencastproject.episode',u'version':u'1.4.4',u'wadl':u'http://matterhorn.example.edu80/episode/?_wadl&_type=xml'},...Get list of current workflow instances…>>>wfs=client.workflows()>>>forwfinwfs:printwf.id+": "+wf.state1646:STOPPED1649:STOPPED1651:STOPPED1655:STOPPED4211:SUCCEEDED14479:SUCCEEDED14486:SUCCEEDED441:STOPPED445:STOPPED...… or just the successful ones…>>>wfs=client.workflows(state="SUCCEEDED")… or the operations for a particular instance…>>>wf=client.workflow(instance_id=1646)>>>ops=wf.operations>>>foropinops:printop.id+": "+op.stateapply-acl:SUCCEEDEDtag:SUCCEEDEDtag:SUCCEEDEDinspect:SUCCEEDEDprepare-av:SUCCEEDEDprepare-av:SUCCEEDEDcompose:SUCCEEDEDcompose:SUCCEEDED...Get the list of currently configured capture agents>>>cas=client.agents()>>>forcaincas:printca.name+": "+ca.stateepiphan001:unknownepiphan002:unknownewave001:idleewave002:idlencast001:idlencast002:shutting_downEndpoint Object Wrapperspyhorn attempts to make the Matterhorn API responses more convenient to work with
by wrapping the json response data in a set of classes that provide easy access
via object attributes and automatic “dereferencing” of associated data.The following endpoint data classes are defined:WorkflowWorkflowOperationServiceJobEpisodeMediapackageMediaTrackCaptureAgentUserActionSearchThese are just the initial set because they represent the data I needed to deal
with in the other projects that prompted the creation of pyhorn. It is trivial
to add additional wrapper classes. Pull requests welcome!Attribute accessEndpoint data classes inherit frompyhorn.endpoints.base.EndpointObj. The
json response data is stored in a_rawattribute and made accessible via
dot-notation by overriding__getattr__. A simple illustration:>>>frompyhorn.endpoints.baseimportEndpointObj>>>obj=EndpointObj({"foo":"bar","baz":[1,2,3]},client)>>>obj.foobar>>>obj.baz[1,2,3]>>>obj.abcTraceback......AttributeError:responsedatafor<class'pyhorn.endpoints.base.EndpointObj'> has no key 'abc'At this point the dot-notation access only works for top-level values. There is aEndpointObj.raw_getmethod
that accepts apath_keyargument if you need to access something deeper in the response
structure.>>>obj=EndpointObj({"foo":{"bar":{"baz":1}}})>>>obj.raw_get("foo.bar.baz")1DereferencingIn a handful of cases accessing certain attributes (@property, actually)
of an endpoint data wrapper object
will return an instance or instances of a different wrapper class. For example,Workflow.operationswill extract the operation data from the raw json and
return a list ofWorkflowOperationobjects that wrap the individual operation
data structures contained in the original response.This works also for dereferencing data that requires an additional request to the
Matterhorn API. For instance, Accessing theWorkflowOperation.jobproperty
triggers a request to the/services/job/{job_id}.json, with the response
being wrapped in aServiceJobobject and returned.The current list of these dereferencing relationships is:Workflow.operations-> list ofWorkflowOperationobjectsWorkflow.job->ServiceJobWorkflow.episode->EpisodeWorkflow.mediapackage->MediapackageWorkflowOperation.job->ServiceJobServiceJob.parent->ServiceJobServiceJob.children-> list ofServiceJobobjectsEpisode.mediapackage->MediapackageMediapackage.tracks-> list ofMediaTrackobjectsUserAction.episode->SearchEpisodeSetting Maintenance ModeAs of v0.4.0 you can toggle the maintenance mode on a host.>>>hosts=client.hosts()>>>forhostinhosts:host.set_maintenance(True)CachingAs of v0.7.0 the use of requests_cache has been dropped in favor of an internal
cache that stores the responses from a subset of the single-item endpoint
methods. A future goal is to allow more granular control over the caching policy,
but for now the following endpoint responses are cached:CaptureEndpoint.agentEpisodeEndpoint.episodeSearchEndpoint.episodeWorkflow.instanceCaching works via a decorator function on the endpoint methods. The JSON response
data from the Matterhorn API is cached in-memory with each entry assigned a
time-to-live (ttl) value to control expiration. Each cached method also has
a configuredmax_entriesvalue. If/when the number of entries reaches that
limit a cull operation will prune 1/3 of the existing entries.To disable caching altogether passcache_enabled=Falseto theMHClientconstructor.To clear the cache callclient.clear_cache().TestingDuring development pyhorn tests are executed usingpytest.To run the tests from a local git clone:pipinstall-rtests/requirements.txtthenpythonsetup.pytestLicensepyhorn is licensed under the Apache 2.0 licenseCopyright2015 President and Fellows of Harvard CollegeRelease History0.1.0 (2014-10-23)Birth!0.1.1 (2014-10-28)copyright tweak0.1.2 (2014-10-28)blerg. forgot to update history with last version bump.0.2.0 (2014-11-12)expanded endpoint methods and wrapper objectsbetter endpoint class test coverage and fixture/mocking approach0.3.0 (2015-05-07)UserAction.episode now fetches from SearchEndpointnew SearchEndpoint for fetching episode datanew client methods: search_episodes(), search_episode()0.3.1 (2015-08-04)bug fix in client http exception handling0.4.1 (2015-08-27)Additional services endpoint methodsbasic service listing and statisticsmethods for getting count of queued/running jobsmaintenance on/offAdded request timeoutsUnhandled http exceptions are now re-raised0.5.0 (2015-10-30)added is_live() method to UserActionworkflow is now a property Mediapackage objects0.6.0 (2016-04-14)add newincludeDeletedparam for episode search0.7.0 (2016-04-14)ripped out the braindead use of requests_cachenew per-endpoint method caching mechanism0.8.0 (2016-07-29)allow client creation and usage without user/pass auth
(note: requests will fail for endpoints that require auth)0.8.1 (2016-09-20)SearchEpisode endpoint was missingsortparam0.9.0 (2018-08-29)Python 3 compatibility!