|
| 1 | +# guidata AI Coding Agent Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +**guidata** is the foundational library of the PlotPyStack, providing automatic GUI generation from Python data structures. It enables declarative definition of parameter sets that automatically generate Qt editing widgets. |
| 6 | + |
| 7 | +### Technology Stack |
| 8 | + |
| 9 | +- **Python**: 3.9+ (`from __future__ import annotations`) |
| 10 | +- **Core**: NumPy (≥1.22), h5py (≥3.6), QtPy (≥1.9) |
| 11 | +- **GUI**: Qt via QtPy (PyQt5/PyQt6/PySide6) |
| 12 | +- **Testing**: pytest |
| 13 | +- **Linting**: Ruff (preferred), Pylint |
| 14 | + |
| 15 | +### Architecture |
| 16 | + |
| 17 | +``` |
| 18 | +guidata/ |
| 19 | +├── dataset/ # Core DataSet system (items, types, serialization) |
| 20 | +├── widgets/ # Ready-to-use Qt widgets (console, editors, browsers) |
| 21 | +├── io/ # HDF5, JSON, INI serialization |
| 22 | +├── utils/ # CLI tools (translations, build, cleanup) |
| 23 | +├── config.py # Configuration and translation setup |
| 24 | +├── configtools.py # Image/icon path management |
| 25 | +├── qthelpers.py # Qt utility functions |
| 26 | +└── tests/ # pytest suite |
| 27 | +``` |
| 28 | + |
| 29 | +## Development Workflows |
| 30 | + |
| 31 | +### Running Commands |
| 32 | + |
| 33 | +```powershell |
| 34 | +python -m pytest --ff # Run tests |
| 35 | +python -m ruff format # Format code |
| 36 | +python -m ruff check --fix # Lint with auto-fix |
| 37 | +python -m guidata.utils.translations scan --name guidata --directory . # Update .po files |
| 38 | +``` |
| 39 | + |
| 40 | +### CLI Tools |
| 41 | + |
| 42 | +guidata provides command-line utilities: |
| 43 | + |
| 44 | +```powershell |
| 45 | +gtrans scan --name myapp --directory . # Scan for translatable strings |
| 46 | +gtrans compile --name myapp --directory . # Compile .mo files |
| 47 | +greqs all # Generate requirements docs |
| 48 | +gbuild # Secure package build |
| 49 | +gclean # Cleanup build artifacts |
| 50 | +``` |
| 51 | + |
| 52 | +## Core Patterns |
| 53 | + |
| 54 | +### DataSet System |
| 55 | + |
| 56 | +The heart of guidata - declarative parameter definitions: |
| 57 | + |
| 58 | +```python |
| 59 | +import guidata.dataset as gds |
| 60 | + |
| 61 | +class ProcessingParams(gds.DataSet): |
| 62 | + """Parameters for my processing.""" |
| 63 | + |
| 64 | + threshold = gds.FloatItem("Threshold", default=0.5, min=0, max=1) |
| 65 | + method = gds.ChoiceItem("Method", ["fast", "accurate"], default="fast") |
| 66 | + enabled = gds.BoolItem("Enable feature", default=True) |
| 67 | + |
| 68 | + # Factory method for script-friendly instantiation |
| 69 | + @staticmethod |
| 70 | + def create(threshold: float = 0.5, method: str = "fast") -> ProcessingParams: |
| 71 | + return ProcessingParams(threshold=threshold, method=method) |
| 72 | +``` |
| 73 | + |
| 74 | +### Available Data Items |
| 75 | + |
| 76 | +| Item Type | Purpose | |
| 77 | +|-----------|---------| |
| 78 | +| `IntItem`, `FloatItem` | Numeric input with optional bounds | |
| 79 | +| `StringItem`, `TextItem` | Single/multi-line text | |
| 80 | +| `BoolItem` | Checkbox | |
| 81 | +| `ChoiceItem`, `MultipleChoiceItem` | Single/multiple selection | |
| 82 | +| `ColorItem`, `FontFamilyItem` | Color/font pickers | |
| 83 | +| `FileOpenItem`, `FileSaveItem`, `DirectoryItem` | Path selection | |
| 84 | +| `DateItem`, `DateTimeItem` | Date/time pickers | |
| 85 | +| `FloatArrayItem` | NumPy array editor | |
| 86 | +| `DictItem` | Dictionary editor | |
| 87 | + |
| 88 | +### DataSet Groups and Tabs |
| 89 | + |
| 90 | +Organize items visually: |
| 91 | + |
| 92 | +```python |
| 93 | +class MyParams(gds.DataSet): |
| 94 | + # Tab groups |
| 95 | + _bg = gds.BeginTabGroup("Settings") |
| 96 | + |
| 97 | + _t1 = gds.BeginGroup("General") |
| 98 | + name = gds.StringItem("Name") |
| 99 | + _t1e = gds.EndGroup("General") |
| 100 | + |
| 101 | + _t2 = gds.BeginGroup("Advanced") |
| 102 | + iterations = gds.IntItem("Iterations", default=100) |
| 103 | + _t2e = gds.EndGroup("Advanced") |
| 104 | + |
| 105 | + _bge = gds.EndTabGroup("Settings") |
| 106 | +``` |
| 107 | + |
| 108 | +### Serialization |
| 109 | + |
| 110 | +DataSets support multiple formats: |
| 111 | + |
| 112 | +```python |
| 113 | +# HDF5 |
| 114 | +from guidata.io import HDF5Reader, HDF5Writer |
| 115 | +with HDF5Writer("params.h5") as writer: |
| 116 | + params.serialize(writer) |
| 117 | + |
| 118 | +# JSON |
| 119 | +from guidata.dataset import dataset_to_json, json_to_dataset |
| 120 | +json_str = dataset_to_json(params) |
| 121 | +restored = json_to_dataset(json_str) |
| 122 | +``` |
| 123 | + |
| 124 | +### GUI Integration |
| 125 | + |
| 126 | +Display/edit DataSets in dialogs: |
| 127 | + |
| 128 | +```python |
| 129 | +# Edit in modal dialog |
| 130 | +params = ProcessingParams() |
| 131 | +if params.edit(): # Returns True if OK clicked |
| 132 | + print(f"Threshold: {params.threshold}") |
| 133 | + |
| 134 | +# Embed in custom widget |
| 135 | +from guidata.dataset.qtwidgets import DataSetEditGroupBox |
| 136 | +groupbox = DataSetEditGroupBox("Parameters", ProcessingParams) |
| 137 | +``` |
| 138 | + |
| 139 | +## Coding Conventions |
| 140 | + |
| 141 | +### Type Annotations |
| 142 | + |
| 143 | +```python |
| 144 | +from __future__ import annotations |
| 145 | +``` |
| 146 | + |
| 147 | +### Translations |
| 148 | + |
| 149 | +```python |
| 150 | +from guidata.config import _ |
| 151 | + |
| 152 | +label = _("Processing parameters") # ✅ Translatable |
| 153 | +``` |
| 154 | + |
| 155 | +### Docstrings |
| 156 | + |
| 157 | +Google-style: |
| 158 | + |
| 159 | +```python |
| 160 | +def create_widget(parent: QWidget | None = None) -> DataSetEditGroupBox: |
| 161 | + """Create parameter editing widget. |
| 162 | +
|
| 163 | + Args: |
| 164 | + parent: Parent widget |
| 165 | +
|
| 166 | + Returns: |
| 167 | + Configured edit group box |
| 168 | + """ |
| 169 | +``` |
| 170 | + |
| 171 | +## Key Files Reference |
| 172 | + |
| 173 | +| File | Purpose | |
| 174 | +|------|---------| |
| 175 | +| `guidata/dataset/__init__.py` | All DataSet exports | |
| 176 | +| `guidata/dataset/dataitems.py` | Item definitions (IntItem, etc.) | |
| 177 | +| `guidata/dataset/datatypes.py` | DataSet base class | |
| 178 | +| `guidata/dataset/qtwidgets.py` | Qt widget generation | |
| 179 | +| `guidata/dataset/io.py` | Serialization support | |
| 180 | +| `guidata/config.py` | Configuration, `_()` function | |
| 181 | +| `guidata/qthelpers.py` | Qt utilities | |
| 182 | +| `guidata/utils/translations.py` | Translation CLI | |
| 183 | + |
| 184 | +## Related Projects |
| 185 | + |
| 186 | +- **PythonQwt**: Low-level Qt plotting (sibling) |
| 187 | +- **PlotPy**: Interactive plotting using guidata (downstream) |
| 188 | +- **Sigima/DataLab**: Scientific applications (downstream) |
0 commit comments