38
38
39
39
40
40
class TornadoResponse (object ):
41
- """This class registers tornado methods with arguments in the same order they are called
42
- from TornadoResponse instance to call them later in the main thread .
41
+ """This class registers tornadoes with arguments in the order they are called
42
+ from TornadoResponse to call them later.
43
43
44
- This class can be useful if you are afraid to use Tornado methods in a non-main thread due to a warning from Tornado that "methods on RequestHandler and elsewhere in Tornado are not thread-safe"
45
- https://www.tornadoweb.org/en/stable/web.html#thread-safety-notes.
46
-
47
- This is used in exceptional cases, in most cases it is not required,
48
- just use `return S_OK(data)` instead.
49
-
50
- Usage example::
44
+ Use::
51
45
52
46
def web_myEndpoint(self):
53
- # We need not only to return the result but also to set a header.
54
- resp = TornadoResponse('data')
55
- resp.set_header("Content-Type", "application/x-tar")
56
- # And for example redirect to another place
57
- return resp.redirect('https://server')
47
+ resp = TornadoResponse("data")
48
+ resp.set_status(400)
49
+ return resp
58
50
"""
59
51
60
- # Let's see what methods RequestHandler has
61
52
__attrs = inspect .getmembers (RequestHandler )
62
53
63
54
def __init__ (self , payload = None , status_code = None ):
@@ -70,7 +61,6 @@ def __init__(self, payload=None, status_code=None):
70
61
self .status_code = status_code
71
62
self .actions = []
72
63
for mName , mObj in self .__attrs :
73
- # Let's make sure that this is the usual RequestHandler method
74
64
if inspect .isroutine (mObj ) and not mName .startswith ("_" ) and not mName .startswith ("get" ):
75
65
setattr (self , mName , partial (self .__setAction , mName ))
76
66
@@ -82,31 +72,23 @@ def __setAction(self, mName, *args, **kwargs):
82
72
:return: TornadoResponse instance
83
73
"""
84
74
self .actions .append ((mName , args , kwargs ))
85
- # Let's return the instance of the class so that it can be returned immediately. For example:
86
- # resp = TornadoResponse('data')
87
- # return resp.redirect('https://server')
88
75
return self
89
76
90
77
def _runActions (self , reqObj ):
91
- """Calling methods in the order of their registration.
92
- This method is called at the end of the request, when the main work is already done in the thread.
93
- Look the :py:meth:`_finishFuture` method.
78
+ """Calling methods in the order of their registration
94
79
95
80
:param reqObj: RequestHandler instance
96
81
"""
97
- # Assign a status code if it has been transmitted.
98
82
if self .status_code :
99
83
reqObj .set_status (self .status_code )
100
84
for mName , args , kwargs in self .actions :
101
85
getattr (reqObj , mName )(* args , ** kwargs )
102
- # Will we check if the finish method has already been called.
103
86
if not reqObj ._finished :
104
- # if not what are we waiting for?
105
87
reqObj .finish (self .payload )
106
88
107
89
108
90
class BaseRequestHandler (RequestHandler ):
109
- """Base class for all the Handlers that uses HTTP tornado framework on server side .
91
+ """Base class for all the Handlers.
110
92
It directly inherits from :py:class:`tornado.web.RequestHandler`
111
93
112
94
Each HTTP request is served by a new instance of this class.
@@ -122,8 +104,8 @@ class BaseRequestHandler(RequestHandler):
122
104
123
105
class TornadoInstance(BaseRequestHandler):
124
106
125
- # Prefix of methods names if need to use a special prefix. By default its "export_".
126
- METHOD_PREFIX = "web_ "
107
+ # Prefix of methods names
108
+ METHOD_PREFIX = "export_ "
127
109
128
110
@classmethod
129
111
def _getServiceName(cls, request):
@@ -133,7 +115,7 @@ def _getServiceName(cls, request):
133
115
134
116
@classmethod
135
117
def _getServiceInfo(cls, serviceName, request):
136
- ''' Fill service information. By default return empty dictionary.
118
+ ''' Fill service information.
137
119
'''
138
120
return {'serviceName': serviceName,
139
121
'serviceSectionPath': PathFinder.getServiceSection(serviceName),
@@ -174,8 +156,12 @@ def post(self, *args, **kwargs): # pylint: disable=arguments-differ
174
156
# retVal is :py:class:`tornado.concurrent.Future`
175
157
self._finishFuture(retVal)
176
158
177
- In order to pass information around and keep some states, we use instance attributes.
178
- These are initialized in the :py:meth:`.initialize` method.
159
+ For compatibility with the existing :py:class:`DIRAC.Core.DISET.TransferClient.TransferClient`,
160
+ the handler can define a method ``export_streamToClient``. This is the method that will be called
161
+ whenever ``TransferClient.receiveFile`` is called. It is the equivalent of the DISET
162
+ ``transfer_toClient``.
163
+ Note that this is here only for compatibility, and we discourage using it for new purposes, as it is
164
+ bound to disappear.
179
165
"""
180
166
181
167
# Because we initialize at first request, we use a flag to know if it's already done
@@ -190,8 +176,7 @@ def post(self, *args, **kwargs): # pylint: disable=arguments-differ
190
176
# System name with which this component is associated
191
177
SYSTEM = None
192
178
193
- # Authorization requirements, properties that applied by default to all handler methods, if defined.
194
- # Nonte: `auth_methodName` will have a higher priority.
179
+ # Auth requirements
195
180
AUTH_PROPS = None
196
181
197
182
# Type of component
@@ -204,12 +189,7 @@ def post(self, *args, **kwargs): # pylint: disable=arguments-differ
204
189
_idps = IdProviderFactory ()
205
190
_idp = {}
206
191
207
- # Which grant type to use. This definition refers to the type of authorization, ie which algorithm will be used to verify the incoming request and obtain user credentials.
208
- # These algorithms will be applied in the same order as in the list.
209
-
210
- # SSL - add to list to enable certificate reading
211
- # JWT - add to list to enable reading Bearer token
212
- # VISITOR - add to list to enable authorization as visitor, that is, without verification
192
+ # Which grant type to use
213
193
USE_AUTHZ_GRANTS = ["SSL" , "JWT" ]
214
194
215
195
@classmethod
@@ -362,8 +342,9 @@ def initializeHandler(cls, serviceInfo):
362
342
And it must be a class method. This method is called only one time,
363
343
at the first request
364
344
365
- :param dict serviceInfo: infos about services, it contains information about service, e.g.:
366
- 'serviceName', 'serviceSectionPath', 'csPaths' and 'URL'
345
+ :param dict ServiceInfoDict: infos about services, it contains
346
+ 'serviceName', 'serviceSectionPath',
347
+ 'csPaths' and 'URL'
367
348
"""
368
349
pass
369
350
@@ -441,22 +422,17 @@ def _getMethodArgs(self, args):
441
422
def _getMethodAuthProps (self ):
442
423
"""Resolves the hard coded authorization requirements for method.
443
424
444
- List of required :mod:`~DIRAC.Core.Security.Properties`.
445
-
446
425
:return: list
447
426
"""
448
- # Convert default authorization requirements to list
449
427
if self .AUTH_PROPS and not isinstance (self .AUTH_PROPS , (list , tuple )):
450
428
self .AUTH_PROPS = [p .strip () for p in self .AUTH_PROPS .split ("," ) if p .strip ()]
451
- # Use auth_< method name > as primary value of the authorization requirements
452
429
return getattr (self , "auth_" + self .mehtodName , self .AUTH_PROPS )
453
430
454
431
def _getMethod (self ):
455
432
"""Get method function to call.
456
433
457
434
:return: function
458
435
"""
459
- # Get method object using prefix and method name from request
460
436
methodObj = getattr (self , "%s%s" % (self .METHOD_PREFIX , self .mehtodName ), None )
461
437
if not callable (methodObj ):
462
438
sLog .error ("Invalid method" , self .mehtodName )
0 commit comments