spacr.qt.ask_for_the_path¶
When the usual way of finding something fails, ask for it.
THESE ARE BACKUPS, not the normal route. The ordinary resolution runs first every time; this is reached only once it has already failed. A run that works today must not gain a dialog, and a user who never hits the failure must never see one.
A DIALOG IS BETTER THAN AN ERROR HERE because the information is one the user has and the program does not. The current behaviour on each of these is to stop with a message naming the thing that is missing – which means the program already knows precisely what to ask for. Asking is strictly more useful than reporting, and costs one dialog instead of one aborted run.
What every prompt owes, and what this module enforces so a caller cannot forget one:
SAY WHAT WAS TRIED FIRST, so a typo in a setting is distinguishable from a genuinely missing folder;
VALIDATE BEFORE ACCEPTING – a chosen folder with nothing in it is the same failure one step later;
ASK ONCE PER RUN, not once per image, per well or per plate;
WRITE IT BACK and say so, because a setting that changes without being announced is worse than one that does not;
BE REFUSABLE: cancel means the run stops with the error it would have given anyway;
NEVER APPEAR HEADLESS. In a script, a test or a batch run there is nobody to answer, so the fallback resolves to the original error rather than blocking on a dialog nobody can see. This is the one that would hang a pipeline overnight, and it is checked before anything else.
Functions¶
|
A validator: the folder must hold at least one file with a suffix. |
|
Ask for a database, a table within it, and a column within that. |
|
Ask for a folder after the usual resolution has failed. |
|
Every column of one table, in the order the table declares them. |
|
Drop every remembered answer. For tests, and for a new run. |
|
What was already answered for |
|
Whether there is a person who could answer a dialog. |
|
Every table in a SQLite file, or an empty list if it is not one. |
Module Contents¶
- spacr.qt.ask_for_the_path.a_folder_holding(*suffixes: str) Callable[[str], str | None][source]¶
A validator: the folder must hold at least one file with a suffix.
A chosen folder with nothing in it is the same failure one step later, which is what makes validating before accepting worth the code.
- spacr.qt.ask_for_the_path.ask_for_a_database_column(key: str, *, tried: str, what: str = 'Coordinate column', parent=None, chooser: Callable[..., str] | None = None, pick: Callable[..., str | None] | None = None) Tuple[Tuple[str, str, str] | None, str][source]¶
Ask for a database, a table within it, and a column within that.
THREE ANSWERS, NOT ONE, because that is what the coordinate stream needs and asking for them one at a time is what makes the second and third answerable: the tables offered are the ones the chosen database actually holds, and the columns are that table’s. A blank field would ask the user to remember a name the program can read.
- Parameters:
key – what is being asked for; the answer is remembered under it.
tried – what was tried and did not work, shown in each title.
chooser – injected for tests; defaults to a real file dialog.
pick – injected for tests; defaults to a real list dialog. Called
(title, prompt, options)and returns the choice or None.
- Returns:
((database, table, column), why), or(None, why). The reason always says WHICH of the three stops – nobody there, a cancel, or a database with nothing in it – because a caller that prints it is the only account the user gets.
Backing out of a later step returns to the earlier one rather than abandoning the whole form, so choosing the wrong database costs one click instead of the run.
- spacr.qt.ask_for_the_path.ask_for_a_folder(key: str, *, tried: str, what: str, validate: Callable[[str], str | None] | None = None, parent=None, chooser: Callable[..., str] | None = None) Tuple[str | None, str][source]¶
Ask for a folder after the usual resolution has failed.
- Parameters:
key – what is being asked for. The answer is remembered under it, so the second image of a run does not ask again.
tried – what was tried and did not work, said before the chooser so the user knows why they are being asked.
what – a short name for the thing wanted, for the dialog title.
validate – given a chosen path, returns None when it is usable or a sentence saying why it is not. The dialog stays open on a refusal.
chooser – injected for tests. Defaults to a real folder dialog.
- Returns:
(path, why).pathis None when nobody answered, when the user cancelled, or when there is nobody there – andwhyalways says which, because those are three different situations.
- spacr.qt.ask_for_the_path.columns_in(database: str, table: str) list[source]¶
Every column of one table, in the order the table declares them.
PRAGMAtakes no bound parameters, so the table name is quoted here. SQLite escapes a quote inside a quoted identifier by doubling it, and a table really can be namedcell"s– unescaped, the identifier ends early and the whole table reads as having no columns at all.- Parameters:
database – path to the SQLite file, opened read-only; any failure yields an empty list.
table – name of the table whose columns are listed; embedded double quotes are escaped before it is quoted into the
PRAGMA.
- spacr.qt.ask_for_the_path.forget() None[source]¶
Drop every remembered answer. For tests, and for a new run.
- spacr.qt.ask_for_the_path.remembered(key: str) str | None[source]¶
What was already answered for
key, if anything.- Parameters:
key – the key an
ask_for_...call remembered its answer under. ReturnsNonewhen nothing was answered for it in this run.
- spacr.qt.ask_for_the_path.somebody_is_there() bool[source]¶
Whether there is a person who could answer a dialog.
False under pytest, with no display, or before a QApplication exists. Checked FIRST and on its own, because getting it wrong does not show a dialog to nobody – it BLOCKS, and a blocked batch run looks like a hang.
- spacr.qt.ask_for_the_path.tables_in(database: str) list[source]¶
Every table in a SQLite file, or an empty list if it is not one.
Never raises: a path the user chose is a path that may be anything, and “this file holds no tables” is the sentence the form needs rather than an exception it would have to catch anyway.
- Parameters:
database – path to the file to read, opened read-only as SQLite. Any failure to open or query it yields an empty list.
Nested helpers¶
- a_folder_holding.check(path: str) str | None¶
Say what is wrong with a path, or
Nonewhen it will do.Returns the COMPLAINT rather than a bool, so the caller can show the reason instead of a bare refusal.
spacr/qt/ask_for_the_path.py:136
- ask_for_a_database_column.chooser(title, start='')¶
Open the database file dialog. Injected for testing.
spacr/qt/ask_for_the_path.py:251
- ask_for_a_database_column.pick(title, prompt, options)¶
Ask which column, from the ones the database actually has.
spacr/qt/ask_for_the_path.py:260
- ask_for_a_folder.chooser(title, start='')¶
Open the folder dialog. Injected so the flow can be tested.
spacr/qt/ask_for_the_path.py:112