Source code for gavo.web.syncrender
"""
The DALI sync renderer.
This is, in principle, trivial and could just go into vodal.
But then there's sufficiently many hacks in the vicinity of this that
a module of its own seems warranted. Also, we're for now keeping
DALIRenderer here, which for now is a no-op only used for registration.
This *could* later become some sort of alias for allowed="sync,async"
defaultRenderer="info". But let's see how the caproles discussion works out.
"""
#c Copyright 2008-2023, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL. See the
#c COPYING file in the source distribution.
from twisted.python import failure
from twisted.web import server
from gavo import base
from gavo import utils
from gavo.protocols import dali
from gavo.protocols import tap
from gavo.svcs import streaming
from gavo.web import grend
from gavo.web import vosi
[docs]class DALIRenderer(grend.ServiceBasedPage):
"""A meta-renderer for DALI-like multi-renderer services (sync, async, ...)
This, for now, can only be used for creating registry records.
"""
name = "dali"
[docs] def render(self, request):
raise NotImplementedError("DALI renderers do not render."
" I'm not joking.")
[docs] @classmethod
def makeAccessURL(self, basePath):
return basePath
[docs]class SyncRenderer(grend.ServiceBasedPage):
"""a DALI sync renderer.
In principle, this is just a shallow parser of the input parameter
and renders tables as VOTables.
In practice, there are a few legacy hacks making this a bit more complicated
after all.
"""
name = "sync"
resultType = base.votableType
urlUse = "base"
parameterStyle = "dali"
[docs] def render(self, request):
# We need a bit of extra behaviour for TAP support, which isn't
# quite DALI sync
try:
if self.service.core.name_=="tapCore":
requestValue = request.strargs.get("REQUEST", [""])[0].lower()
if requestValue=="getcapabilities":
return vosi.VOSICapabilityRenderer(request, self.service
).render(request)
tap.mangleUploads(request)
else:
# Not TAP: use DALI standard upload mangling.
dali.mangleUploads(request)
self.runAsync(request.strargs
).addCallback(self._formatOutput, request
).addErrback(self._handleFailure, request
).addErrback(request.finishCallback)
except Exception:
return self._handleFailure(failure.Failure(), request)
return server.NOT_DONE_YET
def _formatOutput(self, result, request):
f, type = result
def writeTable(outputFile):
utils.cat(f, outputFile)
request.setHeader("content-type", str(type))
# if request has an accumulator, we're testing; this might be sync,
# so we're shortcutting.
if hasattr(request, "accumulator"):
writeTable(request)
request.finish()
else:
return streaming.streamOut(writeTable, request)
def _handleFailure(self, flr, request):
if not isinstance(flr.value, base.Error):
base.ui.notifyFailure(flr)
return dali.serveDALIError(request, flr.value)