Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion papyrus/api/routes/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,35 @@
from papyrus.config import get_settings
from papyrus.core.database import get_db
from papyrus.core.rate_limit import limiter
from papyrus.schemas.sync import PowerSyncUploadRequest, PowerSyncUploadResponse
from papyrus.schemas.sync import (
DataSyncSettingsResponse,
FileStorageSettings,
PowerSyncUploadRequest,
PowerSyncUploadResponse,
)
from papyrus.services import sync as sync_service

router = APIRouter()
DBSession = Annotated[AsyncSession, Depends(get_db)]


@router.get(
"/settings",
response_model=DataSyncSettingsResponse,
summary="Get public data sync settings",
)
async def get_data_sync_settings() -> DataSyncSettingsResponse:
"""Return public sync capabilities for client custom-server setup."""
settings = get_settings()
return DataSyncSettingsResponse(
data_sync_url=settings.powersync_service_url,
Comment on lines +31 to +33
file_storage=FileStorageSettings(
supported=True,
quota_bytes=settings.file_storage_quota_bytes,
),
)


@router.post(
"/powersync-upload",
response_model=PowerSyncUploadResponse,
Expand Down
1 change: 1 addition & 0 deletions papyrus/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Settings(BaseSettings):
powersync_token_expire_minutes: int = 5
powersync_service_url: str = "http://localhost:8081"
powersync_service_port: int = 8081
file_storage_quota_bytes: int = 1_073_741_824
powersync_jwks_uri: str | None = None
powersync_source_role: str | None = None
powersync_source_password: str | None = None
Expand Down
14 changes: 14 additions & 0 deletions papyrus/schemas/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,17 @@ class PowerSyncUploadResponse(BaseModel):
"""Summary of an applied PowerSync upload transaction."""

applied_count: int


class FileStorageSettings(BaseModel):
"""Public file storage capability advertised by this server."""

supported: bool
quota_bytes: int
Comment on lines +72 to +73


class DataSyncSettingsResponse(BaseModel):
"""Public sync settings used by clients for custom server discovery."""

data_sync_url: str
file_storage: FileStorageSettings
Comment on lines +79 to +80
20 changes: 20 additions & 0 deletions tests/api/routes/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@
from papyrus.models import SyncBook, User


async def test_sync_settings_are_public_and_hide_implementation_details(client: AsyncClient, monkeypatch):
"""Return public data sync settings for one-URL custom server discovery."""
from papyrus.main import settings as app_settings

monkeypatch.setattr(app_settings, "powersync_service_url", "https://sync.papyrus.test")
monkeypatch.setattr(app_settings, "file_storage_quota_bytes", 1_073_741_824)

response = await client.get("/v1/sync/settings")

assert response.status_code == 200
assert response.json() == {
"data_sync_url": "https://sync.papyrus.test",
"file_storage": {
"supported": True,
"quota_bytes": 1_073_741_824,
},
}
assert "powersync" not in response.text.lower()


async def test_legacy_sync_routes_are_removed(client: AsyncClient, auth_headers: dict[str, str]):
"""PowerSync is the only supported synchronization contract."""
assert (await client.get("/v1/sync/status", headers=auth_headers)).status_code == 404
Expand Down
Loading