Skip to main content

lokate

The python client for lokate, the Arkitekt backup of a phone's location timeline: points, visits, trips and places, uploaded idempotently and restorable page by page.

Installation

pip install lokate

Usage

Every lokate operation is a method of the Lokate client, in a blocking and an a-prefixed async flavour. The server keys everything by the token's user and writes by its device (client_device claim).

In an arkitekt app

The client is injected by annotation. Add the service to your app and ask for lokate: Lokate:

from arkitekt import App, run
from lokate import Lokate, lokate_service

app = App("where-was-i", "0.1.0", services=[lokate_service])


@app.action
async def places_i_keep(lokate: Lokate) -> list[str]:
    """The names of my places, from the server copy."""
    names, cursor = [], None
    while True:
        page = await lokate.aget_changes(cursor=cursor)
        names += [place.name for place in page.places]
        cursor = page.next_cursor
        if not page.has_more:
            return names


if __name__ == "__main__":
    run(app)

From a script

from arkitekt import easy
from lokate import lokate_service

with easy("my-script", lokate_service) as lokate:
    state = lokate.get_sync_state()
    print(state.point_count, state.last_point_ts)

Standalone

Without arkitekt, build the client over a rath link of your own:

import datetime
from lokate import Lokate
from lokate.api.schema import PointInput
from lokate.rath import LokateRath

lokate = Lokate(rath=LokateRath(link=...))

with lokate:
    result = lokate.upload_points([
        PointInput(client_id="fix-1", ts=datetime.datetime.now(datetime.UTC), lat=48.2, lon=16.37),
    ])
    print(result.accepted, result.duplicates)

What the protocol guarantees:

  • Every write can be retried. upload_points counts points it already has as duplicates. replace_segments(from_=...) and merge_places leave unchanged rows alone.
  • A point is keyed by (device, client_id, ts). Never send one client_id with two different timestamps.
  • Batches hold at most 1000 rows, and so does a get_changes page.
  • Leave defaulted arguments out rather than passing None. For set_retention, though, days=None is meaningful: it means keep forever.

Development

The generated API (lokate/api/schema.py) comes from the checked-in schema.graphql and the documents in graphql/. The config comment in graphql.config.yaml has the command that refreshes the schema from a lokate-server checkout. Then regenerate with turms:

uvx --with 'graphql-core<3.3' --with-editable . --from <path to turms> turms gen
uv run pytest -m "not integration"   # no server needed
uv run pytest -m integration          # a real lokate + postgres/PostGIS via dokker

Until the server's first image is published, the integration suite needs a gitignored tests/integration/docker-compose.local.yml that builds jhnnsrs/lokate from a local lokate-server checkout.

See RELEASING.md for how versions are cut.

Metadata

Release files for lokate 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lokate 1.0.0
File Size Uploaded Provenance
lokate-1.0.0.tar.gz 13.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for lokate 1.0.0
File Interpreter ABI Platform
lokate-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.8 kB

Release files / lokate-1.0.0.tar.gz

Download URL lokate-1.0.0.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
d12f2b8ade79adeacc74e4a64b234e5dd2f068d521f0716b006dd193385e8ee0
BLAKE2b-256 checksum
How to use checksums
9e33d01133576741b3f14b21fff2887334fd964175fd82fcd633be9b75015b7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / lokate-1.0.0-py3-none-any.whl

Download URL lokate-1.0.0-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8dc8fddc2655dbfbad51003d7232b52ef02211aacb05297684775f71d8ab3416
BLAKE2b-256 checksum
How to use checksums
23dc169e19f5d7eeac32e76e03cec10c6a15289abfd549aadd9ff165d8ab5363
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for lokate 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page