mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-10-05 20:28:23 +00:00
SQLite stores every INTEGER as 64-bit, so a set of portability defects stayed invisible until the application database ran on PostgreSQL: - Monetary columns hold millisatoshis but mapped to INT4, capping a key balance at 2_147_483_647 msats (~0.0215 BTC); asyncpg rejects anything larger. Unix timestamp columns had the same width, so long-dated expiries and the 2038 boundary would overflow. Both are widened to BIGINT by a migration that is a no-op on SQLite, where the width does not exist. - Secret.nsec_state was a bare Python Enum, which makes PostgreSQL demand a native `nsecstate` type that the migration never created, so every read or write of the secrets singleton failed and took node bootstrap with it. It is now a non-native enum, rendering VARCHAR on both backends. - Model-path persistence imported the SQLite-only INSERT .. ON CONFLICT construct, which does not compile against PostgreSQL. The upsert is now built for the dialect bound to the session. - The Alembic version-clear recovery path built a sync engine from the async URL, which left postgresql+asyncpg intact and raised MissingGreenlet. It now runs through the configured async driver. - The WAL PRAGMA is gated on the bound dialect rather than a DATABASE_URL prefix. SQLite-only Cashu wallet maintenance stays scoped to .wallet/*.sqlite3 and the log-derived analytics index is untouched. - PostgreSQL migration failures and unknown revisions now fail closed instead of stamping head. PostgreSQL rolls back DDL transactionally, so stamping after an error can mark migrations applied that never committed. Existing SQLite recovery behaviour is unchanged. Adds asyncpg and two test suites: dialect-portability invariants that run in the normal suite, and an opt-in integration suite covering the full Alembic chain plus the billing, reservation, refund, invoice and payout paths against a real server, enabled by ROUTSTR_TEST_POSTGRES_URL and skipped without it.
121 lines
3.5 KiB
TOML
121 lines
3.5 KiB
TOML
[project]
|
|
name = "routstr"
|
|
version = "0.4.7"
|
|
description = "Payment proxy for your LLM endpoint using cashu and nostr."
|
|
readme = "README.md"
|
|
requires-python = ">=3.11"
|
|
|
|
dependencies = [
|
|
"fastapi[standard-no-fastapi-cloud-cli]>=0.141",
|
|
"aiosqlite>=0.20",
|
|
"asyncpg>=0.30", # PostgreSQL backend for DATABASE_URL=postgresql+asyncpg://
|
|
"sqlmodel>=0.0.42", # Python 3.14 deferred-annotation support
|
|
"httpx[socks]>=0.28.1",
|
|
"h11>=0.16",
|
|
"greenlet>=3.2.1",
|
|
"alembic>=1.13",
|
|
"python-json-logger>=2.0.0",
|
|
"cashu>=0.20",
|
|
"marshmallow>=3.13,<4.0",
|
|
"websockets>=12.0",
|
|
"nostr-sdk>=0.45.1,<0.46",
|
|
"mdurl==0.1.2",
|
|
"pillow>=10",
|
|
"openai>=1.98.0",
|
|
"litellm>=1.101.2,<1.102",
|
|
"orjson>=3.10",
|
|
]
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"mypy>=1.15.0",
|
|
"ruff>=0.11.6",
|
|
"openai>=1.76.0",
|
|
"pytest>=8.0.0",
|
|
"pytest-asyncio>=0.24.0",
|
|
"pytest-cov>=6.1.1",
|
|
"httpx>=0.25.2",
|
|
"psutil>=5.9.0",
|
|
"aiohttp>=3.9.0",
|
|
"pytest-benchmark>=4.0.0",
|
|
"routstr",
|
|
]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
python_files = "test_*.py"
|
|
python_classes = "Test*"
|
|
python_functions = "test_*"
|
|
asyncio_mode = "auto"
|
|
asyncio_default_fixture_loop_scope = "function"
|
|
addopts = [
|
|
"-v",
|
|
"--tb=short",
|
|
"--strict-markers",
|
|
"--disable-warnings",
|
|
"-p",
|
|
"no:warnings",
|
|
]
|
|
markers = [
|
|
"asyncio: marks tests as async (deselect with '-m \"not asyncio\"')",
|
|
"integration: marks tests as integration tests (deselect with '-m \"not integration\"')",
|
|
"unit: marks tests as unit tests",
|
|
"slow: marks tests as slow running (deselect with '-m \"not slow\"')",
|
|
"requires_real_mint: marks tests that require a running Cashu mint instance",
|
|
"requires_docker: marks tests that require Docker services running (deselect with '-m \"not requires_docker\"')",
|
|
"performance: marks tests that measure performance metrics",
|
|
]
|
|
|
|
[build-system]
|
|
requires = ["setuptools", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[tool.setuptools]
|
|
packages = ["routstr"]
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I"]
|
|
ignore = ["E501"]
|
|
exclude = ["examples"]
|
|
|
|
[tool.mypy]
|
|
python_version = "3.11"
|
|
ignore_missing_imports = true
|
|
disallow_untyped_defs = true
|
|
check_untyped_defs = true
|
|
disallow_untyped_calls = true
|
|
disallow_incomplete_defs = true
|
|
disallow_untyped_decorators = true
|
|
|
|
[tool.uv.sources]
|
|
routstr = { workspace = true }
|
|
|
|
# Security floors. cashu 0.20.x caps httpx, h11, fastapi, cryptography,
|
|
# setuptools and wheel below their patched versions. routstr uses only cashu's
|
|
# wallet modules, not its server paths, so the caps are safe to lift here.
|
|
[tool.uv]
|
|
# coincurve 20's build config uses cmake.verbose, removed in
|
|
# scikit-build-core 0.10. This keeps its source build working on Python 3.14.
|
|
build-constraint-dependencies = ["scikit-build-core<0.10"]
|
|
override-dependencies = [
|
|
# httpx 0.28 (required by litellm 1.93) removed the `proxies` kwarg cashu
|
|
# passes on every mint call; routstr/cashu_compat.py restores it for cashu.
|
|
"httpx[socks]>=0.28.1,<1.0",
|
|
"importlib-metadata>=8.0.0,<9.0",
|
|
"h11>=0.16.0",
|
|
"fastapi[standard-no-fastapi-cloud-cli]>=0.141",
|
|
"cryptography>=49.0.0",
|
|
"setuptools>=83.0.0",
|
|
"wheel>=0.46.2",
|
|
]
|
|
|
|
# Transitive deps whose dependents allow the patched version but don't require
|
|
# it. Constraints raise the floor without bypassing any upstream pin.
|
|
constraint-dependencies = [
|
|
"starlette>=1.3.1",
|
|
"httpcore>=1.0.9", # 1.0.8 caps h11<0.15
|
|
# 1.76 is the first grpcio-tools release with CPython 3.14 wheels.
|
|
"grpcio>=1.76.0,<2.0.0",
|
|
"grpcio-tools>=1.76.0,<2.0.0",
|
|
]
|