server.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 import os
3 import rospy
4 from rospkg import RosPack
5 import threading
6 import logging
7 import json
8 
9 from flask import Flask, render_template, send_from_directory, make_response
10 from waitress.server import create_server
11 
12 rospy.init_node('vizanti_flask_node')
13 
14 param_host = rospy.get_param('~host', '0.0.0.0')
15 param_port = rospy.get_param('~port', 5000)
16 param_port_rosbridge = rospy.get_param('~port_rosbridge', 5001)
17 param_base_url = rospy.get_param('~base_url', '')
18 param_default_widget_config = rospy.get_param('~default_widget_config', '')
19 
20 public_dir = RosPack().get_path('vizanti') + '/public/'
21 
22 app = Flask(__name__, static_folder=public_dir, template_folder=public_dir)
23 app.debug = rospy.get_param('~flask_debug', True)
24 
25 if param_default_widget_config != "":
26  param_default_widget_config = os.path.expanduser(param_default_widget_config)
27 else:
28  param_default_widget_config = os.path.join(app.static_folder, "assets/default_layout.json")
29 
30 def get_file(path):
31  with open(param_default_widget_config, 'r') as f:
32  file_content = f.read()
33  js_module = f"const content = {json.dumps(file_content)};\nexport default content;"
34  response = make_response(js_module)
35  response.headers['Content-Type'] = 'application/javascript'
36  return response
37 
38 def get_files(path, valid_extensions):
39  templates_dir = os.path.join(app.static_folder, path)
40  file_list = []
41 
42  for root, dirs, files in os.walk(templates_dir):
43  for file in files:
44  if os.path.splitext(file)[1] in valid_extensions:
45  file_path = os.path.join(root, file)
46  with open(file_path, 'r') as f:
47  file_content = f.read()
48  file_list.append({'path': os.path.relpath(file_path, templates_dir), 'content': file_content})
49 
50  js_module = f"const files = {json.dumps(file_list)};\n\nexport default files;"
51 
52  #fetch workaround hackery for webkit support on HTTP
53  response = make_response(js_module)
54  response.headers['Content-Type'] = 'application/javascript'
55  return response
56 
57 def get_paths(path, valid_extensions):
58  templates_dir = os.path.join(app.static_folder, path)
59  file_list = []
60 
61  for root, dirs, files in os.walk(templates_dir):
62  for file in files:
63  if os.path.splitext(file)[1] in valid_extensions:
64  file_list.append(os.path.relpath(os.path.join(root, file), templates_dir))
65 
66  js_module = f"const paths = {json.dumps(file_list)};\n\nexport default paths;"
67 
68  response = make_response(js_module)
69  response.headers['Content-Type'] = 'application/javascript'
70  return response
71 
72 @app.route(param_base_url + '/')
73 def index():
74  return render_template('index.html', base_url=param_base_url)
75 
76 @app.route(param_base_url + '/templates/files')
78  return get_files("templates", ['.html', '.js', '.css'])
79 
80 @app.route(param_base_url + '/assets/robot_model/paths')
82  return get_paths("assets/robot_model", ['.png'])
83 
84 @app.route(param_base_url + '/ros_launch_params')
86  params = {
87  "port": param_port,
88  "port_rosbridge": param_port_rosbridge
89  }
90  js_module = f"const params = {json.dumps(params)};\n\nexport default params;"
91  response = make_response(js_module)
92  response.headers['Content-Type'] = 'application/javascript'
93  return response
94 
95 @app.route(param_base_url + '/default_widget_config')
97  return get_file(param_default_widget_config)
98 
99 @app.route(param_base_url + '/<path:path>')
100 def serve_static(path):
101  return send_from_directory(app.static_folder, path)
102 
103 class ServerThread(threading.Thread):
104 
105  def __init__(self, app, host='0.0.0.0', port=5000):
106  threading.Thread.__init__(self)
107  self.daemon = True
108 
109  self.log = logging.getLogger('waitress')
110  self.log.setLevel(logging.INFO)
111  handler = logging.StreamHandler()
112  handler.setFormatter(logging.Formatter(
113  '[%(levelname)s] [%(asctime)s] [waitress]: %(message)s '
114  ))
115  self.log.addHandler(handler)
116 
117  self.app = app
118  self.host = host
119  self.port = port
120  self.ctx = app.app_context()
121  self.ctx.push()
122 
123  self._server = None
124  self._stop_event = threading.Event()
125 
126  def run(self):
127  self._server = create_server(self.app, host=self.host, port=self.port)
128  try:
129  self._server.run()
130  except KeyboardInterrupt:
131  self.shutdown()
132 
133  def shutdown(self):
134  if self._server:
135  self._server.close() # This triggers waitress to stop accepting new connections
136  self._stop_event.set() # Signal that we're stopping
137  rospy.loginfo("Waitress server shutting down...")
138 
139 server = ServerThread(app, param_host, param_port)
140 server.start()
141 
142 rospy.on_shutdown(server.shutdown)
143 rospy.spin()
server.ServerThread.ctx
ctx
Definition: server.py:120
server.ServerThread.host
host
Definition: server.py:118
server.serve_static
def serve_static(path)
Definition: server.py:100
server.ServerThread.log
log
Definition: server.py:109
server.ServerThread.daemon
daemon
Definition: server.py:107
server.list_ros_launch_params
def list_ros_launch_params()
Definition: server.py:85
server.ServerThread._server
_server
Definition: server.py:123
server.get_paths
def get_paths(path, valid_extensions)
Definition: server.py:57
server.ServerThread.__init__
def __init__(self, app, host='0.0.0.0', port=5000)
Definition: server.py:105
server.ServerThread.shutdown
def shutdown(self)
Definition: server.py:133
server.ServerThread.run
def run(self)
Definition: server.py:126
server.ServerThread._stop_event
_stop_event
Definition: server.py:124
server.ServerThread.port
port
Definition: server.py:119
server.ServerThread
Definition: server.py:103
server.list_template_files
def list_template_files()
Definition: server.py:77
server.get_default_widget_config
def get_default_widget_config()
Definition: server.py:96
server.index
def index()
Definition: server.py:73
server.ServerThread.app
app
Definition: server.py:117
server.get_file
def get_file(path)
Definition: server.py:30
server.get_files
def get_files(path, valid_extensions)
Definition: server.py:38
server.list_robot_model_files
def list_robot_model_files()
Definition: server.py:81


vizanti
Author(s): MoffKalast
autogenerated on Wed May 21 2025 02:34:06