Added basic HTTP server
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							
								
								
									
										71
									
								
								single_ursim_control/http_server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								single_ursim_control/http_server.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
 | 
			
		||||
import json
 | 
			
		||||
import logging
 | 
			
		||||
from threading import Thread
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# This section might be a little fragile, but thankfully crashing this won't take the whole process down
 | 
			
		||||
# Since it's running in it's own thread
 | 
			
		||||
# Although the process might become unresponsive
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
class ControlRequestHandler(BaseHTTPRequestHandler):
 | 
			
		||||
 | 
			
		||||
    def log_message(self, format, *args):
 | 
			
		||||
        self.server._logger.debug(format % args)
 | 
			
		||||
 | 
			
		||||
    def _handle_request(self, method: str, data: bytes = None):
 | 
			
		||||
        _, name, *path = str(self.path).split("/")
 | 
			
		||||
        method_name = f"{method}_{name}"
 | 
			
		||||
 | 
			
		||||
        if hasattr(self.server._methods_instance, method_name):
 | 
			
		||||
            status, result = getattr(self.server._methods_instance, method_name)(path, data)
 | 
			
		||||
 | 
			
		||||
            self.send_response(status)
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                stringified_result = json.dumps(result)
 | 
			
		||||
                content_type = 'application/json'
 | 
			
		||||
            except TypeError:
 | 
			
		||||
                stringified_result = str(result)
 | 
			
		||||
                content_type = 'text/plain; charset=UTF-8'
 | 
			
		||||
 | 
			
		||||
            self.send_header('Content-type', content_type)
 | 
			
		||||
            self.end_headers()
 | 
			
		||||
            self.wfile.write(stringified_result.encode('utf-8'))
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            self.send_response(404)
 | 
			
		||||
            self.send_header('Content-type', 'text/plain')
 | 
			
		||||
            self.end_headers()
 | 
			
		||||
            self.wfile.write(b"NOT FOUND")
 | 
			
		||||
 | 
			
		||||
    def do_GET(self):
 | 
			
		||||
        self._handle_request('GET', None)
 | 
			
		||||
 | 
			
		||||
    def do_POST(self):
 | 
			
		||||
        if self.headers['Content-Length']:
 | 
			
		||||
            content_length = int(self.headers['Content-Length'])
 | 
			
		||||
            post_data = self.rfile.read(content_length)
 | 
			
		||||
        else:
 | 
			
		||||
            post_data = None
 | 
			
		||||
 | 
			
		||||
        self._handle_request('POST', post_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ControllerHTTPServer(Thread):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, methods_instance, port: int = 8000):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self._logger = logging.getLogger("http")
 | 
			
		||||
        self._http_server = ThreadingHTTPServer(('', port), ControlRequestHandler)
 | 
			
		||||
        self._http_server._methods_instance = methods_instance
 | 
			
		||||
        self._http_server._logger = self._logger
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        self._logger.info("Starting HTTP Server...")
 | 
			
		||||
        self._http_server.serve_forever()
 | 
			
		||||
        self._logger.info("Stopped HTTP Server...")
 | 
			
		||||
 | 
			
		||||
    def shutdown(self):
 | 
			
		||||
        self._http_server.shutdown()
 | 
			
		||||
@@ -1,12 +1,26 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
from config import Config
 | 
			
		||||
from plugins import WaitPlugin
 | 
			
		||||
from plugin_repository import PluginRepository
 | 
			
		||||
from program_executor import ProgramExecutor
 | 
			
		||||
from http_server import ControllerHTTPServer
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HTTPControl:
 | 
			
		||||
 | 
			
		||||
    def GET_status(self, path, data):
 | 
			
		||||
        return 200, "Very good!"
 | 
			
		||||
 | 
			
		||||
    def POST_terminate(self, path, data):
 | 
			
		||||
        return 200, "Will do sir!"
 | 
			
		||||
 | 
			
		||||
    def POST_continue(self, path, data):
 | 
			
		||||
        return 201, "Will do sir!"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    # init
 | 
			
		||||
    logging.basicConfig(
 | 
			
		||||
@@ -14,6 +28,8 @@ def main():
 | 
			
		||||
        format="%(asctime)s [%(levelname)s]: %(name)s: %(message)s",
 | 
			
		||||
        level=logging.DEBUG
 | 
			
		||||
    )
 | 
			
		||||
    http_server = ControllerHTTPServer(HTTPControl())
 | 
			
		||||
    http_server.start()
 | 
			
		||||
    compiler_repo = PluginRepository()
 | 
			
		||||
    compiler_repo.register_plugin(WaitPlugin)
 | 
			
		||||
 | 
			
		||||
@@ -21,6 +37,9 @@ def main():
 | 
			
		||||
    compiler_repo.load_plugin("wait")
 | 
			
		||||
    program = []
 | 
			
		||||
    program.append(compiler_repo.get_compiler("wait").compile(secs=2))
 | 
			
		||||
    program.append(compiler_repo.get_compiler("wait").compile(secs=3))
 | 
			
		||||
    program.append(compiler_repo.get_compiler("wait").compile(secs=10))
 | 
			
		||||
    program.append(compiler_repo.get_compiler("wait").compile(secs=10))
 | 
			
		||||
 | 
			
		||||
    # execute:
 | 
			
		||||
    executor = ProgramExecutor(program)
 | 
			
		||||
@@ -29,6 +48,7 @@ def main():
 | 
			
		||||
    # End of execution
 | 
			
		||||
    executor.join()
 | 
			
		||||
    compiler_repo.close()
 | 
			
		||||
    http_server.shutdown()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user