/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pyserver/api_server.py

  • Committer: Suren A. Chilingaryan
  • Date: 2016-03-02 22:36:19 UTC
  • mfrom: (346.1.35 pcitool)
  • Revision ID: csa@suren.me-20160302223619-r1zd62x6kwbyd321
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import sys
 
3
 
 
4
import pcilib
 
5
 
1
6
import time
2
 
import os
3
 
import pcipywrap
4
7
import json
5
 
import sys
6
8
from optparse import OptionParser
7
 
 
8
 
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
9
 
from SocketServer import ThreadingMixIn
10
 
import threading
11
 
 
12
 
pcilib = None
 
9
from multiprocessing import Process
 
10
 
 
11
if sys.version_info >= (3,0):
 
12
   from http.server import HTTPServer, BaseHTTPRequestHandler
 
13
   from socketserver import ThreadingMixIn
 
14
else:
 
15
   from SocketServer import ThreadingMixIn
 
16
   from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
13
17
 
14
18
class MultiThreadedHTTPServer(ThreadingMixIn, HTTPServer):
15
19
    pass
16
20
 
17
21
class PcilibServerHandler(BaseHTTPRequestHandler):
18
 
   locks = list()
19
 
   lock_global = 0
20
22
   
21
 
   #def __init__(s, pcilib, *args):
22
 
   #   s.pcilib = pcilib
23
 
   #   BaseHTTPRequestHandler.__init__(s, *args)
 
23
   def __init__(s, pcilib, *args):
 
24
      s.pcilib = pcilib
 
25
      BaseHTTPRequestHandler.__init__(s, *args)
24
26
   
25
27
   def do_HEAD(s):
26
28
      s.send_response(200)
28
30
      s.end_headers()
29
31
      
30
32
   def do_GET(s):
 
33
      #run request in separate process
 
34
      p = Process(target=s.do_GET_worker, args=())
 
35
      p.start()
 
36
      p.join()
 
37
      
 
38
   def do_GET_worker(s):
31
39
      length = int(s.headers['Content-Length'])
32
40
      
33
41
      #deserialize input data
73
81
 
74
82
            registers = dict()
75
83
            try:
76
 
               registers = pcilib.get_registers_list(bank)
 
84
               registers = s.pcilib.get_registers_list(bank)
77
85
            except Exception as e:
78
86
               s.error(str(e), data) 
79
87
               return
101
109
            
102
110
            register = dict()
103
111
            try:
104
 
               register = pcilib.get_register_info(reg, bank)
 
112
               register = s.pcilib.get_register_info(reg, bank)
105
113
            except Exception as e:
106
114
               s.error(str(e), data) 
107
115
               return
119
127
            
120
128
            properties = dict()
121
129
            try:
122
 
               properties = pcilib.get_property_list(branch)
 
130
               properties = s.pcilib.get_property_list(branch)
123
131
            except Exception as e:
124
132
               s.error(str(e), data) 
125
133
               return
142
150
            #parse command arguments and convert them to string
143
151
            reg = str(data.get('reg', None))
144
152
            bank = data.get('bank', None)
145
 
            if not bank is None:
146
 
                                   bank = str(bank)
 
153
            if(not bank is None):
 
154
               bank = str(bank)
147
155
            
148
156
            value = 0
149
157
            try:
150
 
               value = pcilib.read_register(reg, bank)
 
158
               value = s.pcilib.read_register(reg, bank)
151
159
            except Exception as e:
152
160
               s.error(str(e), data) 
153
161
               return
174
182
               
175
183
            #parse command arguments and convert them to string
176
184
            reg = str(data.get('reg', None))
177
 
            value = str(data.get('value', None))
 
185
            value = data.get('value', None)
178
186
            bank = data.get('bank', None)
179
 
            if not bank is None:
180
 
                                   bank = str(bank)
 
187
            if(not bank is None):
 
188
               bank = str(bank)
181
189
            
182
190
            try:
183
 
               pcilib.write_register(value, reg, bank)
 
191
               s.pcilib.write_register(value, reg, bank)
184
192
            except Exception as e:
185
193
               s.error(str(e), data) 
186
194
               return
202
210
            
203
211
            value = 0
204
212
            try:
205
 
               value = pcilib.get_property(prop)
 
213
               value = s.pcilib.get_property(prop)
206
214
            except Exception as e:
207
215
               s.error(str(e), data) 
208
216
               return
226
234
               s.error('message doesnt contains "value" field, '
227
235
                       'which is required for "set_property" command', data)
228
236
               return
229
 
               
 
237
            
230
238
            #parse command arguments and convert them to string
231
239
            prop = str(data.get('prop', None))
232
 
            value = str(data.get('value', None))
 
240
            value = data.get('value', None)
233
241
            
234
242
            try:
235
 
               pcilib.set_property(value, prop)
 
243
               s.pcilib.set_property(value, prop)
236
244
            except Exception as e:
237
245
               s.error(str(e), data) 
238
246
               return
252
260
            #parse command arguments and convert them to string
253
261
            lock_id = str(data.get('lock_id'))
254
262
            
255
 
            #check if lock already setted
256
 
            #if lock_id in PcilibServerHandler.locks:
257
 
            #   s.error('Lock with id: ' + lock_id + 
258
 
            #           'already setted by this server',
259
 
            #           data)
260
 
            #   return
261
 
            
262
263
            try:
263
 
               pcilib.lock(lock_id)
 
264
               s.pcilib.lock(lock_id)
264
265
            except Exception as e:
265
266
               s.error(str(e), data) 
266
267
               return
267
 
               
268
 
            PcilibServerHandler.locks.append(lock_id)
269
268
            
270
269
            #Success! Create and send reply
271
270
            s.wrapMessageAndSend({'status': 'ok'}, data)
283
282
            lock_id = str(data.get('lock_id'))
284
283
            
285
284
            try:
286
 
               pcilib.try_lock(lock_id)
 
285
               s.pcilib.try_lock(lock_id)
287
286
            except Exception as e:
288
287
               s.error(str(e), data) 
289
288
               return
295
294
            
296
295
         elif(command == 'unlock'):
297
296
            #check required arguments
298
 
            #if not 'lock_id' in data:
299
 
            #   s.error('message doesnt contains "lock_id" field, '
300
 
            #           'which is required for "unlock" command', data)
301
 
            #   return
 
297
            if not 'lock_id' in data:
 
298
               s.error('message doesnt contains "lock_id" field, '
 
299
                       'which is required for "unlock" command', data)
 
300
               return
302
301
               
303
302
            #parse command arguments and convert them to string
304
 
            #lock_id = str(data.get('lock_id'))
 
303
            lock_id = str(data.get('lock_id'))
305
304
            
306
 
            #try:
307
 
            #   pcilib.unlock(lock_id)
308
 
            #except Exception as e:
309
 
            #   s.error(str(e), data) 
310
 
            #   return
311
 
            #
312
 
            #remove lock from locks list
313
 
            #if lock_id in PcilibServerHandler.locks:
314
 
            #   PcilibServerHandler.locks.remove(lock_id)
315
 
            time.sleep(20)
 
305
            try:
 
306
               s.pcilib.unlock(lock_id)
 
307
            except Exception as e:
 
308
               s.error(str(e), data) 
 
309
               return
 
310
 
316
311
            #Success! Create and send reply
317
312
            s.wrapMessageAndSend({'status': 'ok'}, data)
318
313
            
319
314
            
320
315
            
 
316
         elif(command == 'get_scripts_list'):
 
317
            scripts = list()
 
318
            try:
 
319
               scripts = s.pcilib.get_scripts_list()
 
320
            except Exception as e:
 
321
               s.error(str(e), data) 
 
322
               return
 
323
 
 
324
            #Success! Create and send reply
 
325
            s.wrapMessageAndSend({'status': 'ok', 'scripts': scripts}, data)
 
326
         
 
327
         
 
328
         
 
329
         elif(command == 'run_script'):
 
330
            #check required arguments
 
331
            if not 'script_name' in data:
 
332
               s.error('message doesnt contains "script_name" field, '
 
333
                       'which is required for "run_script" command', data)
 
334
               return
 
335
            #parse command arguments and convert them to string
 
336
            script_name = str(data.get('script_name'))
 
337
            value = data.get('value', None)
 
338
            
 
339
            out = None
 
340
            try:
 
341
               out = s.pcilib.run_script(script_name, value)
 
342
            except Exception as e:
 
343
               s.error(str(e), data) 
 
344
               return
 
345
 
 
346
            #Success! Create and send reply
 
347
            if(type(out) == bytearray or type(out) == bytes):
 
348
               s.send_response(200)
 
349
               s.send_header('content-disposition', 'inline; filename=value')
 
350
               s.send_header('content-type', 'application/octet-stream')
 
351
               s.end_headers()
 
352
               s.wfile.write(out)
 
353
            else:
 
354
               s.wrapMessageAndSend({'status': 'ok', 'value': out}, data)
 
355
            
 
356
            
 
357
            
321
358
         #elif(command == 'lock_global'):
322
359
         #   #check if global_lock already setted by server
323
 
         #   print 'aaa'
324
 
         #   if PcilibServerHandler.lock_global:
325
 
         #
326
 
         #      s.error('global lock already setted by this server', data)
327
 
         #      return
328
 
         #      
329
360
         #   try:
330
 
         #      pcilib.lock_global()
 
361
         #      s.pcilib.lock_global()
331
362
         #   except Exception as e:
332
363
         #      s.error(str(e), data)
333
364
         #      return
334
365
         #   
335
 
         #   PcilibServerHandler.lock_global = 1
336
 
         #   
337
366
         #   #Success! Create and send reply
338
367
         #   s.wrapMessageAndSend({'status': 'ok'}, data)
339
368
            
341
370
         
342
371
         #elif(command == 'unlock_global'):
343
372
         #   try:
344
 
         #      pcilib.unlock_global()
 
373
         #      s.pcilib.unlock_global()
345
374
         #   except Exception as e:
346
375
         #      s.error(str(e), data)
347
376
         #      return
348
377
         #   
349
 
         #   PcilibServerHandler.lock_global = 0
350
 
         #   
351
378
         #   #Success! Create and send reply
352
379
         #   s.wrapMessageAndSend({'status': 'ok'}, data)
353
380
         
354
 
         
355
 
                
 
381
      
356
382
         else:
357
 
                    s.error('command "' + command + '" undefined', data)
358
 
                    return
 
383
            s.error('command "' + command + '" undefined', data)
 
384
            return
359
385
      else:
360
 
                  s.error('message doesnt contains "command" field, which is required', data)
361
 
                  return
362
 
                  
363
 
       
364
 
      #print str(s.headers['content-type'])
365
 
      #print post_data['some']
 
386
         s.error('message doesnt contains "command" field, which is required', data)
 
387
         return
 
388
        
 
389
        
366
390
      
367
 
   #"""open device context """
 
391
   #open device context 
368
392
   #def openPcilibInstance(s, device, model):
369
 
   #   pcilib = pcipywrap.create_pcilib_instance(device, model)
 
393
   #   s.pcilib = pcipywrap.create_pcilib_instance(device, model)
370
394
         
371
 
   """Send help message"""
 
395
   #Send help message
372
396
   def help(s, received_message = None):
373
397
      usage = str('Usage:\n'
374
398
      '  Server receive commands via http GET with json packet.\n'
446
470
      '      lock_id: - lock id\n'
447
471
      '\n'
448
472
      
 
473
      '  command: get_scripts_list - Get aviable scripts with description\n'
 
474
      '\n'
 
475
      
 
476
      '  command: run_script - Run specified script\n'
 
477
      '    required fields\n'
 
478
      '      script_name: - script name (without extension)\n'
 
479
      '      value: - input value in json format\n'
 
480
      '\n'
 
481
      
449
482
      '\n')
450
 
      out = {'status': 'ok', 'usage' : usage}
451
 
      s.wrapMessageAndSend(out, received_message)
 
483
      
 
484
      #send help as plain text
 
485
      s.send_response(200)
 
486
      s.send_header('content-type', 'text/plain')
 
487
      s.end_headers()
 
488
      if sys.version_info >= (3,0):
 
489
         s.wfile.write(bytes(usage, 'UTF-8'))
 
490
      else:
 
491
         s.wfile.write(usage)
452
492
 
453
 
   """Send error message with text description"""     
 
493
   #Send error message with text description    
454
494
   def error(s, info, received_message = None):
455
495
      out = dict()
456
496
      
465
505
      s.end_headers()
466
506
      if not received_message is None:
467
507
         message['received_message'] = received_message
468
 
      message['thread'] = threading.currentThread().getName()
469
 
      s.wfile.write(json.dumps(message))
 
508
      if sys.version_info >= (3,0):
 
509
         s.wfile.write(bytes(json.dumps(message), 'UTF-8'))
 
510
      else:
 
511
         s.wfile.write(json.dumps(message))
 
512
      
 
513
      
 
514
class ApiServer(MultiThreadedHTTPServer):
 
515
   def __init__(self, device='/dev/fpga0', model=None, adress=('0.0.0.0', 9000)):
 
516
      #redirect logs to exeption
 
517
      pcilib.redirect_logs_to_exeption()
 
518
      #pass Pcipywrap to to server handler
 
519
      self.lib = pcilib.pcilib(device, model)
 
520
      def handler(*args):
 
521
         PcilibServerHandler(self.lib, *args)
 
522
      MultiThreadedHTTPServer.__init__(self, adress, handler)
470
523
 
471
524
if __name__ == '__main__':
472
525
   
481
534
   parser.add_option("-m", "--model",  action="store",
482
535
                     type="string", dest="model", default=None,
483
536
                     help="Memory model (autodetected)")
 
537
 
484
538
   opts = parser.parse_args()[0]
485
539
   
486
 
   HOST_NAME = ''
 
540
   HOST_NAME = '0.0.0.0'
487
541
   PORT_NUMBER = opts.port
488
542
   MODEL = opts.model
489
543
   DEVICE = opts.device
490
544
   
491
 
   
492
 
   
493
 
   #Set enviroment variables, if it not setted already
494
 
   if not 'APP_PATH' in os.environ:
495
 
      APP_PATH = ''
496
 
      file_dir = os.path.dirname(os.path.abspath(__file__))
497
 
      APP_PATH = str(os.path.abspath(file_dir + '/../..'))
498
 
      os.environ["APP_PATH"] = APP_PATH
499
 
 
500
 
   if not 'PCILIB_MODEL_DIR' in os.environ:   
501
 
      os.environ['PCILIB_MODEL_DIR'] = os.environ["APP_PATH"] + "/xml"
502
 
      
503
 
   if not 'LD_LIBRARY_PATH' in os.environ: 
504
 
      os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib"
505
 
   
506
 
   
507
 
   
508
 
   #redirect logs to exeption
509
 
   pcipywrap.__redirect_logs_to_exeption()
510
 
   
511
 
   #pass Pcipywrap to to server handler
512
 
   global pcilib
513
 
   pcilib = pcipywrap.Pcipywrap(DEVICE, MODEL)
514
 
   #def handler(*args):
515
 
   #   PcilibServerHandler(lib, *args)
516
 
   
517
545
   #start server
518
 
   httpd = MultiThreadedHTTPServer((HOST_NAME, PORT_NUMBER), PcilibServerHandler)
519
 
   
520
 
   print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
 
546
   httpd = ApiServer(DEVICE, MODEL, (HOST_NAME, PORT_NUMBER))
 
547
   
 
548
   print(time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER))
 
549
   
521
550
   try:
522
551
      httpd.serve_forever()
523
552
   except KeyboardInterrupt:
524
 
      #unlocking global lock
525
 
      if PcilibServerHandler.lock_global:
526
 
         lib.unlock_global()
527
 
         PcilibServerHandler.lock_global = False
528
 
         
529
 
      #delete created locks
530
 
      for lock in PcilibServerHandler.locks:
531
 
         lib.unlock(lock)
532
 
      del PcilibServerHandler.locks[:]
533
553
      pass
534
554
      
535
 
      
536
 
      
537
 
      
538
555
   httpd.server_close()
539
 
   print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)
 
556
   
 
557
   print(time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER))