Skip to content

feat: use new AppAPI endpoint for ExApp status report#414

Merged
oleksandr-nc merged 1 commit intomainfrom
feat/exapp-status-report-endpoint
Mar 2, 2026
Merged

feat: use new AppAPI endpoint for ExApp status report#414
oleksandr-nc merged 1 commit intomainfrom
feat/exapp-status-report-endpoint

Conversation

@oleksandr-nc
Copy link
Contributor

@oleksandr-nc oleksandr-nc commented Mar 2, 2026

Fix for some flaky situations where ExApp can fail to update it's status during install/update in AppAPI will be only for the new endpoint:

nextcloud/app_api#807

Summary by CodeRabbit

  • Changed

    • App initialization status reporting now uses a new standardized endpoint for reporting progress and errors.
  • Chores

    • Package version updated to 0.24.2.dev0.

@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

Updates the app initialization status endpoint from the deprecated dynamic path /apps/status/{appId} to the new fixed path /ex-app/status for both synchronous and asynchronous flows. Version and changelog updated; tests adjusted to relax datetime comparisons to date-only.

Changes

Cohort / File(s) Summary
Version & Changelog
CHANGELOG.md, nc_py_api/_version.py
Bumped package version to 0.24.2.dev0 and added release entry noting the set_init_status endpoint change.
Endpoint Migration
nc_py_api/nextcloud.py
Replaced OCS PUT target from dynamic /apps/status/{appId} to fixed /ex-app/status in both sync and async init-status routines; payload and signatures unchanged.
Tests
tests/actual_tests/files_sharing_test.py
Adjusted expire_date assertions to compare only the date portion (sync and async variants).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: migrating from the deprecated /apps/status/{appId} endpoint to the new /ex-app/status endpoint for ExApp status reporting.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/exapp-status-report-endpoint

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
nc_py_api/nextcloud.py (1)

426-440: ⚠️ Potential issue | 🟠 Major

Fix backward-compatibility fallback in set_init_status for older AppAPI versions.

Lines 435 and 569 now use only /ocs/v1.php/apps/app_api/ex-app/status (AppAPI 3.0.0+). Deployments with older AppAPI versions will receive a 404. Add fallback to the deprecated /apps/status/{appId} endpoint on NextcloudExceptionNotFound.

Note: The attribute name in the proposed fix should be self.app_cfg.app_name, not self.app_cfg.name.

Suggested fix
 def set_init_status(self, progress: int, error: str = "") -> None:
     """Sets state of the app initialization.
 
     :param progress: a number from ``0`` to ``100`` indicating the percentage of application readiness for work.
         After sending ``100`` AppAPI will enable the application.
     :param error: if non-empty, signals to AppAPI that the application cannot be initialized successfully.
     """
-    self._session.ocs(
-        "PUT",
-        "/ocs/v1.php/apps/app_api/ex-app/status",
-        json={
-            "progress": progress,
-            "error": error,
-        },
-    )
+    payload = {
+        "progress": progress,
+        "error": error,
+    }
+    try:
+        self._session.ocs("PUT", "/ocs/v1.php/apps/app_api/ex-app/status", json=payload)
+    except NextcloudExceptionNotFound:
+        self._session.ocs(
+            "PUT",
+            f"/ocs/v1.php/apps/app_api/apps/status/{self.app_cfg.app_name}",
+            json=payload,
+        )

 async def set_init_status(self, progress: int, error: str = "") -> None:
     """Sets state of the app initialization.
 
     :param progress: a number from ``0`` to ``100`` indicating the percentage of application readiness for work.
         After sending ``100`` AppAPI will enable the application.
     :param error: if non-empty, signals to AppAPI that the application cannot be initialized successfully.
     """
-    await self._session.ocs(
-        "PUT",
-        "/ocs/v1.php/apps/app_api/ex-app/status",
-        json={
-            "progress": progress,
-            "error": error,
-        },
-    )
+    payload = {
+        "progress": progress,
+        "error": error,
+    }
+    try:
+        await self._session.ocs("PUT", "/ocs/v1.php/apps/app_api/ex-app/status", json=payload)
+    except NextcloudExceptionNotFound:
+        await self._session.ocs(
+            "PUT",
+            f"/ocs/v1.php/apps/app_api/apps/status/{self.app_cfg.app_name}",
+            json=payload,
+        )

Also applies to: 560-574

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nc_py_api/nextcloud.py` around lines 426 - 440, Update set_init_status to
catch NextcloudExceptionNotFound when calling the new endpoint and retry the
request against the legacy endpoint "/apps/status/{appId}" using
self.app_cfg.app_name as the appId; specifically, wrap the existing
self._session.ocs(...) call in a try/except for NextcloudExceptionNotFound, and
in the except block call self._session.ocs with the deprecated path and the same
json payload (progress and error) so older AppAPI versions receive the fallback;
apply the same pattern to the other similar call around lines 560-574.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Around line 18-23: Remove the duplicated release heading "## [0.24.1 -
2026-02-25]" and either delete the repeated section block or merge its entries
into the original 0.24.1 release section so there is only one "## [0.24.1 -
2026-02-25]" heading in CHANGELOG.md; locate occurrences of the heading text to
find both sections and keep/merge content under the first instance, removing the
second.

---

Outside diff comments:
In `@nc_py_api/nextcloud.py`:
- Around line 426-440: Update set_init_status to catch
NextcloudExceptionNotFound when calling the new endpoint and retry the request
against the legacy endpoint "/apps/status/{appId}" using self.app_cfg.app_name
as the appId; specifically, wrap the existing self._session.ocs(...) call in a
try/except for NextcloudExceptionNotFound, and in the except block call
self._session.ocs with the deprecated path and the same json payload (progress
and error) so older AppAPI versions receive the fallback; apply the same pattern
to the other similar call around lines 560-574.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6ca6b3 and b2b2d44.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • nc_py_api/_version.py
  • nc_py_api/nextcloud.py

Comment on lines +18 to +23
## [0.24.1 - 2026-02-25]

### Fixed

- Use FileLock with atomic rename for safe concurrent model downloads #396

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove duplicated 0.24.1 release section.

Line 18 reintroduces ## [0.24.1 - 2026-02-25], which already exists at Line 5. This duplicates release history and triggers MD024 (no-duplicate-heading).

Suggested fix
-## [0.24.1 - 2026-02-25]
-
-### Fixed
-
-- Use FileLock with atomic rename for safe concurrent model downloads `#396`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## [0.24.1 - 2026-02-25]
### Fixed
- Use FileLock with atomic rename for safe concurrent model downloads #396
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 18-18: Multiple headings with the same content

(MD024, no-duplicate-heading)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CHANGELOG.md` around lines 18 - 23, Remove the duplicated release heading "##
[0.24.1 - 2026-02-25]" and either delete the repeated section block or merge its
entries into the original 0.24.1 release section so there is only one "##
[0.24.1 - 2026-02-25]" heading in CHANGELOG.md; locate occurrences of the
heading text to find both sections and keep/merge content under the first
instance, removing the second.

Signed-off-by: Oleksander Piskun <oleksandr2088@icloud.com>
@oleksandr-nc oleksandr-nc force-pushed the feat/exapp-status-report-endpoint branch from b2b2d44 to b1b13a5 Compare March 2, 2026 12:03
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
nc_py_api/nextcloud.py (1)

433-440: ⚠️ Potential issue | 🟠 Major

Implement fallback to deprecated endpoint for AppAPI < 3.0.0 compatibility.

The switch to /ex-app/status is recent (from AppAPI 3.0.0+, released Aug 2024). While the old endpoint /ocs/v1.php/apps/app_api/apps/status/{appId} is deprecated, it remains functional. To maintain backwards compatibility with older AppAPI installations, catch NextcloudExceptionNotFound on the new endpoint and retry with the legacy route in both sync and async methods.

Backwards-compatible implementation
 def set_init_status(self, progress: int, error: str = "") -> None:
     """Sets state of the app initialization.

     :param progress: a number from ``0`` to ``100`` indicating the percentage of application readiness for work.
         After sending ``100`` AppAPI will enable the application.
     :param error: if non-empty, signals to AppAPI that the application cannot be initialized successfully.
     """
-    self._session.ocs(
-        "PUT",
-        "/ocs/v1.php/apps/app_api/ex-app/status",
-        json={
-            "progress": progress,
-            "error": error,
-        },
-    )
+    payload = {
+        "progress": progress,
+        "error": error,
+    }
+    try:
+        self._session.ocs("PUT", "/ocs/v1.php/apps/app_api/ex-app/status", json=payload)
+    except NextcloudExceptionNotFound:
+        self._session.ocs(
+            "PUT",
+            f"/ocs/v1.php/apps/app_api/apps/status/{self._session.cfg.app_name}",
+            json=payload,
+        )

 async def set_init_status(self, progress: int, error: str = "") -> None:
     """Sets state of the app initialization.

     :param progress: a number from ``0`` to ``100`` indicating the percentage of application readiness for work.
         After sending ``100`` AppAPI will enable the application.
     :param error: if non-empty, signals to AppAPI that the application cannot be initialized successfully.
     """
-    await self._session.ocs(
-        "PUT",
-        "/ocs/v1.php/apps/app_api/ex-app/status",
-        json={
-            "progress": progress,
-            "error": error,
-        },
-    )
+    payload = {
+        "progress": progress,
+        "error": error,
+    }
+    try:
+        await self._session.ocs("PUT", "/ocs/v1.php/apps/app_api/ex-app/status", json=payload)
+    except NextcloudExceptionNotFound:
+        await self._session.ocs(
+            "PUT",
+            f"/ocs/v1.php/apps/app_api/apps/status/{self._session.cfg.app_name}",
+            json=payload,
+        )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nc_py_api/nextcloud.py` around lines 433 - 440, Wrap the call to
self._session.ocs that posts to "/ocs/v1.php/apps/app_api/ex-app/status" in a
try/except that catches NextcloudExceptionNotFound and, on that exception,
retries the request against the legacy route
"/ocs/v1.php/apps/app_api/apps/status/{appId}" (substituting the current app id
variable in scope, e.g. app_id or appId). Apply the same pattern to the async
counterpart (await self._session.ocs) so both sync and async methods first try
the new ex-app/status endpoint and fall back to the deprecated
apps/status/{appId} endpoint when NextcloudExceptionNotFound is raised.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@nc_py_api/nextcloud.py`:
- Around line 433-440: Wrap the call to self._session.ocs that posts to
"/ocs/v1.php/apps/app_api/ex-app/status" in a try/except that catches
NextcloudExceptionNotFound and, on that exception, retries the request against
the legacy route "/ocs/v1.php/apps/app_api/apps/status/{appId}" (substituting
the current app id variable in scope, e.g. app_id or appId). Apply the same
pattern to the async counterpart (await self._session.ocs) so both sync and
async methods first try the new ex-app/status endpoint and fall back to the
deprecated apps/status/{appId} endpoint when NextcloudExceptionNotFound is
raised.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b2b2d44 and b1b13a5.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • nc_py_api/_version.py
  • nc_py_api/nextcloud.py
  • tests/actual_tests/files_sharing_test.py

@codecov
Copy link

codecov bot commented Mar 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.87%. Comparing base (c54b64a) to head (b1b13a5).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #414   +/-   ##
=======================================
  Coverage   94.87%   94.87%           
=======================================
  Files          46       46           
  Lines        5540     5540           
=======================================
  Hits         5256     5256           
  Misses        284      284           
Files with missing lines Coverage Δ
nc_py_api/_version.py 100.00% <100.00%> (ø)
nc_py_api/nextcloud.py 96.26% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@oleksandr-nc oleksandr-nc merged commit b803cb5 into main Mar 2, 2026
15 checks passed
@oleksandr-nc oleksandr-nc deleted the feat/exapp-status-report-endpoint branch March 2, 2026 12:16
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.

1 participant