Source code for fplaneserver.flask.views

from flask import current_app, g, jsonify, request, send_file
from flask_login import login_required

from fplaneserver.flask import app

import datetime as dt
import os


[docs]@app.route('/fplane/', methods=['GET']) @app.route('/fplane/<string:datestr>', methods=['GET']) def get_current_fplane(datestr=None): """Get the fplane file for a given date, or the current one of datestr is not given or is one of latest or current .. :quickref: Fplane; Get an fplane file Retrieve the the fplane file for a given date or the current one. """ g.logger.debug('Connecting to database', extra=g.extra) from awise.common.config.Profile import profiles profiles.create_profile(username=current_app.config['DB_USERNAME'], password=current_app.config['DB_PASSWORD'], dbname=current_app.config['DB_NAME'], project=current_app.config['DB_PROJECT']) from awise.common.database.Database import database if not database.connected(): # pragma: nocover database.connect() from hetwise.Spectrograph import write_fplane, NoIFUError from fplaneserver.lib.helpers import get_bool g.logger.debug('Retrieving fplane file', extra=g.extra) try: spooldir = current_app.config['SPOOL_DIR'] if not os.path.exists(spooldir) or not os.path.isdir(spooldir): raise FileNotFoundError except KeyError: # pragma: nocover return jsonify({'error': 'Spooldir not configured!'}), 500 except FileNotFoundError: return jsonify({'error': 'Spooldir not found!'}), 500 if datestr is None or datestr in ['latest', 'current']: datestr = dt.datetime.utcnow().strftime('%Y%m%d') g.logger.debug('Attempting to retrieve fplane file for %s' % datestr, extra=g.extra) data = request.args fname = 'fplane'+datestr+'.txt' pname = spooldir + '/' + fname if os.path.exists(pname) and get_bool(data, 'cache', False): # The use of cachedd version should be used carefully, # the server doesn't know if the database was changed. g.logger.debug('Sending cached file', extra=g.extra) else: try: g.logger.info('Requesting for %s' % datestr, extra=g.extra) write_fplane(pname, datestr, verbose=False, full_fplane=get_bool(data, 'full_fplane', True), use_ifupos=get_bool(data, 'actual_pos', False)) except IndexError: emsg = 'Failed to find virus instrument in database' g.logger.error(emsg, extra=g.extra) return jsonify(emsg), 400 except NoIFUError as e: g.logger.error('Writing fplane file %s failed with %s' % (fname, str(e)), extra=g.extra) return jsonify(str(e)), 400 except Exception as e: # pragma: nocover g.logger.exception(e, extra=g.extra) g.logger.error('Writing fplane file %s failed with %s' % (fname, str(e)), extra=g.extra) return jsonify(str(e)), 400 return send_file(pname, as_attachment=True)
[docs]@app.route('/fplane', methods=['POST']) @login_required def update_fplane(): """Update the spectrograph configuration .. :quickref: Fplane; Update spectrograph config The datestr is used as the starting date of the new configuration The data section of the request must be a json dictionary. Its structure must be:: {config: config dictionary commit: True | False} The ``config`` is the dictionary retrieved from TCS using:: syscmd -V 'get_hardware_status' The ``commit`` is boolean flag, specifying if the update should be commited to the database The fplaneserver updates the database tables and returns a new fplane file. """ g.logger.debug('Connecting to database', extra=g.extra) from awise.common.config.Profile import profiles profiles.create_profile(username=current_app.config['DB_USERNAME'], password=current_app.config['DB_PASSWORD'], dbname=current_app.config['DB_NAME'], project=current_app.config['DB_PROJECT']) from awise.common.database.Database import database if not database.connected(): # pragma: nocover database.connect() from hetwise.util.MailHandler import send_mail from fplaneserver.lib.helpers import parse_config, create_ifus, get_bool, \ ParserError, NoSpectrographError g.logger.debug('Updating fplane', extra=g.extra) data = request.get_json(force=True, silent=True) if not data: return jsonify({'error': 'No data in request'}), 400 g.logger.debug('Data is: %s' % str(data), extra=g.extra) if 'config' not in data: return jsonify({'error': 'No configuration dict in request'}), 400 config = data['config'] try: if isinstance(config, str): # Try to load from string, this might throw a ValueError import ast config = ast.literal_eval(config) if not isinstance(config, dict): raise ValueError() except ValueError: return jsonify({'error': 'configuration must be a dict or string' ' of a dict!'}), 400 g.logger.debug('Config is: %s' % str(config), extra=g.extra) try: dtime, specconf = parse_config(config) except (ParserError, NoSpectrographError) as e: g.logger.error('Failed to parse configuration!', extra=g.extra) return jsonify(str(e)), 400 except Exception as e: g.logger.exception(e, extra=g.extra) g.logger.error('Failed to parse configuration!', extra=g.extra) return jsonify(str(e)), 400 fromaddr = 'hetdex@mpe.mpg.de' toaddr = 'snigula@mpe.mpg.de' commit = get_bool(data, 'commit', False) try: logstr = create_ifus(specconf, dtime, commit=commit, check_time=get_bool(data, 'check_time', True)) if len(logstr): g.logger.info(logstr, extra=g.extra) try: if commit: send_mail(fromaddr, toaddr, 'Fplane configuration updated', logstr) else: send_mail(fromaddr, toaddr, 'Fplane configuration would be updated', logstr) except ConnectionRefusedError: # pragma: nocover g.logger.error('Failed to send mail!', extra=g.extra) except Exception as e: g.logger.exception(e.args[0], extra=g.extra) g.logger.error('Failed to update configuration!', extra=g.extra) try: send_mail(fromaddr, toaddr, 'Fplane configuration update failed', e.args[1]+e.args[0]) except ConnectionRefusedError: # pragma: nocover g.logger.error('Failed to send mail!', extra=g.extra) return jsonify(str(e)), 400 if len(logstr): if commit: return 'Spectrographs updated and commited', 200 else: return 'Spectrographs updated and NOT commited', 200 else: return 'No spectrographs updated, no changes found', 200