Skip to main content

settings manaager for pyhton

Project description

Lazy Settings

codecov

this project is a port of django's settings tool, with a few adjustments to work with any project

Features

  • manage user and package settings
  • allow manual configuration
  • can work with multiple projects via registering (experimental)
  • tools for testing

Usage

this project is a port of django's settings, so most things that you can do with django's setting, you can do here, with a few adjustments.

for users:

for a normal use

you need to set SETTINGS_MODULE, value of SETTINGS_MODULE is a dotted path to the file so if your file is in my_project.settings.py, you should set the env var as my_project.settings

there is two way to set this:

  1. environment variable which should point to a python module (file) all your settings should be defined in this module (or imported in this module)

there are many ways to set an environment variable

you can export it manually, use a library like environs, use a tool like direnv or set it via python's os module os.environ.setdefault("SETTINGS_MODULE", "dir_to_file.settings")

just be sure the env variable is set before accessing the settings

  1. you can use pyproject.toml to declare the settings module:
[lazy-settings]
SETTINGS_MODULE = "some_dir.settings"

if env variable is defined, toml will not be read.

you can install rtoml(rust) or tomli(C) to speed up toml parsing, if none of these are installed, tomllib from stdlib will be used. if both rtoml and tomli are installed, rtoml will be used.

settings object

you can use the lazy_settings.conf.settings object which hold all the settings in your project and packages that use this tool

the interface is like this:

from lazy_settings.conf import settings

# read a settings and check its value
assert settings.MY_SETTINGS == "something"

# alter a setting (you probably shouldn't use this)
settings.MY_SETTINGS = "something else"

# loop over all settings
for setting in settings:
    print(setting)

# check if a setting exists
if getattr(settings, "THAT_SETTINGS"):
    pass

for manual use

to manually configure the settings object, you can look at django's docs since the same logic is used here

note that the register functionality is available here as well, tho, again, it's experimental.

for package developers

put your projects default settings in a file (or a class) all settings should be uppercased

then in a place where it's ensured to be read by python, have this code:

from lazy_settings.conf import settings

from my_project import default_settings

settings.register(default_settings)

or you can use getattr.

note that the register functionality is experimental.

for testing

lazy-settings comes with tools for testing.

these tools are avilable at lazy_settings.test.

test tools work with both pytest and unittest.

when used with pytest, if a class is decorated, a fixture called settings_fixture will be added to the class, so don't use the same name to prevent shadowing.

if a class is not a subclass of unittest.TestCase, it's considered a pytest test suite, so you can't use class decorators with mixin test classes.

override_settings

this can be used as both a context manager and a decorator to override a setting, the change will be reverted once the scope is over.

if used as a class decorator, all tests in class will be effected, if used as a function/method decorator, only that function will be effected

example with class test suite:

from lazy_settings.test import override_settings
# pytest
@override_settings(A_SETTING="new value", NEW_SETTING="this wasn't in the file")
class TestOverridentSettings:
    def test_overriden_settings(self):
        assert settings.A_SETTING == "new value"
        assert settings.NEW_SETTING == "this wasn't in the file"


# async pytest        
@override_settings(A_SETTING="new value", NEW_SETTING="this wasn't in the file")
class TestOverridentSettingsAsync:
    @override_settings(A_SETTING="another one")
    async def test_override_after_override(self):
        assert settings.A_SETTING == "another one"



from unittest import TestCase, IsolatedAsyncioTestCase

# unittest
@override_settings(A_SETTING="new value", NEW_SETTING="this wasn't in the file")
class OverridentSettingsUnitTest(TestCase):
    def test_overriden_settings(self):
        self.assertEqual(settings.A_SETTING, "new value")
        self.assertEqual(settings.NEW_SETTING, "this wasn't in the file")
        


# async unittest        
@override_settings(A_SETTING="new value", NEW_SETTING="this wasn't in the file")
class AsyncOverridentSettingsUnitTest(IsolatedAsyncioTestCase):
    @override_settings(A_SETTING="another one")
    async def test_override_after_override(self):
        self.assertEqual(settings.A_SETTING, "another one")

example with function decorator:

@override_settings(A_SETTING="something new")
def test_override_settings_function_decorator():
    assert settings.A_SETTING == "something new"


@override_settings(A_SETTING="something new")
async def test_override_settings_async_function_decorator():
    assert settings.A_SETTING == "something new"

example with context manager:

def test_override_settings_context_manager_in_function():
    with override_settings(A_SETTING="context!!"):
        assert settings.A_SETTING == "context!!"

    assert settings.A_SETTING == "something"

modify_settings

modify_settings allows you to run append, prepend and remove so you don't have to re-write the list

this can also be used as both a decorator and a context manager

example as a class decorator

rom lazy_settings.test import modify_settings

# pytest
@modify_settings(LIST_BASED_SETTING={"append": "three", "prepend": "zero"})
class TestModifySettings:
    def test_modified_settings(self):
        assert len(settings.LIST_BASED_SETTING) == 4
        assert settings.LIST_BASED_SETTING[0] == "zero"
        assert settings.LIST_BASED_SETTING[-1] == "three"


# async pytest        
@modify_settings(LIST_BASED_SETTING={"append": "three", "prepend": "zero"})
class TestModifySettingsAsync:
    @modify_settings(LIST_BASED_SETTING={"remove": "two"})
    async def test_modify_after_modify(self):
        assert len(settings.LIST_BASED_SETTING) == 3
        assert "two" not in settings.LIST_BASED_SETTING



from unittest import TestCase, IsolatedAsyncioTestCase        

# unittest        
@modify_settings(LIST_BASED_SETTING={"append": "three", "prepend": "zero"})
class ModifySettingsUnitTest(TestCase):
    def test_modified_settings(self):
        self.assertEqual(len(settings.LIST_BASED_SETTING), 4)
        self.assertEqual(settings.LIST_BASED_SETTING[0], "zero")
        self.assertEqual(settings.LIST_BASED_SETTING[-1], "three")



# async unittest        
@modify_settings(LIST_BASED_SETTING={"append": "three", "prepend": "zero"})
class AsyncModifySettingsUnitTest(IsolatedAsyncioTestCase):
    @modify_settings(LIST_BASED_SETTING={"remove": "two"})
    async def test_modify_after_modify(self):
        self.assertEqual(len(settings.LIST_BASED_SETTING), 3)
        self.assertNotIn("two", settings.LIST_BASED_SETTING)

example as function decorator

@modify_settings(LIST_BASED_SETTING={"append": "things", "prepend": "first things"})
def test_modify_settings_fucntion_decorator():
    assert settings.LIST_BASED_SETTING == ["first things", "one", "two", "things"]


@modify_settings(LIST_BASED_SETTING={"append": "things", "prepend": "first things"})
async def test_modify_settings_async_fucntion_decorator():
    assert settings.LIST_BASED_SETTING == ["first things", "one", "two", "things"]

example as context manager

def test_modify_settings_context_manager_in_function():
    with modify_settings(
        LIST_BASED_SETTING={"append": "three", "prepend": "zero"},
    ):
        assert settings.LIST_BASED_SETTING == ["zero", "one", "two", "three"]
    assert settings.LIST_BASED_SETTING == ["one", "two"]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lazy_settings-0.1.0.tar.gz (71.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lazy_settings-0.1.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file lazy_settings-0.1.0.tar.gz.

File metadata

  • Download URL: lazy_settings-0.1.0.tar.gz
  • Upload date:
  • Size: 71.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.3

File hashes

Hashes for lazy_settings-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dc95f65258506f4d1f3be1e771a132695e65f1bf545f6cc009c5800d76fcc92e
MD5 96068cb38bf20f0b6357cce4efc63313
BLAKE2b-256 198662ff7b53430326e2ebd0b28dc0c5ff4e0fbef59f8871e38260832265c0b9

See more details on using hashes here.

File details

Details for the file lazy_settings-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for lazy_settings-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 886a6bc2f7113e30f0350559764af588a0435d3c6024b16cf849b2a65fef1bf0
MD5 81b54fa541f7eba5addf6e9d1e5f4ecc
BLAKE2b-256 f3be7ccb820857d96721faddd695d6a3f842301ae7fdf17676d8964e778b2f4e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page