manifest
Whether one project has answered each question a plugin can ask about it.
from plexora.api import manifestEvery surface in Plexora -- a plugin's Requires, the edit page, the Open
Project card's "Needs setup" badge, the CLI, the Python API -- asks some form
of "does this project have X yet". This module is the one place that answers
it, so every reader agrees on what "has a table" means.
This module tracks three states, not two:
PRESENT-- the user answered this, and the answer is recorded.GUESSED-- there is a value, but Plexora worked it out. A guess that happens to be right is still a guess, so the first tool that depends on one shows it back once, for confirmation.MISSING-- nothing, and nothing to show back.
Plus NOT_APPLICABLE, for a question this project's format cannot be asked
at all: an AnnData's x/y do not exist as columns, because the adapter builds
them from a read spec, so offering two column selects for them is a form
with no possible answer in it. That is a different thing from missing.
Members
summary
summary(project: Project) -> dictThe short form a project card or a CLI listing is drawn from.
Deliberately not the whole manifest: a page listing two hundred projects wants a handful of facts about each, not the full set of questions.
projectProjectrequiredThe project to summarize.
dictThe image kind, the segmentation and table status, the dataset type, what is still unresolved, whether the project needs setup, and its layer count and modalities.
status
status(project: Project, key: str) -> dictThe state of one question about a project.
value is what a surface shows back -- a path, a column name, a list --
or None. For "table" on a source that cannot yet be read it is the
dict {src, table, unresolved}, which is what the requirements modal
prefills its data field from: the user already gave the path, so asking
for it again is asking a question they already answered.
projectProjectrequiredThe project to check, e.g. dataset.project from
a ProjectData handle.
keystrrequiredWhich question to ask. One of KEYS.
dict{"status": ..., "value": ..., "confirmed": ...}. status is
one of PRESENT, GUESSED, MISSING or NOT_APPLICABLE.
KeyErrorIf key is not one of KEYS.
answered
answered(project: Project, key: str) -> boolWhether the project holds a value for this question, guessed or given.
Says nothing about who supplied the value -- a predictor's guess counts
as answered here the same as something the user typed in. status() is
what tells the two apart.
projectProjectrequiredThe project to check.
keystrrequiredWhich question to ask. One of KEYS.
boolTrue if status(project, key) is PRESENT or GUESSED.
KeyErrorIf key is not one of KEYS.
open_questions
open_questions(project: Project, keys=None) -> list[str]Which questions this project still cannot answer, in ask order.
A role question ("role:cell_id", and the rest) is withheld while the
table itself is unanswered: asking which column holds the cell id before
any columns exist is a question with no possible answer, and "table"
already covers it.
projectProjectrequiredThe project to check.
keyslist[str]default NoneWhich questions to consider. Defaults to
every key in KEYS.
list[str]The keys from keys this project has not answered, in
KEYS order.
needs_setup
needs_setup(project: Project) -> boolWhether this project is holding a question it cannot answer itself.
Only the one state deserves a badge on a card: a data file was named and something about it is still undecided, so the project silently opens as an image and the user has no other way to find out why. An image-only project is never flagged -- that is a complete, valid project, and the whole premise of "an image alone is enough".
projectProjectrequiredThe project to check.
boolTrue if the project has anything left unresolved.
KEYS
KEYS = ('image', 'segmentation', 'table', 'features', 'markers', 'coordinates', 'role:cell_id', 'role:x', 'role:y', 'role:image_id', 'role:celltype', 'role:z', 'role:t')Every question core can record an answer to, in the order a form should ask them: the files first, then what is inside them, then what the columns mean.
PRESENT
PRESENT = 'present'The user answered this question, and the answer is recorded.
GUESSED
GUESSED = 'guessed'There is a value, but Plexora worked it out rather than being told. A guess that happens to be right is still a guess.
MISSING
MISSING = 'missing'Nothing is recorded, and there is nothing to show back.
NOT_APPLICABLE
NOT_APPLICABLE = 'not_applicable'This project's format cannot be asked this question at all -- a different thing from missing, and not a gap for the user to fill.