def newExam(self): directory = str(self.setExistingDirectory()) if directory: directory = abspath(directory) print(directory) project_count = 1 while os.path.exists(join(directory, DEFAULT_PROJECT_FOLDER_NAME % project_count)): project_count += 1 name = DEFAULT_PROJECT_FOLDER_NAME % project_count project_path = join(directory, name) print('about to create %s at %s' % (name, directory)) # TODO: Fix project creation self.project = model.Project(name, 5, 1, [], []) self.project_path = join(project_path, DEFAULT_PROJECT_FILENAME) # Invoke Autoexam api.init(name, project_path) # Create base project file model.dump_project(self.project, '%s' % self.project_path) os.chdir(project_path) self.startWizard()
def newExam(self): directory = str(self.setExistingDirectory()) if directory: directory = abspath(directory) print(directory) project_count = 1 while os.path.exists( join(directory, DEFAULT_PROJECT_FOLDER_NAME % project_count)): project_count += 1 name = DEFAULT_PROJECT_FOLDER_NAME % project_count project_path = join(directory, name) print('about to create %s at %s' % (name, directory)) # TODO: Fix project creation self.project = model.Project(name, 5, 1, [], []) self.project_path = join(project_path, DEFAULT_PROJECT_FILENAME) # Invoke Autoexam api.init(name, project_path) # Create base project file model.dump_project(self.project, '%s' % self.project_path) os.chdir(project_path) self.startWizard()
def pull_data_singles(username, password, api_url, page_nr, iterations, json_file_path, file_name, review_state, data, to_reduce): # login to the Bika Lims API and pull data, save json file and convert it to csv using json2csv #print('\nStart Time') start_time = ctime() #print(start_time) print('\nWait while we process the data for you ....\n') bar = Bar('Processing', max=iterations) counter = 0 file_name += '_' for i in range(iterations + 1): api_url += str(page_nr) # print(api_url) # print("\n") api_data = requests.get(api_url, auth=(username, password)) # print(api_data.status_code) # print("\n") api_data = json.loads(api_data.text) json_file = str( str(json_file_path) + '\\' + file_name + ' - ' + strftime("%a %d %b %Y - %H%M%S") + '.json') api.init(json_file_path, Path(json_file)) api.list_concat(api_data['objects'], Path(json_file)) file_name += str(counter) api.to_cvs(Path(json_file), file_name, review_state, data, to_reduce, printing=False) # Remove previous concatenation before new concatenation : str(i) if page_nr < 10: api_url = api_url[:-1] elif page_nr >= 10 and page_nr < 100: api_url = api_url[:-2] else: api_url = api_url[:-3] if counter < 10: file_name = file_name[:-1] elif counter >= 10 and page_nr < 100: file_name = file_name[:-2] else: file_name = file_name[:-3] page_nr += 1 # increamenting the loop counter += 1 bar.next() bar.finish() print('\n===== DONE! =====\n') print('Start Time: {}.\nEnd Time: {}.\n'.format(start_time, ctime()))
def init_config(): const.config = _unpack(_load_config()) const.log = const.logzero.setup_logger(formatter=const._formatter, level=const.config.log_level) api.init() core.init()
def entry_point(argv): if config.translation.continuation: green.process.init(config) api.init(argv) try: for arg in argv[1:]: module = space.Module(u'main', {}, extends=base.module) program = evaluator.loader.from_file(arg) result = program.call([module]) os.write(1, (result.repr() + u'\n').encode('utf-8')) except space.Error as error: print_traceback(error) return 1 return 0
def init_w13scan(): root = modulePath() configure = { "debug": False, # debug模式会显示更多信息 "level": 2, "timeout": 30, "retry": 3, "json": "", # 自定义输出json结果路径, "html": True, "threads": 30, # 线程数量, "disable": [], "able": [], "excludes": ["google", "lastpass", '.gov.cn'] # 不扫描的网址 } init(root, configure)
def get_clients(username, password): # Pull and Update Clients if need arise. This will update new provinces and Distric if any file_name = 'Clients' review_state = "none_client" json_file_path = Path( str(os.path.expanduser('~')) + '\\Documents\\Bika LIMS\\json\\') json_file = Path( str(json_file_path) + '\\' + file_name + ' - ' + strftime("%a %d %b %Y - %H%M") + '.json') api.init(json_file_path, json_file) #for update: idealy make a small data pull and get last object number for cliets to determine the required number of api requests page_size = '500' iterations = int('6') api_url = "http://" + str( your_api) + "/@@API/read?portal_type=Client&page_size=" + str( page_size) + "&page_nr=" page_nr = 0 main(username, password, api_url, page_nr, iterations, json_file, file_name, review_state, data="Clients", to_reduce="reduce") clients_file = os.path.abspath( os.path.join(str(os.path.expanduser('~')), 'Documents/Bika Lims/', 'clients')) + '\\' + file_name + '.csv' clients_raw = pd.read_csv(clients_file) clients_filtred = merger.Clients_filter(clients_raw) clients_final = merger.clients_renamer(clients_filtred) clients_final.drop_duplicates(subset=['Client UID'], keep='first', inplace=True) clients_final.to_csv(clients_file, sep=',', encoding='utf-8', header=True, index=False)
import api from app import app if __name__ == '__main__': api.init() app.run(host='127.0.0.1', port=5000)
#!env/bin/python # initialize flask app u"""Starts development server.""" from api import app, init init() app.run(debug=app.config['DEBUG'], host=app.config["HOST"], port=app.config["PORT"])
def run(gui_config_file=None): """Main run method""" default_hwr_path = "localhost:hwr" # path to user's home dir. (works on Win2K, XP, Unix, Mac...) parser = OptionParser(usage="usage: %prog <GUI definition file> [options]") parser.add_option( "", "--logFile", action="store", type="string", help="Log file", dest="logFile", metavar="FILE", default="", ) parser.add_option( "", "--logLevel", action="store", type="string", help="Log level", dest="logLevel", default="INFO", ) parser.add_option( "", "--logTemplate", action="store", type="string", help="Log template", dest="logTemplate", default="", ) parser.add_option( "", "--bricksDirs", action="store", type="string", help="Additional directories for bricks search " + "path (you can also use the CUSTOM_BRICKS_PATH " + "environment variable)", dest="bricksDirs", metavar="dir1" + os.path.pathsep + "dir2...dirN", default="", ) parser.add_option( "", "--hardwareRepository", action="store", type="string", help="Hardware Repository Server host:port (default" + " to %s) (you can also use " % default_hwr_path + "HARDWARE_REPOSITORY_SERVER the environment variable)", metavar="HOST:PORT", dest="hardwareRepositoryServer", default="", ) parser.add_option( "", "--hardwareObjectsDirs", action="store", type="string", help="Additional directories for " + "Hardware Objects search path (you can also use " + "the CUSTOM_HARDWARE_OBJECTS_PATH environment " + "variable)", dest="hardwareObjectsDirs", metavar="dir1" + os.path.pathsep + "dir2...dirN", default="", ) parser.add_option( "-d", "", action="store_true", dest="designMode", default=False, help="start GUI in Design mode", ) parser.add_option( "-m", "", action="store_true", dest="showMaximized", default=False, help="maximize main window", ) parser.add_option( "", "--no-border", action="store_true", dest="noBorder", default=False, help="does not show borders on main window", ) parser.add_option( "", "--style", action="store", type="string", help="Visual style of the application (windows, motif," + "cde, plastique, windowsxp, or macintosh)", dest="appStyle", default=None, ) parser.add_option( "", "--userFileDir", action="store", type="string", help="User settings file stores application related settings " + "(window size and position). If not defined then user home " + "directory is used", dest="userFileDir", default=None, ) parser.add_option("", "--pyqt4", action="store_true", default=None) parser.add_option("", "--pyqt5", action="store_true", default=None) parser.add_option("", "--pyside", action="store_true", default=None) (opts, args) = parser.parse_args() # get config from arguments log_file = opts.logFile log_template = opts.logTemplate hwobj_directories = opts.hardwareObjectsDirs.split(os.path.pathsep) custom_bricks_directories = opts.bricksDirs.split(os.path.pathsep) if opts.userFileDir: user_file_dir = opts.userFileDir else: user_file_dir = os.path.join(os.environ["HOME"], ".mxcube") app_style = opts.appStyle if opts.hardwareRepositoryServer: hwr_path = opts.hardwareRepositoryServer else: # try to set Hardware Repository server from environment hwr_path = os.environ.get("HARDWARE_REPOSITORY_SERVER") if hwr_path is None: hwr_path = default_hwr_path # add bricks directories and hardware objects directories from environment try: custom_bricks_directories += os.environ.get("CUSTOM_BRICKS_PATH", "").split( os.path.pathsep ) except KeyError: pass try: hwobj_directories += os.environ.get("CUSTOM_HARDWARE_OBJECTS_PATH", "").split( os.path.pathsep ) except KeyError: pass try: if not os.path.exists(user_file_dir): os.makedirs(user_file_dir) except BaseException: logging.getLogger().exception( "Unable to create user files directory: %s" % user_file_dir ) custom_bricks_directories = [ _directory for _directory in custom_bricks_directories if _directory ] hwobj_directories = [_directory for _directory in hwobj_directories if _directory] main_application = QtImport.QApplication([]) if app_style: main_application.setStyle(app_style) if len(args) >= 1: if len(args) == 1: gui_config_file = os.path.abspath(args[0]) else: parser.error("Too many arguments.") sys.exit(1) if ( len( os.popen( "ps -aef | grep 'python' -i | grep 'hardwareRepository'" +\ " | grep -v 'grep' | awk '{ print $3 }'" ) .read() .strip() .split("\n") ) > 1 ): QtImport.QMessageBox.warning( None, "Warning", "Another instance of MXCuBE is running.\n", QtImport.QMessageBox.Ok, ) #sys.exit(1) # configure modules HardwareRepository.setHardwareRepositoryServer(hwr_path) HardwareRepository.setUserFileDirectory(user_file_dir) if hwobj_directories: HardwareRepository.addHardwareObjectsDirs(hwobj_directories) if custom_bricks_directories: gui.add_custom_bricks_dirs(custom_bricks_directories) log_lockfile = None if len(log_file) > 0: if gui_config_file: gui.set_logging_name(os.path.basename(gui_config_file), log_template) log_lock_filename = os.path.join( tempfile.gettempdir(), ".%s.lock" % os.path.basename(log_file) ) log_ok = True try: log_lockfile = open(log_lock_filename, "w") except BaseException: log_ok = False else: try: os.chmod(log_lock_filename, 0o666) except BaseException: pass try: fcntl.lockf(log_lockfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) except BaseException: log_ok = False try: log_lockfile.close() except BaseException: pass if not log_ok: index = 1 logfile_details = os.path.splitext(log_file) log_file = "" while index < 10: log_file2 = "%s.%d%s" % (logfile_details[0], index, logfile_details[1]) log_lock_filename2 = os.path.join( tempfile.gettempdir(), ".%s.lock" % os.path.basename(log_file2) ) try: log_lockfile = open(log_lock_filename2, "w") except BaseException: pass else: try: os.chmod(log_lock_filename2, 0o666) except BaseException: pass try: fcntl.lockf( log_lockfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB ) except BaseException: pass else: log_ok = True if log_ok: log_file = log_file2 break index += 1 gui.set_log_file(log_file) # log startup details log_level = getattr(logging, opts.logLevel) logging.getLogger().setLevel(log_level) # logging.getLogger().info("\n\n\n\n") logging.getLogger("HWR").info( "==============================================================================" ) logging.getLogger("HWR").info("Starting MXCuBE v%s" % str(__version__)) logging.getLogger("HWR").info("GUI file: %s" % (gui_config_file or "unnamed")) logging.getLogger("HWR").info("Hardware repository: %s" % hwr_path) logging.getLogger("HWR").info("User file directory: %s" % user_file_dir) if len(log_file) > 0: logging.getLogger("HWR").info("Log file: %s" % log_file) logging.getLogger("HWR").info("System info:") logging.getLogger("HWR").info( " - Python %s on %s" % (platform.python_version(), platform.system()) ) logging.getLogger("HWR").info( " - Qt %s - %s %s" % ( "%d.%d.%d" % tuple(QtImport.qt_version_no), QtImport.qt_variant, "%d.%d.%d" % tuple(QtImport.pyqt_version_no), ) ) if QtImport.mpl_imported: logging.getLogger("HWR").info( " - Matplotlib %s" % "%d.%d.%d" % tuple(QtImport.mpl_version_no) ) else: logging.getLogger("HWR").info(" - Matplotlib not available") logging.getLogger("HWR").info( "------------------------------------------------------------------------------" ) QtImport.QApplication.setDesktopSettingsAware(False) main_application.lastWindowClosed.connect(main_application.quit) supervisor = GUISupervisor.GUISupervisor( design_mode=opts.designMode, show_maximized=opts.showMaximized, no_border=opts.noBorder, ) api.init(hwr_path) supervisor.set_user_file_directory(user_file_dir) # post event for GUI creation main_application.postEvent( supervisor, MyCustomEvent(GUISupervisor.LOAD_GUI_EVENT, gui_config_file) ) # redirect errors to logger ErrorHandler.enable_std_err_redirection() gevent_timer = QtImport.QTimer() gevent_timer.timeout.connect(do_gevent) gevent_timer.start(0) palette = main_application.palette() palette.setColor(QtImport.QPalette.ToolTipBase, QtImport.QColor(255, 241, 204)) palette.setColor(QtImport.QPalette.ToolTipText, QtImport.Qt.black) main_application.setPalette(palette) main_application.setOrganizationName("MXCuBE") main_application.setOrganizationDomain("https://github.com/mxcube") main_application.setApplicationName("MXCuBE") # app.setWindowIcon(QtImport.QIcon("images/icon.png")) main_application.exec_() supervisor.finalize() if log_lockfile is not None: filename = log_lockfile.name try: log_lockfile.close() os.unlink(filename) except BaseException: logging.getLogger().exception("Problem removing the log lock file")
import os from PIL import Image import api from config import USER_PREVIEW_PATH from lib import openImage from lib.system import ensure_path def generate(source, size=(48, 48), path=USER_PREVIEW_PATH, force=True): source_image = openImage.open(source) source_image.thumbnail( (min(source_image.size[0], size[0] * 1), min(source_image.size[0], size[0] * 1)), Image.ANTIALIAS) ensure_path(path) for Action in api.ACTIONS.values(): action = Action() filename = os.path.join(path, action.label + '.png') if os.path.exists(filename) and not force: continue action.init() result = action.apply_pil(source_image.copy()) result.thumbnail(size, Image.ANTIALIAS) result.save(filename) if __name__ == '__main__': api.init() generate('/home/stani/sync/python/phatch/icons/lenna/lenna_new.png')
def initData(self): ''' 初始化界面数据 ''' conf = api.init() return conf
def explore(self, num_rooms): map = {} with open("map.json", "r") as f: try: map = json.loads(f.read()) except: pass traversal_path = [] backtracking = Stack() with open("backtracking.txt", "r") as f: backtracking.stack = f.read().splitlines() response = api.init() available_exits, cooldown = response["exits"], response["cooldown"] num_visited_rooms = 0 for room in map.values(): for available_exit in room["available_exits"]: if available_exit in room["visited_exits"]: num_visited_rooms += 1 break # We're only done after we've visited all rooms. while backtracking.size() > 0: print(f"Waiting {cooldown} second(s).") time.sleep(cooldown) ignored_items = [ "tiny treasure", "small treasure", "shiny treasure", "great treasure" ] for item_name in response["items"]: if item_name in ignored_items: continue item_response = api.take_item(item_name) print(f"Waiting {item_response['cooldown']} second(s).") time.sleep(item_response["cooldown"]) if map.get(str(response["room_id"])) is None: map[str(response["room_id"])] = { "visited_exits": [], "exits": {}, "available_exits": response["exits"], "title": response["title"], "description": response["description"], "coordinates": response["coordinates"], } unvisited_exits = [ ex for ex in available_exits if ex not in map[str(response["room_id"])]["visited_exits"] ] if len(unvisited_exits) > 0: # we can keep exploring. direction = random.choice(unvisited_exits) new_response = api.move(direction) map[str(response["room_id"] )]["exits"][direction] = new_response["room_id"] available_exits, cooldown = new_response[ "exits"], new_response["cooldown"] map[str( response["room_id"])]["visited_exits"].append(direction) traversal_path.append(direction) if map.get(str(new_response["room_id"])) is None: map[str(new_response["room_id"])] = { "visited_exits": [], "exits": {}, "available_exits": new_response["exits"], "title": new_response["title"], "description": new_response["description"], "coordinates": new_response["coordinates"], } # Save the opposite direction of the one we just traveled. # If we run into a dead end at some point, we'll need to move backwards. opposite_direction = opposite_direction_mapping[direction] map[str(new_response["room_id"] )]["exits"][opposite_direction] = response["room_id"] map[str(new_response["room_id"])]["visited_exits"].append( opposite_direction) backtracking.push(opposite_direction) response = new_response else: # we've reached a dead end and must move backwards. num_visited_rooms += 1 backtracking_direction = backtracking.pop() new_response = api.move( backtracking_direction, map[str( response["room_id"])]["exits"][backtracking_direction]) available_exits, cooldown = new_response[ "exits"], new_response["cooldown"] traversal_path.append(backtracking_direction) response = new_response with open("map.json", "w") as f: f.write(json.dumps(map)) with open("backtracking.txt", "w") as f: f.writelines(s + "\n" for s in backtracking.stack) print("Success!")
import os from api import init, app auth_key = os.environ.get("BRAVIA_API_KEY") tv_host = os.environ.get("BRAVIA_DEVICE_HOST") tv_psk = os.environ.get("BRAVIA_DEVICE_PASSCODE") init(auth_key, tv_host, tv_psk) if __name__ == "__main__": app.run()
from flask import Flask, Blueprint, render_template, send_from_directory from flask_restplus import Resource, Api from api import blueprint, init from flask_cors import CORS app = Flask(__name__, static_folder='templates/static') cors = CORS(app, resources={r"/api/*": {"origins": "*"}}) @app.route('/') def index(): return render_template("index.html") #return send_from_directory('./build','index.html'); #set url prefix to test app.register_blueprint(blueprint, url_prefix='/api') if __name__ == '__main__': init() app.run(debug=True, threaded=True, port=5000)
def init(): api.init()
import api if __name__ == '__main__': api_ = api.init() me = api_.get_user() pulls = api.get_hacktober_progress(me) progress = len(pulls) print(f'The progress on your hacktober bar is {progress}/4')
#! /usr/bin/env python import logging from config import config import db import haxdb import mods import api logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger("gunicorn.error") haxdb.init(config, db.db(config["DB"], logger), logger) api.init(haxdb) mods.init(haxdb, api) mods.run() app = haxdb.app if __name__ == "__main__": haxdb.run()
def setUp(self): init()
def analysis_categories(username, password): clear() while True: print( 'From the data categories listed below, what category do you want? \n' ) print( '[1] : Analysis Results \n[2] : Patients \n[3] : Both \n[4] : Return to main Menu\n' ) user_choice = int( input( 'Make your choice (1/2/3) and Press the Return Key [Enter] >>') ) if user_choice == 1: file_name = input( 'Give a Name to the File for saving {e.g Analysis} >>') clear() print( "Data can be in any of the following firts 3 Review States\n") print( "[1] : Published\n[2] : Verified\n[3] : To be Verified\n[4] : Return to previous Menu (Categories)\n[5] : Return to main Menu\n" ) data_type = int( input( 'Make your choice (1/2/3) and Press the Return Key [Enter] >>' )) if data_type == 1: review_state = "published" elif data_type == 2: review_state = "verified" elif data_type == 3: review_state = "to_be_verified" elif data_type == 4: analysis_categories(username, password) else: user_options(username, password) json_file = Path( str(json_file_path) + '\\' + file_name + '_' + review_state + ' - ' + strftime("%a %d %b %Y - %H%M") + '.json') api.init(json_file_path, json_file) #user_info() page_size = input('Enter page size {e.g 5000 } :') iterations = int( input('Enter number of cycles or iterations {e.g 5000 }:')) api_url = "http://" + str( your_api ) + "/@@API/read?catalog_name=bika_catalog_analysisrequest_listing&review_state=" + str( review_state) + "&sort_order=descending&page_size=" + str( page_size) + "&page_nr=" page_nr = 5 main(username, password, api_url, page_nr, iterations, json_file, file_name, review_state) # Return user back to options before exit user_options(username, password) elif user_choice == 2: file_name = input('Enter File save name {e.g Patients } :') # If user mistakenly takes an wrong option let thenm return if file_name == 'return': user_options(username, password) review_state = "none" json_file = Path( str(json_file_path) + '\\' + file_name + ' - ' + strftime("%a %d %b %Y - %H%M") + '.json') api.init(json_file_path, json_file) #user_info() page_size = input('Enter page size {e.g 5000 }:') iterations = int( input('Enter number of cycles or iterations {e.g 2 }:')) api_url = "http://" + str( your_api ) + "/@@API/read?catalog_name=bikahealth_catalog_patient_listing&sort_order=descending&page_size=" + str( page_size) + "&page_nr=" page_nr = 0 main(username, password, api_url, page_nr, iterations, json_file, file_name, review_state) # Return user back to options before exit user_options(username, password) elif user_choice == 3: patients_file_name = input( 'Enter Patients File save name {e.g Patients } :') analysis_file_name = input( 'Enter Analysis File save name {e.g Analysis } :') patients_review_state = "none" print( "Data can be in any of the following firts 3 Review States\n") print( "[1] : Published\n[2] : Verified\n[3] : To be Verified\n[4] : Return to previous Menu (Categories)\n[5] : Return to main Menu\n" ) data_type = int( input( 'Make your choice (1/2/3) and Press the Return Key [Enter] >>' )) if data_type == 1: analysis_review_state = "published" elif data_type == 2: analysis_review_state = "verified" elif data_type == 3: analysis_review_state = "to_be_verified" elif data_type == 4: analysis_categories(username, password) else: user_options(username, password) patient_json_file = Path( str(json_file_path) + '\\' + patients_file_name + ' - ' + strftime("%a %d %b %Y - %H%M") + '.json') analysis_json_file = Path( str(json_file_path) + '\\' + analysis_file_name + '_' + analysis_review_state + ' - ' + strftime("%a %d %b %Y - %H%M") + '.json') api.init(json_file_path, patient_json_file) api.init(json_file_path, analysis_json_file) #user_info() patients_page_size = input('Enter Patients page size {e.g 5000 }:') patients_iterations = int( input( 'Enter number of Patient cycles or iterations {e.g 2 }:')) analysis_page_size = input('Enter Analysis page size {e.g 5000 }:') analysis_iterations = int( input( 'Enter number of Analysis cycles or iterations {e.g 2 }:')) analysis_url = "http://" + str( your_api ) + "/@@API/read?catalog_name=bika_catalog_analysisrequest_listing&review_state=" + str( analysis_review_state ) + "&sort_order=descending&page_size=" + str( analysis_page_size) + "&page_nr=" patient_url = "http://" + str( your_api ) + "/@@API/read?catalog_name=bikahealth_catalog_patient_listing&sort_order=descending&page_size=" + str( patients_page_size) + "&page_nr=" page_nr = 0 print('Patient Data Processing') main(username, password, patient_url, page_nr, patients_iterations, patient_json_file, patients_file_name, patients_review_state) print('Analysis Data Processing') main(username, password, analysis_url, page_nr, analysis_iterations, analysis_json_file, analysis_file_name, analysis_review_state) #break # Return user back to options before exit user_options(username, password) elif user_choice == 4: clear() # Return user back to options before exit user_options(username, password) else: Print( "Please select only from the options provide\nTry Again!!! (:") continue
def _send_json(self, json: Dict[str, Any]): data = dumps(json).encode(errors="replace") self.send_response(200) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(data))) self.end_headers() self.wfile.write(data) def do_POST(self): content_length = self.headers.get("Content-Length") if content_length is None: self.send_error(400, "Content-Length expected") return data = self.rfile.read(int(content_length)) try: self._send_json(jsonrpc.Dispatcher.call(data)) except jsonrpc.JSONRPCError as exc: self._send_json(create_json_with_error(exc)) except Exception as exc: _logger.exception(exc) self.send_error(400) if __name__ == "__main__": db = database.Database(config.DB_HOST, config.DB_NAME, config.DB_USER, config.DB_PASSWORD) api.init(db) server_address = (config.SERVER_HOST, config.SERVER_PORT) httpd = http.server.ThreadingHTTPServer(server_address, JSONRPCHandler) httpd.serve_forever()
from threading import Thread from car_controller import CarController import api if __name__ == '__main__': try: controller = CarController() thread: Thread = Thread(target=lambda: api.init(controller)) thread.setDaemon(True) thread.start() controller.follow_waypoints() except InterruptedError as e: # Shutdown on ctrl+c or window closed print('Shutting down as per user request...') exit(0)