Skip to content

[survey2ddi 3/6] Kobo pull adapter + formtransform kobo command #12

Description

@jstet

Step 3 of 6 for the survey2ddi retirement. Plan: HANDOVER_SURVEY2DDI.md. Best done after the xlsform2ddi --data issue, since kobo transform composes it.

Why

kobo2ddi in CorrelAid/survey2ddi is the only way to go from a Kobo asset UID to a codebook in one step. Its converter half is now duplicated here; its fetch half has no equivalent. Porting the fetch half is what lets that package stop shipping a second DDI implementation.

What to port

kobo2ddi/client.py — 98 lines of httpx, all straightforwardly fetch:

Python Endpoint Notes
list_assets() GET /api/v2/assets/ paginated (next)
get_asset(uid) GET /api/v2/assets/<uid>/ title/metadata
get_submissions(uid) GET /api/v2/assets/<uid>/data/ paginated; returns JSON records
download_xlsform(uid, dest) GET /api/v2/assets/<uid>.xls serves xlsx despite the .xls path — SheetJS reads it, no legacy-BIFF work needed
pull(uid, out) writes submissions.json + form.xlsx into <out>/<uid>/

CLI surface mirroring the Python one:

formtransform kobo list
formtransform kobo pull <uid> -o output/
formtransform kobo transform <uid> -o output/     # pull + xlsform2ddi + data CSV
  • Auth: --token, else KOBO_API_TOKEN. Server: --server-url, else KOBO_SERVER_URL, else https://eu.kobotoolbox.org. Keep the env var names identical so existing .env files keep working; node --env-file replaces python-dotenv, no dependency needed.
  • Kobo submission records are keyed group/name with space-joined select_multiple values — exactly what buildDataCsv's readCell already handles, so transform is pull + the existing emitters with no adapter.

Constraints

  • Node-only, like src/cli.ts and src/fileChoices.ts. Do not re-export the client from src/index.ts. The app must not start shipping an HTTP client, and a node:fs / network import surfacing in the browser bundle is a regression.
  • Fail loudly on a missing token rather than issuing an unauthenticated request.
  • Do not print the token in error messages or verbose output.

Acceptance criteria

  • list / pull / transform behave as the Python CLI does, same env var names
  • Pagination handled for assets and submissions (a >1-page asset is the test that matters)
  • transform produces XML + CSV with a correct caseQnty
  • Browser entry unchanged — nothing new reachable from src/index.ts
  • --help for the command group and each subcommand

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions