From f4a6cf5a16f9eb711f943b97226db442149b3107 Mon Sep 17 00:00:00 2001 From: beubax Date: Wed, 10 Jun 2026 15:28:16 +0530 Subject: [PATCH] feat: add production backend config --- pyproject.toml | 9 ++++++++- src/authsome/server/config.py | 3 +++ tests/server/test_config.py | 31 +++++++++++++++++++++++++++++++ uv.lock | 26 +++++++++++++++++++++++--- 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 tests/server/test_config.py diff --git a/pyproject.toml b/pyproject.toml index 585ecca..8355e34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,6 @@ dependencies = [ "python-multipart>=0.0.27", "py-key-value-aio[disk]", "aiosqlite>=0.20", - "asyncpg>=0.30", "pyjwt>=2.12.1", "argon2-cffi>=25.1.0", "base58>=2.1.1", @@ -49,6 +48,14 @@ dependencies = [ ] [project.optional-dependencies] +postgres = [ + "asyncpg>=0.30", +] +redis = [ + "redis>=5.0", + "py-key-value-aio[redis]", +] + dev = [ "pytest>=7.0", "pytest-asyncio>=1.3.0", diff --git a/src/authsome/server/config.py b/src/authsome/server/config.py index 746aa9b..ad95e58 100644 --- a/src/authsome/server/config.py +++ b/src/authsome/server/config.py @@ -17,6 +17,9 @@ class ServerConfig(AuthsomeConfig): # Store database_url: str | None = Field(default=None, validation_alias="DATABASE_URL") + redis_url: str | None = None + postgres_pool_min_size: int = Field(default=1, ge=1) + postgres_pool_max_size: int = Field(default=10, ge=1) # Lifetimes, in seconds ui_bootstrap_ttl_seconds: int = 300 diff --git a/tests/server/test_config.py b/tests/server/test_config.py new file mode 100644 index 0000000..5eb1f7a --- /dev/null +++ b/tests/server/test_config.py @@ -0,0 +1,31 @@ +from pathlib import Path + +from authsome.server.config import ServerConfig + + +def test_server_config_reads_redis_url(monkeypatch) -> None: + monkeypatch.setenv("AUTHSOME_REDIS_URL", "redis://localhost:6379/0") + + config = ServerConfig() + + assert config.redis_url == "redis://localhost:6379/0" + + +def test_server_config_exposes_postgres_pool_settings(monkeypatch) -> None: + monkeypatch.setenv("AUTHSOME_POSTGRES_POOL_MIN_SIZE", "2") + monkeypatch.setenv("AUTHSOME_POSTGRES_POOL_MAX_SIZE", "9") + expected_min_pool_size = 2 + expected_max_pool_size = 9 + + config = ServerConfig() + + assert config.postgres_pool_min_size == expected_min_pool_size + assert config.postgres_pool_max_size == expected_max_pool_size + + +def test_server_config_defaults_preserve_local_paths(tmp_path: Path) -> None: + config = ServerConfig(home=tmp_path) + + assert config.redis_url is None + assert config.database == str(tmp_path / "server" / "authsome.db") + assert config.kv_store_dir == tmp_path / "server" / "kv_store" diff --git a/uv.lock b/uv.lock index c8a7e88..95ffdc0 100644 --- a/uv.lock +++ b/uv.lock @@ -167,7 +167,6 @@ source = { editable = "." } dependencies = [ { name = "aiosqlite" }, { name = "argon2-cffi" }, - { name = "asyncpg" }, { name = "base58" }, { name = "browser-cookie3" }, { name = "click" }, @@ -199,12 +198,19 @@ dev = [ { name = "ruff" }, { name = "ty" }, ] +postgres = [ + { name = "asyncpg" }, +] +redis = [ + { name = "py-key-value-aio", extra = ["redis"] }, + { name = "redis" }, +] [package.metadata] requires-dist = [ { name = "aiosqlite", specifier = ">=0.20" }, { name = "argon2-cffi", specifier = ">=25.1.0" }, - { name = "asyncpg", specifier = ">=0.30" }, + { name = "asyncpg", marker = "extra == 'postgres'", specifier = ">=0.30" }, { name = "base58", specifier = ">=2.1.1" }, { name = "browser-cookie3", specifier = ">=0.19" }, { name = "click", specifier = ">=8.0" }, @@ -219,6 +225,7 @@ requires-dist = [ { name = "posthog", specifier = ">=3.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.6.0" }, { name = "py-key-value-aio", extras = ["disk"] }, + { name = "py-key-value-aio", extras = ["redis"], marker = "extra == 'redis'" }, { name = "pydantic", specifier = ">=2.0" }, { name = "pydantic-settings", specifier = ">=2.0" }, { name = "pyjwt", specifier = ">=2.12.1" }, @@ -227,12 +234,13 @@ requires-dist = [ { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.0" }, { name = "pytest-timeout", marker = "extra == 'dev'", specifier = ">=2.4.0" }, { name = "python-multipart", specifier = ">=0.0.27" }, + { name = "redis", marker = "extra == 'redis'", specifier = ">=5.0" }, { name = "requests", specifier = ">=2.28" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.9" }, { name = "ty", marker = "extra == 'dev'" }, { name = "uvicorn", specifier = ">=0.30" }, ] -provides-extras = ["dev"] +provides-extras = ["postgres", "redis", "dev"] [package.metadata.requires-dev] dev = [] @@ -1272,6 +1280,9 @@ disk = [ { name = "diskcache" }, { name = "pathvalidate" }, ] +redis = [ + { name = "redis" }, +] [[package]] name = "pyasn1" @@ -1628,6 +1639,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] +[[package]] +name = "redis" +version = "8.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/ae/ed461cca5780b5fc8b9fe8ca0ed98d89508645fb9d880c24cc42c087678f/redis-8.0.0.tar.gz", hash = "sha256:a00c5355432051ac14e593b8b197fc76c887ee12d55a0984f69328a1115fdc49", size = 5101591, upload-time = "2026-05-28T12:45:13.5Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/e3/b519734372d305bd547534a9f32e4ce9f98552af753dce72cf3483a0ff0b/redis-8.0.0-py3-none-any.whl", hash = "sha256:c938c18338585009f0bc310f4c7e4e4b4d37639356c4ac072cedf3af570c8dc7", size = 499870, upload-time = "2026-05-28T12:45:11.697Z" }, +] + [[package]] name = "requests" version = "2.34.2"