1 """
2 Cores are the standard object for computing things in the DC.
3
4 This module also contains the registry for cores. If you want to
5 be able to refer to cores from within an RD, you need to enter your
6 core here.
7
8 Cores return pairs of a type and a payload. Renderers should normally
9 be prepared to receive (None, OutputTable) and (mime/str, data/str),
10 though individual cores might return other stuff (and then only
11 work with select renderers).
12
13 In general, the input table definition is mandatory, i.e., you have
14 to come up with it. Services do this either ad-hoc from input from
15 the web or using an inputDD.
16
17 The output table, on the other hand, is "advisory", mainly for registry
18 and documentation purposes ("I *could* return this"). In particular
19 DBBasedCores will usually adapt to the service's wishes when it comes
20 to the output table structure, not to mention the ADQL core. This doesn't
21 hurt since whatever is returned comes with structure documentation of
22 its own.
23
24 Cores may also want to adapt to renderers. This is a bit of a hack to
25 support, e.g., form and scs within a single service, which avoids
26 two different VOResource records just because of slightly differning
27 input definitions.
28
29 The interface here is the adaptForRenderer method. It takes a single
30 argument, the renderer, either as a simple name resolvable in the renderer
31 registry, or as a renderer instance or class. It must return a new
32 core instance.
33
34 Currently, two mechanisms for core adaptation are in place:
35
36 (1) generically, inputKeys can have properties onlyForRenderer and
37 notForRenderer with the obvious semantics.
38
39 (2) cores that have condDescs may adapt by virtue of condDesc's
40 adaptForRenderer method.
41 """
42
43
44
45
46
47
48
49 from gavo import base
50 from gavo import rsc
51 from gavo import rscdef
52 from gavo import utils
53 from gavo.svcs import inputdef
54 from gavo.svcs import outputdef
55
56
57 CORE_REGISTRY = {
58
59 "adqlCore": ("protocols.adqlglue", "ADQLCore"),
60 "customCore": ("svcs.customcore", "CustomCore"),
61 "datalinkCore": ("protocols.datalink", "DatalinkCore"),
62 "dbCore": ("svcs.standardcores", "DBCore"),
63 "debugCore": ("svcs.core", "DebugCore"),
64 "fancyQueryCore": ("svcs.standardcores", "FancyQueryCore"),
65 "fixedQueryCore": ("svcs.standardcores", "FixedQueryCore"),
66 "nullCore": ("svcs.standardcores", "NullCore"),
67 "productCore": ("protocols.products", "ProductCore"),
68 "pythonCore": ("svcs.customcore", "PythonCore"),
69 "registryCore": ("registry.oaiinter", "RegistryCore"),
70 "scsCore": ("protocols.scs", "SCSCore"),
71 "siapCutoutCore": ("protocols.siap", "SIAPCutoutCore"),
72 "ssapCore": ("protocols.ssap", "SSAPCore"),
73 "tapCore": ("protocols.tap", "TAPCore"),
74 "uploadCore": ("svcs.uploadcores", "UploadCore"),
75 }
76
77
88
89
91 """The childFactory for a core's outputTable.
92
93 On call, it will return a slightly amended copy of the
94 queried table.
95
96 This means that you must set the queried table before mentioning the
97 outputs.
98 """
99 name_ = "outputTable"
100
107
108
109 -class Core(base.Structure):
110 """A definition of the "active" part of a service.
111
112 A core will receive input from a renderer in the form of a ``svcs.CoreArgs``
113 (see `Core Args`_). A core will return a table or perhaps directly
114 data as discussed in `DaCHS' Service Interface`_ .
115
116 The abstract core element will never occur in resource descriptors. See
117 `Cores Available`_ for concrete cores. Use the names of the concrete
118 cores in RDs.
119 """
120 name_ = "core"
121
122 inputTableXML = None
123 outputTableXML = None
124
125
126
127 _ot_prototype = None
128
129 _rd = rscdef.RDAttribute()
130 _inputTable = base.StructAttribute("inputTable",
131 default=base.NotGiven,
132 childFactory=inputdef.InputTD,
133 description="Description of the input data",
134 copyable=True)
135
136 _outputTable = base.StructAttribute("outputTable",
137 default=base.NotGiven,
138 childFactory=_OutputTableFactory(),
139 description="Table describing what fields are available from this core",
140 copyable=True)
141
142 _original = base.OriginalAttribute()
143
144 _properties = base.PropertyAttribute(copyable=True)
145
153
155 return "<%s at %s>"%(self.__class__.__name__, id(self))
156
159
167
169 """override to configure the custom core before use.
170
171 This is typically where you pull input or output tables
172 from the RD in customCores. Actual DaCHS code should use
173 completeElement as usual.
174 """
175
177 """returns a core object tailored for renderer.
178 """
179 newIT = self.inputTable.adaptForRenderer(renderer)
180 if newIT is self.inputTable:
181 return self
182 else:
183 return self.change(inputTable=newIT)
184
185 - def run(self, service, inputData, queryMeta):
188
190 return ("Polymorphous core element. May contain any of the cores"
191 " mentioned in `Cores Available`_ .")
192
193
195 """a core that returns its arguments stringified in a table.
196
197 You need to provide an external input tables for these.
198 """
199 name_ = "debugCore"
200
201 outputTableXML = """
202 <outputTable>
203 <outputField name="arg_key" type="text"
204 description="Name of an input parameter"/>
205 <outputField name="arg_value" type="text"
206 description="(First) value passed (or None)"/>
207 </outputTable>"""
208
209 - def run(self, service, inputTable, queryMeta):
218