Twisted API for Koji
Async interface to Koji, using Twisted
Access 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 name
from txkoji import Connection from twisted.internet import defer from twisted.internet.task import react @defer.inlineCallbacks def example(reactor): koji = Connection('brew') # Fetch a user. # You may pass an ID or a krb principal here user = yield koji.getUser(3595) # user is a Munch (dict-like) object. print(user.name) if __name__ == '__main__': react(example)
Connecting to a Koji Hub
To connect to a Koji hub, create a new txkoji.Connection instance.
You must pass a string to the constructor. This string is a profile name. For example, if you call Connector('mykoji'), then txkoji will search ~/.koji/config.d/*.conf and /etc/koji.conf.d/*.conf for the [mykoji] config section. This matches what the regular Koji client code does.
Making XML-RPC calls
Koji Hub is an XML-RPC server. You can call any method on the Connection class instance and txkoji will treat it as an XML-RPC call to the hub. For example, this Twisted inlineCallbacks-style code looks up information about a given task ID and tag ID:
@defer.inlineCallbacks def example(reactor): koji = Connection('mykoji') task = yield koji.getTaskInfo(10000) print(task.method) # "createImage" tag = yield koji.getTag(2000) print(tag.name) # "foo-build"
To learn the full Koji XML-RPC API:
You can also read the koji source code to find out details about how each method works.
Your Koji hub must support GSSAPI or Client SSL authentication. You must have a valid Kerberos ticket or SSL keypair.
@defer.inlineCallbacks def example(reactor): koji = Connection('mykoji') result = yield login() print(result) # "True" print('session-id: %s' % koji.session_id) # "Who am I?" user = yield koji.getLoggedInUser() print(user)
Estimating build durations
The txkoji.estimates module provides methods for estimating build times. The average_build_duration() method calls Koji’s getAverageBuildDuration RPC and gives you a datetime.timedelta for a package. For container packages, we do something similar client-side with the average_last_builds() method, averaging the last five builds’ durations.
Caching long-lived object names
Sometimes 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. See examples/cache.py for an example. txkoji’s cache module stores its data in a txkoji subdirectory of the location specified with the $XDG_CACHE_HOME environment variable if that is set. It will fall back to using ~/.cache/txkoji if the $XDG_CACHE_HOME environment variable is not set.
The following RPC methods will return special classes that inherit from the Munch class:
- getBuild returns txkoji.build.Build
- getChannel returns txkoji.channel.Channel
- listBuilds returns a list of txkoji.build.Build
- getTaskInfo returns txkoji.task.Task
- getPackage returns txkoji.package.Package
These classes have their own special helper methods to implement things I found interesting:
- datetime conversions for the start/completion timestamps,
- url properties for representing the objects in Kojiweb,
- Unified property attributes across task methods, like tag, package or is_scratch.
More special return values:
- getAverageBuildDuration returns a datetime.timedelta object instead of a raw float, because this is more useful to do time arithmetic.
- The task_id property is populated on OSBS’s CG container builds (a workaround for https://pagure.io/koji/issue/215).
Koji’s messagebus plugin emits messages to an AMQP broker when certain events happen. The txkoji.messages module has support for parsing these messages into the relevant txkoji Task or Build classes.
- 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’s DeferredLock to 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 support
Packages that use this package
Release history Release notifications | RSS feed
|Filename, size||File type||Python version||Upload date||Hashes|
|Filename, size txkoji-0.10.0.tar.gz (23.3 kB)||File type Source||Python version None||Upload date||Hashes View|