QDA Mode
QDA Mode turns Potato into a qualitative data analysis workspace. It composes Potato's universal qualitative-coding features — the codebook, memos, cases, and full-text search — into one coherent, single-coder workflow tuned for reading and coding a whole corpus (interview transcripts, open-ended survey responses, field notes, documents).
Each of those features also works on its own in standard annotation and in solo mode. QDA Mode is the switch that turns them on together with sensible defaults, so you don't have to wire each one up by hand.
What "QDA Mode" changes
Setting qda_mode.enabled: true is a single-coder posture (one analyst
over the entire corpus, no inter-annotator sampling to protect). On that
basis it flips the universal features to their qualitative defaults:
| Feature | Standard default | Under qda_mode.enabled: true |
|---|---|---|
| Codebook mode | fixed |
open — add / rename / recolor / move / delete codes while coding (opt a scheme in with codebook: true) |
| Memos sidebar | off | on (unless annotation_ui.memos: false) |
| Cases | off | on + auto-detect (unless cases.enabled: false) |
| Admin search | on (universal) | on |
| Annotator search-and-claim | off | allowed — opt in with search.annotator_claim: true |
| In-vivo coding key | i |
i (active for any span + codebook: true scheme) |
A crowdsourcing backend force-locks the codebook to fixed even
under QDA Mode — paid annotators must not reshape the shared codebook.
Every default above can be overridden explicitly; QDA Mode only changes the starting point.
Quick start
annotation_task_name: My Qualitative Study
task_dir: .
output_annotation_dir: annotation_output/
data_files:
- data/interviews.json
item_properties:
id_key: id
text_key: text
qda_mode:
enabled: true # compose codebook + memos + cases + search
codebook_invivo_key: i # mint a code from a text selection (span schemes)
cases: # group excerpts into units of analysis
enabled: true
key: participant_id
attributes: [condition]
search: # let the coder jump to any matching excerpt
enabled: true
annotator_claim: true
annotation_schemes:
- annotation_type: span # span + codebook = in-vivo coding
name: codes
description: Highlight a passage and apply (or mint, via `i`) a code
codebook: true
labels: [access barriers, cost concerns, provider trust]
The cases, search, and annotation_ui.memos blocks are optional —
QDA Mode already turns cases and memos on. Write them only to tune the
defaults (e.g. choose the cases.key, or enable annotator_claim).
A complete runnable example lives in
examples/advanced/qda-mode-example/:
python potato/flask_server.py start \
examples/advanced/qda-mode-example/config.yaml -p 8000
Configuration
qda_mode:
enabled: true
memos:
enabled: true # QDA-Mode memo defaults
show_sidebar_by_default: true
codebook:
enabled: true
mode: open # open | extensible | fixed
| Option | Default | Description |
|---|---|---|
qda_mode.enabled |
false |
Master switch. Initialises QDA Mode and applies the qualitative defaults above. |
qda_mode.memos.enabled |
true |
QDA-Mode memo default. (Memo storage is universal — see Memos.) |
qda_mode.memos.show_sidebar_by_default |
true |
Whether the Notes sidebar starts open. |
qda_mode.codebook.enabled |
true |
Whether the codebook is active. |
qda_mode.codebook.mode |
open |
Annotator edit rights — open / extensible / fixed (see Codebook modes). Equivalent to top-level codebook_mode. |
Unknown qda_mode.* keys are preserved (not rejected) so you can write
forward-compatible YAML for features that land in later phases.
Endpoints
QDA Mode mounts a small blueprint at /qda (it never collides with the
universal /api/* namespace):
| Method | Path | Purpose |
|---|---|---|
| GET | /qda/status |
Always 200. Reports whether QDA Mode is enabled and the resolved memo/codebook config — use it to confirm the mode is wired correctly. |
| GET | /qda/codebook |
QDA-scoped read view: the project codebook tree, flat labels, and cases. Returns 503 when QDA Mode is not enabled. |
The full codebook CRUD, memos, cases, and search APIs live in their own universal namespaces — see the linked feature docs.
How the pieces fit together
- Codebook is the shared, mutable set of codes. Opt a scheme into it
with
codebook: true; under QDA Mode you can grow and reorganise it while coding. - In-vivo coding (a
spanscheme that is alsocodebook: true) lets you mint a code straight from a highlighted passage — presscodebook_invivo_key(defaulti). The composer surfaces near-duplicate codes so you reuse instead of fragmenting. - Memos capture analytic notes on an instance or a specific text selection, private to you or shared with the team.
- Cases group excerpts into units of analysis (a participant, a
document) and lift case-level attributes (e.g.
condition) so the admin code crosstab can tabulate codes by participant-level variables. - Search (FTS5) lets you find any excerpt by text; with
annotator_claim: trueyou can pull a match into your queue.
Exporting your coding
Two exporters turn coded data into qualitative-research deliverables:
codebook— one row per code (hierarchy, description, colour, use count).quotation_report— one row per coded span (the quote, its character offsets, instance, and coder); addinclude_memos=trueto append memo rows too.
python -m potato.export config.yaml --format quotation_report \
--option include_memos=true -o quotations.csv
See Export formats for the column reference.