def _insert_file_to_vw(uploaded_file, model_run_uuid, request): """ to be used in a thread to concurrently upload a file and insert the associated metadata in the virtual watershed data management server """ watershed_name = str(request.form['watershed']) model_name = str(request.form['model']) description = str(request.form['description']) model_set = str(request.form['model_set']) if watershed_name in ['Dry Creek', 'Reynolds Creek']: state = 'Idaho' elif watershed_name == 'Valles Caldera': state = 'New Mexico' elif watershed_name == 'Lehman Creek': state = 'Nevada' _local_vw_client = default_vw_client() uploaded_file_name = secure_filename(uploaded_file.filename) uploaded_file_path = os.path.join(app.config['UPLOAD_FOLDER'], uploaded_file_name) uploaded_file.save(uploaded_file_path) _local_vw_client.upload( model_run_uuid, os.path.join(app.config['UPLOAD_FOLDER'], uploaded_file_name)) input_file = uploaded_file_name parent_uuid = model_run_uuid start_datetime = '2010-01-01 00:00:00' end_datetime = '2010-01-01 01:00:00' # create XML FGDC-standard metadata that gets included in VW metadata fgdc_metadata = \ make_fgdc_metadata(input_file, None, model_run_uuid, start_datetime, end_datetime, model=model_name) # create VW metadata watershed_metadata = metadata_from_file(uploaded_file_path, parent_uuid, model_run_uuid, description, watershed_name, state, start_datetime=start_datetime, end_datetime=end_datetime, model_name=model_name, fgdc_metadata=fgdc_metadata, model_set=model_set, taxonomy='geoimage', model_set_taxonomy='grid') _local_vw_client.insert_metadata(watershed_metadata) time.sleep(1)
def _insert_file_to_vw(uploaded_file, model_run_uuid, request): """ to be used in a thread to concurrently upload a file and insert the associated metadata in the virtual watershed data management server """ uploaded_file = request.files['file'] watershed_name = str(request.form['watershed']) model_name = str(request.form['model']) description = str(request.form['description']) model_run_uuid = str(request.form['uuid']) model_set = str(request.form['model_set']) if watershed_name in ['Dry Creek', 'Reynolds Creek']: state = 'Idaho' elif watershed_name == 'Valles Caldera': state = 'New Mexico' elif watershed_name == 'Lehman Creek': state = 'Nevada' _local_vw_client = default_vw_client() uploaded_file_name = secure_filename(uploaded_file.filename) uploaded_file_path = os.path.join(app.config['UPLOAD_FOLDER'], uploaded_file_name) uploaded_file.save(uploaded_file_path) _local_vw_client.upload( model_run_uuid, os.path.join(app.config['UPLOAD_FOLDER'], uploaded_file_name) ) input_file = uploaded_file_name parent_uuid = model_run_uuid start_datetime = '2010-01-01 00:00:00' end_datetime = '2010-01-01 01:00:00' # create XML FGDC-standard metadata that gets included in VW metadata fgdc_metadata = \ make_fgdc_metadata(input_file, None, model_run_uuid, start_datetime, end_datetime, model=model_name) # create VW metadata watershed_metadata = metadata_from_file(uploaded_file_path, parent_uuid, model_run_uuid, description, watershed_name, state, start_datetime=start_datetime, end_datetime=end_datetime, model_name=model_name, fgdc_metadata=fgdc_metadata, model_set=model_set, taxonomy='geoimage', model_set_taxonomy='grid') _local_vw_client.insert_metadata(watershed_metadata) time.sleep(1)
def setUp(self): # netcdfs we'll use for input and check output against nc_isnobal_input = 'test/data/isnobal_input.nc' nc_isnobal_output = 'test/data/isnobal_output.nc' # connect to the virtual watershed self.vwc = default_vw_client() # load NetCDF inputs and outputs from test data self.input_dataset = open_dataset(nc_isnobal_input) self.output_dataset = open_dataset(nc_isnobal_output) # insert NetCDF test input to virtual watershed input_mr_name = 'webapp-testing-input' modelruns = self.vwc.modelrun_search() unittest_uuids = [r['Model Run UUID'] for r in modelruns.records if r['Model Run Name'] == 'webapp-testing-input'] for u in unittest_uuids: s = self.vwc.delete_modelrun(u) print "pre-test cleanup success on %s: %s" % (u, str(s)) self.model_run_uuid = \ self.vwc.initialize_modelrun( model_run_name=input_mr_name, description='test in vwplatform', researcher_name='Matt Turner', keywords='test,isnobal,webapp') self.vwc.upload(self.model_run_uuid, nc_isnobal_input) self.start_datetime = '2010-10-01 00:00:00' self.end_datetime = '2010-10-01 16:00:00' md = metadata_from_file(nc_isnobal_input, self.model_run_uuid, self.model_run_uuid, 'test input for isnobal run', 'Dry Creek', 'Idaho', model_name='isnobal', start_datetime=self.start_datetime, end_datetime=self.end_datetime, model_set='inputs', taxonomy='geoimage', model_set_taxonomy='grid') # import ipdb; ipdb.set_trace() self.input_uuid = self.vwc.insert_metadata(md).text time.sleep(1)
def list_mr_files(model_run_uuid): # create a local VWClient; avoid any timeout VW_CLIENT = default_vw_client() if request.method == 'GET': records = VW_CLIENT.dataset_search( model_run_uuid=model_run_uuid ).records files = [ { 'name': rec['name'], 'url': [u for u in rec['downloads'][0].values() if 'original' in u][0], 'last_modified': rec['metadata-modified']['all'], 'uuid': rec['uuid'] } for rec in records ] return jsonify({'files': files}) else: model_run_uuid = str(request.form['modelrunUUID']) uploaded_file = request.files['uploadedFile'] if uploaded_file: _insert_file_to_vw(uploaded_file, model_run_uuid, request) else: return jsonify(400, {'status': 'fail', 'reason': 'no file given'}) return jsonify({ 'status': 'success', 'file_name': uploaded_file.filename })
def list_mr_files(model_run_uuid): # create a local VWClient; avoid any timeout VW_CLIENT = default_vw_client() if request.method == 'GET': records = VW_CLIENT.dataset_search( model_run_uuid=model_run_uuid).records files = [{ 'name': rec['name'], 'url': [u for u in rec['downloads'][0].values() if 'original' in u][0], 'last_modified': rec['metadata-modified']['all'], 'uuid': rec['uuid'] } for rec in records] return jsonify({'files': files}) else: model_run_uuid = str(request.form['modelrunUUID']) uploaded_file = request.files['uploadedFile'] if uploaded_file: _insert_file_to_vw(uploaded_file, model_run_uuid, request) else: return jsonify(400, {'status': 'fail', 'reason': 'no file given'}) return jsonify({ 'status': 'success', 'file_name': uploaded_file.filename })
def vw_isnobal(input_dataset_uuid): """ Run isnobal with data from the virtual watershed """ vwc = default_vw_client() input_records = vwc.dataset_search(uuid=input_dataset_uuid).records assert len(input_records) == 1, \ "Current implementation of vw_isnobal requires the user\n" + \ "to use as input a model_run_uuid pointing to a model run\n" + \ "with a single record that is an input. Found %s records" \ % len(input_records) input_record = input_records[0] try: dl_url = input_record['downloads'][0]['nc'] except KeyError as e: e.args = ("downloads or nc not found in isnobal input record") raise if not os.path.exists('tmp/'): os.mkdir('tmp/') model_run_uuid = input_record['model_run_uuid'] writedir = 'tmp/' + model_run_uuid if os.path.exists(writedir): shutil.rmtree(writedir) os.mkdir(writedir) input_file = os.path.join(writedir, 'in.nc') vwc.download(dl_url, input_file) input_nc = netCDF4.Dataset(input_file) output_file = os.path.join(writedir, 'out.nc') isnobal(input_nc, output_file) vwc.upload(model_run_uuid, output_file) parent_model_run_uuid = input_record['parent_model_run_uuid'] now_str = datetime.now().isoformat() watershed = input_record['categories'][0]['location'] state = input_record['categories'][0]['state'] md = metadata_from_file(output_file, parent_model_run_uuid, model_run_uuid, 'output netcdf from isnobal run ' + now_str, watershed, state, model_name='isnobal', model_set='outputs', taxonomy='geoimage', model_set_taxonomy='grid') dataset_uuid = vwc.insert_metadata(md).text shutil.rmtree(writedir) return (dataset_uuid, model_run_uuid)
def setUp(self): """ Clean up pre-existing unittest modelruns and generate new test mr's """ # create a model run and push some meta+data to VW then query files self.vwc = default_vw_client() modelruns = self.vwc.modelrun_search() unittest_uuids = [ r['Model Run UUID'] for r in modelruns.records if 'unittest' in r['Model Run Name'] ] for u in unittest_uuids: s = self.vwc.delete_modelrun(u) print "pre-test cleanup success on %s: %s" % (u, str(s)) self.config = _get_config('vwpy/vwpy/test/test.conf') self.kwargs = { 'keywords': 'Snow,iSNOBAL,wind', 'researcher_name': self.config['Researcher']['researcher_name'], 'description': 'unittest', 'model_run_name': 'unittest' + str(uuid4()) } self.mr_uuid = self.vwc.initialize_modelrun(**self.kwargs) # for testing purposes set parent to itself to make it the root node self.parent_uuid = self.mr_uuid # test_filename = 'vwpy/vwpy/test/data/flat_sample.nc' test_filename = 'test/data/test1.txt' start_datetime = '2010-10-01 00:00:00' end_datetime = '2010-10-01 01:00:00' self.vwc.upload(self.mr_uuid, test_filename) fgdc_md = make_fgdc_metadata(test_filename, self.config, self.mr_uuid, start_datetime, end_datetime) wmd_from_file = metadata_from_file( test_filename, self.parent_uuid, self.mr_uuid, 'testing file list; file #1 starting at 12am', 'Dry Creek', 'Idaho', start_datetime=start_datetime, end_datetime=end_datetime, fgdc_metadata=fgdc_md, model_set_type='grid', taxonomy='geoimage', model_set_taxonomy='grid', model_name='isnobal', epsg=4326, orig_epsg=26911) insert_res = self.vwc.insert_metadata(wmd_from_file) # give a second for the upload and insert to finish successfully time.sleep(1) # now insert the second file so we have at least two to test our lists # test_filename = 'vwpy/vwpy/test/data/ref_in.nc' test_filename = 'test/data/test2.asc' start_datetime = '2010-10-01 09:00:00' end_datetime = '2010-10-01 10:00:00' self.vwc.upload(self.mr_uuid, test_filename) fgdc_md = make_fgdc_metadata(test_filename, self.config, self.mr_uuid, start_datetime, end_datetime) wmd_from_file = metadata_from_file( test_filename, self.parent_uuid, self.mr_uuid, 'testing file list; file #2 starting at 9am', 'Dry Creek', 'Idaho', start_datetime=start_datetime, end_datetime=end_datetime, fgdc_metadata=fgdc_md, model_set_type='grid', model_set='inputs', taxonomy='geoimage', model_set_taxonomy='grid', model_name='isnobal', epsg=4326, orig_epsg=26911) insert_res = self.vwc.insert_metadata(wmd_from_file) time.sleep(1) # initialize a Flask/Werkzeug test client for making API calls self.client = app.test_client()
def resources(): """" Initialize a resource container for either uploading files or an external resource (FTP, TRHEDDS, eventually more) """ # TODO Display current resources that have been shared by the current user # Display form for sharing a data resource form = ResourceForm() if form.validate_on_submit(): _local_vw_client = default_vw_client() # initialize: post to virtual watershed common_kwargs = { 'description': form.description.data, 'keywords': form.keywords.data } extra_vw_kwargs = { 'researcher_name': current_user.name, 'model_run_name': form.title.data, } vw_kwargs = {} vw_kwargs.update(common_kwargs) vw_kwargs.update(extra_vw_kwargs) # in VW language, the database focuses on 'model_runs'. # however, modelers don't just want to share data associated with a # particular model import uuid UUID = str(uuid.uuid4()) try: result_of_vwpost = _local_vw_client.initialize_modelrun( **vw_kwargs) UUID = result_of_vwpost except: pass # get UUID and add full record to the 'resources' table in DB along with # user ID url = (form.url.data or _local_vw_client.dataset_search_url + '&model_run_uuid=' + UUID) resource = Resource(user_id=current_user.id, title=form.title.data, uuid=UUID, url=url, **common_kwargs) db.session.add(resource) print resource try: db.session.commit() flash('Your submission has been accepted') form.reset() except: db.session.rollback() flash('Your submission has been rejected') # When it's been submitted, give URL to view on the Virtual Watershed and # add it to the list above (i.e. reload the page) return render_template('share/index.html', form=form)
import time from flask import render_template, flash, request from flask_login import login_required, current_user from flask import current_app as app from werkzeug import secure_filename from . import share from .forms import ResourceForm from .. import db from ..models import Resource from vwpy import default_vw_client from vwpy import make_fgdc_metadata, metadata_from_file VW_CLIENT = default_vw_client() def allowed_file(filename): return ('.' in filename and filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']) @share.route('/', methods=['GET', 'POST']) @login_required def resources(): """" Initialize a resource container for either uploading files or an external resource (FTP, TRHEDDS, eventually more) """ # TODO Display current resources that have been shared by the current user
def makegrid(): if request.method == 'POST': try: formdata = request.form start_hour = formdata['makegrid-start-hour'] end_hour = formdata['makegrid-end-hour'] st_int = int(start_hour) if st_int <= 9: start_hour = '0' + start_hour end_int = int(start_hour) if end_int <= 9: end_hour = '0' + end_hour start_datetime = \ formdata['makegrid-start-date'] + ' ' + \ ':'.join([start_hour, '00', '00']) end_datetime = \ formdata['makegrid-end-date'] + ' ' + \ ':'.join([end_hour, '00', '00']) # use formdata to fill out submit_job kwargs = { ISUGT_VARNAME_LOOKUP[k]: 'true' for k in formdata.getlist('variables') } end_2_end(start_datetime, end_datetime, **kwargs) out_path = 'isugt_output_jdraw_' + \ datetime.datetime.now().isoformat() + '.zip' os.rename('Output.zip', out_path) if not os.path.exists('.tmp'): os.mkdir('.tmp') nc_out_path = os.path.join('.tmp', str(uuid4()) + '.nc') create_isnobal_dataset(out_path, nc_out=nc_out_path) # init new model run with extra info from form vwc = default_vw_client() print "wrote unzipped tifs to " + out_path print "wrote netcdf to " + nc_out_path print "getting a uuid for model run named " + \ formdata['model_run_name'] + ", user " + current_user.name uu = vwc.initialize_modelrun( model_run_name=formdata['model_run_name'], description=formdata['description'], researcher_name=current_user.name, keywords=formdata['keywords']) print "got a uuid for this model run, it's " + uu res = vwc.upload(uu, nc_out_path) print "uploaded successfully" fgdc_metadata = make_fgdc_metadata(nc_out_path, None, uu, start_datetime, end_datetime, model='isnobal') watershed_md = metadata_from_file(nc_out_path, uu, uu, formdata['description'], 'Reynolds Creek', 'Idaho', model_name='isnobal', fgdc_metadata=fgdc_metadata, model_set='inputs', taxonomy='geoimage', model_set_taxonomy='grid') print "generated metadata" res = vwc.insert_metadata(watershed_md) print "inserted metadata" # update web app resource database url = \ vwc.dataset_search_url + '&model_run_uuid=' + uu new_resource = Resource(user_id=current_user.id, title=formdata['description'], uuid=uu, url=url, description=formdata['description'], keywords=formdata['keywords']) db.session.add(new_resource) try: db.session.commit() return render_template('modeling/makegrid.html', model_run_uuid=uu) except: return render_template( '500.html', message="Could not save new resource to local" " database") except Exception as e: return render_template( '500.html', message="Error running gridding service! System message: \n" + e.message) return render_template('modeling/makegrid.html')
def setUp(self): """ Clean up pre-existing unittest modelruns and generate new test mr's """ # create a model run and push some meta+data to VW then query files self.vwc = default_vw_client() modelruns = self.vwc.modelrun_search() unittest_uuids = [r['Model Run UUID'] for r in modelruns.records if 'unittest' in r['Model Run Name']] for u in unittest_uuids: s = self.vwc.delete_modelrun(u) print "pre-test cleanup success on %s: %s" % (u, str(s)) self.config = _get_config('vwpy/vwpy/test/test.conf') self.kwargs = { 'keywords': 'Snow,iSNOBAL,wind', 'researcher_name': self.config['Researcher']['researcher_name'], 'description': 'unittest', 'model_run_name': 'unittest' + str(uuid4()) } self.mr_uuid = self.vwc.initialize_modelrun(**self.kwargs) # for testing purposes set parent to itself to make it the root node self.parent_uuid = self.mr_uuid # test_filename = 'vwpy/vwpy/test/data/flat_sample.nc' test_filename = 'test/data/test1.txt' start_datetime = '2010-10-01 00:00:00' end_datetime = '2010-10-01 01:00:00' self.vwc.upload(self.mr_uuid, test_filename) fgdc_md = make_fgdc_metadata( test_filename, self.config, self.mr_uuid, start_datetime, end_datetime ) wmd_from_file = metadata_from_file( test_filename, self.parent_uuid, self.mr_uuid, 'testing file list; file #1 starting at 12am', 'Dry Creek', 'Idaho', start_datetime=start_datetime, end_datetime=end_datetime, fgdc_metadata=fgdc_md, model_set_type='grid', taxonomy='geoimage', model_set_taxonomy='grid', model_name='isnobal', epsg=4326, orig_epsg=26911 ) insert_res = self.vwc.insert_metadata(wmd_from_file) # give a second for the upload and insert to finish successfully time.sleep(1) # now insert the second file so we have at least two to test our lists # test_filename = 'vwpy/vwpy/test/data/ref_in.nc' test_filename = 'test/data/test2.asc' start_datetime = '2010-10-01 09:00:00' end_datetime = '2010-10-01 10:00:00' self.vwc.upload(self.mr_uuid, test_filename) fgdc_md = make_fgdc_metadata( test_filename, self.config, self.mr_uuid, start_datetime, end_datetime ) wmd_from_file = metadata_from_file( test_filename, self.parent_uuid, self.mr_uuid, 'testing file list; file #2 starting at 9am', 'Dry Creek', 'Idaho', start_datetime=start_datetime, end_datetime=end_datetime, fgdc_metadata=fgdc_md, model_set_type='grid', model_set='inputs', taxonomy='geoimage', model_set_taxonomy='grid', model_name='isnobal', epsg=4326, orig_epsg=26911 ) insert_res = self.vwc.insert_metadata(wmd_from_file) time.sleep(1) # initialize a Flask/Werkzeug test client for making API calls self.client = app.test_client()
def makegrid(): if request.method == 'POST': try: formdata = request.form start_hour = formdata['makegrid-start-hour'] end_hour = formdata['makegrid-end-hour'] st_int = int(start_hour) if st_int <= 9: start_hour = '0' + start_hour end_int = int(start_hour) if end_int <= 9: end_hour = '0' + end_hour start_datetime = \ formdata['makegrid-start-date'] + ' ' + \ ':'.join([start_hour, '00', '00']) end_datetime = \ formdata['makegrid-end-date'] + ' ' + \ ':'.join([end_hour, '00', '00']) # use formdata to fill out submit_job kwargs = { ISUGT_VARNAME_LOOKUP[k]: 'true' for k in formdata.getlist('variables') } end_2_end(start_datetime, end_datetime, **kwargs) out_path = 'isugt_output_jdraw_' + \ datetime.datetime.now().isoformat() + '.zip' os.rename('Output.zip', out_path) if not os.path.exists('.tmp'): os.mkdir('.tmp') nc_out_path = os.path.join('.tmp', str(uuid4()) + '.nc') create_isnobal_dataset(out_path, nc_out=nc_out_path) # init new model run with extra info from form vwc = default_vw_client() print "wrote unzipped tifs to " + out_path print "wrote netcdf to " + nc_out_path print "getting a uuid for model run named " + \ formdata['model_run_name'] + ", user " + current_user.name uu = vwc.initialize_modelrun( model_run_name=formdata['model_run_name'], description=formdata['description'], researcher_name=current_user.name, keywords=formdata['keywords'] ) print "got a uuid for this model run, it's " + uu res = vwc.upload(uu, nc_out_path) print "uploaded successfully" fgdc_metadata = make_fgdc_metadata( nc_out_path, None, uu, start_datetime, end_datetime, model='isnobal') watershed_md = metadata_from_file( nc_out_path, uu, uu, formdata['description'], 'Reynolds Creek', 'Idaho', model_name='isnobal', fgdc_metadata=fgdc_metadata, model_set='inputs', taxonomy='geoimage', model_set_taxonomy='grid' ) print "generated metadata" res = vwc.insert_metadata(watershed_md) print "inserted metadata" # update web app resource database url = \ vwc.dataset_search_url + '&model_run_uuid=' + uu new_resource = Resource(user_id=current_user.id, title=formdata['description'], uuid=uu, url=url, description=formdata['description'], keywords=formdata['keywords']) db.session.add(new_resource) try: db.session.commit() return render_template('modeling/makegrid.html', model_run_uuid=uu) except: return render_template( '500.html', message="Could not save new resource to local" " database" ) except Exception as e: return render_template( '500.html', message="Error running gridding service! System message: \n" + e.message ) return render_template('modeling/makegrid.html')
from flask import request, render_template, jsonify from flask import current_app as app from flask_login import login_required, current_user from uuid import uuid4 from . import modeling from .. import db from .model_wrappers import vw_isnobal from .gridtoolwrap import end_2_end from ..main.views import _make_panel from ..models import Resource from vwpy import (default_vw_client, make_fgdc_metadata, metadata_from_file) VW_CLIENT = default_vw_client() def id_generator(size=6, chars=string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS'] @modeling.route('/', methods=['GET']) def modeling_index(): return render_template('modeling/index.html')
def resources(): """" Initialize a resource container for either uploading files or an external resource (FTP, TRHEDDS, eventually more) """ # TODO Display current resources that have been shared by the current user # Display form for sharing a data resource form = ResourceForm() if form.validate_on_submit(): _local_vw_client = default_vw_client() # initialize: post to virtual watershed common_kwargs = { 'description': form.description.data, 'keywords': form.keywords.data } extra_vw_kwargs = { 'researcher_name': current_user.name, 'model_run_name': form.title.data, } vw_kwargs = {} vw_kwargs.update(common_kwargs) vw_kwargs.update(extra_vw_kwargs) # in VW language, the database focuses on 'model_runs'. # however, modelers don't just want to share data associated with a # particular model import uuid UUID = str(uuid.uuid4()) try: result_of_vwpost = _local_vw_client.initialize_modelrun(**vw_kwargs) UUID = result_of_vwpost except: pass # get UUID and add full record to the 'resources' table in DB along with # user ID url = (form.url.data or _local_vw_client.dataset_search_url + '&model_run_uuid=' + UUID) resource = Resource(user_id=current_user.id, title=form.title.data, uuid=UUID, url=url, **common_kwargs) db.session.add(resource) print resource try: db.session.commit() flash('Your submission has been accepted') form.reset() except: db.session.rollback() flash('Your submission has been rejected') # When it's been submitted, give URL to view on the Virtual Watershed and # add it to the list above (i.e. reload the page) return render_template('share/index.html', form=form)
from flask import Flask from flask_moment import Moment from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager from config import config from vwpy import default_vw_client moment = Moment() db = SQLAlchemy() login_manager = LoginManager() login_manager.session_protection = 'strong' login_manager.login_view = 'auth.login' vw_client = default_vw_client() def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) config[config_name].init_app(app) moment.init_app(app) db.init_app(app) login_manager.init_app(app) from .main import main as main_blueprint app.register_blueprint(main_blueprint) from .auth import auth as auth_blueprint