gavo.protocols.uwsactions module

Manipulating UWS jobs through a REST interface.

The result documents are defined through the schema uws-1.0.xsd.

Instead of returning XML, they can also raise svcs.SeeOther exceptions. However, these are caught in JobResource._redirectAsNecessary and appended to the base URL auf the TAP service, so you must only give URIs relative to the TAP service’s root URL.

This UWS system should adapt to concrete UWSes; the UWS in use is passed into the top-level functions (doJobAction , getJobList).

The actions pretty much resemble twisted.web Resources; perhaps this should be refactored to use them. For now, however, we don’t pass around resources, we pass around callables that are used within renderers in asyncrender, which lets asyncrender factor out a bit of common functionality. Hm.

class gavo.protocols.uwsactions.DestructionAction[source]

Bases: _SettableAction

attName = 'destructionTime'
static deserializeValue(literal: str, useTime: bool = False) datetime

returns a datetime object for a ISO time literal.

There’s no real timezone support yet, but we accept and ignore various ways of specifying UTC.

By default, this uses plain python datetime because it usually covers a large date range than the time module. The downside is that it does not know about leap seconds. Pass useTime=True to go through time tuples, which know how to deal with them (but may not deal with dates far in the past or future).

>>> parseISODT("1998-12-14")
datetime.datetime(1998, 12, 14, 0, 0)
>>> parseISODT("1998-12-14T13:30:12")
datetime.datetime(1998, 12, 14, 13, 30, 12)
>>> parseISODT("1998-12-14T13:30:12Z")
datetime.datetime(1998, 12, 14, 13, 30, 12)
>>> parseISODT("1998-12-14T13:30:12.224Z")
datetime.datetime(1998, 12, 14, 13, 30, 12, 224000)
>>> parseISODT("19981214T133012Z")
datetime.datetime(1998, 12, 14, 13, 30, 12)
>>> parseISODT("19981214T133012+00:00")
datetime.datetime(1998, 12, 14, 13, 30, 12)
>>> parseISODT("2016-12-31T23:59:60")
Traceback (most recent call last):
ValueError: second must be in 0..59
>>> parseISODT("2016-12-31T23:59:60", useTime=True)
datetime.datetime(2017, 1, 1, 1, 0)
>>> parseISODT("junk")
Traceback (most recent call last):
ValueError: Bad ISO datetime literal: junk (required format: yyyy-mm-ddThh:mm:ssZ)
name = 'destruction'
static serializeValue(dt: datetime) str

returns some ISO8601 representation of a datetime instance.

The reason for preferring this function over a simple str is that datetime’s default representation is too difficult for some other code (e.g., itself); hence, this code suppresses any microsecond part and always adds a Z (where strftime works, utils.isoTimestampFmt produces an identical string).

The behaviour of this function for timezone-aware datetimes is undefined.

For convenience, None is returned as None.

Also for convenience, you can pass in a string; this will then be parsed first, which provides both some basic format validation and guaranteed DALI-compliant serialisation.

>>> formatISODT(datetime.datetime(2015, 10, 20, 12, 34, 22, 250))
'2015-10-20T12:34:22Z'
>>> formatISODT(datetime.datetime(1815, 10, 20, 12, 34, 22, 250))
'1815-10-20T12:34:22Z'
>>> formatISODT(datetime.datetime(2018, 9, 21, 23, 59, 59, 640000))
'2018-09-22T00:00:00Z'
class gavo.protocols.uwsactions.ErrorAction[source]

Bases: JobAction

doGET(job, request)[source]
doPOST(job, request)
mime = 'text/plain'
name = 'error'
class gavo.protocols.uwsactions.ExecDAction[source]

Bases: _SettableAction

attName = 'executionDuration'
deserializeValue

alias of float

name = 'executionduration'
serializeValue

alias of str

class gavo.protocols.uwsactions.JobAction[source]

Bases: object

an action done to a job.

It defines methods do<METHOD> that are dispatched through JobActions.

It must have a name corresponding to the child resource names from the UWS spec.

getResource(job, request, segments)[source]
mime = 'text/xml'
name = None
class gavo.protocols.uwsactions.JobActions(*additionalActions)[source]

Bases: object

A collection of “actions” performed on UWS jobs.

Their names are the names of the child resources of UWS jobs. The basic UWS actions are built in. When constructing those, you can pass in as many additional JobAction subclasses as you want. Set their names to one of UWS standard actions to override UWS behaviour if you think that’s wise.

classmethod addStandardAction(actionClass)[source]
dispatch(action, job, request, segments)[source]
class gavo.protocols.uwsactions.OwnerAction[source]

Bases: JobAction

doGET(job, request)[source]
mime = 'text/plain'
name = 'owner'
class gavo.protocols.uwsactions.ParameterAction[source]

Bases: JobAction

doGET(job, request)[source]
doPOST(job, request)[source]
name = 'parameters'
class gavo.protocols.uwsactions.PhaseAction[source]

Bases: JobAction

doGET(job, request)[source]
doPOST(job, request)[source]
mime = 'text/plain'
name = 'phase'
timeout = 10
class gavo.protocols.uwsactions.QuoteAction[source]

Bases: JobAction

doGET(job, request)[source]
mime = 'text/plain'
name = 'quote'
class gavo.protocols.uwsactions.ResultsAction[source]

Bases: JobAction

Access result (Extension: and other) files in job directory.

doGET(job, request)[source]
getResource(job, request, segments)[source]
name = 'results'
class gavo.protocols.uwsactions.RootAction[source]

Bases: JobAction

Actions for async/jobId.

doDELETE(job, request)[source]

Implements DELETE on a job resource.

This is the UWS-compliant way to delete a job.

doGET(job, request)[source]

Implements GET on a job resource: return the current job metadata.

doPOST(wjob, request)[source]

Implements POST on a job resource.

This is a DaCHS extension to UWS in order to let web browsers delete jobs by passing action=DELETE.

name = ''
class gavo.protocols.uwsactions.StartTimeAction[source]

Bases: JobAction

doGET(job, request)[source]
doPOST(job, request)
mime = 'text/plain'
name = 'startTime'
class gavo.protocols.uwsactions.UWS[source]

Bases: object

the container for elements from the uws namespace.

class UWSElement(id=None)[source]

Bases: Element

class creationTime(id=None)[source]

Bases: UWSElement

class destruction(id=None)[source]

Bases: UWSElement

class detail(href=None, id=None, type=None)[source]

Bases: UWSElement

class endTime(id=None)[source]

Bases: NillableMixin, UWSElement

class errorSummary(hasDetail=None, id=None, type=None)[source]

Bases: UWSElement

class executionDuration(id=None)[source]

Bases: UWSElement

class job(id=None, version='1.1')[source]

Bases: UWSElement

class jobId(id=None)[source]

Bases: UWSElement

class jobInfo(id=None)[source]

Bases: UWSElement

class jobref(href=None, id=None, type=None)[source]

Bases: UWSElement

class jobs(id=None, version='1.1')[source]

Bases: UWSElement

static makeRoot(ob)[source]
class message(id=None)[source]

Bases: UWSElement

class ownerId(id=None)[source]

Bases: NillableMixin, UWSElement

class parameter(byReference=None, id=None, isPost=None)[source]

Bases: UWSElement

class parameters(id=None)[source]

Bases: UWSElement

class phase(id=None)[source]

Bases: UWSElement

class quote(id=None)[source]

Bases: NillableMixin, UWSElement

class result(href=None, id=None, type=None)[source]

Bases: UWSElement

class results(id=None)[source]

Bases: UWSElement

class runId(id=None)[source]

Bases: UWSElement

class startTime(id=None)[source]

Bases: NillableMixin, UWSElement

gavo.protocols.uwsactions.doJobAction(workerSystem, request, segments)[source]

handles the async UI of UWS.

Depending on method and segments, it will return various XML strings and may cause certain actions.

Segments must be a tuple with at least one element, the job id.

gavo.protocols.uwsactions.getErrorSummary(job)[source]
gavo.protocols.uwsactions.getJobList(workerSystem, forOwner=None, phase=None, last=None, after=None)[source]
gavo.protocols.uwsactions.getParametersElement(job)[source]

returns a UWS.parameters element for job.