# Python Client

All notable changes to the GoFigr Python client (`gofigr`).

**Current version:** v2.3.1

***

## v2.3.1 — April 7, 2026

Patch release with Clean Room execution improvements.

### Improvements

* **Auto-injected `publish`** — `publish()` is now available in Clean Room code execution without an explicit import
* **`extra_globals` threading** — extra globals are now propagated through Clean Room execution

### Bug Fixes

* Fixed package install names for several Clean Room dependencies

***

## v2.3.0 — April 7, 2026

Minor release improving watermark sizing and `@reproducible` ergonomics.

### Improvements

* **Short ID watermarks** — watermark size calculation now uses short IDs, producing smaller and cleaner QR codes
* **QR library migration** — switched from `pyqrcodeng` to `python-qrcode`
* **`@reproducible` container support** — decorator now handles tuples, numpy arrays, and nested containers

### Bug Fixes

* Fixed `pad_for_watermark` widening images beyond the figure's intended width
* Fixed `PosixPath` serialization error in `FileData.read`

***

## v2.2.0 — March 29, 2026

Minor release introducing **Auth0 device login** in `gfconfig` and short ID watermark support.

### Highlights

* **Auth0 Device Authorization Flow** — `gfconfig` now supports Auth0 device-code login, automatically opening the browser
* **`gfconfig` UX improvements** — clearer API key prompt and auto-launch of the verification URL
* **Short ID support for watermarks** — produces compact QR codes
* **Auto-assign integration** — detects when AI is disabled and skips title auto-assignment
* **Matplotlib DPI capture** — clean room manifest now records matplotlib DPI for accurate Pyodide rendering

### Breaking Changes

* **Removed `--legacy` flag from `gfconfig`** — legacy auth path is no longer supported in the configuration tool

### Bug Fixes

* `configure()` now resets state so the extension doesn't appear ready from a prior autoconfig run

***

## v2.1.0 — March 19, 2026

Major release replacing the JupyterLab frontend extension with kernel-side notebook detection.

### Highlights

* **Simplified installation** — `pip install gofigr` no longer requires Node.js or JupyterLab build tools
* **`NotebookResolver`** — New unified detection chain (VSCode, Databricks, JPY\_SESSION\_NAME, JS Proxy) with resolution logging for debugging
* **JPY\_SESSION\_NAME detection** — Notebook name resolution now completes in under 1ms via the environment variable set by `jupyter_server` (JupyterLab 3+, Notebook 7+, JupyterHub)
* **Analysis-scoped asset sync** — File syncs (`gf.sync`) are now deferred when using `NotebookName()` until the analysis resolves, preventing unscoped assets
* **Organization logo** — New `logo` field on `gf_Organization` with `logo_image` PIL convenience property

### Bug Fixes

* Fixed widget logo images not rendering due to invalid MIME type (`data:image;base64` → `data:image/png;base64`)
* Fixed `inject_notebook_metadata` using raw proxy-format metadata instead of resolved format, causing silent `KeyError` in deferred sync processing
* Fixed manual `notebook_name`/`notebook_path` in `configure()` not feeding into the resolver
* Fixed stale display trap after reconfiguring with `auto_publish=False`
* Fixed duplicate resolution log entries from `resolve_analysis()`

### Breaking Changes

* **Removed `nest-asyncio` dependency** — code that transitively relied on GoFigr importing it will need to add it explicitly
* **Removed JupyterLab extension** — notebook detection is now handled entirely kernel-side

***

## v2.0.6 — March 12, 2026

* Fixed stale display trap causing `auto_publish=False` to be ignored on extension reload

***

## v2.0.5 — March 12, 2026

* Fixed pickle filename crash when `revision_index` is None (client-side UUID)

***

## v2.0.4 — March 12, 2026

* Fixed display crash on older IPython by falling back to `IPython.core.display`

***

## v2.0.3 — March 12, 2026

* Fixed `importlib.resources.files()` AttributeError on Python 3.8

***

## v2.0.2 — March 12, 2026

Patch release with bug fixes and new configuration options.

### Improvements

* **`auto_configure` switch** — New option to disable automatic configuration on Jupyter extension load
* **Client-side UUID generation** — Revision UUIDs are now generated client-side, reducing two API calls to one during figure publication

### Bug Fixes

* Fixed `sorted()` TypeError for list fields containing dicts
* Fixed null publisher crash when `auto_configure` is disabled

***

## v2.0.1 — March 5, 2026

Patch release improving widget resilience and `@reproducible` ergonomics.

### Improvements

* **Graceful anywidget fallback** — When `anywidget` is missing or its JupyterLab extension is not registered, interactive figures now fall back to non-interactive rendering with a warning banner instead of crashing
* **`check_anywidget_health()` utility** — New diagnostic function for step-by-step troubleshooting of widget issues (checks package installation, traitlets, Jupyter kernel, and provides frontend extension guidance)
* **Bare `@reproducible` support** — The decorator can now be used without parentheses (`@reproducible` is equivalent to `@reproducible()`)

### Files Changed

* `gofigr/reproducible.py` — +142 lines: `_ANYWIDGET_WARNING_HTML`, `check_anywidget_health()`, `_run_interactive_fallback()`, updated `reproducible()` signature

***

## v2.0.0 — March 5, 2026

Major release introducing **Clean Room** reproducibility and **Pyodide** support.

### Clean Room: Reproducible Figures

* **`@reproducible` decorator** — Capture source code, parameters, and package dependencies with every published figure
* **Interactive parameter widgets** — `SliderParam`, `DropdownParam`, `CheckboxParam`, `TextParam`, and `StaticParam` for in-browser figure re-rendering
* Parameter serialization supports JSON (primitives) and Parquet (DataFrames) with 100MB size limit
* Cross-language parameter model enables future R client support

### Pyodide Support

* **`PyodidePublisher`** — Publish figures from browser-based Python environments (e.g., JupyterLite)
* SVG added to default Pyodide image formats for vector export
* Guarded all optional imports (`IPython`, `blake3`, `git`, `py3Dmol`, etc.) for restricted environments

### Performance & Compatibility

* **API v1.4** — `Workspace.list()` uses shallow serialization, significantly speeding up `configure()` in Jupyter
* **Watermark stabilization** — Padding no longer causes figure size shifts on publish
* **Python 3.12 compatibility** — Replaced `pkg_resources` with `pathlib.Path` and updated `importlib.resources` APIs
* Switched from `pyqrcode` to `pyqrcodeng`
* Added `pyarrow` dependency for Parquet support

### Breaking Changes

* API version bumped from v1.3 to v1.4 — requires server v2.5.0+
* `Workspace.list()` no longer returns nested analyses/assets/stories; call `.fetch()` on individual workspaces for full details

***

## v1.3.2 and earlier

Previous releases focused on core figure publishing, Jupyter integration, and workspace management. See the [GitHub repository](https://github.com/GoFigr/gofigr-python) for the full commit history.
