A package for storing service config and secrets
Project description
Service Configurator
Service Configurator is a python library created for managing settings and secrets for your service.
Installation
Use package manager pip to install service-configurator.
pip install service-configurator
Usage
Creating settings classes
All settings classes should derive from BaseSettings or its subclass.
from configurator import BaseSettings, Integer, String
class MySettings(BaseSettings):
user_id = Integer()
password = String()
config = MySettings()
config.user_id = 10
config.password = '123'
print(f'User: {config.user_id} logged with password: {config.password}')
Settings class could have other settings objects as members.
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var1 = Integer()
class MySettings2(BaseSettings):
my_settings = MySettings()
var2 = Integer()
Inheriting from another settings class is also possible. Subclass treats parent's settings as its own.
from configurator import BaseSettings, Integer
class ParentSettings(BaseSettings):
var1 = Integer()
class MySettings(ParentSettings):
var2 = Integer()
equals
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var1 = Integer()
var2 = Integer()
Available settings fields
All implemented settings fields are presented below.
from configurator import BaseSettings, Integer, PositiveInteger, String, Email, Boolean, Float, Url
class MySettings(BaseSettings):
var1 = Integer()
var2 = PositiveInteger()
var3 = String()
var4 = Email()
var5 = Boolean()
var6 = Float()
var7 = Url()
Remember to always include parentheses () when creating settings fields.
Optional fields and default values
Setting fields can be marked as optional using required parameter. In addition to that default value can be set, the default value is returned if field wasn't modified. When these arguments are not provided field is required and it's default value is field type specific.
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var = Integer(required=False, default=50)
Importing settings
You can import settings using:
- python dict object
- json file
- yaml file
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var = Integer()
config = MySettings()
config.from_dict({'var': 12})
config.from_json('file.json')
config.from_yaml('file.yaml')
When importing from python dict object you can use partial_update argument if you don't want to provide all required values, which could be useful when unit testing. By default, an exception is thrown if required values are missing. This option is not accessible for json and yaml imports.
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var1 = Integer()
var2 = Integer()
config = MySettings()
config.from_dict({'var1': 12}, partial_update=True)
Exporting settings
Similar to import you have few export options:
- python dict object
- json file
- yaml file
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var = Integer()
config = MySettings()
config.var = 10
config.to_dict() # {'var': 10}
config.to_json('file.json')
config.to_yaml('file.yaml')
Yaml files are recommended option for storing your configuration.
Generating template files
Template/skeleton config file can be simply generated by creating a new instance of a settings class and using export method.
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var = Integer()
config = MySettings()
config.to_json('file.json.skel')
config.to_yaml('file.yaml.skel')
Setting and getting single field
If you want get or set single attribute you can access is as normal class member.
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var = Integer()
config = MySettings()
config.var = 4
print(config.var) # prints 4
Private settings fields
If you add a non-field member to your config class, it won't be exported or imported. However you can still use it as a normal class member.
from configurator import BaseSettings, Integer
class MySettings(BaseSettings):
var = Integer(default=5)
multiplier = 2
def multiply(self):
return self.var * self.multiplier
config = MySettings()
print(config.multiply()) # prints 10
config.to_dict() # {'var': 5}
Handling exceptions
Configurator throws following exceptions when something goes wrong:
- ValidationError - provided value didn't pass validation checks for the field
- SettingsError - a generic Settings error, read an error message for more information
from configurator import BaseSettings, PositiveInteger, ValidationError, SettingsError
class MySettings(BaseSettings):
var = PositiveInteger()
config = MySettings()
try:
config.var = -1
except ValidationError as ex:
# ValidationError -1 can't be assigned to PositiveInteger
print(f'Validation error: {ex}')
try:
config.from_dict({})
except SettingsError as ex:
# SettingsError missing required field 'var'
print(f'Settings error: {ex}')
Exceptions shouldn't pass silently.
Utility classes
For commonly used sets of settings utility classes were implemented to avoid unnecessary code repetition in multiple services.
All currently implemented utility classes are presented below. Check docs for class destiny.
from configurator import BaseSettings
from configurator.utils import OracleConnectorSettings, BoxSettings
class MySettings(BaseSettings):
oracle_db = OracleConnectorSettings()
box = BoxSettings()
Complete example
from configurator import BaseSettings, String, Email
from configurator.utils import OracleConnectorSettings
class MySettings(BaseSettings):
api_key = String()
report_email = Email(required=False)
oracle_db = OracleConnectorSettings()
config = MySettings()
config.from_yaml('config.yml')
config.yaml
api_key: '123qwerty'
oracle_db:
host: 'http://localhost'
password: 'pass123'
port: 1521
sid: 'db2'
user: 'admin'
report_email: 'report@example.com'
Contributing
Creating new settings fields
- All fields classes are located in the
fields.py
file. - Every field should be inherited from
Field
class or its subclass. - All fields should implement
default
,type
, andvalidate
, unless it's implemented in parent class and changes aren't needed
Example field classes:
# implemented in fields.py
class String(Field):
"""
Class for string type fields.
"""
type_ = str
default = ''
class Email(String):
"""
Class for email fields.
"""
def validate(self, value: str) -> str:
"""Validates email using simple regex."""
value = super().validate(value)
regex = re.compile(r'^\S+@\S+\.\S+$')
if regex.fullmatch(value) is None:
raise ValidationError('Provided string is not a valid email.')
return value
Creating new utility settings
Common sets of parameters used in many services shouldn't be copy-pasted. Instead, a new utility class should be created
in a utils.py
. Create the utility class as a normal settings class.
# implemented in utils.py
class OracleConnectorSettings(BaseSettings):
"""Setting required for connection to oracle database."""
host = Url()
port = Integer()
user = String()
password = String()
sid = String()
def get_connection_url(self):
"""Get connection url for sql alchemy"""
return f"oracle://{self.user}:{self.password}@{self.host}:{self.port}/{self.sid}"
Additional things to consider
- Every class and function should be documented. In addition to that run pydoc3 to generate html documentation after
modifications.
pdoc --html -o docs configurator
- Test coverage of this package is 100% try your best to not lower it.
- Update
__all__
in__init__.py
if needed
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file service-configurator-1.0.0.tar.gz
.
File metadata
- Download URL: service-configurator-1.0.0.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.0 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1fb7effb7519c4bc0e5796737b1f566493c5c92ddc31da39ee60dc84f809b312 |
|
MD5 | 5e349240726dd59eea3b416d205a31b8 |
|
BLAKE2b-256 | c7ad30d3c03d55ec991930bfc552ff94baab81a3fc3a1fdc34d84d334548d33f |
File details
Details for the file service_configurator-1.0.0-py3-none-any.whl
.
File metadata
- Download URL: service_configurator-1.0.0-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.0 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c13a959592a6b26c9af1edbdb75266ab1087f38b06dfb0dc5d0f7c2386f8dcea |
|
MD5 | d813cf55eb2251820c1d7540ec6b9009 |
|
BLAKE2b-256 | d9d3c232e4574926ddb4c12a48233132c56c35cec31323399cf8ac7bc5c8aa57 |