Commit e8297c5b authored by Dominik Rimpf's avatar Dominik Rimpf

ADD: Support for config from fil, env-vars or cli-parameters.

Extended ArgumentParser class.
Added example config-file.
Updated DOC.
parent 2a49ab33
Pipeline #114398 passed with stage
in 23 seconds
......@@ -9,20 +9,33 @@
## Usage
### Init
Initialisation works as followed, for configuration an `APIEndpoint`-Instance has to be passed to the `API-Session` call.
```python
>>> import netdb_client
>>> import netdb_client.util
>>> token = <your token>
>>> api = netdb_client.APISession(base_url=netdb_client.util.default_server, version=netdb_client.util.default_api_version, token=token)
>>> endpoint = netdb_client.APIEndpoint(
base_url='www-net-devel.scc.kit.edu',
version='3.0',
token='<token>'
)
>>> api = netdb_client.APISession(endpoint)
```
Helper function for argument parsing in scripts (implemented with `argparse`):
`util` provides an `ArgumentParser`-Class which can be used for configuration and config loading. This class has been
implemented transparent, so you can extend the arguments or functionality as needed by your application or script.
The functionality has been extended, so the `parse_args()` method checks for environment variables and an config file in "ini"-format.
Variable precendence is as followed (from greatest to least, means the first source overwrites all other):
1. cli-arguments
2. environment variables
3. config-file (default path: `~/.config/netdb_client.ini`)
```python
>>> import netdb_client.util
>>> parser = netdb_client.util.ArgumentParser(description='Beispielbeschreibung für Skript.')
>>> args = parser.parse_args()
>>> endpoint = netdb_client.APIEndpoint(**vars(args))
>>> api = netdb_client.APISession(endpoint)
```
## Examples
......
[DEFAULT]
endpoint = www-net-devel.scc.kit.edu
[www-net-devel.scc.kit.edu]
version = 3.0
token = <token>
[www-net-test.scc.kit.edu]
version = 3.0
token = <token>
[www-net.scc.kit.edu]
version = 3.0
token = <token>
\ No newline at end of file
"""netdb_client helper functions for configuration and response-parsing"""
import argparse
default_server = 'www-net-devel.scc.kit.edu'
default_api_version = '3.0'
import configparser
import os
class ArgumentParser(argparse.ArgumentParser):
"""Argument parser with default common arguments for NetDB-api cli
tools. Includes default values."""
def __init__(self, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
**kwargs):
super(ArgumentParser, self).__init__(formatter_class=formatter_class,
**kwargs)
def __init__(
self,
epilog="The Variables BASE_URL, VERSION and TOKEN can be loaded from config file,"
"environment or from command line arguments.\n"
"Variable precendence is as followed (from greatest to least,"
"means the first listed variable overwrites all other variables):\n"
" 1. cli-arguments\n"
" 2. environment variables\n"
" 3. config-file\n",
formatter_class=argparse.RawTextHelpFormatter,
**kwargs
):
super().__init__(formatter_class=formatter_class,
epilog=epilog, **kwargs)
self.add_argument('--config', '-c',
default=os.path.expanduser('~/.config/netdb_client.ini'),
help='config file path (default: %(default)s)')
self.add_argument('--base-url', '-b',
help='webapi server.\n'
'Environment: "NETDB_BASE_URL"\n'
'Config: [DEFAULT]: endpoint')
self.add_argument('--version',
help='webapi version.\n'
'Environment: "NETDB_VERSION"\n'
'Config: [$endpoint]: version')
self.add_argument('--token', '-t',
help='user API token', required=True)
self.add_argument('--server', '-s', default=default_server,
help='webapi server')
self.add_argument('--api-version', default=default_api_version,
help='webapi version')
help='user API token.\n'
'Environment: "NETDB_TOKEN"\n'
'Config: [$endpoint]: token')
def parse_args(self, args=None, namespace=None):
args = super(ArgumentParser, self).parse_args(args, namespace)
args = super().parse_args(args, namespace)
config = configparser.ConfigParser()
if os.path.isfile(os.path.expanduser(args.config)):
config.read(os.path.expanduser(args.config))
def load_configoption(option):
if getattr(args, option) is None:
setattr(args, option, os.getenv(f'NETDB_{option.upper()}', None))
if getattr(args, option) is None:
if option == 'base_url':
setattr(args, option, config.get('DEFAULT', 'endpoint', fallback=None))
else:
setattr(args, option, config.get(args.base_url, option, fallback=None))
if getattr(args, option) is None:
self.error(
f'No {option} specified (looked in args, environment variable '
f'"NETDB_{option.upper()}", config-file in "{args.config}")'
)
# load base_url first!
for configoption in ['base_url', 'token', 'version']:
load_configoption(configoption)
return args
def list_to_generator_map_one2one(array, value):
"""Mapping function to convert list of dicts to an mapping with value as key for each dict. (1 to 1 Mapping)
Returns an generator object."""
return ((item[value], item) for item in array)
def list_to_generator_map_one2one(array, key_name):
"""Mapping function to convert list of dicts to an mapping with value as key for each dict
(1 to 1 Mapping). Returns an generator object."""
return ((item[key_name], item) for item in array)
def list_to_generator_map_one2many(array, value):
"""Mapping function to convert list of dicts to an mapping with values as key for each lists. (1 to n Mapping)
Returns an generator object."""
def list_to_generator_map_one2many(array, key_name):
"""Mapping function to convert list of dicts to an mapping with values as key for each lists
(1 to n Mapping). Returns an generator object."""
res = {}
for item in array:
if not item[value] in res:
res[item[value]] = []
res[item[value]].append(item)
if not item[key_name] in res:
res[item[key_name]] = []
res[item[key_name]].append(item)
for key, value in res.items():
yield key, value
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment