Skip to main content

fielddash

Documentation: https://lambdageo.github.io/fielddash/

Schema-driven dashboards for field data collection (Epicollect5), built directly from the form schema. Every question is identified by Epicollect's stable ref, and its input type (radio, checkbox, integer, location, ...) automatically dictates the filter, chart, and map representation. Modifying, adding, or reordering questions in the form does not break the dashboard, and setting up a new fieldwork survey requires only a YAML configuration file.

Ready-to-use pages:

  • Overview: summary indicators, map, submissions over time, collectors.
  • Highlights: curated charts configured in your YAML.
  • Questions: all questions grouped by section, with search, text-field toggle, and dynamic cross-tabulation.
  • Data: searchable table with CSV and Excel export.

Installation

Install it in an isolated environment rather than globally.

One environment per project (recommended). Works everywhere and is required for deployment and custom pages:

mkdir my-survey && cd my-survey
python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install fielddash
fielddash init .

Nothing installed first. pipx or uv can run init once; then create the environment from the generated requirements.txt:

pipx run fielddash init my-survey       # or: uvx fielddash init my-survey
cd my-survey
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

Command line only. If you never edit code in the project, pipx install fielddash (or uv tool install fielddash) is enough for init, fields and run. The streamlit_app.py generated by --deploy imports fielddash, so it needs the per-project environment above.

For development: git clone https://github.com/LambdaGeo/fielddash && cd fielddash && pip install -e ".[dev]".

Quickstart

The example project lives in the repository; it is not part of the PyPI package.

git clone https://github.com/LambdaGeo/fielddash && cd fielddash
python -m venv .venv && source .venv/bin/activate
pip install -e .
fielddash run examples/waste/project.yaml

The example uses anonymized household survey data on solid waste management (Itaqui-Bacanga, São Luís – MA) and showcases a custom project page (Recycling).

Setting Up a New Field Project

  1. Scaffold the project folder:

    fielddash init my-survey            # project.yaml, requirements.txt, .env.example, .gitignore
    fielddash init my-survey --deploy   # + streamlit_app.py, secrets example
    fielddash init my-survey --source json   # offline project reading data/ (git-ignored)
    

    Then cp .env.example .env and fill in the project slug and the Epicollect app credentials (generated under Apps in your project's administration area):

    PROJECT_MY_SURVEY=project-slug
    MY_SURVEY_CLIENT_ID=...
    MY_SURVEY_CLIENT_SECRET=...
    

    Public projects do not require credentials: simply omit credentials in the config.

  2. The generated project.yaml starts minimal (or write it by hand):

    title: "My Field Survey"
    source:
      type: epicollect
      project: ${PROJECT_MY_SURVEY}    # slug, or the literal value
      credentials: MY_SURVEY
    
  3. Inspect the form fields to select aliases, filters, and highlights:

    fielddash fields project.yaml
    
  4. Complete the configuration (all keys below are optional) and run fielddash run project.yaml:

    subtitle: "Research team, institution..."
    fields:            # alias -> ref suffix, column, or question label
      neighborhood: "5401ce"
      waste_dest: "48c35e"
    types:             # force type (e.g. treat free text as category)
      neighborhood: category
    ignore: [created_by, "3401cb"]   # hide fields (e.g. collector email)
    filters: [created_at, neighborhood]
    highlights:
      - {field: waste_dest, by: neighborhood, title: "Waste destination by neighborhood"}
    sections:          # tabs on the Questions page (default: form groups)
      - {title: "Profile", fields: [age, gender]}
    map: {field: location, popup: [neighborhood]}
    extensions: [pages]              # .py files or directories with custom pages
    timezone: America/Fortaleza
    cache_minutes: 5
    

    (Portuguese keys from early versions — titulo, fonte, campos, ... — still load but are deprecated and emit a warning.)

Running fielddash run folder/ will scan all .yaml files in the directory and present a project selector in the sidebar. To work offline or test without internet access, use source: {type: json, data: ..., schema: ...} (as shown in examples/waste/project.yaml).

Using in a Custom Streamlit Script / Deployment

The dashboard can also be invoked as a Python function inside your own Streamlit app:

# streamlit_app.py
import fielddash

fielddash.dashboard("projects/")          # or "projects/waste.yaml"

Relative paths are resolved relative to the current directory or the script folder. Run with:

streamlit run streamlit_app.py

Streamlit Community Cloud

  1. Create the project with the deploy files and try it locally:
    mkdir my-survey && cd my-survey
    python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
    pip install fielddash
    fielddash init . --deploy
    cp .env.example .env          # fill in, then edit project.yaml
    streamlit run streamlit_app.py
    
  2. Push the folder to a GitHub repository. .env and .streamlit/secrets.toml are git-ignored: credentials never go to the repo.
  3. On share.streamlit.io choose Create app, pick the repository and branch, and set streamlit_app.py as the main file.
  4. Under Advanced settings → Secrets (later: Settings → Secrets) paste the content of .streamlit/secrets.toml.example, filled in:
    FIELD_ACCESS_PIN = "choose-a-code"
    PROJECT_MY_SURVEY = "project-slug"
    MY_SURVEY_CLIENT_ID = "..."
    MY_SURVEY_CLIENT_SECRET = "..."
    
  5. Deploy, then share the app link, or https://<your-app>.streamlit.app/?token=<code> to skip the login screen.

Notes:

  • Use source: {type: epicollect} for the cloud. A type: json project reads data/, which is git-ignored on purpose (it may hold personal data), so it only works locally.
  • Without FIELD_ACCESS_PIN the app is public: anyone with the link sees the data.

fielddash checks environment variables and .env first, then falls back to st.secrets (also resolving ${VAR} references in YAML). The data cache is shared among server sessions, so Epicollect receives at most one request per project every cache_minutes.

Restricting access

A deployed Streamlit app is public by default. Add fielddash.require_access() before fielddash.dashboard(...) (fielddash init --deploy already does) and set FIELD_ACCESS_PIN in the secrets: visitors then see a login screen, or can use a link ending in ?token=<code>. Without the variable the call does nothing.

Self-Hosted Server

fielddash run projects/ --server.port 8501 --server.headless true

(e.g., as a systemd service behind an Nginx reverse proxy with HTTPS).

Custom Pages

A project-specific page is a standard .py file listed in extensions:

from fielddash.core.registry import page
from fielddash.ui.charts import render_field


@page("Recycling", order=40)
def render(ctx):
    ds = ctx.dataset
    render_field(ds, ctx.df, ds.field("recycle_habit"), by=ds.field("neighborhood"))
  • ctx.df provides the data with all active sidebar filters applied.
  • ds.field("alias") resolves the field (column, type, options) dynamically by its stable schema ref.
  • Additional data sources (e.g. KoboToolbox, CSV) can be registered with @source("type").

Project Structure

fielddash/
  cli.py            CLI commands `fielddash init`, `run` and `fields`
  scaffold.py       templates and writer behind `fielddash init`
  access.py         `fielddash.require_access()`: optional PIN/token gate
  web.py            `fielddash.dashboard()`: config, cache, filters, navigation
  app.py            Streamlit entry point used by `fielddash run`
  core/schema.py    Epicollect schema parser -> list[Field], column naming, reconciliation
  core/normalize.py raw entries -> typed series (ordered categories, lists, coords, datetimes)
  core/config.py    YAML config parser (+ ${VAR} resolution from .env and secrets)
  sources/          data source plugins (@source): epicollect (API, pagination), json
  ui/               dynamic filters, charts, and maps based on field types
  views/            default pages (@page): Overview, Highlights, Questions, Data
examples/           example projects with anonymized datasets
tests/              pytest test suite (schema, index shifting, AppTest integration)
docs/               MkDocs site (`mkdocs serve`); docs/history/ holds the original development plan

Running Tests

pytest

Building the Documentation

pip install -e ".[docs]"
mkdocs serve            # http://127.0.0.1:8000
mkdocs build --strict   # what CI runs

Releasing (maintainers)

  1. Bump the version in pyproject.toml, fielddash/__init__.py and CITATION.cff.
  2. Publish a GitHub Release: .github/workflows/publish.yml builds the package and uploads it to PyPI through Trusted Publishing (no token stored).

One-time setup on pypi.org → Publishing → Add a new pending publisher: project fielddash, owner LambdaGeo, repository fielddash, workflow publish.yml. PyPI never lets a published version be overwritten, so check with python -m build && twine check dist/* (and optionally TestPyPI) first.

Authors

  • Sergio Costa (@LambdaGeo) — Universidade Federal do Maranhão (UFMA)
  • André Moura Lima (@AndreMouraL) — Universidade Federal do Maranhão (UFMA)
  • Ricardo Luvizotto Santos — Universidade Federal do Maranhão (UFMA)
  • Marianna Basso Jorge — Universidade Federal do Maranhão (UFMA)

License

MIT — see LICENSE.

Metadata

Release files for fielddash 0.1.1

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

Source distribution (sdist)

Source distribution for fielddash 0.1.1
File Size Uploaded
fielddash-0.1.1.tar.gz 37.6 kB Details

Built distribution (wheel)

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

Total release size: 75.5 kB

Release files / fielddash-0.1.1.tar.gz

Download URL fielddash-0.1.1.tar.gz
Size 37.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9f3779c862fb170b8579daabdbd326197e1edfc4516e1ef3183e4be3e86e4fcc
BLAKE2b-256 checksum
How to use checksums
2598c94daa43bfed721f105f3fb6957e2473453e4e64334bf38e8e66071c1c58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / fielddash-0.1.1-py3-none-any.whl

Download URL fielddash-0.1.1-py3-none-any.whl
Size 37.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8fccd3fc1435ddd9c736674cd6e4209f760eb93eac2b8c8a36607a2cb1a97d23
BLAKE2b-256 checksum
How to use checksums
7b86eb0012b4c67ec1f0305478bf6c2d2f724c53319f8c9a2e0b001971ef782f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

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