-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmodpython.py
executable file
·141 lines (123 loc) · 4.75 KB
/
modpython.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""Use as a mod_python handler in apache.
Apache configuration example:
<Location "/mdsplusEvents/">
SetHandler python-program
PythonHandler MDSplus.modpython
PythonPath "['/usr/local/myeventhandlers'] + sys.path"
PythonDebug On
PythonOption UDP_EVENTS yes
or
PythonOption EVENT_SERVER host[:port]
</Location>
This configuration will handle requests such as:
http://mywebserver-host/mdsplusEvents/event-name
http://mywebserver-host/mdsplusEvents/event-name?timeout=5
http://mywebserver-host/mdsplusEvents/event-name?timeout=50&handler=myhandler
If no handler is used in the url then the default handler will be used.
The default handler does the following:
If the event occurs before the timeout (default timeout is 60 seconds):
returns a page of xml which looks like:
<event><name>event-name</name><time>time-of-event</time></event> or
<event><name>event-name</name><time>time-of-event</time><data>
<data_bytes>[byte1,byte2,byte3,....,byte4]</data_bytes>
<data_text>text_bytes</data_text></data>
</event>
If the event times out then returns an empty page with status of NO_RESPONSE(204)
If there is an error during processing the event it returns a page of xml which
looks like:
<exception>text-of-exception</exception> and a status of BAD_REQUEST
If a handler is specified, a module of the name of handler specified will be
imported and the function called "handler" in that module will be called with
two arguments, the req and the MDSplus event instance in that order. The handler can use the req
object to write the response and the event object to get the event data. The
event-instance.exception will = None if no problem occurred during the event processing or
the exception string if an error occurred. The handler should return a valid
HTTP status if it handles the event otherwise it can return None to resume the
default processing. The following is a handler used on the C-Mod experiment
for monitoring the shot cycle state machine. Information about the state and
shot number is encoded in an event called CMOD_COUNTDOWN_EVENT.
from mod_python import apache
import time
import numpy
import sys,os
states=["starting", "standby", "cooldown", "test", "recool", "init", "check", "pulse", "abort"]
lastData=None
lastTime=time.time()
def handler(req,e):
if e.exception is None:
req.content_type="text/xml"
data=e.getRaw().data()
shot=int(data[range(4,8)].view(numpy.uint32).item())
toState=states[int(data[1])]
fromState=states[int(data[0])]
req.write('<?xml version="1.0" encoding="ISO-8859-1" ?>')
req.write("<cmodState><shot>%d</shot><toState>%s</toState><fromState>%s</fromState></cmodState>" % (shot,toState,fromState))
return apache.OK
"""
from MDSplus import Event
import time
import os
from mod_python import apache
from cgi import parse_qs
class myevent(Event):
def run(self):
self.cancel()
def handler(req):
try:
opts=req.get_options()
if "UDP_EVENTS" in opts:
value=opts["UDP_EVENTS"].upper()
if value=="YES":
os.putenv('UDP_EVENTS','yes')
if "EVENT_SERVER" in opts:
os.putenv("mds_event_server",opts['EVENT_SERVER'])
except:
pass
os.putenv('UDP_EVENTS','yes')
event=req.path_info.rsplit('/')[-1]
args=parse_qs(str(req.args))
timeout=60
try:
timeout=int(args['timeout'][-1])
except:
pass
try:
event=args['event'][-1]
except:
pass
if 'handler' in args:
specialHandler=__import__(args['handler'][-1])
if hasattr(specialHandler,'handler'):
specialHandler=specialHandler.handler
else:
raise Exception(str(dir(specialHandler)))
else:
specialHandler=None
e=myevent(event,timeout)
e.join()
req.headers_out['Cache-Control']='no-store, no-cache, must-revalidate'
req.headers_out['Pragma']='no-cache'
req.content_type="text/xml"
if specialHandler is not None:
result = specialHandler(req,e)
if result is not None:
return result
if e.exception is None:
data=e.getRaw()
t=time.ctime(e.time)
req.write('<?xml version="1.0" encoding="ISO-8859-1" ?>'+"<event><name>%s</name><time>%s</time>" % (event,t))
if data is not None:
dtext=""
for c in data:
dtext = dtext+chr(int(c))
req.write("<data><bytes>%s</bytes><text>%s</text></data>" % (data.tolist(),dtext))
req.write("</event>")
return apache.OK
else:
if 'Timeout' in str(e.exception):
req.content_type="text/plain"
return apache.HTTP_NO_CONTENT
else:
req.exception=True
req.write('<?xml version="1.0" encoding="ISO-8859-1" ?>'+"\n<exception>%s</exception>" % (e.exception,))
return apache.HTTP_BAD_REQUEST