# PSEUDOCODE The purpose of this document is to sketch one possible way to structure the GCBM endpoints. The general concept is to maintain the configuration of a GCBM simulation in memory and synchronise any user changes to files saved on the server. It is incomplete and not optimised. There may be simpler ways to achieve the desired behaviour. I propose we separate the Flask endpoints from the pre-processing logic. People more fluent in Python can show me how this is best achieved, please. Please take the good ideas and discard the bad ones. Make it your own. ## gcbm.py ```python Class GCBMSimulation: def __init__: create_simulation_folder() create_file_index() def create_file_index(self): # create a global index self.files = dict() # create sub-indexes of different types self.config = list() self.parameters = list() # this is the input_db self.classifiers = list() self.disturbances = list() self.covariates = list() #this is e.g. temperature # store config in key-value pair for config_file in list_files('../templates/config/'): with read_json(config_file) as config: self.files[config_file] = config self.config.append(config_file) sync_config(config_file) def add_file(self, file): if(is_disturbance(file)): self.disturbances.append(file) self.update_disturbance_config() if(is_classifer(file)): self.classifiers.append(file) self.update_classifier_config() ... save(file) def sync_config(self, file, config_file): if(is.null(config_file)) config_file = change_extension(file, '.json') # check for any user changes with read_json(config_file) as saved_config if(self.files[file] != saved_config): write(self.files[file], config_file) def update_disturbance_config(self): for file in self.disturbances: config_file = change_extension(file, '.json') # use templates for new inputs if(!exists(self.config(config_file))): generate_disturbance_config(file) sync_config(file, config_file) # synchronise parent config (ugly - improvements welcome) self.files['modules_cbm.json']['Modules']['CBMDisturbanceListener']['settings']['vars'] = self.disturbances sync_config('modules_cbm.json') ... def generate_disturbance_config(self, file): with read_json('templates/disturbances/example.json') as config: with raster.open(file) as disturbance: # extract meta data config['resolution'] = disturbance.resolution ... # set flags for fields requiring user input config['has_year'] = False config['has_type'] = False ... config_file = change_extension(file, '.json') # append to global indexes self.files[file] = config self.config.append(config_file) # save output sync_config(file, config_file) # example payload: # { # "year": 2011, # "disturbance_type": "Wildfire", # "transition": 1 # } def set_disturbance_attributes(self, file, attributes): config = self.files[file] config["attributes"] = attributes # set flags for user input if(is_year(config['attributes']['year'])): config['has_year'] = True ... # cascade changes to saved files self.files[file] = config self.update_disturbance_config() def check_disturbances(self): missing_year = list() missing_type = list() for disturbance in self.disturbances: if(!disturbance.has_year) missing_year.append(disturbance) if(!disturbance.has_type) missing_type.append(disturbance) ... return [missing_year, missing_type] ``` ## app.py ```python from gcbm import GCBMSimulation # POST @new def new(title): sim = GCBMSimulation() save(sim, title) # GET @load def load(title) sim = open(title) # POST @upload def upload(): for file in request.files: # need some way to access upload flags if(request.file.flag == '-d') file.is_disturbance = True ... sim.add_file(file) # GET @files def get_files(): return sim.files.keys # GET @files/config def show_config(file): return sim.files[file] # POST @file/config def edit_config(file, config) sim.files[file] = config sim.sync_config(file) # GET @disturbances def get_disturbances(): return sim.disturbances # POST @disturbances def set_disturbances(file): sim.disturbances.append(file) # GET @disturbances/config def show_disturbance_config(disturbance): return sim.files[disturbance] # POST @disturbances/config def edit_disturbance_config(disturbance, attributes): sim.set_disturbance_attributes(disturbance, attributes) # GET @disturbances/check def check_disturbance_config(): return sim.check_disturbances() ```