astro py:docs

- Index
- Modules

### Navigation

- next »
- « previous |
- Astropy v0.3 »
- Configuration system (`astropy.config`)

# Configuration system (`astropy.config`)

## Introduction

The astropy configuration system is designed to give users control of various parameters used in astropy or affiliated packages without delving into the source code to make those changes.

## Getting Started

The Astropy configuration options are most easily set by modifying the configuration file. It will be automatically generated with all the default values the first time you import Astropy. You can find the exact location by doing:

    from astropy.config import get_config_dir

    print get_config_dir()

And you should see the location of your configuration directory. The standard scheme generally puts your configuration directory in `$HOME/.astropy/config`, but if you’ve set the environment variable `XDG_CONFIG_HOME` and the `$XDG_CONFIG_HOME/astropy` directory exists, it will instead be there.

Once you’ve found the configuration file, open it with your favorite editor. It should have all of the sections you might want, with descriptions and the type of the value that is accepted. Feel free to edit this as you wish, and any of these changes will be reflected when you next start Astropy. Or, if you want to see your changes immediately in your current Astropy session, just do:

    from astropy.config import reload_config

    reload_config()

Note

If for whatever reason your `$HOME/.astropy` directory is not accessible (i.e., you have astropy running somehow as root but you are not the root user), the best solution is to set the `XDG_CONFIG_HOME` and `XDG_CACHE_HOME` environment variables pointing to directories, and create an `astropy` directory inside each of those. Both the configuration and data download systems will then use those directories and never try to access the `$HOME/.astropy` directory.

## Using `config`

### Accessing Values

The value of a configuration object can be accessed by calling the object as a function. For instance to get the default URL for astropy remote data do:

    >>> from astropy.utils.data import DATAURL
    >>> DATAURL()
    'http://data.astropy.org/'

To interactively see more information about a configuration object there are two options:

    >>> DATAURL
    <ConfigurationItem: name='dataurl' value='http://data.astropy.org/' at 0x1032c4290>
    >>> print DATAURL
    ConfigurationItem: dataurl
      cfgtype='string'
      defaultvalue='http://data.astropy.org/'
      description='URL for astropy remote data site.'
      module=astropy.utils.data
      value='http://data.astropy.org/'

### Changing Values at Run-time

The configuration system is most conveniently used by modifying configuration files as described above. Values can also, however, be modified in an active python session using the `set()` method. A run-time `ConfigurationItem` object can be used to make these changes. These items are found in the same module as the configuration section they are in, and usually have the same name as in the configuration files, but in all caps.

For example, if there is a part of your configuration file that looks like:

    [utils.data]

    # URL for astropy remote data site.
    dataurl = http://data.astropy.org/

    # Time to wait for remote data query (in seconds).
    remote_timeout = 3.0

You should be able to modify the values at run-time this way:

    >>> from astropy.utils.data import DATAURL, REMOTE_TIMEOUT
    >>> DATAURL()
    'http://data.astropy.org/'
    >>> DATAURL.set('http://astropydata.mywebsite.com')
    >>> DATAURL()
    'http://astropydata.mywebsite.com'
    >>> REMOTE_TIMEOUT()
    3.0
    >>> REMOTE_TIMEOUT.set(4.5)
    >>> REMOTE_TIMEOUT()
    4.5

Note that this will not permanently change these values in the configuration files - just for the current session. To change the configuration files, after you’ve made your changes, you can do:

    >>> DATAURL.save()
    >>> REMOTE_TIMEOUT.save()

Or to save all modifications to configuration items in `astropy.utils.data` (which includes the changes made above), do:

    >>> from astropy.config import save_config
    >>> save_config('astropy.utils.data')

### Reloading Configuration

Instead of modifying the variables in python, you can also modify the configuration files and then reload them. For example, if you modify the configuration file to say:

    [utils.data]

    # URL for astropy remote data site.
    dataurl = http://myotherdata.mywebsite.com/

    # Time to wait for remote data query (in seconds).
    remote_timeout = 6.3

And then run the following commands:

    >>> DATAURL.reload()
    >>> REMOTE_TIMEOUT.reload()

This should update the variables with the values from the configuration file:

    >>> DATAURL()
    'http://myotherdata.mywebsite.com/'
    >>> REMOTE_TIMEOUT()
    6.3

Or if you want to reload all astropy configuration at once, use the `reload_config` function:

    >>> config.reload_config('astropy')

### Developer Usage

Configuration items should be used wherever an option or setting is needed that is either tied to a system configuration or should persist across sessions of astropy or an affiliated package. Admittedly, this is only a guideline, as the precise cases where a configuration item is preferred over, say, a keyword option for a function is somewhat personal preference. It is the preferred form of persistent configuration, however, and astropy packages must all use it (and it is recommended for affiliated packages).

The Reference guide below describes the full interface for a `ConfigurationItem` - this is a guide for typical developer usage. In almost all cases, a configuration item should be defined and used in the following manner:

    """ This is the docstring at the beginning of a module
    """
    from astropy.config import ConfigurationItem

    SOME_SETTING = ConfigurationItem('some_setting', 1, 'A description.')
    ANOTHER_SETTING = ConfigurationItem('another_set', 'a string val',
                                       'A longer description of what this does.')

    ... implementation ...
    def some_func():
        #to get the value of these options, I might do:
        something = SOME_SETTING() + 2
        return ANOTHER_SETTING() + ' Also, I added text.'

It is highly recommended that any configuration items be placed at the top of a module like this, as they can then be easily found when viewing the source code and the automated tools to generate the default configuration files can also locate these items.

#### Item Types and Validation

If not otherwise specified, a `ConfigurationItem` gets its type from the type of the `defaultvalue` it is given when it is created. The item can only be set to be an object of this type. Hence:

    SOME_SETTING = ConfigurationItem('some_setting', 1, 'A description.')
    SOME_SETTING.set(1.2)

will fail, because `1.2` is a float and `1` is an int.

Note that if you want the configuration item to be limited to a particular set of specific options, you should pass in a list as the `defaultvalue` option. The first entry in the list will be taken as the default, and the list as a whole gives all the valid options. For example:

    AN_OPTION = ConfigurationItem('an_option', ['a', 'b', 'c'], "This option can be 'a', 'b', or 'c'")
    AN_OPTION.set('b')  # succeeds
    AN_OPTION.set('c')  # succeeds
    AN_OPTION.set('d')  # fails!
    AN_OPTION.set(6)  # fails!

Finally, a ConfigurationItem can be explicitly give a type via the `cfgtype` option:

    AN_INT_SETTING = ConfigurationItem('an_int_setting', 1, 'A description.', cfgtype='integer')
    AN_INT_SETTING.set(3)  # works fine
    AN_INT_SETTING.set(4.2)  #fails!

If the default value’s type doesn’t match `cfgtype`, the `ConfigurationItem` cannot be created:

    >>> AN_INT_SETTING = ConfigurationItem('an_int_setting', 4.2, 'A description.', cfgtype='integer')
    VdtTypeError: the value "4.2" is of the wrong type.

hence the default behavior (of automatically determining `cfgtype`) is usually what you want. The main exception is when you want your configuration item to be a list. The default behavior will treat that as a list of options unless you explicitly tell it that the `ConfigurationItem` itself is supposed to be a list:

    >>> A_LIST_SETTING = ConfigurationItem(a_list_setting', [1, 2, 3], 'A description.')
    >>> A_LIST_SETTING()
    1
    >>> A_LIST_SETTING = ConfigurationItem(a_list_setting', [1, 2, 3], 'A description.', cfgtype='list')
    >>> A_LIST_SETTING()
    [1, 2, 3]

Details of all the valid `cfgtype` items can be found in the validation section of the configobj manual. We simply list the valid values here for quick reference:

- ‘integer’
- ‘float’
- ‘boolean’
- ‘string’
- ‘ip_addr’
- ‘list’
- ‘tuple’
- ‘int_list’
- ‘float_list’
- ‘bool_list’
- ‘string_list’
- ‘ip_addr_list’
- ‘mixed_list’
- ‘option’
- ‘pass’

#### Usage Tips

There are a couple important gotchas to remember about using configuration items in your code. First, it is tempting to do something like:

    SOME_SETTING = ConfigurationItem('SOME_SETTING' ,1 ,'A description.')

    def some_func():
        return SOME_SETTING + 2  # WRONG, you wanted SOME_SETTING() + 2

but this is incorrect, because `SOME_SETTING` instead of `SOME_SETTING()` will yield a `ConfigurationItem` object, instead of the value of that item (an integer, in this case).

The second point to keep in mind is that `ConfigurationItem` objects can be changed at runtime by users. So you always read their values instead of just storing their initial value to some other variable (or used as a default for a function). For example, the following will work, but is incorrect usage:

    SOME_SETTING = ConfigurationItem('SOME_SETTING',1,'A description.')

    def some_func(val=SOME_SETTING()):
        return val + 2

This works fine as long as the user doesn’t change its value during runtime, but if they do, the function won’t know about the change:

    >>> some_func()
    3
    >>> SOME_SETTING.set(3)
    >>> some_func()  # naively should return 5, because 3 + 2 = 5
    3

There are two ways around this. The typical/intended way is:

    def some_func():
        """
        The `SOME_SETTING` configuration item influences this output
        """
        return SOME_SETTING() + 2

Or, if the option needs to be available as a function parameter:

    def some_func(val=None):
        """
        If not specified, `val` is set by the `SOME_SETTING` configuration item.
        """
        return (SOME_SETTING() if val is None else val) + 2

## See Also

Logging system (overview of `astropy.logger`)

## Reference/API

### astropy.config Module

This module contains configuration and setup utilities for the `astropy` project. This includes all functionality related to the affiliated package index.

#### Functions

`get_cache_dir`() | Determines the Astropy cache directory name and creates the directory if it doesn’t exist.
`get_config`([packageormod, reload]) | Gets the configuration object or section associated with a particular package or module.
`get_config_dir`([create]) | Determines the Astropy configuration directory name and creates the directory if it doesn’t exist.
`reload_config`([packageormod]) | Reloads configuration settings from a configuration file for the root package of the requested package/module.
`save_config`([packageormod, filename]) | Saves all configuration settings to the configuration file for the root package of the requested package/module.

#### Classes

`ConfigurationItem`(name[, defaultvalue, ...]) | A setting and associated value stored in the astropy configuration files.
`ConfigurationMissingWarning` | A Warning that is issued when the configuration directory cannot be accessed (usually due to a permissions problem).
`InvalidConfigurationItemWarning` | A Warning that is issued when the configuration value specified in the astropy configuration file does not match the type expected for that configuration value.