diff options
Diffstat (limited to 'python-coveo-settings.spec')
-rw-r--r-- | python-coveo-settings.spec | 675 |
1 files changed, 675 insertions, 0 deletions
diff --git a/python-coveo-settings.spec b/python-coveo-settings.spec new file mode 100644 index 0000000..2102811 --- /dev/null +++ b/python-coveo-settings.spec @@ -0,0 +1,675 @@ +%global _empty_manifest_terminate_build 0 +Name: python-coveo-settings +Version: 2.1.1 +Release: 1 +Summary: Settings driven by environment variables. +License: Apache-2.0 +URL: https://github.com/coveooss/coveo-python-oss/tree/main/coveo-settings +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/3c/3f/8b484f15584ca17e9453dddb6eafacb7e084ac2b564f392197e870f2a67f/coveo_settings-2.1.1.tar.gz +BuildArch: noarch + + +%description +# coveo-settings + +Whenever you want the user to be able to configure something through an environment variable, this module has your back: + +```python +from coveo_settings import StringSetting, BoolSetting + +DATABASE_URL = StringSetting('project.database.url') +DATABASE_USE_SSL = BoolSetting('project.database.ssl') +``` + +The user can then configure the environment variables `project.database.url` and `project.database.ssl` to configure the application. + +When accessed, the values are automatically converted to the desired type: + +- `StringSetting` will always be a string +- `BoolSetting` is either True or False, but accepts "yes|no|true|false|1|0" as input (case-insensitive, of course) +- `IntSetting` and `FloatSetting` are self-explanatory +- `DictSetting` allows you to use JSON maps +- `PathSetting` gives a Path instance, and also implements PathLike and the `/` operator + +If the input cannot be converted to the value type, an `TypeConversionConfigurationError` exception is raised. + +A default (fallback) value may be specified. The fallback may be a `callable`. + +A validation callback may be specified for custom logic and error messages. + +Not limited to environment variables; supports redirection to custom implementations. + +**A setting can be set as sensitive for logging purposes. When logging, use repr(setting) to get the correct representation.** + + + +## Accessing the value + +There are various ways to obtain the value: + +```python +from coveo_settings import BoolSetting + +DATABASE_USE_SSL = BoolSetting('project.database.ssl') + +# this method will raise an exception if the setting has no value and no fallback +use_ssl = bool(DATABASE_USE_SSL) +use_ssl = DATABASE_USE_SSL.get_or_raise() +assert use_ssl in [True, False] + +# this method will not raise an exception +use_ssl = DATABASE_USE_SSL.value +assert use_ssl in [True, False, None] + +# use "is_set" to check if there is a value set for this setting; skips validation check +if DATABASE_USE_SSL.is_set: + use_ssl = bool(DATABASE_USE_SSL) + +# use "is_valid" to verify if the value passes the validation callback. implies is_set. +if not DATABASE_USE_SSL.is_valid: + ... +``` + + +## Loose environment key matching + +Matching the key of the environment variable `project.database.ssl` is done very loosely: + +- case-insensitive +- dots and underscores are ignored completely (`foo_bar` and `f__ooba.r` are equal) + - useful for some runners that don't support dots in environment variable keys + + +## Use ready validation + +You can quickly validate that a string is in a specific list like this: + +```python +from coveo_settings.settings import StringSetting +from coveo_settings.validation import InSequence + +ENV = StringSetting("environment", fallback="dev", validation=InSequence("prod", "staging", "dev")) +``` + + +## Redirection + +You can register custom redirection schemes in order to support any data source. + +Much like `https://` is a clear scheme, you may register callback functions to trigger when the value of a setting +starts with the scheme(s) you define. For instance, let's support a custom API and a file storage: + +```python +from coveo_settings import settings_adapter, StringSetting, ConfigValue + + +@settings_adapter("internal-api::") +def internal_api_adapter(key: str) -> ConfigValue: + # the scheme was automatically removed for convenience; only the resource remains + assert "internal-api::" not in key + return "internal api" # implement logic to obtain value from internal api + + +@settings_adapter("file::", strip_scheme=False) +def file_adapter(key: str) -> ConfigValue: + # you can keep the scheme by specifying `strip_scheme=False` + assert key.startswith("file::") + return "file adapter" # implement logic to parse the key and retrieve the setting value + + +assert StringSetting('...', fallback="internal-api::settings/user-name").value == "internal api" +assert StringSetting('...', fallback="file::settings.yaml/user-name").value == "file adapter" + + +# even though we used `fallback` above, the redirection is driven by the user: +import os + +REDIRECT_ME = StringSetting('test') +os.environ['test'] = "file::user.json::name" +assert REDIRECT_ME.value == "file adapter" +os.environ['test'] = "internal-api::url" +assert REDIRECT_ME.value == "internal api" +``` + +Keep in mind that there's no restriction on the prefix scheme; it's your responsibility to pick something unique +that can be set as the value of an environment variable. + + +### Redirection is recursive + +The value of a redirection may be another redirection and may juggle between adapters. +A limit of 50 redirections is supported: + +```python +import os + +from coveo_settings import StringSetting + + +os.environ["expected"] = "final value" +os.environ["redirected"] = "env->expected" +os.environ["my-setting"] = "env->redirected" + +assert StringSetting("my-setting").value == "final value" +``` + +### Builtin environment redirection + +The builtin redirection scheme `env->` can be used to redirect to a different environment variable. +The example below demonstrates the deprecation/migration of `my-setting` into `new-setting`: + +```python +import os + +from coveo_settings import StringSetting + +os.environ["new-setting"] = "correct-value" +os.environ["my-setting"] = "env->new-setting" + +assert StringSetting("my-setting").value == "correct-value" +``` + +## Cached + +You can set a setting to cache the first valid value with `cached=True`. +This is particularly useful in redirection scenarios to avoid repeating requests too often. + + +## Setting the value + +You can override the value using `setting.value = "some value"` and clear the override with `setting.value = None`. +Clearing the override resumes the normal behavior of the environment variables and the fallback value, if set. + +This is typically used as a way to propagate CLI switches globally. +For mocking scenarios, refer to the `Mocking` section below. + + +## Mocking + +When you need a setting value for a test, use the `mock_config_value` context manager: + +```python +from coveo_settings import StringSetting +from coveo_settings.mock import mock_config_value + +SETTING = StringSetting(...) + +assert not SETTING.is_set +with mock_config_value(SETTING, 'new-value'): + assert SETTING.is_set +``` + +You can also clear the value: + +```python +from coveo_settings import StringSetting +from coveo_settings.mock import mock_config_value + +SETTING = StringSetting(..., fallback='test') + +assert SETTING.is_set +with mock_config_value(SETTING, None): + assert not SETTING.is_set +``` + + +%package -n python3-coveo-settings +Summary: Settings driven by environment variables. +Provides: python-coveo-settings +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-coveo-settings +# coveo-settings + +Whenever you want the user to be able to configure something through an environment variable, this module has your back: + +```python +from coveo_settings import StringSetting, BoolSetting + +DATABASE_URL = StringSetting('project.database.url') +DATABASE_USE_SSL = BoolSetting('project.database.ssl') +``` + +The user can then configure the environment variables `project.database.url` and `project.database.ssl` to configure the application. + +When accessed, the values are automatically converted to the desired type: + +- `StringSetting` will always be a string +- `BoolSetting` is either True or False, but accepts "yes|no|true|false|1|0" as input (case-insensitive, of course) +- `IntSetting` and `FloatSetting` are self-explanatory +- `DictSetting` allows you to use JSON maps +- `PathSetting` gives a Path instance, and also implements PathLike and the `/` operator + +If the input cannot be converted to the value type, an `TypeConversionConfigurationError` exception is raised. + +A default (fallback) value may be specified. The fallback may be a `callable`. + +A validation callback may be specified for custom logic and error messages. + +Not limited to environment variables; supports redirection to custom implementations. + +**A setting can be set as sensitive for logging purposes. When logging, use repr(setting) to get the correct representation.** + + + +## Accessing the value + +There are various ways to obtain the value: + +```python +from coveo_settings import BoolSetting + +DATABASE_USE_SSL = BoolSetting('project.database.ssl') + +# this method will raise an exception if the setting has no value and no fallback +use_ssl = bool(DATABASE_USE_SSL) +use_ssl = DATABASE_USE_SSL.get_or_raise() +assert use_ssl in [True, False] + +# this method will not raise an exception +use_ssl = DATABASE_USE_SSL.value +assert use_ssl in [True, False, None] + +# use "is_set" to check if there is a value set for this setting; skips validation check +if DATABASE_USE_SSL.is_set: + use_ssl = bool(DATABASE_USE_SSL) + +# use "is_valid" to verify if the value passes the validation callback. implies is_set. +if not DATABASE_USE_SSL.is_valid: + ... +``` + + +## Loose environment key matching + +Matching the key of the environment variable `project.database.ssl` is done very loosely: + +- case-insensitive +- dots and underscores are ignored completely (`foo_bar` and `f__ooba.r` are equal) + - useful for some runners that don't support dots in environment variable keys + + +## Use ready validation + +You can quickly validate that a string is in a specific list like this: + +```python +from coveo_settings.settings import StringSetting +from coveo_settings.validation import InSequence + +ENV = StringSetting("environment", fallback="dev", validation=InSequence("prod", "staging", "dev")) +``` + + +## Redirection + +You can register custom redirection schemes in order to support any data source. + +Much like `https://` is a clear scheme, you may register callback functions to trigger when the value of a setting +starts with the scheme(s) you define. For instance, let's support a custom API and a file storage: + +```python +from coveo_settings import settings_adapter, StringSetting, ConfigValue + + +@settings_adapter("internal-api::") +def internal_api_adapter(key: str) -> ConfigValue: + # the scheme was automatically removed for convenience; only the resource remains + assert "internal-api::" not in key + return "internal api" # implement logic to obtain value from internal api + + +@settings_adapter("file::", strip_scheme=False) +def file_adapter(key: str) -> ConfigValue: + # you can keep the scheme by specifying `strip_scheme=False` + assert key.startswith("file::") + return "file adapter" # implement logic to parse the key and retrieve the setting value + + +assert StringSetting('...', fallback="internal-api::settings/user-name").value == "internal api" +assert StringSetting('...', fallback="file::settings.yaml/user-name").value == "file adapter" + + +# even though we used `fallback` above, the redirection is driven by the user: +import os + +REDIRECT_ME = StringSetting('test') +os.environ['test'] = "file::user.json::name" +assert REDIRECT_ME.value == "file adapter" +os.environ['test'] = "internal-api::url" +assert REDIRECT_ME.value == "internal api" +``` + +Keep in mind that there's no restriction on the prefix scheme; it's your responsibility to pick something unique +that can be set as the value of an environment variable. + + +### Redirection is recursive + +The value of a redirection may be another redirection and may juggle between adapters. +A limit of 50 redirections is supported: + +```python +import os + +from coveo_settings import StringSetting + + +os.environ["expected"] = "final value" +os.environ["redirected"] = "env->expected" +os.environ["my-setting"] = "env->redirected" + +assert StringSetting("my-setting").value == "final value" +``` + +### Builtin environment redirection + +The builtin redirection scheme `env->` can be used to redirect to a different environment variable. +The example below demonstrates the deprecation/migration of `my-setting` into `new-setting`: + +```python +import os + +from coveo_settings import StringSetting + +os.environ["new-setting"] = "correct-value" +os.environ["my-setting"] = "env->new-setting" + +assert StringSetting("my-setting").value == "correct-value" +``` + +## Cached + +You can set a setting to cache the first valid value with `cached=True`. +This is particularly useful in redirection scenarios to avoid repeating requests too often. + + +## Setting the value + +You can override the value using `setting.value = "some value"` and clear the override with `setting.value = None`. +Clearing the override resumes the normal behavior of the environment variables and the fallback value, if set. + +This is typically used as a way to propagate CLI switches globally. +For mocking scenarios, refer to the `Mocking` section below. + + +## Mocking + +When you need a setting value for a test, use the `mock_config_value` context manager: + +```python +from coveo_settings import StringSetting +from coveo_settings.mock import mock_config_value + +SETTING = StringSetting(...) + +assert not SETTING.is_set +with mock_config_value(SETTING, 'new-value'): + assert SETTING.is_set +``` + +You can also clear the value: + +```python +from coveo_settings import StringSetting +from coveo_settings.mock import mock_config_value + +SETTING = StringSetting(..., fallback='test') + +assert SETTING.is_set +with mock_config_value(SETTING, None): + assert not SETTING.is_set +``` + + +%package help +Summary: Development documents and examples for coveo-settings +Provides: python3-coveo-settings-doc +%description help +# coveo-settings + +Whenever you want the user to be able to configure something through an environment variable, this module has your back: + +```python +from coveo_settings import StringSetting, BoolSetting + +DATABASE_URL = StringSetting('project.database.url') +DATABASE_USE_SSL = BoolSetting('project.database.ssl') +``` + +The user can then configure the environment variables `project.database.url` and `project.database.ssl` to configure the application. + +When accessed, the values are automatically converted to the desired type: + +- `StringSetting` will always be a string +- `BoolSetting` is either True or False, but accepts "yes|no|true|false|1|0" as input (case-insensitive, of course) +- `IntSetting` and `FloatSetting` are self-explanatory +- `DictSetting` allows you to use JSON maps +- `PathSetting` gives a Path instance, and also implements PathLike and the `/` operator + +If the input cannot be converted to the value type, an `TypeConversionConfigurationError` exception is raised. + +A default (fallback) value may be specified. The fallback may be a `callable`. + +A validation callback may be specified for custom logic and error messages. + +Not limited to environment variables; supports redirection to custom implementations. + +**A setting can be set as sensitive for logging purposes. When logging, use repr(setting) to get the correct representation.** + + + +## Accessing the value + +There are various ways to obtain the value: + +```python +from coveo_settings import BoolSetting + +DATABASE_USE_SSL = BoolSetting('project.database.ssl') + +# this method will raise an exception if the setting has no value and no fallback +use_ssl = bool(DATABASE_USE_SSL) +use_ssl = DATABASE_USE_SSL.get_or_raise() +assert use_ssl in [True, False] + +# this method will not raise an exception +use_ssl = DATABASE_USE_SSL.value +assert use_ssl in [True, False, None] + +# use "is_set" to check if there is a value set for this setting; skips validation check +if DATABASE_USE_SSL.is_set: + use_ssl = bool(DATABASE_USE_SSL) + +# use "is_valid" to verify if the value passes the validation callback. implies is_set. +if not DATABASE_USE_SSL.is_valid: + ... +``` + + +## Loose environment key matching + +Matching the key of the environment variable `project.database.ssl` is done very loosely: + +- case-insensitive +- dots and underscores are ignored completely (`foo_bar` and `f__ooba.r` are equal) + - useful for some runners that don't support dots in environment variable keys + + +## Use ready validation + +You can quickly validate that a string is in a specific list like this: + +```python +from coveo_settings.settings import StringSetting +from coveo_settings.validation import InSequence + +ENV = StringSetting("environment", fallback="dev", validation=InSequence("prod", "staging", "dev")) +``` + + +## Redirection + +You can register custom redirection schemes in order to support any data source. + +Much like `https://` is a clear scheme, you may register callback functions to trigger when the value of a setting +starts with the scheme(s) you define. For instance, let's support a custom API and a file storage: + +```python +from coveo_settings import settings_adapter, StringSetting, ConfigValue + + +@settings_adapter("internal-api::") +def internal_api_adapter(key: str) -> ConfigValue: + # the scheme was automatically removed for convenience; only the resource remains + assert "internal-api::" not in key + return "internal api" # implement logic to obtain value from internal api + + +@settings_adapter("file::", strip_scheme=False) +def file_adapter(key: str) -> ConfigValue: + # you can keep the scheme by specifying `strip_scheme=False` + assert key.startswith("file::") + return "file adapter" # implement logic to parse the key and retrieve the setting value + + +assert StringSetting('...', fallback="internal-api::settings/user-name").value == "internal api" +assert StringSetting('...', fallback="file::settings.yaml/user-name").value == "file adapter" + + +# even though we used `fallback` above, the redirection is driven by the user: +import os + +REDIRECT_ME = StringSetting('test') +os.environ['test'] = "file::user.json::name" +assert REDIRECT_ME.value == "file adapter" +os.environ['test'] = "internal-api::url" +assert REDIRECT_ME.value == "internal api" +``` + +Keep in mind that there's no restriction on the prefix scheme; it's your responsibility to pick something unique +that can be set as the value of an environment variable. + + +### Redirection is recursive + +The value of a redirection may be another redirection and may juggle between adapters. +A limit of 50 redirections is supported: + +```python +import os + +from coveo_settings import StringSetting + + +os.environ["expected"] = "final value" +os.environ["redirected"] = "env->expected" +os.environ["my-setting"] = "env->redirected" + +assert StringSetting("my-setting").value == "final value" +``` + +### Builtin environment redirection + +The builtin redirection scheme `env->` can be used to redirect to a different environment variable. +The example below demonstrates the deprecation/migration of `my-setting` into `new-setting`: + +```python +import os + +from coveo_settings import StringSetting + +os.environ["new-setting"] = "correct-value" +os.environ["my-setting"] = "env->new-setting" + +assert StringSetting("my-setting").value == "correct-value" +``` + +## Cached + +You can set a setting to cache the first valid value with `cached=True`. +This is particularly useful in redirection scenarios to avoid repeating requests too often. + + +## Setting the value + +You can override the value using `setting.value = "some value"` and clear the override with `setting.value = None`. +Clearing the override resumes the normal behavior of the environment variables and the fallback value, if set. + +This is typically used as a way to propagate CLI switches globally. +For mocking scenarios, refer to the `Mocking` section below. + + +## Mocking + +When you need a setting value for a test, use the `mock_config_value` context manager: + +```python +from coveo_settings import StringSetting +from coveo_settings.mock import mock_config_value + +SETTING = StringSetting(...) + +assert not SETTING.is_set +with mock_config_value(SETTING, 'new-value'): + assert SETTING.is_set +``` + +You can also clear the value: + +```python +from coveo_settings import StringSetting +from coveo_settings.mock import mock_config_value + +SETTING = StringSetting(..., fallback='test') + +assert SETTING.is_set +with mock_config_value(SETTING, None): + assert not SETTING.is_set +``` + + +%prep +%autosetup -n coveo-settings-2.1.1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-coveo-settings -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 2.1.1-1 +- Package Spec generated |