コード例 #1
0
ファイル: cli.py プロジェクト: lspitler/panoptes-utils
def config_getter(context, key, parse=True, default=None):
    """Get an item from the config server by key name, using dotted notation (e.g. 'location.elevation')

    If no key is given, returns the entire config.
    """
    host = context.obj.get('host')
    port = context.obj.get('port')
    try:
        # The nargs=-1 makes this a tuple so we get first entry.
        key = key[0]
    except IndexError:
        key = None
    logger.debug(f'Getting config  key={key!r}')
    try:
        config_entry = get_config(key=key,
                                  host=host,
                                  port=port,
                                  parse=parse,
                                  default=default)
    except Exception as e:
        logger.error(f'Error while trying to get config: {e!r}')
        click.secho(f'Error while trying to get config: {e!r}', fg='red')
    else:
        logger.debug(f'Config server response:  config_entry={config_entry!r}')
        click.echo(config_entry)
コード例 #2
0
ファイル: error.py プロジェクト: lspitler/panoptes-utils
    def __init__(self, msg=None, exit=False):
        self.msg = msg

        if self.msg:
            logger.error(str(self))

        if exit:
            self.exit_program(self.msg)
コード例 #3
0
def write_fits(data, header, filename, exposure_event=None, **kwargs):
    """Write FITS file to requested location.

    >>> from panoptes.utils.images import fits as fits_utils
    >>> data = np.random.normal(size=100)
    >>> header = { 'FILE': 'delete_me', 'TEST': True }
    >>> filename = str(getfixture('tmpdir').join('temp.fits'))
    >>> fits_utils.write_fits(data, header, filename)
    >>> assert os.path.exists(filename)

    >>> fits_utils.getval(filename, 'FILE')
    'delete_me'
    >>> data2 = fits_utils.getdata(filename)
    >>> assert np.array_equal(data, data2)

    Args:
        data (array_like): The data to be written.
        header (dict): Dictionary of items to be saved in header.
        filename (str): Path to filename for output.
        exposure_event (None|`threading.Event`, optional): A `threading.Event` that
            can be triggered when the image is written.
        kwargs (dict): Options that are passed to the `astropy.io.fits.PrimaryHDU.writeto`
            method.
    """
    if not isinstance(header, fits.Header):
        header = fits.Header(header)

    hdu = fits.PrimaryHDU(data, header=header)

    # Create directories if required.
    if os.path.dirname(filename):
        os.makedirs(os.path.dirname(filename), mode=0o775, exist_ok=True)

    try:
        hdu.writeto(filename, **kwargs)
    except OSError as err:
        logger.error(f'Error writing image to {filename}: {err!r}')
    else:
        logger.debug(f'Image written to {filename}')
    finally:
        if exposure_event:
            exposure_event.set()
コード例 #4
0
ファイル: cli.py プロジェクト: lspitler/panoptes-utils
def run(context,
        config_file=None,
        save_local=True,
        load_local=False,
        heartbeat=True):
    """Runs the config server with command line options.

    This function is installed as an entry_point for the module, accessible
     at `panoptes-config-server`.
    """
    host = context.obj.get('host')
    port = context.obj.get('port')
    server_process = server.config_server(config_file,
                                          host=host,
                                          port=port,
                                          load_local=load_local,
                                          save_local=save_local,
                                          auto_start=False)

    try:
        print(f'Starting config server. Ctrl-c to stop')
        server_process.start()
        print(
            f'Config server started on  server_process.pid={server_process.pid!r}. '
            f'Set "config_server.running=False" or Ctrl-c to stop')

        # Loop until config told to stop.
        while server_is_running():
            time.sleep(heartbeat)

        server_process.terminate()
        server_process.join(30)
    except KeyboardInterrupt:
        logger.info(
            f'Config server interrupted, shutting down {server_process.pid}')
        server_process.terminate()
    except Exception as e:  # pragma: no cover
        logger.error(f'Unable to start config server {e!r}')
コード例 #5
0
def get_config_entry():
    """Get config entries from server.

    Endpoint that responds to GET and POST requests and returns
    configuration item corresponding to provided key or entire
    configuration. The key entries should be specified in dot-notation,
    with the names corresponding to the entries stored in the configuration
    file. See the `scalpl <https://pypi.org/project/scalpl/>`_ documentation
    for details on the dot-notation.

    The endpoint should receive a JSON document with a single key named ``"key"``
    and a value that corresponds to the desired key within the configuration.

    For example, take the following configuration:

    .. code:: javascript

        {
            'location': {
                'elevation': 3400.0,
                'latitude': 19.55,
                'longitude': 155.12,
            }
        }

    To get the corresponding value for the elevation, pass a JSON document similar to:

    .. code:: javascript

        '{"key": "location.elevation"}'

    Returns:
        str: The json string for the requested object if object is found in config.
        Otherwise a json string with ``status`` and ``msg`` keys will be returned.
    """
    params = dict()
    if request.method == 'GET':
        params = request.args
    elif request.method == 'POST':
        params = request.get_json()

    verbose = params.get('verbose', True)
    log_level = 'DEBUG' if verbose else 'TRACE'

    # If requesting specific key
    logger.log(log_level, f'Received  params={params!r}')

    if request.is_json:
        try:
            key = params['key']
            logger.log(log_level, f'Request contains  key={key!r}')
        except KeyError:
            return jsonify({
                'success': False,
                'msg': "No valid key found. Need json request: {'key': <config_entry>}"
            })

        if key is None:
            # Return all
            logger.log(log_level, 'No valid key given, returning entire config')
            show_config = app.config['POCS']
        else:
            try:
                logger.log(log_level, f'Looking for  key={key!r} in config')
                show_config = app.config['POCS_cut'].get(key, None)
            except Exception as e:
                logger.error(f'Error while getting config item: {e!r}')
                show_config = None
    else:
        # Return entire config
        logger.log(log_level, 'No valid key given, returning entire config')
        show_config = app.config['POCS']

    logger.log(log_level, f'Returning  show_config={show_config!r}')
    logger.log(log_level, f'Returning {show_config!r}')
    return jsonify(show_config)