Skip to main content

The official SDK for integrating homelessness data into the Comhom Platform.

Project description

Uploading Answers with comhom_sdk.py

This guide is for end users who want to upload answer data to Comhom using a file.

Script location: sdk/comhom_sdk.py

Before you start

You need:

  • Python 3.10+
  • A valid API key with permission to upload answers
  • A data file in .json or .csv format

If needed, install dependency:

pip install jsonschema

When you generate an API key on the platform, it is downloaded as comhom.key. The SDK uses that filename by default for --api-key-file.

Your organization is resolved automatically from the API key — you do not pass an organization ID to the SDK.

1) Prepare your API key file

Create a plain text file (for example comhom.key) that contains only your key:

your-api-key-here

2) Prepare your answers file

You can use JSON or CSV.

Each row is one answer. Required fields:

Field Description
respondent_code Stable, pseudonymous identifier for the respondent
question_code Code of the question being answered
value The answer (format depends on question type; see below)
answered_at Date the answer was collected (YYYY-MM-DD)
consent_signed Whether the respondent consented to data use (true / false)

Question codes and values

Valid question_code values come from the Comhom question catalogue. Examples from the platform fixtures:

question_code Type Example value
sex_gender Single choice cisgender_woman
age Single choice 25_34
nationality Single choice national_country
A2 Date 2026-01-10
A4 Single choice programme_completion
A5 Program housing_first (your org's program code)
A6 Multiple choice ["cm", "hn"]

Value formats:

  • Single choice — one option code (for example sex_gendercisgender_woman, or age25_34).
  • Multiple choice — a list of option codes (for example A6["cm", "hn"]).
  • DateYYYY-MM-DD (for example A22026-01-10).
  • Program (A5) — a program code from your organization (created on the platform first; not a global option).

Only rows with consent_signed: true are loaded.

JSON format

Use either:

  • A top-level array of answers, or
  • An object with an answers array

Example — one beneficiary with micro- and meso-variable answers:

[
  {
    "respondent_code": "hash_7f3a9c2e",
    "question_code": "sex_gender",
    "answered_at": "2026-06-15",
    "consent_signed": true,
    "value": "cisgender_woman"
  },
  {
    "respondent_code": "hash_7f3a9c2e",
    "question_code": "age",
    "answered_at": "2026-06-15",
    "consent_signed": true,
    "value": "25_34"
  },
  {
    "respondent_code": "hash_7f3a9c2e",
    "question_code": "A2",
    "answered_at": "2026-06-15",
    "consent_signed": true,
    "value": "2026-01-10"
  },
  {
    "respondent_code": "hash_7f3a9c2e",
    "question_code": "A5",
    "answered_at": "2026-06-15",
    "consent_signed": true,
    "value": "housing_first"
  },
  {
    "respondent_code": "hash_7f3a9c2e",
    "question_code": "A6",
    "answered_at": "2026-06-15",
    "consent_signed": true,
    "value": ["cm", "hn"]
  }
]

CSV format

Required columns:

  • respondent_code
  • question_code
  • answered_at
  • consent_signed
  • value

answered_at is the collection/snapshot date for each answer. If your source system does not track per-answer timestamps, set one date for the whole export.

Upload behavior:

  • Duplicate rows in the same file for the same beneficiary/question/date: the last row wins.
  • Same value as the latest known snapshot on or before that date: the row is skipped (safe to re-upload).
  • Same date with a changed value: the existing snapshot is updated.
  • New date with a changed value: a new history row is created.

Example:

respondent_code,question_code,answered_at,consent_signed,value
hash_7f3a9c2e,sex_gender,2026-06-15,true,cisgender_woman
hash_7f3a9c2e,age,2026-06-15,true,25_34
hash_7f3a9c2e,A2,2026-06-15,true,2026-01-10
hash_7f3a9c2e,A5,2026-06-15,true,housing_first
hash_7f3a9c2e,A6,2026-06-15,true,"[""cm"",""hn""]"

3) Run the upload

python3 sdk/comhom_sdk.py upload \
  --input-file "/path/to/answers.json" \
  --api-key-file comhom.key

If your input is CSV, just change --input-file to the CSV path.

By default, uploads go to sandbox. Add --production to target production.

Generating synthetic answers (optional)

You can generate synthetic answers to a file using the platform's answer upload JSON schema. The SDK fetches the org-specific schema automatically using your API key. Generation is separate from upload: write a file with generate, then upload it with upload.

python3 sdk/comhom_sdk.py generate \
  --total-answers 1000 \
  --respondent-count 20 \
  --output-file "/path/to/synthetic_answers.json" \
  --api-key-file comhom.key

To upload the generated file:

python3 sdk/comhom_sdk.py upload \
  --input-file "/path/to/synthetic_answers.json" \
  --api-key-file comhom.key

The output format is determined by the extension:

  • .json -> JSON array
  • .csv -> CSV with the required columns

Command options

upload

Option Short Required Description
--input-file -i Yes Path to .json or .csv file
--api-key-file -k No Path to API key file (default: comhom.key)
--production -p No Upload to production (default is sandbox)
--batch-size -b No Answers per request (default 500)

generate

Option Short Required Description
--total-answers -n Yes Number of synthetic answers to generate
--output-file -o Yes Path to write .json or .csv output
--respondent-count -c No Number of respondent codes to use (default 1)
--respondent-prefix -p No Prefix for respondent codes (default R)
--answered-at -a No Fixed answered date (YYYY-MM-DD) for all answers
--days-back -d No If --answered-at is not set, random date within last N days (default 365; use 0 for today only)
--seed -s No Seed for deterministic generation
--api-key-file -k No Path to API key file (default: comhom.key)

validate

Option Short Required Description
--input-file -i Yes Path to .json or .csv file
--api-key-file -k No Path to API key file (default: comhom.key)
--errors-file -e No Write all validation errors to a CSV file when validation fails

delete

Option Short Required Description
--respondent-code -r Yes Beneficiary/respondent code whose answers to delete
--api-key-file -k No Path to API key file (default: comhom.key)
--production -p No Delete production data instead of sandbox (default is sandbox)

What the script does

upload

  1. Read your API key from file
  2. Read and parse your JSON/CSV answers
  3. Download the current upload schema from the platform using your API key (includes org-specific enums such as A5 program codes)
  4. Validate your file locally before sending
  5. Upload answers in batches

generate

  1. Fetch the answer upload JSON schema from the platform using your API key
  2. Generate synthetic answers that conform to the schema
  3. Write them to a JSON or CSV file

validate

  1. Read and parse your JSON/CSV answers
  2. Download the current upload schema from the platform using your API key
  3. Validate every answer row locally without uploading

Example:

python3 sdk/comhom_sdk.py validate \
  --input-file "/path/to/answers.json" \
  --api-key-file comhom.key \
  --errors-file errors.csv

delete

  1. Read your API key from file
  2. Resolve your organization from the API key
  3. Delete all answers for the given respondent_code in sandbox or production

Example:

python3 sdk/comhom_sdk.py delete \
  --respondent-code hash_7f3a9c2e \
  --api-key-file comhom.key

Success and errors

  • On success, upload returns counts for created, updated, and skipped rows.
  • On failure, you will see an error message and no further batches are sent.
  • When validate fails, use --errors-file to export every error row for review.

Common issues:

  • Wrong API key or no permission
  • Missing required columns in CSV
  • Invalid date format (must be YYYY-MM-DD)
  • consent_signed not set to true
  • Invalid question_code or option code for that question
  • A5 value not matching a program code in your organization
  • Extra/invalid fields that do not match schema

Notes

  • By default, uploads go to sandbox.
  • Use --production (or -p) to upload to or delete from production.
  • The API key file defaults to comhom.key if --api-key-file is omitted.
  • Client-side schema validation checks structure and required fields before upload.
  • Question-specific value validation is finalized by the server during upload.
  • Keep comhom.key out of source control.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

comhom_sdk-0.1.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

comhom_sdk-0.1.0-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file comhom_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: comhom_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for comhom_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c6c63289df57c5b09fbe9d8ab2efc1fc734ff179acea85e5ec7bc4061215c55c
MD5 56509719ba36509639819f3fe7be07ef
BLAKE2b-256 b96b8dde42974ccacfab4b697214648ca33f9745de320ed425cf90f61c43f97f

See more details on using hashes here.

File details

Details for the file comhom_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: comhom_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for comhom_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9f35cfc8e0a833f5d8b2984b1791b8df4ce44a60ce6799f8451bd9cac28ce0a2
MD5 dfa5f6cc1bf3e45a0537fe7c3969e5a5
BLAKE2b-256 3825d21ecc9a05225f3aa6ff4e09338cd77ba4b2ed1bc8d8ef5a4bf07029aff9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page