Package: txkoji
Async interface to Koji, using TwistedAccess Koji’s XML-RPC API asynchronously (non-blocking) using the Twisted
framework.This supports the GSSAPI or Client SSL login methods.Simple Example: Fetching a user’s namefromtxkojiimportConnectionfromtwisted.internetimportdeferfromtwisted.internet.taskimportreact@defer.inlineCallbacksdefexample(reactor):koji=Connection('brew')# Fetch a user.# You may pass an ID or a krb principal hereuser=yieldkoji.getUser(3595)# user is a Munch (dict-like) object.print(user.name)if__name__=='__main__':react(example)Connecting to a Koji HubTo connect to a Koji hub, create a newtxkoji.Connectioninstance.You must pass a string to the constructor. This string is a profile name. For
example, if you callConnector('mykoji'), then txkoji will search~/.koji/config.d/*.confand/etc/koji.conf.d/*.conffor the[mykoji]config section. This matches what the regular Koji client code
does.Making XML-RPC callsKoji Hub is an XML-RPC server. You can call any method on theConnectionclass instance and txkoji will treat it as an XML-RPC call to the hub. For
example, this TwistedinlineCallbacks-style code looks up information about
a given task ID and tag ID:@defer.inlineCallbacksdefexample(reactor):koji=Connection('mykoji')task=yieldkoji.getTaskInfo(10000)print(task.method)# "createImage"tag=yieldkoji.getTag(2000)print(tag.name)# "foo-build"To learn the full Koji XML-RPC API:koji list-apiYou can also read thekoji source codeto find
out details about how each method works.Logging inYour Koji hub must support GSSAPI or Client SSL authentication. You must have a
valid Kerberos ticket or SSL keypair.@defer.inlineCallbacksdefexample(reactor):koji=Connection('mykoji')result=yieldlogin()print(result)# "True"print('session-id:%s'%koji.session_id)# "Who am I?"user=yieldkoji.getLoggedInUser()print(user)Estimating build durationsThetxkoji.estimatesmodule provides methods for estimating build times.
Theaverage_build_duration()method calls Koji’sgetAverageBuildDurationRPC and gives you adatetime.timedeltafor a
package. For container packages, we do something similar client-side with theaverage_last_builds()method, averaging the last five builds’ durations.Caching long-lived object namesSometimes all you have is a user id number or tag id number, and you want the
user’s name or tag’s name instead.txkoji includes a read-through cache for obtaining the user name or tag name.
Seeexamples/cache.pyfor an example. txkoji’s cache module stores its data
in atxkojisubdirectory of the location specified with the$XDG_CACHE_HOMEenvironment variable if that is set. It will fall back to
using~/.cache/txkojiif the$XDG_CACHE_HOMEenvironment variable is
not set.Rich objectsThe following RPC methods will return special classes that inherit from the
Munch class:getBuildreturnstxkoji.build.BuildgetChannelreturnstxkoji.channel.ChannellistBuildsreturns alistoftxkoji.build.BuildgetTaskInforeturnstxkoji.task.TaskgetPackagereturnstxkoji.package.PackageThese classes have their own special helper methods to implement things I found
interesting:datetimeconversions for the start/completion timestamps,urlproperties for representing the objects in Kojiweb,Unified property attributes across task methods, liketag,packageoris_scratch.More special return values:getAverageBuildDurationreturns adatetime.timedeltaobject instead
of a raw float, because this is more useful to do time arithmetic.Thetask_idproperty is populated on OSBS’s CG container builds (a
workaround forhttps://pagure.io/koji/issue/215).Message ParsingKoji’s messagebus plugin emits messages to an AMQP broker when certain events
happen. Thetxkoji.messagesmodule has support for parsing these messages
into the relevant txkojiTaskorBuildclasses.TODO:More KojiException subclasses for other possible XML-RPC faults?Implement krbV authentication (probably not unless there is an alternative to
python-krbV).MikeM noted,
the callnum parameter will need special handling. We might need Twisted’sDeferredLockto ensure we only have one auth’d RPC in flight at a time.
It’s not really clear to me if we can actually hit a callnum error here. More
integration testing needed for this.Ensure that Brew’s “build time” equals the longest “buildArch” time for a
task, and not something else, like the buildSRPMFromSCM time, nor even the
overall build task’s time. This has implications for estimating scratch
builds. (comparing our tasks’ times to getAverageBuildDuration)Multi-call supportPackages that use this packagehelga-koji