Skip to content

Replace flask with fastapi and celery with taskiq#869

Merged
PythonFZ merged 50 commits intomainfrom
fastapi-replacement
Mar 6, 2026
Merged

Replace flask with fastapi and celery with taskiq#869
PythonFZ merged 50 commits intomainfrom
fastapi-replacement

Conversation

@PythonFZ
Copy link
Copy Markdown
Member

No description provided.

PythonFZ and others added 30 commits February 20, 2026 17:19
Remove the old Flask/Celery/eventlet backend (src/, app/, tests/)
and replace with the new FastAPI/TaskIQ async codebase.

Carried-over files (docs, CI, Docker, misc) will be adapted
in subsequent commits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add authors, license from original ZnDraw
- Add docs dependency group (sphinx, furo, etc.)
- Add playwright to dev deps for screenshot tests
- Add [full] optional dependency (molify)
- Remove local uv.sources (editable paths)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge guidelines from both old ZnDraw and zndraw-fastapi AGENTS.md
into a concise version. CLAUDE.md is a symlink to AGENTS.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Drop MongoDB service (deferred)
- Add bun setup for frontend build
- Keep Redis service, Python matrix, codecov

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove Celery worker service (replaced by built-in TaskIQ workers)
- Remove MongoDB service (deferred)
- Remove FLASK_SECRET_KEY env var
- Keep LMDB storage for both standalone and production

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove --file-browser flags (not in new CLI).
Server startup and shutdown commands are otherwise the same.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace Flask-SocketIO → FastAPI with Socket.IO,
Celery Workers → TaskIQ Workers in mermaid diagram.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
README is backend-agnostic — all Python API examples use the
ZnDraw client which works identically with the new FastAPI backend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
src/zndraw/static/ is generated by hatch_build.py during wheel
build and should not be committed to the repository.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
socket.off() returns Socket which TS rejects as useEffect cleanup.
Wrap in block statement to discard return value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generated from pyproject.toml with all deps resolving from PyPI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TcpFakeServer (fakeredis) speaks RESP3 but redis-py defaults to RESP2,
causing Protocol Error on all Redis operations in dev mode. Pass
protocol=3 when connecting to the fake server.

Also fix shutdown endpoint URL: /v1/shutdown -> /v1/admin/shutdown
(admin router has /v1/admin prefix).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update port from 5000 to 8000 (new DEFAULT_PORT)
- Use /v1/health endpoint for server readiness check
- Use process.terminate() instead of zndraw --shutdown for cleanup
- Update register_extension -> register_job (new client API)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
REST + socket broadcast with ZnDrawTqdm client subclass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10-task TDD plan: Redis keys, schemas, routes, client API, ZnDrawTqdm, frontend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract progress_trackers from room join response
- Use snake_case field names from backend events
- Remove progress_init handler (data comes via join response)
- Remove roomId filter (events are room-scoped)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use ZnDrawTqdm to show progress both in terminal and in the ZnDraw UI
when uploading frames via extend(). Removes rich dependency for uploads.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the single `progress: float` percentage field with tqdm-style
fields (n, total, elapsed, unit) so the frontend can render item counts,
elapsed time, and rate — matching tqdm's display for both known and
unknown totals.

- Fix snake_case/camelCase mismatch that caused NaN% in frontend (C1)
- Remove dead `roomId` field from Progress TS interface (C2)
- Add Redis EXPIRE (1h TTL) on progress hash for orphaned cleanup
- Rewrite ProgressNotifications to show "42/100 frames [00:05, 8.4/s]"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Provides the old vis.progress_bar(...) API as a context manager that
wraps ZnDrawTqdm, marked with typing_extensions.deprecated so type
checkers and runtime both emit deprecation warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eanup

Replace user-id-based edit lock with server-issued UUID lock tokens
(Lock-Token header, inspired by WebDAV RFC 4918). Acquire uses atomic
Redis SET NX to prevent TOCTOU races. Disconnect handler releases locks
immediately when the holding session's socket drops. TTL is configurable
via Settings.edit_lock_ttl (ZNDRAW_EDIT_LOCK_TTL env, default 10s).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35 tests across 10 spec files covering frames navigation, geometry
drawing, editing mode, edit lock (two-tab), camera sessions, chat,
extensions, registration, socket sync, and frame invalidation.
Runs headed with 4 parallel workers against a live ZnDraw server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fsspec file objects lack a .name attribute, so ASE's auto-detection
falls back to magic-byte sniffing which fails on text-mode streams.
Pass the format explicitly via ase.io.formats.filetype(path).

Also extends the register_fs E2E test to cover the full file browser
flow: browse directories, open LoadFileDialog, submit load task, and
verify frames appear in the room.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PythonFZ and others added 2 commits February 26, 2026 19:23
Replace the separate Python Playwright system (misc/test_screenshots.py)
with a Playwright E2E spec that uses localStorage theme injection via
addInitScript, eliminating fragile double-click theme toggling. Each test
captures one screenshot; a for-loop creates two parallel describe blocks
(light/dark) with unique room names per theme.

- Extract spawnPY/waitForBgReady from registration.spec.ts to helpers.ts
- Add docs-screenshots.spec.ts with 27 tests x 2 themes = 54 tests
- Delete misc/test_screenshots.py, misc/conftest.py, misc/lightmode/,
  misc/darkmode/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

Important

Review skipped

Too many files!

This PR contains 232 files, which is 82 over the limit of 150.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a85a4da0-f58a-42f4-92f5-bd54244b350a

📥 Commits

Reviewing files that changed from the base of the PR and between a40504b and 1331b08.

⛔ Files ignored due to path filters (68)
  • docs/source/_static/screenshots/darkmode/analysis_1d.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/analysis_2d.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/bookmarks.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/camera.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/chat.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/chat_frame_reference.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/chat_progress.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/chat_smiles.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/constraint_visualization.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/curve_editing.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/custom_modifier.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/drawing_mode.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/dynamic_properties_dropdown.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/editing_axis_constraint.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/editing_mode.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/file_browser.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/geometries.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/geometry_viewer.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/locked_room.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/molecule_builder.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/molecule_builder_editor.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/overview.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/progress_tracker.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/property_inspector.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/python_connection.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/rooms.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/selection.png is excluded by !**/*.png
  • docs/source/_static/screenshots/darkmode/timeline.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/analysis_1d.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/analysis_2d.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/bookmarks.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/camera.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/chat.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/chat_frame_reference.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/chat_progress.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/chat_smiles.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/constraint_visualization.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/curve_editing.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/custom_modifier.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/drawing_mode.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/dynamic_properties_dropdown.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/editing_axis_constraint.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/editing_mode.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/file_browser.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/geometries.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/geometry_viewer.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/locked_room.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/molecule_builder.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/molecule_builder_editor.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/overview.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/progress_tracker.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/property_inspector.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/python_connection.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/rooms.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/selection.png is excluded by !**/*.png
  • docs/source/_static/screenshots/lightmode/timeline.png is excluded by !**/*.png
  • frontend/bun.lock is excluded by !**/*.lock
  • frontend/src/logo.svg is excluded by !**/*.svg
  • frontend/src/react.svg is excluded by !**/*.svg
  • frontend/src/zndraw.png is excluded by !**/*.png
  • misc/darkmode/analysis.png is excluded by !**/*.png
  • misc/darkmode/box.png is excluded by !**/*.png
  • misc/darkmode/overview.png is excluded by !**/*.png
  • misc/darkmode/python.png is excluded by !**/*.png
  • misc/lightmode/analysis.png is excluded by !**/*.png
  • misc/lightmode/box.png is excluded by !**/*.png
  • misc/lightmode/overview.png is excluded by !**/*.png
  • misc/lightmode/python.png is excluded by !**/*.png
📒 Files selected for processing (232)
  • .github/workflows/test.yaml
  • .gitignore
  • AGENTS.md
  • app/src/components/AdminPanel.tsx
  • app/src/components/ExtensionStatusChips.tsx
  • app/src/components/JobHistoryPanel.tsx
  • app/src/components/ProgressNotifications.tsx
  • app/src/components/SecondaryPanel.tsx
  • app/src/components/filesystem/FilesystemSelector.tsx
  • app/src/components/jsonforms-renderers/TransformEditor.tsx
  • app/src/hooks/useDefaultCamera.ts
  • app/src/hooks/useDragAndDrop.tsx
  • app/src/hooks/useRestManager.ts
  • app/src/hooks/useSchemas.ts
  • app/src/myapi/client.ts
  • app/src/pages/fileBrowser.tsx
  • app/src/pages/remoteFileBrowser.tsx
  • app/src/socket.ts
  • app/src/store.tsx
  • app/src/types/chat.ts
  • app/src/types/jobs.ts
  • app/src/utils/auth.ts
  • app/src/utils/jobUtils.ts
  • docker/production/docker-compose.yaml
  • docker/standalone/docker-compose.yaml
  • docs/plans/2026-02-24-progress-bar-design.md
  • docs/plans/2026-02-24-progress-bar-plan.md
  • docs/plans/2026-02-26-constraint-visualization-design.md
  • docs/plans/2026-02-26-constraint-visualization-plan.md
  • docs/plans/2026-02-26-default-camera-design.md
  • docs/source/developer-guide.rst
  • docs/source/python-api.rst
  • frontend/.gitignore
  • frontend/README.md
  • frontend/bun-env.d.ts
  • frontend/bunfig.toml
  • frontend/e2e/camera-session.spec.ts
  • frontend/e2e/chat-features.spec.ts
  • frontend/e2e/constraint-visualization.spec.ts
  • frontend/e2e/docs-screenshots.spec.ts
  • frontend/e2e/editing.spec.ts
  • frontend/e2e/extensions-analysis.spec.ts
  • frontend/e2e/frame-invalidation.spec.ts
  • frontend/e2e/frames-navigation.spec.ts
  • frontend/e2e/geometry-drawing.spec.ts
  • frontend/e2e/helpers.ts
  • frontend/e2e/registration.spec.ts
  • frontend/e2e/socket-sync.spec.ts
  • frontend/e2e/ui-panels-chat.spec.ts
  • frontend/package.json
  • frontend/playwright.config.ts
  • frontend/src/App.tsx
  • frontend/src/components/AddPlotButton.tsx
  • frontend/src/components/AdminPanel.tsx
  • frontend/src/components/BookmarkLayer.tsx
  • frontend/src/components/CameraManager.js
  • frontend/src/components/Canvas.tsx
  • frontend/src/components/CanvasErrorState.tsx
  • frontend/src/components/CanvasLoadingState.tsx
  • frontend/src/components/ChatWindow.tsx
  • frontend/src/components/ConnectionDialog.tsx
  • frontend/src/components/ConnectionStatus.tsx
  • frontend/src/components/DropOverlay.tsx
  • frontend/src/components/DuplicateRoomDialog.tsx
  • frontend/src/components/FigureWindow.tsx
  • frontend/src/components/FrameReference.tsx
  • frontend/src/components/FrameSelectionInput.tsx
  • frontend/src/components/JobHistoryPanel.tsx
  • frontend/src/components/JobListItem.tsx
  • frontend/src/components/JobStatusChips.tsx
  • frontend/src/components/LoginDialog.tsx
  • frontend/src/components/PathTracingRenderer.tsx
  • frontend/src/components/PathtracingUpdater.tsx
  • frontend/src/components/PrimaryDrawer.tsx
  • frontend/src/components/ProgressBar.tsx
  • frontend/src/components/ProgressNotifications.tsx
  • frontend/src/components/RegisterDialog.tsx
  • frontend/src/components/RoomManagementMenu.tsx
  • frontend/src/components/SceneLighting.tsx
  • frontend/src/components/SecondaryPanel.tsx
  • frontend/src/components/SelectionGroupsPanel.tsx
  • frontend/src/components/SelectionLayer.tsx
  • frontend/src/components/SelectionTrackOverlay.tsx
  • frontend/src/components/SelectionsPanel.tsx
  • frontend/src/components/SettingsPanel.tsx
  • frontend/src/components/SiMGenButtons.tsx
  • frontend/src/components/SiMGenTutorialDialog.tsx
  • frontend/src/components/SideBar.tsx
  • frontend/src/components/UserProfileDialog.tsx
  • frontend/src/components/WindowManager.tsx
  • frontend/src/components/filesystem/FileBreadcrumbs.tsx
  • frontend/src/components/filesystem/FileList.tsx
  • frontend/src/components/filesystem/FilesystemSelector.tsx
  • frontend/src/components/filesystem/LoadFileDialog.tsx
  • frontend/src/components/filesystem/index.ts
  • frontend/src/components/geometry/DeleteConfirmDialog.tsx
  • frontend/src/components/geometry/GeometryForm.tsx
  • frontend/src/components/geometry/GeometryGrid.tsx
  • frontend/src/components/geometry/GeometryPanel.tsx
  • frontend/src/components/jsonforms-renderers/ArrayEditorDialog.tsx
  • frontend/src/components/jsonforms-renderers/ArrayFieldToolbar.tsx
  • frontend/src/components/jsonforms-renderers/CustomColorPicker.tsx
  • frontend/src/components/jsonforms-renderers/CustomDynamicEnumWithColorPicker.tsx
  • frontend/src/components/jsonforms-renderers/CustomRangeSlider.tsx
  • frontend/src/components/jsonforms-renderers/CustomSmilesEditor.tsx
  • frontend/src/components/jsonforms-renderers/CustomSmilesPackEditor.tsx
  • frontend/src/components/jsonforms-renderers/DynamicEnumRenderer.tsx
  • frontend/src/components/jsonforms-renderers/MaterialEditor.tsx
  • frontend/src/components/jsonforms-renderers/OwnershipToggleRenderer.tsx
  • frontend/src/components/jsonforms-renderers/PositionAttachmentRenderer.tsx
  • frontend/src/components/jsonforms-renderers/PropertyInspectorRenderer.tsx
  • frontend/src/components/jsonforms-renderers/SmilesEditDialog.tsx
  • frontend/src/components/jsonforms-renderers/StaticValueDisplay.tsx
  • frontend/src/components/jsonforms-renderers/StringEnumControl.tsx
  • frontend/src/components/jsonforms-renderers/TransformEditor.tsx
  • frontend/src/components/jsonforms-renderers/Vertices2DRenderer.tsx
  • frontend/src/components/jsonforms-renderers/components/PropertySelector.tsx
  • frontend/src/components/shared/FormLabelWithHelp.tsx
  • frontend/src/components/shared/LoadingSkeletons.tsx
  • frontend/src/components/shared/MoleculePreview.tsx
  • frontend/src/components/three/Arrow.tsx
  • frontend/src/components/three/Bonds.tsx
  • frontend/src/components/three/Box.tsx
  • frontend/src/components/three/Camera.tsx
  • frontend/src/components/three/Cell.tsx
  • frontend/src/components/three/Curve.tsx
  • frontend/src/components/three/DrawingIndicator.tsx
  • frontend/src/components/three/EditingIndicator.tsx
  • frontend/src/components/three/Floor.tsx
  • frontend/src/components/three/GeometryErrorBoundary.tsx
  • frontend/src/components/three/HoverInfoBox.tsx
  • frontend/src/components/three/KeyboardShortcutsHandler.tsx
  • frontend/src/components/three/MultiGeometryTransformControls.tsx
  • frontend/src/components/three/Particles.tsx
  • frontend/src/components/three/PathtracingScreenshotCapture.tsx
  • frontend/src/components/three/Plane.tsx
  • frontend/src/components/three/ScreenshotProvider.tsx
  • frontend/src/components/three/Shape.tsx
  • frontend/src/components/three/StaticInfoBox.tsx
  • frontend/src/components/three/VirtualCanvas.tsx
  • frontend/src/components/three/crosshair.tsx
  • frontend/src/components/three/materials.tsx
  • frontend/src/constants/fileTypes.ts
  • frontend/src/constants/layout.ts
  • frontend/src/formStore.ts
  • frontend/src/frontend.tsx
  • frontend/src/hooks/useCameraControls.ts
  • frontend/src/hooks/useChat.ts
  • frontend/src/hooks/useDefaultCamera.ts
  • frontend/src/hooks/useDragAndDrop.tsx
  • frontend/src/hooks/useFigures.ts
  • frontend/src/hooks/useFrameBatch.ts
  • frontend/src/hooks/useFrameEditing.ts
  • frontend/src/hooks/useFrameLoadTime.ts
  • frontend/src/hooks/useFramePrefetcher.ts
  • frontend/src/hooks/useGeometries.ts
  • frontend/src/hooks/useGeometryCameraSync.ts
  • frontend/src/hooks/useGeometryEditing.ts
  • frontend/src/hooks/useGeometryPersistence.ts
  • frontend/src/hooks/useJobs.ts
  • frontend/src/hooks/useKeyboardShortcuts.ts
  • frontend/src/hooks/useMoleculeImage.ts
  • frontend/src/hooks/usePathtracingMesh.ts
  • frontend/src/hooks/usePropertyInspector.ts
  • frontend/src/hooks/usePropertyInspectorSettings.ts
  • frontend/src/hooks/useRegisterFrameKeys.ts
  • frontend/src/hooks/useSchemas.ts
  • frontend/src/hooks/useSettings.ts
  • frontend/src/hooks/useSocketManager.ts
  • frontend/src/hooks/useStepControl.ts
  • frontend/src/index.css
  • frontend/src/index.html
  • frontend/src/myapi/client.ts
  • frontend/src/pages/filesystemBrowser.tsx
  • frontend/src/pages/landingPage.tsx
  • frontend/src/pages/roomList.tsx
  • frontend/src/pages/templateSelection.tsx
  • frontend/src/roomsStore.tsx
  • frontend/src/socket.ts
  • frontend/src/store.tsx
  • frontend/src/stores/geometryStore.ts
  • frontend/src/stores/slices/connectionSlice.ts
  • frontend/src/stores/slices/lockSlice.ts
  • frontend/src/stores/slices/playbackSlice.ts
  • frontend/src/stores/slices/sceneSlice.ts
  • frontend/src/stores/slices/uiSlice.ts
  • frontend/src/stores/windowManagerStore.ts
  • frontend/src/types/chat.ts
  • frontend/src/types/jobs.ts
  • frontend/src/types/property-inspector.ts
  • frontend/src/types/room-config.ts
  • frontend/src/utils/arrayEditor.ts
  • frontend/src/utils/auth.ts
  • frontend/src/utils/bookmarks.ts
  • frontend/src/utils/cameraUtils.ts
  • frontend/src/utils/colorUtils.ts
  • frontend/src/utils/convertInstancedMesh.ts
  • frontend/src/utils/formStorage.ts
  • frontend/src/utils/geometryData.ts
  • frontend/src/utils/geometryDefaults.ts
  • frontend/src/utils/geometryEditing.ts
  • frontend/src/utils/jobUtils.ts
  • frontend/src/utils/jsonforms.ts
  • frontend/src/utils/keyboard.ts
  • frontend/src/utils/msgpack-numpy.ts
  • frontend/src/utils/propertyFormatting.ts
  • frontend/src/utils/remark-frame-link.js
  • frontend/src/utils/roomTracking.ts
  • frontend/src/utils/roomValidation.ts
  • frontend/src/utils/screenshot.ts
  • frontend/src/utils/threeObjectPools.ts
  • frontend/src/utils/transformProcessor.ts
  • frontend/src/utils/versionCompatibility.ts
  • frontend/tsconfig.json
  • frontend/vite.config.ts
  • hatch_build.py
  • main.py
  • misc/conftest.py
  • misc/test_screenshots.py
  • pyproject.toml
  • skills/zndraw/SKILL.md
  • src/zndraw-mcp/README.md
  • src/zndraw-mcp/__init__.py
  • src/zndraw/.gitignore
  • src/zndraw/__init__.py
  • src/zndraw/analytics.py
  • src/zndraw/api_manager.py
  • src/zndraw/app.py
  • src/zndraw/app/__init__.py
  • src/zndraw/app/bookmark_routes.py
  • src/zndraw/app/chat_utils.py
  • src/zndraw/app/constants.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fastapi-replacement

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.07%. Comparing base (a40504b) to head (1331b08).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff             @@
##             main     #869       +/-   ##
===========================================
+ Coverage   79.82%   92.07%   +12.24%     
===========================================
  Files         166      147       -19     
  Lines       20447    14783     -5664     
===========================================
- Hits        16322    13611     -2711     
+ Misses       4125     1172     -2953     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

PythonFZ and others added 4 commits February 26, 2026 19:37
The CI workflow runs `pytest --cov` but pytest-cov was not listed
in the dev dependency group, causing test failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The gitignored src/zndraw/static/ directory was excluded from wheel
builds. Adding it as a hatch artifact ensures the Vite build output
is packaged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add room-wide default camera so new browser sessions inherit a specific
view instead of hardcoded Camera() defaults.

Backend:
- default_camera column on Room model
- GET/PUT /v1/rooms/{room_id}/default-camera endpoints
- Server-side camera clone in room_join()
- Auto-clear on geometry delete
- DefaultCameraInvalidate socket event for real-time sync

Frontend:
- useDefaultCamera React Query hook
- Star icon toggle in GeometryGrid for Camera-type rows
- Socket listener for cache invalidation

Python client:
- vis.default_camera property with client-side validation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@PythonFZ PythonFZ force-pushed the fastapi-replacement branch from 401e08e to 1226761 Compare February 26, 2026 19:18
PythonFZ and others added 12 commits February 26, 2026 20:46
Avoids slow first-request latency by pre-populating sys.modules
via asyncio.to_thread during lifespan, after all services are ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reintroduce constraints-fixed-atoms default geometry and enhance
TransformEditor with a constraint selector for path autocomplete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use SkipJsonSchema to exclude fields that cause broken anyOf tabs
or "No applicable renderer" errors in the JSONForms-based editor:
- selection (list[int] | None) on all geometries
- variant (Literal const) on Curve
- bond_order_radius_scale (dict[float, float]) on Bond

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New rooms now include a constraint visualization geometry using
InArrayTransform to overlay red wireframe spheres on constrained atoms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verify that new rooms include the constraints-fixed-atoms geometry
with correct InArrayTransform config for position and radius, and
that constraint data survives the client append/retrieve cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When source is "constraints", the path field is replaced with a MUI
Select dropdown that fetches actual constraint entries from the current
frame and lets the user pick one (e.g., "#0: FixAtoms — indices: [0, 2]").
Selection sets path to "{index}.kwargs.indices" automatically. Shows a
loading spinner while fetching and "No constraints in current frame"
when empty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds end-to-end tests that verify constraint geometries (FixAtoms,
FixedLine) appear correctly in the geometry panel and render in
the 3D scene.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a new subsection under Geometries documenting automatic constraint
visualization with an acetic acid example showing FixAtoms usage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use butyric acid (CCCC(=O)O) with constrained carbon chain for a
realistic molecular example in the Playwright test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mera bug

- Add constraint_visualization screenshot test to docs-screenshots.spec.ts
  with zoomed-in default camera for better visibility
- Update python-api.rst to use molify.smiles2conformers and add light/dark
  mode screenshot directives
- Fix frozen Camera setattr bug in socketio.py room_join — use model_copy
  instead of mutating the frozen Pydantic model
- Add FixAtoms modifier extension

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add simgen_enabled field to Settings (ZNDRAW_SIMGEN_ENABLED env var),
read it in get_global_settings() instead of hardcoding False. Also
clean up utility.py to use SettingsDep instead of raw Depends().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@PythonFZ PythonFZ force-pushed the fastapi-replacement branch from 858c17a to 09f90a4 Compare February 26, 2026 21:49
@PythonFZ PythonFZ marked this pull request as ready for review March 6, 2026 10:06
@PythonFZ PythonFZ merged commit 3b9f5e1 into main Mar 6, 2026
4 of 6 checks passed
@PythonFZ PythonFZ deleted the fastapi-replacement branch March 6, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants