PropertyMe Cache And OAuth

PropertyMe is treated as the source of truth. Alba Core should keep working from the privacy-shaped local cache when live API access is unavailable.

app.propertyme.cache.load_property_cache(path: str | Path) list[PropertyRecord][source]

Load privacy-shaped real PropertyMe data from disk.

The loader intentionally fails if the cache is missing. Tests and demos should use real cached records, not silently fall back to fake properties.

Example: load the local cache

from app.propertyme.cache import load_property_cache

properties = load_property_cache("data/propertyme_property_seed_latest.json")

print(len(properties))
print(properties[0].to_public_dict())
class app.propertyme.oauth.PropertyMeOAuthConfig(client_id: str, client_secret: str, redirect_uri: str, auth_url: str, token_url: str, scope: str)[source]

OAuth settings required to start or refresh a PropertyMe session.

is_ready() bool[source]

Return True when all required OAuth fields are present.

app.propertyme.oauth.build_authorization_url(config: PropertyMeOAuthConfig, state: str | None = None) tuple[str, str][source]

Build the PropertyMe authorisation URL and state token.

app.propertyme.oauth.token_exchange_payload(config: PropertyMeOAuthConfig, code: str) Mapping[str, str][source]

Return the form payload for exchanging an auth code for tokens.

app.propertyme.oauth.refresh_payload(config: PropertyMeOAuthConfig, refresh_token: str) Mapping[str, str][source]

Return the form payload for refreshing an access token.

Example: build OAuth requests

from app.propertyme.oauth import (
    PropertyMeOAuthConfig,
    build_authorization_url,
    refresh_payload,
    token_exchange_payload,
)

config = PropertyMeOAuthConfig(
    client_id="from-env",
    client_secret="from-env",
    redirect_uri="http://localhost:65385/home/callback",
    auth_url="https://login.propertyme.com/connect/authorize",
    token_url="https://login.propertyme.com/connect/token",
    scope="offline_access property_read",
)

auth_url, state = build_authorization_url(config)
token_payload = token_exchange_payload(config, code="callback-code")
refresh_body = refresh_payload(config, refresh_token="stored-refresh-token")

print(auth_url)
print(state)
print(token_payload["grant_type"])
print(refresh_body["grant_type"])
class app.propertyme.client.PropertyMeClient(access_token: str, base_url: str = 'https://app.propertyme.com/api/v1')[source]

Small HTTP client for PropertyMe endpoints used by the backend.

The Alba Core should keep working from cache when this client is unavailable.

async list_rentals() list[dict[str, Any]][source]

Fetch rental lots from PropertyMe and validate the response shape.

async save_rentals_cache(path: str | Path) int[source]

Save a raw rentals response to disk and return the number of records.

This is a low-level helper. Before committing any cache, map or redact it into the privacy-shaped format used by PropertyRecord.

Example: refresh a raw rental cache

import asyncio

from app.propertyme.client import PropertyMeClient

async def main() -> None:
    client = PropertyMeClient(access_token="from-secure-storage")
    count = await client.save_rentals_cache("reference/propertyme_rentals_raw.json")
    print(count)

asyncio.run(main())

Raw exports should be mapped or redacted before they are used as committed test fixtures.