Skip to main content

Python configuration management with multiple storage backends

Project description

PyConfBox ๐ŸŽฏ

Python Configuration Management with Multiple Storage Backends

PyConfBox๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜, ์‹œ์Šคํ…œ๋ณ€์ˆ˜, ๊ธ€๋กœ๋ฒŒ๋ณ€์ˆ˜ ๋“ฑ ๋ชจ๋“  ์„ค์ •์„ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ Python ์„ค์ • ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

  • ๐Ÿ—๏ธ ๋‹ค์–‘ํ•œ ์ €์žฅ์†Œ ์ง€์›: Memory, Environment, File (JSON/YAML/TOML), SQLite, Redis
  • ๐ŸŽฏ ๋ฒ”์œ„(Scope) ์‹œ์Šคํ…œ: env, global, local, system, secret, django ๋ฒ”์œ„ ์ง€์›
  • ๐Ÿ”’ ๋ถˆ๋ณ€์„ฑ(Immutability) ์ œ์–ด: ์„ค์ •๋ณ„ ๋ถˆ๋ณ€ ์ง€์ • ๋ฐ ์ „์ฒด ๋ฆด๋ฆฌ์ฆˆ ๋ชจ๋“œ
  • ๐Ÿ”„ ์ž๋™ ํƒ€์ž… ๋ณ€ํ™˜: ๋ฌธ์ž์—ด โ†’ int, float, bool, list, dict ์ž๋™ ๋ณ€ํ™˜
  • ๐Ÿ”Œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์•„ํ‚คํ…์ฒ˜: ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์ €์žฅ์†Œ ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์‹œ์Šคํ…œ
  • ๐Ÿ“Š ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ: ์„ค์ • ํ†ต๊ณ„ ๋ฐ ์ƒํƒœ ์ถ”์ 

๐Ÿš€ ๋น ๋ฅธ ์‹œ์ž‘

์„ค์น˜

pip install pyconfbox

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

from pyconfbox import Config, ConfigScope

# Config ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
config = Config(default_storage="memory", fallback_storage="environment")

# ๊ธฐ๋ณธ ์„ค์ •
config.set("app_name", "MyApp")
config.set("debug", True)

# ํƒ€์ž… ๋ณ€ํ™˜
config.set("port", "8080", data_type=int)
config.set("timeout", "30.5", data_type=float)
config.set("hosts", "localhost,127.0.0.1", data_type=list)

# ๋ฒ”์œ„๋ณ„ ์„ค์ •
config.set("database_url", "sqlite:///app.db", scope=ConfigScope.LOCAL)
config.set("secret_key", "super-secret", scope=ConfigScope.SECRET, immutable=True)

# ์„ค์ • ์กฐํšŒ
app_name = config.get("app_name")
port = config.get("port")  # ์ž๋™์œผ๋กœ int ํƒ€์ž…
hosts = config.get("hosts")  # ์ž๋™์œผ๋กœ list ํƒ€์ž…

# ๋ฒ”์œ„๋ณ„ ์กฐํšŒ
global_configs = config.get_by_scope(ConfigScope.GLOBAL)
secret_configs = config.get_by_scope(ConfigScope.SECRET)

# ๋ฆด๋ฆฌ์ฆˆ ๋ชจ๋“œ (๋ชจ๋“  ์„ค์ • ๊ณ ์ •)
config.release()

ํŒŒ์ผ ์ €์žฅ์†Œ ์‚ฌ์šฉ

from pyconfbox import Config, JSONStorage, YAMLStorage, TOMLStorage

# JSON ํŒŒ์ผ ์ €์žฅ์†Œ
json_storage = JSONStorage('config.json')
config = Config(default_storage=json_storage)

config.set('app_name', 'MyApp')
config.set('version', '1.0.0')
config.set('features', ['auth', 'cache', 'logging'])

# YAML ํŒŒ์ผ ์ €์žฅ์†Œ
yaml_storage = YAMLStorage('config.yaml')
config = Config(default_storage=yaml_storage)

config.set('database', {
    'host': 'localhost',
    'port': 5432,
    'name': 'myapp_db'
})

# TOML ํŒŒ์ผ ์ €์žฅ์†Œ 
toml_storage = TOMLStorage('config.toml')
config = Config(default_storage=toml_storage)

config.set('owner', {
    'name': 'John Doe',
    'email': 'john@example.com'
})

SQLite ์ €์žฅ์†Œ ์‚ฌ์šฉ

from pyconfbox import Config, SQLiteStorage

# ์ธ๋ฉ”๋ชจ๋ฆฌ SQLite
memory_storage = SQLiteStorage()  # ":memory:"
config = Config(default_storage=memory_storage)

# ํŒŒ์ผ SQLite
file_storage = SQLiteStorage('config.db')
config = Config(default_storage=file_storage)

config.set('session_timeout', 3600)
config.set('max_connections', 100)

# ๋ฐฐ์น˜ ์—…๋ฐ์ดํŠธ
batch_data = {
    'env': 'production',
    'region': 'us-west-2',
    'replicas': 3
}
file_storage.update(batch_data)

๐Ÿ“‹ ์„ค์ • ๋ฒ”์œ„(Scope)

๋ฒ”์œ„ ์„ค๋ช… ์‚ฌ์šฉ ์˜ˆ์‹œ
env ํ™˜๊ฒฝ๋ณ€์ˆ˜ OS ํ™˜๊ฒฝ๋ณ€์ˆ˜, ํ”„๋กœ์„ธ์Šค๋ณ„ ์„ค์ •
global ๊ธ€๋กœ๋ฒŒ๋ณ€์ˆ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์—ญ ์„ค์ •
local ๋กœ์ปฌ๋ณ€์ˆ˜ ๋ชจ๋“ˆ/ํด๋ž˜์Šค๋ณ„ ์ง€์—ญ ์„ค์ •
system ์‹œ์Šคํ…œ๋ณ€์ˆ˜ ์‹œ์Šคํ…œ ๋ ˆ๋ฒจ ์„ค์ •
secret ๋น„๋ฐ€๋ณ€์ˆ˜ ์•”ํ˜ธํ™”๊ฐ€ ํ•„์š”ํ•œ ๋ฏผ๊ฐํ•œ ์„ค์ •
django Django์„ค์ • Django ์ „์šฉ ์„ค์ •

๐Ÿ—๏ธ ์ €์žฅ์†Œ ์•„ํ‚คํ…์ฒ˜

๋‚ด์žฅ ์ €์žฅ์†Œ

  • Memory: ์ธ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ์†Œ (๊ธฐ๋ณธ)
  • Environment: ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ €์žฅ์†Œ (์ฝ๊ธฐ ์ „์šฉ)
  • File: ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์ €์žฅ์†Œ (JSON, YAML, TOML)
  • Redis: Redis ์ €์žฅ์†Œ
  • SQLite: SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ €์žฅ์†Œ

ํ”Œ๋Ÿฌ๊ทธ์ธ ์ €์žฅ์†Œ (๋ณ„๋„ ํŒจํ‚ค์ง€)

  • pyconfbox-mysql: MySQL ์ €์žฅ์†Œ
  • pyconfbox-postgresql: PostgreSQL ์ €์žฅ์†Œ
  • pyconfbox-mongodb: MongoDB ์ €์žฅ์†Œ
  • pyconfbox-django: Django ํ†ตํ•ฉ ํ”Œ๋Ÿฌ๊ทธ์ธ

๐Ÿ”’ ๋ถˆ๋ณ€์„ฑ ๊ด€๋ฆฌ

# ๊ฐœ๋ณ„ ์„ค์ • ๋ถˆ๋ณ€ ์ง€์ •
config.set("api_key", "secret", immutable=True)

# ๋ถˆ๋ณ€ ์„ค์ • ๋ณ€๊ฒฝ ์‹œ๋„ (์˜ˆ์™ธ ๋ฐœ์ƒ)
try:
    config.set("api_key", "new_secret")
except ImmutableConfigError:
    print("๋ถˆ๋ณ€ ์„ค์ •์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!")

# ์ „์ฒด ์„ค์ • ๊ณ ์ • (๋ฆด๋ฆฌ์ฆˆ ๋ชจ๋“œ)
config.release()

# ๋ฆด๋ฆฌ์ฆˆ ํ›„ ์„ค์ • ๋ณ€๊ฒฝ ์‹œ๋„ (์˜ˆ์™ธ ๋ฐœ์ƒ)
try:
    config.set("new_key", "value")
except ReleasedConfigError:
    print("๋ฆด๋ฆฌ์ฆˆ๋œ ์„ค์ •์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!")

๐Ÿ”„ ์ž๋™ ํƒ€์ž… ๋ณ€ํ™˜

# ๋ฌธ์ž์—ด โ†’ ์ •์ˆ˜
config.set("port", "8080", data_type=int)
assert config.get("port") == 8080

# ๋ฌธ์ž์—ด โ†’ ๋ถˆ๋ฆฐ
config.set("debug", "true", data_type=bool)
assert config.get("debug") is True

# ๋ฌธ์ž์—ด โ†’ ๋ฆฌ์ŠคํŠธ (์ฝค๋งˆ ๊ตฌ๋ถ„)
config.set("hosts", "localhost,127.0.0.1", data_type=list)
assert config.get("hosts") == ["localhost", "127.0.0.1"]

# ๋ฌธ์ž์—ด โ†’ ๋”•์…”๋„ˆ๋ฆฌ (JSON)
config.set("db_config", '{"host": "localhost", "port": 5432}', data_type=dict)
assert config.get("db_config") == {"host": "localhost", "port": 5432}

๐Ÿ“Š ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฐ ํ†ต๊ณ„

metadata = config.get_metadata()

print(f"์ด ์„ค์ • ๊ฐœ์ˆ˜: {metadata.total_configs}")
print(f"๋ฒ”์œ„๋ณ„ ๊ฐœ์ˆ˜: {metadata.scopes}")
print(f"์ €์žฅ์†Œ๋ณ„ ๊ฐœ์ˆ˜: {metadata.storages}")
print(f"๋ถˆ๋ณ€ ์„ค์ • ๊ฐœ์ˆ˜: {metadata.immutable_count}")
print(f"๋ฆด๋ฆฌ์ฆˆ ์—ฌ๋ถ€: {metadata.is_released}")

๐Ÿ”Œ ๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•

ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ ‘๋‘์–ด ์‚ฌ์šฉ

config = Config(
    default_storage="environment",
    env_prefix="MYAPP_"
)

# MYAPP_DEBUG ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์กฐํšŒ
debug = config.get("DEBUG")

๋‹ค์ค‘ ์ €์žฅ์†Œ ํด๋ฐฑ

config = Config(
    default_storage="redis",
    fallback_storage="memory"
)

# Redis์—์„œ ๋จผ์ € ์ฐพ๊ณ , ์—†์œผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฐพ๊ธฐ
value = config.get("key", default="default_value")

์ €์žฅ์†Œ๋ณ„ ์„ค์ • ์ง€์ •

# ํŠน์ • ์ €์žฅ์†Œ์— ์ €์žฅ
config.set("cache_key", "value", storage="redis")
config.set("temp_data", "value", storage="memory")

๐Ÿงช ํ…Œ์ŠคํŠธ

# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •
uv sync --dev

# ํ…Œ์ŠคํŠธ ์‹คํ–‰
uv run pytest

# ์ปค๋ฒ„๋ฆฌ์ง€์™€ ํ•จ๊ป˜ ํ…Œ์ŠคํŠธ
uv run pytest --cov=pyconfbox

# ํŠน์ • ํ…Œ์ŠคํŠธ ์‹คํ–‰
uv run pytest tests/test_config.py -v

๐Ÿ“š ๋ฌธ์„œ

๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ ๋ผ์ด์„ ์Šค

์ด ํ”„๋กœ์ ํŠธ๋Š” MIT ๋ผ์ด์„ ์Šค ํ•˜์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ LICENSE ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๐Ÿ”— ๊ด€๋ จ ๋งํฌ


Made with โค๏ธ by PyConfBox Team

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

pyconfbox-0.1.0.tar.gz (67.6 kB view details)

Uploaded Source

Built Distribution

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

pyconfbox-0.1.0-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pyconfbox-0.1.0.tar.gz
  • Upload date:
  • Size: 67.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.12

File hashes

Hashes for pyconfbox-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c4e3b59986354217e69a0bc642f60e32561c76a599bb5f47bde7312e9515b9b8
MD5 1a5b144d335cdec758f95309262052df
BLAKE2b-256 5e12ee6710bf680d68c9c74440973f63ae533963e40e5dd79e8687161944b414

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyconfbox-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.12

File hashes

Hashes for pyconfbox-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f595b45f54022103478801efc866ae6d48f444e697364fe07070f3a02881b13
MD5 118ea65fa0815f405b334f2299cb4dc0
BLAKE2b-256 1555a9d8520ea1f4927712155fd6d92e62c0999f03f5593ba59e786ff47f728e

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