docs: split Autodesk connector docs into user + developer pages

`autodesk.rst` had grown to mix end-user concerns (where do my tokens
live, how do I install the bundle, why isn't sign-in working) with
developer concerns (cargo build, fmt/clippy/test, packaging script
flow, per-OS toolchain notes, CI). Reorganise into:

* **`autodesk.rst`** — Autodesk Connector. User-facing. Bonsai-Viewer-
  level intro (Forma/APS/Docs, "Add from cloud"); install-from-zip
  per OS; first-run setup (client ID, OAuth port, browser redirect);
  where settings / cache / OAuth tokens live; proxy / TLS guidance
  for corporate installs.

* **`autodesk_development.rst`** — Autodesk Connector Development.
  Developer-facing. Tech stack (FLTK, ureq, keyring, dirs, serde,
  chrono, webbrowser); `cargo build --release`; `cargo test
  --all-features` / clippy / fmt-check; protocol probing via stdio
  pipe; packaging via `packaging/build.py`; per-OS build / keychain
  / codesign notes; CI workflow overview. Absorbs the entirety of
  the old `autodesk_packaging.rst`, which is removed.

`connectors/index.rst` toctree updated: `autodesk_packaging` →
`autodesk_development`. `cloud_sync_protocol.rst` untouched —
language-agnostic protocol spec.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-06-04 15:57:40 +10:00
parent 9d9f4054f6
commit ce7d2fa329
6 changed files with 279 additions and 1257 deletions
+92 -67
View File
@@ -1,107 +1,132 @@
Autodesk Connector
==================
The Autodesk connector integrates Bonsai Viewer with Autodesk Forma, APS, and
Docs. It implements the cloud connector protocol and runs as a separate process
that Bonsai Viewer launches and communicates with over standard input and
standard output.
The connector UI is built with CustomTkinter. The Python runtime used for
development or packaging must include ``tkinter``. On Gentoo, make sure
``dev-lang/python`` is built with ``USE="tk"``.
The Autodesk connector lets Bonsai Viewer open and save projects and models
hosted on Autodesk Forma, APS, and Docs.
Install
-------
From the repository root:
The connector ships pre-built next to the Bonsai Viewer executable. There
should be nothing for users to install.
If you do want to manually install a specific version, extract the zip into the
``connectors`` directory beside the Bonsai Viewer executable:
Linux:
.. code-block:: bash
cd src/bonsaiviewer-autodesk
python -m venv venv
source venv/bin/activate
pip install -e .
unzip autodesk-linux-x86_64.zip -d <application-dir>/connectors/
Run
---
macOS:
.. code-block:: bash
bonsaiviewer-autodesk
unzip autodesk-macos-arm64.zip -d "<application-dir>/connectors/"
The connector launches without configuration. On first run, open the settings
dialog to configure the Autodesk client ID and OAuth callback port.
Windows PowerShell:
For direct protocol testing, send newline-delimited JSON-RPC 2.0 requests on
standard input:
.. code-block:: powershell
.. code-block:: json
Expand-Archive autodesk-windows-x86_64.zip -DestinationPath "<application-dir>\connectors\"
{"jsonrpc":"2.0","id":"0","method":"open_settings"}
{"jsonrpc":"2.0","id":"1","method":"pull_ifcfed_interactive"}
{"jsonrpc":"2.0","id":"2","method":"pull_models","params":[{"display_name":"foo.ifc","id":"abc","source":{"connector":"autodesk","hub_id":"b.hub","project_id":"b.proj","item_id":"urn:adsk...","version_id":"latest"}}]}
{"jsonrpc":"2.0","id":"3","method":"push_ifcfed_interactive","params":{"path":"/tmp/project.ifcfed"}}
{"jsonrpc":"2.0","id":"4","method":"push_ifcfed","params":{"path":"/tmp/project.ifcfed","manifest":{"connector":"autodesk","hub_id":"b.hub","project_id":"b.proj","item_id":"urn:adsk..."}}}
Bonsai Viewer discovers the connector on next launch.
Bonsai Viewer is expected to launch this binary once per session and keep it
alive until shutdown. Closing the connector's standard input triggers a clean
exit.
First-run setup
---------------
Configuration
-------------
The first time you sign in, the connector needs an Autodesk APS client ID.
You provide one through the connector's settings dialog.
The connector reads the Autodesk client ID from ``settings.json`` in the
connector config directory, written by the settings dialog.
- **Client ID** — the APS application client ID you created in the Autodesk
developer portal. Used as the OAuth audience.
- **OAuth callback port** — defaults to ``8080``. The OAuth callback host is
always ``localhost``. Change this if ``8080`` is already in use on your
machine.
The OAuth callback host is always ``localhost``. The callback port defaults to
``8080`` and can be changed in the settings dialog.
When you sign in, the connector opens your default browser at the Autodesk
authorization page. After you approve, the redirect lands back at
``http://localhost:<port>/`` and the connector picks up the auth code, then
exchanges it for tokens via PKCE.
The config directory is platform-specific:
Where things are stored
-----------------------
The connector writes three things to disk: a small settings file, a cache
of resolved files, and OAuth tokens.
**Settings** (``settings.json``) — the client ID and OAuth port you set
above:
- Linux: ``~/.config/bonsaiviewer-autodesk/``
- macOS: ``~/Library/Application Support/bonsaiviewer-autodesk/``
- Windows: ``%APPDATA%\bonsaiviewer-autodesk\``
OAuth tokens are stored in the OS keychain, keyed by the client ID. Changing
the client ID starts a fresh sign-in session. The keychain backend is Secret
Service on Linux, Keychain on macOS, and Credential Manager on Windows.
Cache
-----
The connector owns its own cache. On Linux, resolved files live under:
**Cache** — every file you pull from Autodesk lands here under a content-
hashed directory:
.. code-block:: text
~/.cache/bonsaiviewer-autodesk/
~/.cache/bonsaiviewer-autodesk/ (Linux)
~/Library/Caches/bonsaiviewer-autodesk/ (macOS)
%LOCALAPPDATA%\bonsaiviewer-autodesk\Cache\ (Windows)
ifcfeds/<hash>/<name>.ifcfed[.manifest]
models/<hash>/<filename>
Each resolved file is the sole child in its directory so Bonsai Viewer can
write sidecar files, such as ``.ifcview``, next to it without colliding. A new
resolved model version lands in a fresh ``models/<hash>/`` directory. Old cache
directories may be removed manually to clear space.
write sidecar files (``.ifcview``, etc.) next to it without colliding. A
new version of a cloud model lands in a fresh ``models/<hash>/``
directory. Old cache directories can be deleted manually to reclaim disk
space; the connector will re-resolve them on next request.
Status
------
**OAuth tokens** — stored in your OS keychain, keyed by client ID:
Implemented:
- Linux: Secret Service (gnome-keyring, KWallet, …)
- macOS: Keychain
- Windows: Credential Manager
- strict JSON-RPC 2.0 host over stdio
- APS PKCE sign-in with keyring-backed token storage
- hub, project, and folder browsing
- ``pull_ifcfed_interactive``, ``pull_ifcfed``, ``pull_models``, and
``pull_models_interactive``
- ``push_ifcfed_interactive``, ``push_ifcfed``,
``push_model_interactive``, and ``push_model``
- ``open_settings`` for client ID, callback port, and sign-out
- connector-managed cache with one resolved file per directory
- adjacent ``.ifcfed.manifest`` files written and read alongside
``.ifcfed`` files
To fully sign out, use the connector's settings dialog "Sign out" button.
Token removal can also be done from the keychain UI directly if needed.
Not implemented:
Connecting through a proxy
--------------------------
- JSON-RPC notifications for progress streaming; the connector shows its own
progress dialog
- cancellation of in-flight downloads
- subdirectory upload layouts inside push destinations
The connector uses the host platform's native TLS trust store, so corporate
TLS-intercepting proxies that ship a custom CA work as long as that CA is
installed at the OS level. There is no ``cacerts.pem`` bundled inside the
connector that you would otherwise need to override.
HTTP/SOCKS proxy support is not exposed today. If you need to route through
a proxy, set ``HTTP_PROXY``/``HTTPS_PROXY`` in Bonsai Viewer's launch
environment and check ``ureq``'s upstream documentation for the supported
schemes.
Troubleshooting
---------------
**"Connector not found" on viewer launch.** Confirm the layout under
``<application-dir>/connectors/autodesk/``: it must contain
``connector.json`` and ``bonsaiviewer-autodesk[.exe]`` at the top level.
If you unzipped one level too deep you may have
``connectors/autodesk/autodesk/connector.json`` — flatten it.
**Sign-in browser tab loads, but the redirect never closes the loop.**
Check the OAuth callback port hasn't been changed under you (e.g. by
another local service binding ``8080``). Change the port in the settings
dialog and re-sign-in. Verify ``localhost`` resolves correctly — corporate
DNS occasionally rewrites it.
**Keychain prompt loop on Linux.** A Secret Service provider must be
running; gnome-keyring-daemon or KWallet. Headless servers without one of
those installed will fail token reads.
**Some pulls fail with HTTP 403.** Your APS client ID needs Autodesk Docs
and/or Forma scopes enabled on the developer portal. The connector requests
the union of scopes it knows about, but you must approve them on the
application side.
**Logs.** The connector writes diagnostic lines to its standard error
stream. Bonsai Viewer captures and surfaces these in the cloud-connector
status panel. The level of detail is fixed for now; structured logging is
a future improvement.
@@ -0,0 +1,186 @@
Autodesk Connector Development
==============================
This page describes building, testing, packaging, and protocol-level debugging
of the Autodesk connector for developers. For end-user install and
configuration see :doc:`autodesk`.
Tech stack
----------
The connector is a single Rust binary at ``src/bonsaiviewer-autodesk/`` in
the IfcOpenShell repository. Key crates:
- **fltk** (``fltk-bundled`` feature) — UI toolkit, statically linked at
build time, so the produced executable has no system Tcl/Tk, Qt, or GTK
dependency.
- **ureq** (``tls`` + ``native-certs``) — blocking HTTP client. The
``native-certs`` feature pulls the system trust store; no bundled CA file
or OpenSSL runtime.
- **keyring** (``apple-native`` + ``windows-native`` +
``sync-secret-service``) — OS keychain abstraction for OAuth token
storage.
- **dirs** — platform-specific config / cache / data directories.
- **serde** / ``serde_json`` — JSON-RPC framing and APS response parsing.
- **chrono** — token-expiry math.
- **webbrowser** — opens the system default browser for the OAuth redirect.
Build from source
-----------------
From the repository root:
.. code-block:: bash
cd src/bonsaiviewer-autodesk
cargo build --release
The binary lands at ``target/release/bonsaiviewer-autodesk``.
A debug build (``cargo build``) at ``target/debug/bonsaiviewer-autodesk``
is fine for iterating on UI or RPC logic; release-mode strip + LTO is what
the packaging script ships.
Run
---
.. code-block:: bash
./target/release/bonsaiviewer-autodesk
The connector launches without configuration. The first interaction should
be to open the settings dialog (either from Bonsai Viewer or via the
``open_settings`` JSON-RPC method below) and configure the APS client ID +
OAuth callback port.
Bonsai Viewer is expected to launch this binary once per session and keep
it alive until shutdown. Closing the connector's standard input triggers a
clean exit.
Test and lint
-------------
The Rust source tree ships unit tests, integration tests under ``tests/``,
and clippy-clean lints. From the connector directory:
.. code-block:: bash
cargo test --all-features
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all -- --check
CI runs the same three commands in
``.github/workflows/build-bonsaiviewer-autodesk.yml``.
Protocol probing
----------------
The connector speaks newline-delimited JSON-RPC 2.0 over stdio. For
debugging without Bonsai Viewer in the loop, pipe requests in directly:
.. code-block:: bash
./target/release/bonsaiviewer-autodesk <<'EOF'
{"jsonrpc":"2.0","id":"0","method":"open_settings"}
{"jsonrpc":"2.0","id":"1","method":"pull_ifcfed_interactive"}
EOF
Useful methods at a glance:
.. code-block:: json
{"jsonrpc":"2.0","id":"0","method":"open_settings"}
{"jsonrpc":"2.0","id":"1","method":"pull_ifcfed_interactive"}
{"jsonrpc":"2.0","id":"2","method":"pull_models","params":[{"display_name":"foo.ifc","id":"abc","source":{"connector":"autodesk","hub_id":"b.hub","project_id":"b.proj","item_id":"urn:adsk...","version_id":"latest"}}]}
{"jsonrpc":"2.0","id":"3","method":"push_ifcfed_interactive","params":{"path":"/tmp/project.ifcfed"}}
{"jsonrpc":"2.0","id":"4","method":"push_ifcfed","params":{"path":"/tmp/project.ifcfed","manifest":{"connector":"autodesk","hub_id":"b.hub","project_id":"b.proj","item_id":"urn:adsk..."}}}
The cross-connector wire format is defined in :doc:`cloud_sync_protocol`.
Packaging
---------
The connector ships as a folder dropped into the Bonsai Viewer connectors
directory. The folder contains a single statically linked Rust executable
and a JSON manifest — no runtime interpreter, no vendored libraries
directory.
Cargo does not cross-compile out of the box (FLTK in particular wants the
host toolchain), so each operating system and architecture builds its own
package, typically through a CI matrix.
**Output:**
.. code-block:: text
dist/
autodesk/
connector.json
bonsaiviewer-autodesk[.exe]
autodesk-<os>-<arch>.zip
The ``autodesk/`` folder is what Bonsai Viewer expects under the
``connectors`` directory bundled next to the viewer executable
(``<application-dir>/connectors/``).
**Build:**
.. code-block:: bash
cd src/bonsaiviewer-autodesk
python packaging/build.py
``packaging/build.py`` uses only the Python standard library — no
``pip install`` step — and is a thin wrapper around ``cargo``. It:
1. cleans ``dist/``
2. runs ``cargo build --release``
3. copies ``connector.json`` and the produced binary into ``dist/autodesk/``
4. zips the folder as ``dist/autodesk-<os>-<arch>.zip``
Platform notes
~~~~~~~~~~~~~~
**Linux.** Build on the oldest glibc you intend to support — binaries
built on a newer glibc will not run on older distributions. Ubuntu 22.04
LTS (glibc 2.35) is a reasonable lowest common denominator in 2026. The
runtime keyring backend is Secret Service via the ``keyring`` crate's
``sync-secret-service`` feature (gnome-keyring, KWallet, …). End users
need a Secret Service provider running.
Expected output: ``autodesk-linux-x86_64.zip`` and/or an ARM64 archive.
**macOS.** Each architecture builds separately. To support Apple Silicon
and Intel, build on each architecture and ship two zips, or post-process
with ``lipo`` to produce universal binaries. The runtime keyring backend
is the system Keychain (``keyring`` crate's ``apple-native`` feature). For
distribution outside the developer's machine, codesign the executable and
notarize the bundle — unsigned binaries trigger Gatekeeper warnings.
Codesigning is left to the caller.
Expected output: ``autodesk-macos-arm64.zip`` and/or
``autodesk-macos-x86_64.zip``.
**Windows.** Build with the MSVC toolchain (Rustup default
``-x86_64-pc-windows-msvc`` target). The runtime keyring backend is
Credential Manager (``keyring`` crate's ``windows-native`` feature).
The Rust executable defaults to the Windows console subsystem, which is
appropriate because the connector speaks JSON-RPC over stdio. Bonsai
Viewer must launch it without showing a console window, for example with
Qt's ``QProcess::setCreateProcessArgumentsModifier`` and
``CREATE_NO_WINDOW``.
For distribution, sign the executable with an Authenticode certificate to
avoid SmartScreen warnings. Signing is left to the caller.
Expected output: ``autodesk-windows-x86_64.zip``.
CI
--
``.github/workflows/build-bonsaiviewer-autodesk.yml`` runs ``cargo fmt
--check``, ``cargo clippy -- -D warnings``, and
``cargo test --all-features``, then matrix-builds the four shipping
packages (Linux x86_64, macOS arm64, macOS x86_64, Windows x86_64) and
uploads each ``autodesk-<os>-<arch>.zip`` as an artefact.
@@ -1,130 +0,0 @@
Packaging the Autodesk Connector
================================
The Autodesk connector is shipped as a self-contained folder that can be
dropped into the Bonsai Viewer connectors directory. PyInstaller bundles the
Python interpreter, Qt, and dependencies so end users do not need Python
installed.
PyInstaller does not cross-compile. Each operating system must build its own
package, typically through a CI matrix.
Output
------
.. code-block:: text
dist/
autodesk/
connector.json
bonsaiviewer-autodesk[.exe]
_internal/...
autodesk-<os>-<arch>.zip
The ``autodesk/`` folder is what Bonsai Viewer expects under the
``connectors`` directory bundled next to the viewer executable
(``<application-dir>/connectors/``).
Build
-----
.. code-block:: bash
cd src/bonsaiviewer-autodesk
python -m venv venv
source venv/bin/activate
pip install -e ".[build]"
python packaging/build.py
On Windows, activate the virtual environment with
``venv\Scripts\activate``.
The build script:
1. cleans ``dist/`` and ``build/``
2. runs PyInstaller against ``packaging/bonsaiviewer-autodesk.spec``
3. renames the produced folder to ``autodesk/``
4. copies ``connector.json`` into it
5. zips the folder as ``autodesk-<os>-<arch>.zip``
The UI uses Tcl/Tk through CustomTkinter, which keeps the bundle small. Expect
roughly 50 MB unpacked or 21 MB zipped per OS. The Python used to build must
include ``tkinter``.
Linux
-----
Build on the oldest glibc you intend to support. Binaries built on a newer
glibc will not run on older distributions. Ubuntu 22.04 LTS, with glibc 2.35,
is a reasonable lowest common denominator in 2026.
The runtime keyring backend is Secret Service, such as gnome-keyring or
KWallet. End users need a Secret Service provider running.
Expected output: ``autodesk-linux-x86_64.zip`` and/or an ARM64 archive.
macOS
-----
Each architecture builds separately. To support Apple Silicon and Intel, build
on each architecture and ship two zips, or post-process with ``lipo`` to
produce universal binaries.
The runtime keyring backend is the system Keychain. For distribution outside
the developer's machine, codesign the executable and Tcl/Tk dylibs and notarize
the bundle. Unsigned binaries trigger Gatekeeper warnings. Codesigning is left
to the caller; the spec's ``codesign_identity`` field can be wired up.
Expected output: ``autodesk-macos-arm64.zip`` and/or
``autodesk-macos-x86_64.zip``.
Windows
-------
Build with the Microsoft Visual C++ runtime available, which is usually true
for modern Python distributions. The runtime keyring backend is Credential
Manager.
The executable is built with ``console=True`` because the connector speaks
JSON-RPC over stdio. Bonsai Viewer must launch it without showing a console
window, for example with Qt's ``QProcess::setCreateProcessArgumentsModifier``
and ``CREATE_NO_WINDOW``.
For distribution, sign the executable with an Authenticode certificate to avoid
SmartScreen warnings. Signing is left to the caller.
Expected output: ``autodesk-windows-x86_64.zip``.
Install a Built Connector
-------------------------
Extract the zip into the ``connectors`` directory next to the Bonsai Viewer
executable.
Linux:
.. code-block:: bash
unzip dist/autodesk-linux-x86_64.zip -d <application-dir>/connectors/
macOS:
.. code-block:: bash
unzip dist/autodesk-macos-arm64.zip -d "<application-dir>/connectors/"
Windows PowerShell:
.. code-block:: powershell
Expand-Archive dist\autodesk-windows-x86_64.zip -DestinationPath "<application-dir>\connectors\"
Bonsai Viewer discovers the connector on next launch.
Out of Scope
------------
- signing and notarization
- CI matrix setup
- auto-update
- universal macOS binaries via ``lipo``
+1 -1
View File
@@ -11,4 +11,4 @@ returns the metadata needed to keep them connected to the cloud source.
cloud_sync_protocol
autodesk
autodesk_packaging
autodesk_development