chore(ExApp): migrate and split AppAPI documentation to relevant manuals

Signed-off-by: Edward Ly <contact@edward.ly>
This commit is contained in:
Edward Ly
2024-10-21 14:36:14 -07:00
parent 29de99dc30
commit 5710cfd898
57 changed files with 4049 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ Table of contents
configuration_server/index
occ_command
apps_management
exapps_management/index
configuration_user/index
configuration_files/index
file_workflows/index

View File

@@ -0,0 +1,19 @@
Concepts
========
API Access Control Mechanism
----------------------------
Each application defines list of API groups it intends to access.
This system easily allows you to increase the level of trust in applications.
Even prior to installation, it's possible to ascertain the API groups to which an application will gain access.
Extensible Deployment
---------------------
The system should support the expansion and integration of new deployment methods, avoiding any tight coupling with a specific deployment type.
Applications should be capable of indicating the deployment methods they can accommodate.
Given the evolving landscape of new technologies and the potential emergence of more intricate or simplified deployment options,
the system is architected to seamlessly embrace the integration of novel deployment modes.

View File

@@ -0,0 +1,135 @@
.. _create-deploy-daemon:
Creation of Deploy Daemon
=========================
The Deploy Daemon (DaemonConfig) is used to orchestrate the deployment of ExApps.
.. note::
Currently only ``docker-install`` and ``manual-install`` deployment methods are supported.
The recommended daemon configuration is using `AppAPI Docker Socket Proxy <https://github.com/cloud-py-api/docker-socket-proxy>`_.
.. image:: ./img/app_api_3.png
You can choose one of the basic configuration templates and adjust to your needs.
.. note:: We highly recommend to use UI to create Deploy Daemons.
Register Deploy daemon form
^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. ``Name``: unique name of the Deploy daemon
2. ``Display name``: the name that will be displayed in the UI
3. ``Deployment method``: by default you will need to choose ``docker_install``, ``manual_install`` is for development or custom use case of manual ExApp installation
4. ``Daemon Host``: hostname/IP address + port of the Deploy daemon
5. ``Nextcloud URL``: autofilled with current domain, you might need to change the protocol to http/https depending on your setup
6. ``Set as default daemon``: check if you want set new Deploy daemon as default
7. ``Enable https``: check if your Deploy daemon (Docker Socket Proxy) is configured with TLS
8. Deploy Config:
9. ``Network``: Docker network name, depends on your networking setup, enforces to "host" if "Enable https" is checked
10. ``HaProxy password``: password for Docker Socket Proxy, if it is configured with TLS
11. ``Compute Device``: CPU, CUDA or ROCm, depending on your hardware config on Deploy daemon host machine
12. ``Add additional option`` (see :ref:`additional_options_list`): setup additional KEY + VALUE deploy config options
.. note::
For remote DSP setup, it should expose the ports on the host.
.. _create-deploy-daemon-cli:
OCC CLI
^^^^^^^
There are a few commands to manage Deploy Daemons:
1. Register ``occ app_api:daemon:register``
2. Unregister ``occ app_api:daemon:unregister``
3. List registered daemons ``occ app_api:daemon:list``
Register
--------
Register Deploy Daemon (DaemonConfig).
Command: ``app_api:daemon:register [--net NET] [--haproxy_password HAPROXY_PASSWORD] [--compute_device COMPUTE_DEVICE] [--set-default] [--] <name> <display-name> <accepts-deploy-id> <protocol> <host> <nextcloud_url>``
Arguments
*********
* ``name`` - unique name of the daemon (e.g. ``docker_local_sock``)
* ``display-name`` - name of the daemon (e.g. ``My Local Docker``, will be displayed in the UI)
* ``accepts-deploy-id`` - type of deployment (``docker-install`` or ``manual-install``)
* ``host`` - **path to docker-socket** or the Docker Socket Proxy: ``address:port``
* ``protocol`` - protocol used to communicate with the Daemon/ExApps (``http`` or ``https``)
* ``nextcloud_url`` - Nextcloud URL, Daemon config required option (e.g. ``https://nextcloud.local``)
Options
*******
* ``--net [network-name]`` - ``[required]`` network name to bind docker container to (default: ``host``)
* ``--haproxy_password HAPROXY_PASSWORD`` - ``[optional]`` password for AppAPI Docker Socket Proxy
* ``--compute_device GPU`` - ``[optional]`` GPU device to expose to the daemon (e.g. ``cpu|cuda|rocm``, default: ``cpu``)
* ``--set-default`` - ``[optional]`` set created daemon as default for ExApps installation
DeployConfig
************
DeployConfig is a set of additional options in Daemon config, which are used in deployment algorithms to configure
ExApp container.
.. code-block:: json
{
"net": "host",
"nextcloud_url": "https://nextcloud.local",
"haproxy_password": "some_secure_password",
"computeDevice": {
"id": "cuda",
"name": "CUDA (NVIDIA)",
},
}
DeployConfig options
********************
* ``net`` **[required]** - network name to bind docker container to (default: ``host``)
* ``nextcloud_url`` **[required]** - Nextcloud URL (e.g. ``https://nextcloud.local``)
* ``haproxy_password`` *[optional]* - password for AppAPI Docker Socket Proxy
* ``computeDevice`` *[optional]* - Compute device to attach to the daemon (e.g. ``{ "id": "cuda", "label": "CUDA (NVIDIA)" }``)
Unregister
----------
Unregister Deploy Daemon (DaemonConfig).
Command: ``app_api:daemon:unregister <daemon-config-name>``
List registered daemons
-----------------------
List registered Deploy Daemons (DaemonConfigs).
Command: ``app_api:daemon:list``
Nextcloud AIO
^^^^^^^^^^^^^
In case of AppAPI installed in AIO, default Deploy Daemon is registered automatically.
It is possible to register additional Deploy Daemons with the same ways as described above.
.. _additional_options_list:
Additional options
^^^^^^^^^^^^^^^^^^
There is a possibility to add additional options to the Deploy Daemon configuration,
which are key-value pairs.
Currently, the following options are available:
- ``OVERRIDE_APP_HOST`` - can be used to override the host that will be used for ExApp binding (not passed to ExApp container envs)

View File

@@ -0,0 +1,384 @@
.. _deploy-configs:
Deployment configurations
=========================
Currently, only one kind of application deployment is supported:
* **Docker Deploy Daemon**
Docker Deploy Daemon
--------------------
Orchestrates the deployment of applications as Docker containers.
.. warning::
The administrator is responsible for the security actions taken to configure the Docker daemon connected to the Nextcloud instance.
These schemes are only examples of possible configurations.
We recommend that you use the `AppAPI Docker Socket Proxy <https://github.com/cloud-py-api/docker-socket-proxy>`_ or `AIO Docker Socket Proxy <#nextcloud-in-docker-aio-all-in-one>`_ container.
There are several Docker Daemon Deploy configurations (example schemes):
* Nextcloud and Docker on the **same host** (via socket or DockerSocketProxy)
* Nextcloud on the host and Docker on a **remote** host (via DockerSocketProxy with HTTPS)
* Nextcloud and **ExApps** in the **same Docker** (via DockerSocketProxy)
* Nextcloud in AIO Docker and **ExApps** in the **same Docker** (via AIO DockerSocketProxy)
NC & Docker on the Same-Host
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The simplest configuration is when Nextcloud is installed on the host and Docker is on the same host and applications are deployed to it.
.. mermaid::
stateDiagram-v2
classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
Host
state Host {
Nextcloud --> Daemon : /var/run/docker.sock
Daemon --> Containers
state Containers {
ExApp1
--
ExApp2
--
ExApp3
}
}
class Nextcloud nextcloud
class Daemon docker
class ExApp1 python
class ExApp2 python
class ExApp3 python
Suggested config values(template *Custom default*):
1. Daemon host: ``/var/run/docker.sock``
2. HTTPS checkbox: *not supported using docker socket*
3. Network: ``host``
4. HaProxy password: **not supported using raw docker socket, should be empty**
---
Suggested way to communicate with Docker via `Docker Socket Proxy container <https://github.com/cloud-py-api/docker-socket-proxy>`_.
.. mermaid::
stateDiagram-v2
classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
Host
state Host {
Nextcloud --> DockerSocketProxy: by port
Docker --> Containers
Docker --> DockerSocketProxy : /var/run/docker.sock
state Containers {
DockerSocketProxy --> ExApp1
DockerSocketProxy --> ExApp2
DockerSocketProxy --> ExApp3
}
}
class Nextcloud nextcloud
class Docker docker
class ExApp1 python
class ExApp2 python
class ExApp3 python
Suggested config values(template *Docker Socket Proxy*):
1. Daemon host: ``localhost:2375``
Choose **A** or **B** option:
A. Docker Socket Proxy should be deployed with ``network=host`` and ``BIND_ADDRESS=127.0.0.1``
B. Docker Socket Proxy should be deployed with ``network=bridge`` and it's port should be published to host's 127.0.0.1(e.g. **-p 127.0.0.1:2375:2375**)
2. HTTPS checkbox: **disabled**
3. Network: ``host``
4. HaProxy password: **should not be empty**
.. warning::
Be careful with option ``A``, by default **Docker Socket Proxy** binds to ``*`` if ``BIND_ADDRESS`` is not specified during container creation.
Check opened ports after finishing configuration.
Docker on a remote host
^^^^^^^^^^^^^^^^^^^^^^^
Distributed configuration occurs when Nextcloud is installed on one host and Docker is located on a remote host, resulting in the deployment of applications on the remote host.
Benefit: no performance impact on Nextcloud host.
In this case, the AppAPI uses a Docker Socket Proxy deployed on remote host to access docker socket and ExApps.
.. mermaid::
stateDiagram-v2
classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
Direction LR
Host1 --> Host2 : by port
state Host1 {
Nextcloud
}
state Host2 {
[*] --> DockerSocketProxy : by port
Daemon --> Containers
state Containers {
[*] --> DockerSocketProxy : /var/run/docker.sock
DockerSocketProxy --> ExApp1
DockerSocketProxy --> ExApp2
DockerSocketProxy --> ExApp3
}
}
class Nextcloud nextcloud
class Daemon docker
class ExApp1 python
class ExApp2 python
class ExApp3 python
Suggested config values(template *Docker Socket Proxy*):
1. Daemon host: ADDRESS_OF_REMOTE_MACHINE (e.g. **server_name.com:2375**)
2. HTTPS checkbox: ``enabled``
3. Network: ``host``
4. HaProxy password: **should not be empty**
NC & ExApps in the same Docker
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Applications are deployed in the same docker where Nextcloud resides.
Suggested way to communicate with Docker: via ``docker-socket-proxy``.
.. mermaid::
stateDiagram-v2
classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
Host
state Host {
Daemon --> Containers
state Containers {
[*] --> DockerSocketProxy : /var/run/docker.sock
Nextcloud --> DockerSocketProxy: by port
--
DockerSocketProxy --> ExApp1
DockerSocketProxy --> ExApp2
}
}
class Nextcloud nextcloud
class Daemon docker
class ExApp1 python
class ExApp2 python
class ExApp3 python
Suggested config values(template *Docker Socket Proxy*):
1. Daemon host: nextcloud-appapi-dsp:2375
2. HTTPS checkbox: ``disabled``
3. Network: `user defined network <https://docs.docker.com/network/#user-defined-networks>`_
4. HaProxy password: **should not be empty**
.. note::
Network **should not be the default docker's bridge** as it does not support DNS resolving by container names.
This means that **Docker Socket Proxy**, **Nextcloud** and **ExApps** containers should all be in the same docker network, different from the default **bridge**.
.. _nextcloud-in-docker-aio-all-in-one:
Nextcloud in Docker AIO (all-in-one)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In case of AppAPI is in Docker AIO setup (installed in Nextcloud container).
.. note::
AIO Docker Socket Proxy container must be enabled.
.. mermaid::
stateDiagram-v2
classDef docker fill: #1f97ee, color: transparent, font-size: 34px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
classDef docker2 fill: #1f97ee, color: transparent, font-size: 20px, stroke: #364c53, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/docker.png) no-repeat center center / contain
classDef nextcloud fill: #006aa3, color: transparent, font-size: 34px, stroke: #045987, stroke-width: 1px, background: url(https://raw.githubusercontent.com/cloud-py-api/app_api/main/docs/img/nextcloud.svg) no-repeat center center / contain
classDef python fill: #1e415f, color: white, stroke: #364c53, stroke-width: 1px
Host
state Host {
Daemon --> Containers
state Containers {
[*] --> NextcloudAIOMasterContainer : /var/run/docker.sock
[*] --> DockerSocketProxy : /var/run/docker.sock
NextcloudAIOMasterContainer --> Nextcloud
AppAPI --> Nextcloud : installed in
Nextcloud --> DockerSocketProxy
DockerSocketProxy --> ExApp1
DockerSocketProxy --> ExApp2
DockerSocketProxy --> ExApp3
}
}
class Nextcloud nextcloud
class Daemon docker
class Daemon2 docker2
class ExApp1 python
class ExApp2 python
class ExApp3 python
AppAPI will automatically create default default DaemonConfig to use AIO Docker Socket Proxy as orchestrator to create ExApp containers.
.. note::
Default DaemonConfig will be created only if the default DaemonConfig is not already registered.
Default AIO Deploy Daemon
*************************
Nextcloud AIO has a specifically created Docker Socket Proxy container to be used as the Deploy Daemon in AppAPI.
It has `fixed parameters <https://github.com/cloud-py-api/app_api/blob/main/lib/DeployActions/AIODockerActions.php#L52-L74)>`_:
* Name: ``docker_aio``
* Display name: ``AIO Docker Socket Proxy``
* Accepts Deploy ID: ``docker-install``
* Protocol: ``http``
* Host: ``nextcloud-aio-docker-socket-proxy:2375``
* Compute device: ``CPU``
* Network: ``nextcloud-aio``
* Nextcloud URL (passed to ExApps): ``https://$NC_DOMAIN``
Docker Socket Proxy security
****************************
AIO Docker Socket Proxy has strictly limited access to the Docker APIs described in `HAProxy configuration <https://github.com/nextcloud/all-in-one/blob/main/Containers/docker-socket-proxy/haproxy.cfg>`_.
NC to ExApp Communication
-------------------------
Each type of DeployDaemon necessarily implements the ``resolveExAppUrl`` function.
It has such prototype:
.. code-block:: php
public function resolveExAppUrl(
string $appId, string $protocol, string $host, array $deployConfig, int $port, array &$auth
) {}
where:
* **protocol** is daemon protocol value
* **host** is daemon host value, *can be DNS:port or IP:PORT or even path to docker socket*.
* **port** is an integer with ExApp port
* **deployConfig** can be custom for each Daemon type
* **auth** is an optional array, with *Basic Authentication* data if needed to access ExApp
.. note::
Starting with AppAPI version ``2.5.0``, the optional additional parameter *OVERRIDE_APP_HOST* can be used to
override the host that will be used for ExApp binding.
It can be ``0.0.0.0`` in some specific configurations, when VPN is used
or both Nextcloud instance and ExApps are one the same physical machine but different virtual environments.
Also you can specify something like ``10.10.2.5`` and in this case ``ExApp`` wil try to bind to that address and
AppAPI will try to send request s directly to this address assuming that ExApp itself bound on it.
The simplest implementation is in **Manual-Install** deploy type:
.. code-block:: php
public function resolveExAppUrl(
string $appId, string $protocol, string $host, array $deployConfig, int $port, array &$auth
): string {
$auth = [];
if (isset($deployConfig['additional_options']['OVERRIDE_APP_HOST']) &&
$deployConfig['additional_options']['OVERRIDE_APP_HOST'] !== ''
) {
$wideNetworkAddresses = ['0.0.0.0', '127.0.0.1', '::', '::1'];
if (!in_array($deployConfig['additional_options']['OVERRIDE_APP_HOST'], $wideNetworkAddresses)) {
$host = $deployConfig['additional_options']['OVERRIDE_APP_HOST'];
}
}
return sprintf('%s://%s:%s', $protocol, $host, $port);
}
Here we see that AppAPI send requests to **host**:**port** specified during daemon creation.
Now let's take a look at the Docker Daemon implementation of ``resolveExAppUrl``:
.. code-block:: php
public function resolveExAppUrl(
string $appId, string $protocol, string $host, array $deployConfig, int $port, array &$auth
): string {
$auth = [];
if (isset($deployConfig['additional_options']['OVERRIDE_APP_HOST']) &&
$deployConfig['additional_options']['OVERRIDE_APP_HOST'] !== ''
) {
$wideNetworkAddresses = ['0.0.0.0', '127.0.0.1', '::', '::1'];
if (!in_array($deployConfig['additional_options']['OVERRIDE_APP_HOST'], $wideNetworkAddresses)) {
return sprintf(
'%s://%s:%s', $protocol, $deployConfig['additional_options']['OVERRIDE_APP_HOST'], $port
);
}
}
$host = explode(':', $host)[0];
if ($protocol == 'https') {
$exAppHost = $host;
} elseif (isset($deployConfig['net']) && $deployConfig['net'] === 'host') {
$exAppHost = 'localhost';
} else {
$exAppHost = $appId;
}
if (isset($deployConfig['haproxy_password']) && $deployConfig['haproxy_password'] !== '') {
$auth = [self::APP_API_HAPROXY_USER, $deployConfig['haproxy_password']];
}
return sprintf('%s://%s:%s', $protocol, $exAppHost, $port);
}
Here we have much more complex algorithm of detecting to where requests should be send.
First of all if protocol is set to ``https`` AppAPI always send requests to daemon host,
and this is in case of ``https`` it is a HaProxy that will forward requests to ExApps that will be listen on ``localhost``
Briefly it will look like this(*haproxy_host==daemon host value*):
NC --> *https* --> ``haproxy_host:ex_app_port`` --> *http* --> ``localhost:ex_app_port``
When protocol is not ``https`` but ``http``, then what will be the endpoint where to send requests is determined by ``$deployConfig['net']`` value.
If ``net`` is defined and equal to ``host`` then AppAPI assumes that ExApp is installed somewhere in the current host network and will be available on ``localhost`` loop-back adapter.
NC --> *http* --> ``localhost:ex_app_port``
In all other cases ExApp should be available by it's name: e.g. when using docker **custom bridge** network all containers available by DNS.
NC --> *http* --> ``app_container_name:ex_app_port``
This three different types of communication covers all most popular configurations.

View File

@@ -0,0 +1,85 @@
Installation
============
There are two ways to install the AppAPI: from the `AppStore <https://apps.nextcloud.com/apps/app_api>`_ or from the source code.
.. note::
AppAPI 3.0.0 is the last version supported Nextcloud 27.
Installation from the AppStore
------------------------------
Simply navigate to the Apps management page in your Nextcloud and setup the AppAPI from the Tools category.
Installation from the source code
---------------------------------
To install the AppAPI from the source code, follow these steps:
1. Clone the AppAPI repository into your apps directory
*******************************************************
Clone the latest main branch:
.. code-block:: bash
git clone https://github.com/cloud-py-api/app_api.git
or clone a specific version by specifying the version tag:
.. code-block:: bash
git clone https://github.com/cloud-py-api/app_api.git --branch <version-tag>
where ``<version-tag>`` is the version you want to install.
2. Build frontend assets in production mode
********************************************
.. code-block:: bash
npm ci && npm run build
3. Enable the AppAPI
********************
.. code-block:: bash
./occ app:enable --force app_api
To install it in development mode, follow the instructions on this page: :ref:`dev-setup`.
4. Setup Deploy daemon
**********************
Upon the successful installation of the AppAPI, a one-time configuration is essential.
Details on this configuration can be found in the subsequent section: :ref:`create-deploy-daemon`.
4.1 Deploy daemon configuration
*******************************
Deploy daemon configuration steps:
1. Go to the AppAPI admin settings.
2. Click on the "Register Daemon" button.
3. Fill in the required fields:
- ``Name``: unique name of the Deploy daemon
- ``Display name``: the name that will be displayed in the UI
- ``Deployment method``: by default you will need to choose ``docker_install``, ``manual_install`` is for development or custom use case of manual ExApp installation
- ``Daemon Host``: hostname/IP address + port of the Deploy daemon
- ``Nextcloud URL``: autofilled with current domain, you might need to change the protocol to http/https depending on your setup
- ``Set as default daemon``: check if you want set new Deploy daemon as default
- ``Enable https``: check if your Deploy daemon (Docker Socket Proxy) is configured with TLS
- Deploy Config:
- ``Network``: Docker network name, depends on your networking setup, enforces to "host" if "Enable https" is checked
- ``HaProxy password``: password for Docker Socket Proxy, if it is configured with TLS
- ``Compute Device``: CPU, CUDA or ROCm, depending on your hardware config on Deploy daemon host machine
- ``Add additional option`` (see :ref:`additional_options_list`): setup additional KEY + VALUE deploy config options
4. Check connection: to verify configuration is correct
5. Register: to save the Deploy daemon configuration
Deployment configuration examples can be found :ref:`here <deploy-configs>`.

View File

@@ -0,0 +1,117 @@
Managing External Applications
==============================
There are two ways to manage ExApps:
1. Using OCC CLI tool
2. Using the ExApp Management UI
OCC CLI
^^^^^^^
There are several commands to work with ExApps:
1. Register
2. Unregister
3. Update
4. Enable
5. Disable
6. List ExApps
7. List ExApp users (removed since AppAPI 3.0.0)
8. List ExApp scopes
Register
--------
Command: ``app_api:app:register [--force-scopes] [--info-xml INFO-XML] [--json-info JSON-INFO] [--] <appid> <daemon-config-name>``
The register command is the first ExApp installation step.
Arguments
*********
* ``appid`` - unique name of the ExApp (e.g. ``app_python_skeleton``, must be the same as in deployed container)
* ``daemon-config-name`` - unique name of the daemon (e.g. ``docker_local_sock``)
Options
*******
* ``--force-scopes`` *[optional]* - force scopes approval
* ``--json-info JSON-INFO`` **[optional]** - ExApp deploy JSON info (json string)
* ``--info-xml INFO-XML`` **[optional]** - path to info.xml file (url or local absolute path)
Unregister
----------
Command: ``app_api:app:unregister [--rm-data] [--force] [--silent] [--] <appid>``
To remove an ExApp you can use the unregister command.
There are additional options to keep the ExApp persistent storage (data volume).
Arguments
*********
* ``appid`` - unique name of the ExApp (e.g. ``app_python_skeleton``, must be the same as in deployed container)
Options
*******
* ``--rm-data`` *[optional]* - remove ExApp persistent storage (data volume)
* ``--force`` *[optional]* - continue removal even if some error occurs.
* ``--silent`` *[optional]* - print a minimum of information, display only some errors, if any.
Update
------
Command: ``app_api:app:update [--info-xml INFO-XML] [--force-update] [--force-scopes] [-e|--enabled] [--] <appid>``
ExApp will be updated if there is a new version available.
Arguments
*********
* ``appid`` - unique name of the ExApp (e.g. ``app_python_skeleton``, must be the same as in deployed container)
Options
*******
* ``--info-xml INFO-XML`` **[optional]** - path to info.xml file (url or local absolute path)
* ``--force-update`` *[optional]* - force ExApp update (do not prompt for confirmation)
* ``--force-scopes`` *[optional]* - force scopes approval (accept all scopes)
* ``-e|--enabled`` *[optional]* - enable ExApp after update
Enable
------
Command: ``app_api:app:enable <appid>``
Disable
-------
Command: ``app_api:app:disable <appid>``
List ExApps
-----------
Command: ``app_api:app:list``
ListExApps command will show all ExApps:
.. code-block::
ExApps:
appid (Display Name): version [enabled/disabled]
to_gif_example (To Gif Example): 1.0.0 [enabled]
upscaler_example (Upscaler Example): 1.0.0 [enabled]
Using the ExApp Management UI
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ExApps management is similar to default Apps management.
To access ExApps management navigate using Admin settings dropdown menu or from AppAPI admin settings section.
.. note::
ExApps management support only apps from App Store. For manual-install type use CLI ExApps management commands.

View File

@@ -0,0 +1,97 @@
.. _test_deploy:
Test Deploy Daemon
------------------
You can test each Daemon configuration deployment from the AppAPI Admin settings.
.. image:: ./img/test_deploy.png
Status Checks
^^^^^^^^^^^^^
The Deploy test installs a `test-deploy <https://github.com/cloud-py-api/test-deploy>`_ ExApp
to verify each step of the deployment process, including a hardware support check -
for each compute device, there is a separate Docker image.
.. note::
The Test Deploy ExApp container is not removed after the test as it's needed for logs and status checks.
You can remove it after testing from the External Apps page.
The Docker images are also not removed from the Daemon; you can clean up unused images with the ``docker image prune`` command.
.. image:: ./img/test_deploy_modal_4.png
Register
********
The Register step is the first step; it checks if the ExApp is registered in Nextcloud.
Image Pull
**********
The Image Pull step downloads the ExApp Docker image.
Possible errors:
- Image not found (e.g. not public, no image found for your hardware architecture)
- Image pull failed (e.g., due to network issues)
- Image pull timeout
- Your Docker Socket Proxy is not configured correctly and blocks access to this Docker Engine API
Container Started
*****************
The Container Started step verifies that the ExApp container is created and started successfully.
Possible errors:
- Container failed to start with GPU support (may be missing or misconfigured)
- For NVIDIA, refer to the `NVIDIA Docker configuration docs <https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html>`_.
- For AMD, refer to the `ROCm Docker configuration docs <https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html>`_.
- The ExApp issue during startup (e.g. not enough memory)
Heartbeat
*********
The Heartbeat step checks if the container's health check is finished and the container is healthy.
The ExApp might have additional pre-configuration logic during this step.
Possible errors:
- ExApp failed to start a web server, e.g., if the port is already in use (this should be visible in the container logs)
- ExApp heartbeat_count keeps increasing, this may indicate that the ExApp couldn't start properly
- Nextcloud can not reach the ExApp container, e.g., due to a network issue or a firewall
Init
****
The Init step checks if the ExApp is initialized and ready to use.
During the init step, the ExApp may perform downloads of extra stuff required for it.
Possible errors:
- Initialization failed (e.g., due to network issues or timeout)
Enabled
*******
The Enabled step checks if the ExApp is enabled and ready to use.
During this step, the ExApp registers all the required and available APIs of the Nextcloud AppFramework.
Possible errors:
- ExApp did not respond to the enable request
- ExApp failed to enable due to a failure in registering AppAPI Nextcloud AppFramework APIs (this should be visible both in the container logs and in the Nextcloud logs if there are any errors)
Download Logs
^^^^^^^^^^^^^
You can download the logs of the last test deploy attempt container.
.. note::
Downloading Docker container logs is only possible for containers using the json-file or journald logging drivers.

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 127 87.2" style="enable-background:new 0 0 127 87.2;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path id="path1052" class="st0" d="M63.6,3.8C51,3.8,40.3,12.3,37,23.9c-2.9-6.1-9.1-10.4-16.3-10.4c-9.9,0-18,8.1-18,18 c0,9.9,8.1,18,18,18c7.2,0,13.4-4.3,16.3-10.4c3.3,11.6,14,20.1,26.6,20.1c12.5,0,23.1-8.4,26.5-19.8c2.9,6,9.1,10.2,16.2,10.2 c9.9,0,18-8.1,18-18c0-9.9-8.1-18-18-18c-7.1,0-13.2,4.2-16.2,10.2C86.7,12.2,76.1,3.8,63.6,3.8z M63.6,14.3 c9.5,0,17.1,7.6,17.1,17.1c0,9.5-7.6,17.1-17.1,17.1c-9.5,0-17.1-7.6-17.1-17.1C46.5,21.9,54.1,14.3,63.6,14.3z M20.7,24 c4.2,0,7.4,3.3,7.4,7.4c0,4.2-3.3,7.4-7.4,7.4c-4.2,0-7.4-3.3-7.4-7.4C13.3,27.3,16.6,24,20.7,24z M106.3,24c4.2,0,7.4,3.3,7.4,7.4 c0,4.2-3.3,7.4-7.4,7.4c-4.2,0-7.4-3.3-7.4-7.4C98.8,27.3,102.1,24,106.3,24z"></path>
<path id="path1174" class="st0" d="M15.4,67.4c-0.4,0-0.5,0.2-0.5,0.6v14.6c0,0.4,0.2,0.5,0.5,0.5h0.4c0.4,0,0.5-0.2,0.5-0.5V70.4 l7.9,12.3c0,0.1,0.1,0.1,0.1,0.1c0,0,0,0,0,0c0,0,0.1,0,0.1,0.1c0,0,0,0,0.1,0c0,0,0,0,0,0c0.1,0,0.1,0,0.2,0h0.4 c0.4,0,0.5-0.2,0.5-0.5V68c0-0.4-0.2-0.6-0.5-0.6h-0.4c-0.4,0-0.6,0.2-0.6,0.6v12.1l-7.9-12.3c0,0-0.1-0.1-0.1-0.1 c-0.1-0.1-0.2-0.2-0.4-0.2L15.4,67.4z M110.8,67.6c-0.4,0-0.2,0.2-0.2,0.6v5c0,0.5,0,0.9,0,0.9h0c0,0-1-2.2-3.6-2.2 c-2.9,0-5,2.3-4.9,5.7c0,3.4,1.9,5.8,4.8,5.8c2.9,0,3.8-2.3,3.8-2.3h0.1c0,0-0.1,0.3-0.1,0.7v0.9c0,0.4,0.2,0.5,0.6,0.5h0.4 c0.4,0,0.5-0.2,0.5-0.6V68.2c0-0.4-0.6-0.6-0.9-0.6H110.8z M71.8,67.7c-0.4,0-0.1,0.2-0.1,0.6v12.3c0,2.4,1.6,2.7,2.5,2.7 c0.4,0,0.6-0.2,0.6-0.6v-0.4c0-0.4-0.2-0.5-0.5-0.5c-0.5-0.1-1.2-0.2-1.2-1.6v-12c0-0.4-0.6-0.6-0.9-0.6L71.8,67.7z M53.8,69 c-0.4,0-0.6,0.2-0.6,0.6v2.6v1.3v5.7c0,2.6,1.5,4.1,3.9,4.1c0.5,0,0.6-0.1,0.6-0.5v-0.3c0-0.4-0.1-0.5-0.6-0.6 c-0.9-0.1-2.4-0.4-2.4-2.9v-5.5h2.3c0.4,0,0.6-0.1,0.6-0.5v-0.2c0-0.4-0.2-0.6-0.6-0.6h-2.3v-2.6c0-0.4-0.1-0.6-0.5-0.6L53.8,69z M33.8,71.8c-3,0-5.4,2.2-5.5,5.8c0,3.4,2.5,5.8,5.8,5.8c1.8,0,3.1-0.8,3.7-1.2c0.3-0.2,0.3-0.5,0.2-0.7l-0.2-0.2 c-0.2-0.3-0.4-0.4-0.7-0.2c-0.5,0.4-1.5,1-2.9,1c-2.3,0-4.2-1.6-4.3-4.4h8c0.3,0,0.6-0.3,0.6-0.6C38.4,73.9,36.8,71.8,33.8,71.8z M65,71.8c-3.3,0-5.8,2.4-5.8,5.8c0,3.4,2.5,5.8,5.8,5.8c2,0,3.4-1,3.9-1.4c0.3-0.3,0.3-0.5,0.1-0.8L68.8,81 c-0.2-0.3-0.4-0.4-0.7-0.2C67.6,81.3,66.6,82,65,82c-2.4,0-4.3-1.8-4.3-4.4c0-2.7,1.9-4.5,4.3-4.5c1.3,0,2.3,0.7,2.8,1 c0.3,0.2,0.6,0.2,0.8-0.1l0.2-0.3c0.3-0.3,0.2-0.6-0.1-0.8C68.1,72.6,66.9,71.8,65,71.8L65,71.8z M81.9,71.8 c-3.2,0-5.8,2.5-5.8,5.7c0,3.3,2.6,5.8,5.8,5.8c3.2,0,5.8-2.5,5.8-5.8C87.8,74.3,85.1,71.8,81.9,71.8z M49.5,72 c-0.1,0-0.2,0.1-0.4,0.2l-2,2.4l-1.5,1.8l-2.3-2.7L42,72.2c-0.1-0.1-0.2-0.2-0.4-0.2c-0.1,0-0.3,0-0.4,0.2l-0.3,0.3 c-0.3,0.2-0.3,0.5,0,0.7l2,2.4l1.7,2l-2.5,2.9c0,0,0,0,0,0L40.9,82c-0.2,0.3-0.2,0.6,0.1,0.8l0.3,0.3c0.3,0.2,0.5,0.2,0.7-0.1 l2-2.4l1.5-1.8l2.3,2.7c0,0,0,0,0,0l1.2,1.5c0.2,0.3,0.5,0.3,0.8,0.1l0.3-0.3c0.3-0.2,0.3-0.5,0-0.7l-2-2.4l-1.7-2l2.5-2.9 c0,0,0,0,0,0l1.2-1.5c0.2-0.3,0.2-0.6-0.1-0.8l-0.3-0.3C49.7,72,49.6,71.9,49.5,72L49.5,72z M90.7,72c-0.4,0-0.5,0.2-0.5,0.6v6.5 c0,2.9,2.1,4.3,4.7,4.3c2.6,0,4.7-1.4,4.7-4.3v-6.5c0.1-0.4-0.1-0.6-0.5-0.6h-0.4c-0.4,0-0.6,0.2-0.6,0.6v6.1 c0,1.7-1.1,3.3-3.3,3.3c-2.1,0-3.3-1.6-3.3-3.3v-6.1c0-0.4-0.2-0.6-0.6-0.6L90.7,72z M33.8,73c1.6,0,3,1.2,3.1,3.5h-6.9 C30.3,74.3,31.9,73,33.8,73z M81.9,73.1c2.4,0,4.3,1.9,4.3,4.4c0,2.6-1.9,4.5-4.3,4.5c-2.4,0-4.3-2-4.3-4.5 C77.6,75.1,79.6,73.1,81.9,73.1z M107.1,73.1c2.4,0,3.5,2.2,3.5,4.4c0,3.2-1.7,4.5-3.6,4.5c-2.1,0-3.5-1.8-3.5-4.5 C103.5,74.8,105.1,73.1,107.1,73.1z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -0,0 +1,13 @@
=================
ExApps management
=================
.. toctree::
:maxdepth: 2
Installation
DeployConfigurations
CreationOfDeployDaemon
TestDeploy
ManagingExternalApplications
Concepts

View File

@@ -0,0 +1,59 @@
.. _dev-setup:
Setting up dev environment
==========================
We highly recommend using `Julius Haertl docker setup <https://github.com/juliushaertl/nextcloud-docker-dev>`_ for the Nextcloud dev setup.
Suggested IDE: **PhpStorm**, though you can certainly use any IDE of your preference such as **VS Code** or **Vim**.
Get last version from GitHub
""""""""""""""""""""""""""""
Assuming you're in the ``apps`` folder of Nextcloud with command :command:`git`::
git clone https://github.com/cloud-py-api/app_api.git
Change to the ``app_api`` directory with :command:`shell`::
cd app_api
Then, build frontend assets in development mode with :command:`shell`::
npm ci && npm run dev
After this, you can enable it from the directory where the ``occ`` command resides, with :command:`shell`::
./occ app:enable --force app_api
In Place of a Conclusion
""""""""""""""""""""""""
There are several make commands available to ease frequent development actions.
To see the complete list, execute ``make help``.
Docker remote API
*****************
The Docker Engine remote API can be easily configured via ``make dock2port`` command.
The command will create a docker container to provide remote Docker Engine API.
Afterward, register DaemonConfigs in Nextcloud using ``make dock-port`` command.
Docker by socket
****************
For Docker via socket, use the command ``make dock-sock``.
This registers DaemonConfigs in Nextcloud for the default socket connection (``/var/run/docker.sock``).
Make sure that socket has enough permissions for Nextcloud and webserver user to access it
and actually forwarded to the container:
.. code-block::
...
volumes:
...
- /var/run/docker.sock:/var/run/docker.sock
...

View File

@@ -0,0 +1,161 @@
Corporate Proxy - Permanent Settings for PHP CLI
================================================
If you're using our application within a corporate network that requires proxy settings, you might encounter issues when running PHP CLI commands that attempt to access the internet.
To resolve this, you need to configure permanent proxy settings for the PHP CLI environment.
Symptoms
--------
When running the command:
.. code-block:: bash
php occ app_api:app:register --force-scopes test-deploy docker_socket_proxy --info-xml https://raw.githubusercontent.com/cloud-py-api/test-deploy/main/appinfo/info.xml --test-deploy-mode --no-ansi --no-warnings
You may receive an error similar to:
.. code-block:: text
file_get_contents(https://raw.githubusercontent.com/cloud-py-api/test-deploy/main/appinfo/info.xml): Failed to open stream: Connection timed out at /var/www/html/custom_apps/app_api/lib/Service/ExAppService.php#277
Cause
-----
This issue occurs because the PHP CLI environment does not have the proxy settings configured, unlike the web PHP environment which may already be using proxy settings specified in your web server configuration.
Permanent Solution
------------------
To permanently configure proxy settings for PHP CLI, you can either modify the PHP CLI `php.ini` file or set environment variables system-wide.
Method 1: Edit PHP CLI `php.ini` File
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. **Locate the PHP CLI `php.ini` File**
Run the following command to find the loaded configuration file for PHP CLI:
.. code-block:: bash
php --ini
Look for the line:
.. code-block:: text
Loaded Configuration File: /path/to/php.ini
2. **Edit the `php.ini` File**
Open the `php.ini` file in a text editor with appropriate permissions:
.. code-block:: bash
sudo nano /path/to/php.ini
3. **Add Proxy Settings**
Add the following lines to configure the proxy settings:
.. code-block:: ini
[HTTP]
; Proxy settings for HTTP
http.proxy_host = "proxy.example.com"
http.proxy_port = 8080
http.proxy_user = "username"
http.proxy_password = "password"
[HTTPS]
; Proxy settings for HTTPS
https.proxy_host = "proxy.example.com"
https.proxy_port = 8080
https.proxy_user = "username"
https.proxy_password = "password"
Replace the placeholders with your actual proxy server details:
- `proxy.example.com`: Your proxy server address.
- `8080`: Your proxy server port.
- `username`: Your proxy username (if required).
- `password`: Your proxy password (if required).
4. **Save and Close the File**
Save the changes and exit the text editor.
5. **Verify the Configuration**
Run the PHP CLI command again:
.. code-block:: bash
php occ app_api:app:register
It should now be able to access the internet through the proxy.
**Note:** Not all PHP functions respect the proxy settings in `php.ini`. If issues persist, consider using system-wide environment variables.
Method 2: Set System-Wide Environment Variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. **Edit Shell Profile**
For a permanent solution, add the proxy settings to the system-wide environment variables. Open the `/etc/environment` file:
.. code-block:: bash
sudo nano /etc/environment
2. **Add Proxy Environment Variables**
Add the following lines to the file:
.. code-block:: bash
http_proxy="http://proxy.example.com:8080"
https_proxy="http://proxy.example.com:8080"
# If your proxy requires authentication:
http_proxy="http://username:password@proxy.example.com:8080"
https_proxy="http://username:password@proxy.example.com:8080"
Replace the placeholders with your actual proxy details.
3. **Apply the Changes**
Log out and log back in, or reboot the system to apply the changes.
4. **Verify the Configuration**
Run the command again:
.. code-block:: bash
php occ app_api:app:register --force-scopes test-deploy docker_socket_proxy --info-xml https://raw.githubusercontent.com/cloud-py-api/test-deploy/main/appinfo/info.xml --test-deploy-mode --no-ansi --no-warnings
It should now work without connectivity issues.
**Note:** This method sets the proxy settings for all users and applications on the system.
Troubleshooting
---------------
- **Incorrect Proxy Details**
Ensure all proxy details are correct. Incorrect hostnames, ports, or credentials will prevent connectivity.
- **Environment Variables Not Loaded**
Make sure the environment variables are correctly loaded. A system reboot or re-login may be necessary.
- **Firewall Restrictions**
Verify with your network administrator that your system is allowed to access the internet through the proxy.
Contact Support
---------------
If you've followed these steps and still experience issues, please contact our support team for further assistance.

View File

@@ -0,0 +1,8 @@
Docker Container Registry
=========================
How to use a private Docker container registry with authentication?
*******************************************************************
Currently, we don't support the authentication for Docker container registry.
The ExApp images must be publicly available.

View File

@@ -0,0 +1,56 @@
Docker Socket Proxy
===================
The recommended way to setup AppAPI Deploy daemon
is to use our `Docker Socket Proxy implementation <https://github.com/cloud-py-api/docker-socket-proxy>`_.
Nextcloud AppAPI DSP
--------------------
Nextcloud AppAPI DSP (Docker Socket Proxy) - is a simple Docker container that provides a secure way to access the Docker Engine API and ExApps.
It is secured with haproxy Basic authentication.
There are two parts of reverse proxy configuration:
- HaProxy config for `Docker Engine API <https://github.com/cloud-py-api/docker-socket-proxy/blob/main/haproxy.cfg.template>`_
- HaProxy config for `ExApps <https://github.com/cloud-py-api/docker-socket-proxy/blob/main/haproxy_ex_apps.cfg.template>`_
.. note::
For remote Docker Socket Proxy setup, it should expose the ports on the host.
.. _faq_nextcloud-aio-docker-socket-proxy:
Nextcloud AIO
-------------
Nextcloud AIO implements `Docker Socket Proxy container <https://github.com/nextcloud/all-in-one/tree/main/Containers/docker-socket-proxy>`_ which automatically setting up,
you just need to tick the checkbox in AIO configuration interface to enable it.
AppAPI automatically creates the default Deploy daemon configuration in Nextcloud AIO.
See :ref:`nextcloud-in-docker-aio-all-in-one` for more details.
.. note::
Nextcloud AIO is not limited to its default Deploy daemon.
You can setup any other Deploy daemon (local or remote) to use it in AppAPI.
Other implementations
---------------------
Our implementation is inspired by `Tecnativa Docker Socket Proxy <https://github.com/Tecnativa/docker-socket-proxy>`_,
by default, it restricts access to the required by AppAPI Docker Engine APIs.
In this case, you will have to enable these APIs via the environment variables:
- ``IMAGES=1``
- ``CONTAINER=1``
- ``POST=1``
.. note::
For local Deploy daemon setup other implementations of Docker Socket Proxy may be enough.
But for remote Deploy daemon setup, we recommend using our DSP,
as `we allow <https://github.com/cloud-py-api/docker-socket-proxy/blob/main/haproxy.cfg.template>`_ only the Docker Engine APIs we actually use in AppAPI,
and it is additionally secured with haproxy authentication.

View File

@@ -0,0 +1,28 @@
GPU support
-----------
How to enable GPU support for the Deploy daemon?
************************************************
To enable GPU support, you have to specify the GPU compute device when registering the Deploy daemon configuration.
In this way, by default, AppAPI will create ExApp containers with request to the Docker Engine to attach all available GPU devices.
This also involves the specific ExApp supporting work with GPU internally
and the necessary Docker runtime toolkits installed on the Deploy daemon host:
- For NVIDIA, refer to the `NVIDIA Docker configuration docs <https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html>`_.
- For AMD, refer to the `ROCm Docker configuration docs <https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/docker.html>`_.
.. note::
If you encounter any issues with GPU support, it is highly dependent on the specific GPU device,
software libraries and therefore ExApps support of different hardware, or other factors.
Please, feel free to ask for help by creating an issue.
How to limit the number of GPUs per ExApp?
******************************************
Currently, there is no such configuration option.
AppAPI attaches all available GPU devices to each ExApp container on the same Deploy daemon.

View File

@@ -0,0 +1,22 @@
Scaling
=======
AppAPI delegates the scaling task to the ExApps itself.
This means, that the ExApp must be designed in a way to be able to scale vertically.
As for the horizontal scaling, currently, it is not possible.
Except, for example, the Server-Workers architecture, is a good way to support basic scaling capabilities,
where the Server is your ExApp and the Workers are the external machines that can work with the ExApp
using Nextcloud user authentication.
Aadditional clients (or workers) can be (optionally) added (or attached) to the ExApp
to increase the capacity and performance.
GPUs scaling
------------
Currently, if Deploy daemon configured with GPUs available,
AppAPI by default will attach all available GPU devices to each ExApp container on this Deploy daemon.
This means, that these GPUs are shared between all ExApps on the same Deploy daemon.
Therefore, for the ExApps that require GPU and uses it heavily,
it is recommended to have a separate Deploy daemon (host) for them.

View File

@@ -0,0 +1,53 @@
Troubleshooting
===============
This section describes common steps to troubleshoot specific issues.
How to troubleshoot networking issues?
--------------------------------------
Networking issues can be not so straightforward to identify and resolve.
Here are some common steps to verify the network configuration:
- Verify that the Deploy daemon is running and accessible (AppAPI admin settings - Select Deploy daemon - Check connection).
- Verify the network mode and access levels, firewall, vpn, etc.
- Verify that Nextcloud is reachable from the Deploy daemon host
- Verify that the Deploy daemon host is reachable from the Nextcloud host
- Verify that Nextcloud is reachable from the ExApp container
- Verify if there is no DNS resolution issues
- Verify is there is no SSL certificate issues
- If there are HTTP 401 Unauthorized errors, check the ExApp (``docker logs nc_app_<appid>``) / Nextcloud logs, on which API route it fails to authenticate, try to re-enable AppAPI and re-install the ExApp.
.. note::
If your case is not documented here, or doesn't exists on GitHub issues,
please feel free to ask it by creating an issue in the `AppAPI repository <https://github.com/cloud-py-api/app_api/issues>`_.
ExApp deployment issues
-----------------------
The deployment issues questions are covered in the :ref:`Test Deploy <test_deploy>` section.
Generally speaking, there are three steps to find the proper error message to understand the problem:
1. Check Nextcloud logs
2. Check ExApp container logs (available only if ExApp container is created and/or running)
3. Check Deploy daemon host logs (``journalctl -u docker.service``)
4. Check Docker Socket Proxy logs (if used, and if needed, e.g. for SSL or 401 errors check)
Failed to create volume
-----------------------
If you encounter "Failed to create volume" error, please check the following:
- Make sure that there is enough disk space on the host machine.
- Check the Docker system logs while reproducing the issue (``journalctl -u docker.service``).
ExApps management list of apps from AppStore is empty
-----------------------------------------------------
This issue may occur if you are loading the ExApps management (or regular Apps management) page
frequently during the short period of time and therefore your IP can be blocked by the AppStore rate-limits protection.
Please, wait for a while and try again.

View File

@@ -0,0 +1,24 @@
Frequently Asked Questions
==========================
This section contains the most common or problematic questions
that users or developers may encounter when working with AppAPI.
It can be used as pointer to another parts of the documentation, as it usually refers to,
or provide a brief answer.
.. note::
This section will be updated with time, as new questions arise.
If you have a question that is not listed here or the answer is not enough for you, please feel free to
ask it by creating an issue in the `AppAPI repository <https://github.com/nextcloud/app_api/issues>`_.
.. toctree::
:maxdepth: 2
DockerContainerRegistry
DockerSocketProxy
GpuSupport
Scaling
BehindCompanyProxy
Troubleshooting

View File

@@ -0,0 +1,29 @@
=================
ExApp development
=================
**ExApps** (short for "External Apps") are Nextcloud apps that are developed in another programming language (outside of PHP) using the AppAPI OCS API.
AppAPI is a project introduced by Nextcloud to revolutionize the process of application development within the Nextcloud ecosystem.
Overview
--------
The main tasks of the AppAPI ecosystem are:
* Providing a reliable and fast method for authenticating applications
* Supporting various application deployment options
* Offering a clear and straightforward application administration interface
* Ensuring a reliable implementation of all the necessary missing APIs for applications
* Supplying clear, understandable documentation and support on how to implement libraries in other programming languages for writing next-gen applications for Nextcloud
If you have any questions or corrections regarding the documentation,
we would be glad to address them in discussions, incorporate corrections through pull requests,
and handle complex problems through issues.
.. toctree::
:maxdepth: 2
DevSetup
tech_details/index.rst
notes_for_developers/index.rst
faq/index.rst

View File

@@ -0,0 +1,25 @@
.. _DevelopmentEnvironment:
Development environment
=======================
The development environment for AppAPI first of all requires a default Nextcloud dev setup.
You can find more information on that in the `Nextcloud development environment docs <https://docs.nextcloud.com/server/latest/developer_manual/getting_started/devenv.html>`_.
The AppAPI dev setup steps listed :ref:`here <dev-setup>`.
Deploy daemons types
--------------------
There are two types of Deploy daemons that can be used for development and testing of ExApp:
1. ``manual_install``: This type of Deploy daemon is running manually in the host machine.
You can create it in AppAPI admin settings using template.
This is useful for development of ExApp, when you run your ExApp manually in the host.
2. ``docker_install``: This type of Deploy daemon is running in a Docker container.
Docker Socket Proxy
-------------------
For development and testing locally, the simplest is to use the `Nextcloud AppAPI DSP HTTP <https://github.com/cloud-py-api/docker-socket-proxy?tab=readme-ov-file#httplocal>`_.

View File

@@ -0,0 +1,124 @@
.. _ExAppDevelopment:
ExApp development
=================
ExApp development process is similar to the development of the regular Nextcloud PHP app,
and should follow the same guidelines in terms of security, design and coding style (`ref <https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html>`_)
based on your programming language standards.
Despite the fact, that ExApp can be developed in any language, it's still recommended to have the understanding
of the Nextcloud `PHP request life cycle <https://docs.nextcloud.com/server/latest/developer_manual/basics/request_lifecycle.html>`_ and other basic concepts,
as they are usually similar to the ExApp backend to which Nextcloud communicates.
You can think about ExApp like a microservice (Docker container)
that runs separately from Nextcloud on the Deploy daemon, which can be remote or local.
The communication between Nextcloud and ExApp is done via network secured with AppAPI authentication (:ref:`app_api_auth`).
Lets go through the ExApp development steps briefly.
0. Setting up the development environment
-----------------------------------------
First of all, you need to have a Nextcloud dev setup, refer to :ref:`DevelopmentEnvironment` for more details.
1. Starting from template
-------------------------
Next step, is to setup the ExApp skeleton.
There are several ExApp examples available so you can have a look at them and start from.
The ExApp template and examples:
- ``[Python]`` `App Skeleton <https://github.com/cloud-py-api/app-skeleton-python>`_
- ``[Python]`` `UI Example Skeleton <https://github.com/cloud-py-api/ui_example>`_
- ``[Python]`` `More complex ExApp UI example with 3rdparty service <https://github.com/cloud-py-api/visionatrix>`_
- ``[GoLang]`` `Go Lang ExApp example <https://github.com/cloud-py-api/file_to_text_example>`_
- etc.
They contain the basic structure of the ExApp, including:
- Dockerfile
- ExApp backend
- ExApp frontend
- Manual translations tools setup and example script to convert translation files to Nextcloud l10n format and for your programming language
- Some necessary GitHub workflows (e.g. `Docker image build workflows <https://github.com/cloud-py-api/visionatrix/tree/main/.github/workflows>`_)
More details are available in the :ref:`ExAppOverview` section.
3. Development
--------------
The development process basically contains from the following steps:
- Implement the ExApp <-> Nextcloud :ref:`lifecycle methods <ex_app_lifecycle_methods>`:
#. ``/heartbeat``: ExApp heartbeat method.
#. ``/init``: ExApp initialization method.
#. ``/enabled``: ExApp enable/disable method.
- Implement the ExApp backend API and logic.
- Implement the ExApp frontend (Nextcloud Vue.js app) [optional].
4. Packaging
------------
The ExApp packaging can be done manually, or via GitHub actions.
It is recommended to use GitHub actions for packaging,
as it will automate the process of building the Docker image and pushing it to the Docker registry.
The GitHub action workflow for building Docker images can be found in the `3rdparty service example <https://github.com/cloud-py-api/visionatrix>`_.
4.1 Hardware acceleration
*************************
If your ExApp work with GPUs, you should consider building different Docker images for each compute device.
Currently, there are 3 main compute devices to target with custom Docker images:
- CPU (default, no specific tag)
- GPU: CUDA (NVIDIA) (``<image_name>:<version>-cuda``)
- GPU: ROCm (AMD) (``<image_name>:<version>-rocm``)
.. note::
If the Deploy daemon configured with the GPU compute device,
AppAPI will try to pull the Docker image with the GPU support first (``<image_name>:<version>-<cuda|rocm>``, `ref PR <https://github.com/cloud-py-api/app_api/pull/340>`_).
If the image is not found, AppAPI will try to pull the base (CPU) image (``<image_name>:<version>``).
Dockerfile
**********
The Dockerfile is required to build the Docker image for the ExApp.
The guideline for writing the Dockerfile can be found in the `Dockerfile best practices <https://docs.docker.com/develop/develop-images/dockerfile_best-practices/>`_.
Short recommendations:
1. Keep the Dockerfile as small as possible.
2. Use minimal base images to keep the image size small.
3. Place rarely changing instructions at the top of the Dockerfile to take advantage of Docker's caching mechanism.
Logging
*******
The logs in Docker container are shown from the standard output and error streams.
To be able admin to see the important logs from ExApp container,
you should consider redirecting the logs to the standard output and standard error streams.
More info in `official docs for logging <https://docs.docker.com/config/containers/logging/>`_.
5. AppStore publishing
----------------------
Once the ExApp is ready, and the Docker image is available in the Docker registry,
you can follow `the AppStore publishing process <https://nextcloudappstore.readthedocs.io/en/latest/developer.html>`_.
It's the same as for the regular Nextcloud app, but with the requirement of :ref:`the ExApp specific fields <ex_app_info_xml_metadata>` in the ``appinfo/info.xml`` file.
6. Testing
----------
It is important to ensure that your ExApp works as expected.
We recommend to have different types of dev setup configuration to test all of them.
While the main development is done locally via ``manual_install``, you must also ensure that
the ExApp works correctly in Docker container with http and https Docker Socket proxy.

View File

@@ -0,0 +1,155 @@
.. _ex_app_lifecycle:
ExApp lifecycle
===============
The ExApp lifecycle is a set of communication rules (or protocol) between Nextcloud and ExApp.
They are required as for the microservice architecture of ExApp.
This section is an overview, more details on that here: :ref:`app_installation_flow`, :ref:`app_deployment`.
.. _ex_app_lifecycle_methods:
ExApp lifecycle methods
-----------------------
When ExApp is being installed in Nextcloud, there are several lifecycle steps happening.
The ExApp lifecycle requires the following API endpoint handlers (order is preserved):
- 0. ``healthcheck``: Docker container healthcheck.
- 1. ``/heartbeat``: **[required]** ExApp heartbeat handler.
- 2. ``/init``: **[optional]** ExApp initialization handler.
- 3. ``/enabled``: **[required]** ExApp enable/disable handler.
Healthcheck
***********
Docker allows you to define a custom healthcheck script for your container (specified in the Dockerfile).
You can define here if needed custom container startup logic.
.. note::
AppAPI healthcheck timeout is 15 minutes.
Heartbeat
*********
The ``GET /heartbeat`` method is called periodically by Nextcloud to check the ExApp health status,
if its webserver is running and recieving requests.
URL: ``GET http://localhost:2345/heartbeat``
AppAPI expects a response with HTTP status 200.
This step fails if the ExApp does not respond within 10 minutes.
.. note::
This endpoint should be available **without AppAPIAuth authentication**.
There is a 10 minutes timeout for the ExApp to startup and respond to the ``/heartbeat`` request.
.. _ex_app_lifecycle_init:
Init
****
The ``POST /init`` endpoint is called after the ExApp is enabled in Nextcloud.
This is a trigger for ExApp to start its initialization process, e.g. downloading models, starter data, etc.
.. note::
Default init timeout (``init_timeout``) is 40 minutes. It can be changed by admin in AppAPI settings
or via CLI command ``occ config:app:set app_api init_timeout --value 40 --type mixed``.
URL: ``POST http://localhost:2345/init``
AppAPI expects a response with HTTP status 200.
.. note::
If ExApp doesn't not implement ``/init`` endpoint and AppAPI receives ``HTTP 501 NOT IMPLEMENTED`` or ``HTTP 404 NOT FOUND`` response,
AppAPI enables the ExApp.
The ExApp should update the init progress via the ``PUT /ocs/v2.php/apps/app_api/ex-app/status`` API request,
with ``{ "progress": <number> }`` payload.
Enabled
*******
The ``PUT /enabled?enabled=1|0`` method is called when the ExApp is enabled or disabled in Nextcloud.
The ``enabled`` query parameter is used to determine the ExApp state: 1 - enabled, 0 - disabled.
- ``PUT http://localhost:2345/enabled?enabled=1`` - enable ExApp, during this call ExApp should register all needed APIs
- ``PUT http://localhost:2345/enabled?enabled=0`` - disable ExApp, during this call ExApp should unregister all APIs
AppAPI expects a response with HTTP status 200. Any other status code will be considered as an error.
.. note::
AppAPI timeout for the ``enabled`` handler is 30 seconds.
ExApp lifecycle scheme
----------------------
Let's review a simple ExApp lifecycle scheme:
.. mermaid::
sequenceDiagram
participant Nextcloud
participant ExApp
loop Heartbeat
Nextcloud->>ExApp: HTTP GET /heartbeat
ExApp-->>Nextcloud: /heartbeat HTTP 200
end
Nextcloud->>ExApp: HTTP POST /init
ExApp->>Nextcloud: /init HTTP OK 200
loop Init
ExApp->>ExApp: Download models, starter data, etc.
ExApp-->>Nextcloud: PUT /ocs/v2.php/apps/app_api/ex-app/status { "progress": 50 }
end
Nextcloud->>ExApp: HTTP PUT /enabled?enabled=1
ExApp-->>Nextcloud: Register all needed APIs via OCS API
ExApp->>Nextcloud: /enabled HTTP 200
Nextcloud->>ExApp: HTTP PUT /enabled?enabled=0
ExApp-->>Nextcloud: Unregister all APIs via OCS API
ExApp->>Nextcloud: /enabled HTTP 200
Nextcloud-side ExApp lifecycle methods
--------------------------------------
The Nextcloud-side ExApp lifecycle methods are the OCS APIs.
You can find available AppAPI Nextcloud OCS APIs :ref:`here <app_api_nextcloud_apis>`.
.. note::
ExApp should register all needed APIs during the ``enabled`` method call.
E.g. UI (:ref:`top-menu <top_menu_section>`, :ref:`filesactionmenu <file_actions_menu_section>`), :ref:`occ commands <occ_command>`, etc.
AppAPI Authentication
---------------------
Nextcloud requests to the ExApp are secured with :ref:`AppAPIAuth <app_api_auth>`.
The ExApp should validate the authentication using the same algorithm as AppAPI does.
.. note::
Is it up to the developer to apply the rate limits, bruteforce protection, and other security measures
to the ExApp API endpoints.
Cookies
*******
Along with the AppAPIAuth, ExApp can utilize the Nextcloud cookies of the authenticated user,
who made the request to the ExApp.

View File

@@ -0,0 +1,335 @@
.. _ExAppOverview:
ExApp overview
==============
Basic concept of the AppAPI is to provide a way to develop an app for Nextcloud using any language.
In this way, the ExApp can be written in any language, in particular, the backend part.
Frontend is kept the same. You can think about ExApp as a microservice.
ExApp structure
---------------
The typical ExApp folder structure is the following:
- **appinfo/**: contains the ExApp metadata, which is based on the regular `Nextcloud PHP appinfo <https://docs.nextcloud.com/server/latest/developer_manual/app_development/info.html>`_,
but with additional new fields under the ``external-app`` key.
- **ex_app/**: the ExApp specific folder, which contains the ExApp frontend and backend parts.
- **lib/**: contains the ExApp backend part, which can be written in any language.
- **src/**: contains the ExApp frontend part, which is a regular Nextcloud Vue.js application, with small adjustments to the script loading paths (see :ref:`ExApp specific frontend changes <ex_app_specific_frontend_changes>`).
- **img/**: contains the ExApp images.
- **css/**: contains the ExApp CSS files.
- **l10n**: contains the :ref:`ExApp translations <ex_app_translations>`.
- **translationfiles**: contains the source translation (``.po``, ``.mo``) files for the ExApp.
- **other folders or files**: depends on your case, e.g. screenshots, scripts, etc.
.. _ex_app_info_xml_metadata:
ExApp metadata
**************
The ``<external-app>`` info.xml tag is required for the ExApp metadata.
It should contain the following fields:
.. code-block::
<external-app>
<docker-install>
<registry>ghcr.io</registry>
<image>cloud-py-api/skeleton</image>
<image-tag>latest</image-tag>
</docker-install>
<scopes> // deprecated and removed since AppAPI 3.2.0
<value>FILES</value>
<value>AI_PROVIDERS</value>
...
</scopes>
<system>false</system> // deprecated since AppAPI 3.0.0
</external-app>
- **docker-install**: contains the Docker image information for the ExApp.
- **registry**: the Docker registry where the image is stored.
- **image**: the Docker image name.
- **image-tag**: the Docker image tag (version tag).
- **scopes**: the list of the Nextcloud scopes that the ExApp requires (see :ref:`list of scopes <api_scopes>`).
- **system**: (deprecated since AppAPI 3.0.0) a boolean value that indicates whether the ExApp is a system app or not.
Backend
-------
The ExApp backend part can be implemented in any language and framework you want,
the only requirement here is to follow the microservice architecture and ExApp <-> Nextcloud :ref:`communication flow <ex_app_lifecycle_methods>`.
.. note::
There is a limitation of AppAPI ExApp proxy - the websocket connections are not supported.
Each ExApp container have the environment variables set by AppAPI, you can find more about it :ref:`here <ex_app_env_vars>`.
Persistent storage
******************
For each ExApp, AppAPI creates a Docker volume (``nc_app_<app_id>_data``), that is attached to the ExApp container as a persistent storage.
It is available inside container under the ``/nc_app_<app_id>_data`` path or via ``APP_PERSISTENT_STORAGE`` env passed by AppAPI.
.. _ex_app_specific_frontend_changes:
Frontend
--------
The ExApp frontend part is loaded only for :ref:`TopMenu entry <top_menu_section>`.
It is a regular Nextcloud Vue.js application with a small routing adjustment to the paths,
as they are being loaded via AppAPI proxy from the ExApp server.
To simplify the usage, we declare a few constants:
.. code-block::
export const EX_APP_ID = 'ui_example'
export const EX_APP_MENU_ENTRY_NAME = 'first_menu'
export const APP_API_PROXY_URL_PREFIX = '/apps/app_api/proxy'
export const APP_API_ROUTER_BASE = '/apps/app_api/embedded'
The bootstrap of the Vue app (`UI Example boostrap <https://github.com/cloud-py-api/ui_example/blob/main/src/bootstrap.js>`_) is changes as follows:
.. code-block::
import Vue from 'vue'
import { translate, translatePlural } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { APP_API_PROXY_URL_PREFIX, EX_APP_ID } from './constants/AppAPI.js'
import { getRequestToken } from '@nextcloud/auth'
Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = window.OC
Vue.prototype.OCA = window.OCA
__webpack_public_path__ = generateUrl(`${APP_API_PROXY_URL_PREFIX}/${EX_APP_ID}/js/`) // eslint-disable-line
__webpack_nonce__ = btoa(getRequestToken()) // eslint-disable-line
Frontend routing
****************
The frontend routing base URL is also adjusted to be loaded via AppAPI proxy.
For example, the vuex router has the following base URL configuration:
.. code-block::
...
const router = new VueRouter({
mode: 'history',
base: generateUrl(`${APP_API_ROUTER_BASE}/${EX_APP_ID}/${EX_APP_MENU_ENTRY_NAME}`, ''), // setting base to AppAPI embedded URL
linkActiveClass: 'active',
...
The same applies to the frontend API requests to the ExApp backend API:
.. code-block::
...
axios.get(generateUrl(`${APP_API_PROXY_URL_PREFIX}/${EX_APP_ID}/some_api_endpoint`))
...
.. _ex_app_translations:
L10n translations
-----------------
Currently, only `manual translations <https://docs.nextcloud.com/server/latest/developer_manual/basics/front-end/l10n.html#manual-translation>`_ are supported.
To add support of your programming language from translations string extraction using Nextcloud translation tool,
you just need to add your file extensions to it `in createPotFile <https://github.com/nextcloud/docker-ci/blob/master/translations/translationtool/src/translationtool.php#L69>`_
and down below adjust the ``--language`` and ``keyword`` parameters.
Our examples using translationtool adjusted in the same way:
.. code-block::
diff --git a/translations/translationtool/src/translationtool.php b/translations/translationtool/src/translationtool.php
index 42513563..8aa06618 100644
--- a/translations/translationtool/src/translationtool.php
+++ b/translations/translationtool/src/translationtool.php
@@ -67,7 +67,7 @@ public function createPotFile() {
$this->createFakeFileForVueFiles();
$this->createFakeFileForLocale();
$translatableFiles = $this->findTranslatableFiles(
- ['.php', '.js', '.jsx', '.mjs', '.html', '.ts', '.tsx'],
+ ['.php', '.js', '.jsx', '.mjs', '.html', '.ts', '.tsx', '.py'],
['.min.js']
);
@@ -79,6 +79,8 @@ public function createPotFile() {
$keywords = '';
if (substr($entry, -4) === '.php') {
$keywords = '--keyword=t --keyword=n:1,2';
+ } else if (substr($entry, -3) === '.py') {
+ $keywords = '--keyword=_ --keyword=_n:1,2';
} else {
$keywords = '--keyword=t:2 --keyword=n:2,3';
}
@@ -86,6 +88,8 @@ public function createPotFile() {
$language = '--language=';
if (substr($entry, -4) === '.php') {
$language .= 'PHP';
+ } else if (substr($entry, -3) === '.py') {
+ $language .= 'Python';
} else {
$language .= 'Javascript';
}
where we declaring the methods used in source code for translating strings.
The ExApp translations are stored in the ``l10n`` folder in the ExApp root folder.
For Nextcloud side it still has to contain the files as for regular Nextcloud apps (.js and .json).
There ExApp translation files are copied to the Nextcloud server during installation (removed on uninstall),
and can be used to translate ExApp string on backend or frontend parts the same way as for PHP apps.
.. note::
For the clustered Nextcloud setup, the ExApp translations must be also copied to the other Nextcloud instances,
if the apps folder is not shared between the instances.
It is done automatically only for the instance, where the installation is performed.
You might need to convert the translation files to the format that is used in your language.
And this can be done with simple bash script, as `in our example for Python <https://github.com/cloud-py-api/ui_example/blob/main/scripts/convert_to_locale.sh>`_:
.. code-block::
#!/bin/bash
# This script is used to transform default translation files folders (translationfiles/<lang>/*.(po|mo))
# to the locale folder (locale/<lang>/LC_MESSAGES/*.(po|mo))
cd ..
# Remove the locale/* if it exists to cleanup the old translations
if [ -d "locale" ]; then
rm -rf locale/*
fi
# Create the locale folder if it doesn't exist
if [ ! -d "locale" ]; then
mkdir locale
fi
# Loop through the translation folders and copy the files to the locale folder
# Skip the templates folder
for lang in translationfiles/*; do
if [ -d "$lang" ]; then
lang=$(basename $lang)
if [ "$lang" != "templates" ]; then
if [ ! -d "locale/$lang/LC_MESSAGES" ]; then
mkdir -p locale/$lang/LC_MESSAGES
fi
# Echo the language being copied
echo "Copying $lang locale"
cp translationfiles/$lang/*.po locale/$lang/LC_MESSAGES/
cp translationfiles/$lang/*.mo locale/$lang/LC_MESSAGES/
fi
fi
done
Makefile
--------
It is recommended to follow our Makefile example with the default set of commands:
.. note::
Makefile is written to work in the `nextcloud-docker-dev <https://github.com/juliushaertl/nextcloud-docker-dev>`_ dev setup.
- ``help``: shows the list of available commands.
- ``build-push-cpu``: builds the Docker image for CPU and uploads it to the Docker registry.
- ``build-push-cuda``: builds the Docker image for CUDA and uploads it to the Docker registry.
- ``build-push-rocm``: builds the Docker image for ROCm and uploads it to the Docker registry.
- ``run``: installs the ExApp for Nextcloud latest via the ``occ app_api:app:register`` command, like from UI.
- ``register``: performs registration of running manually ExApp using the ``manual_install`` Deploy daemon.
- ``translation_templates``: execute translationtool.phar to extract translation strings from sources (frontend and backend).
- ``convert_translations_nc``: converts translations to Nextcloud format files (json, js).
- ``convert_to_locale``: copies translations to the common locale/<lang>/LC_MESSAGES/<appid>.(po|mo). Depending on the language, you might need to adjust the script.
Example
*******
Here is an example of regular ExApp Makefile:
.. code-block::
.DEFAULT_GOAL := help
.PHONY: help
help:
@echo "Welcome to Nextcloud Visionatrix. Please use \`make <target>\` where <target> is one of"
@echo " "
@echo " Next commands are only for dev environment with nextcloud-docker-dev!"
@echo " They should run from the host you are developing on(with activated venv) and not in the container with Nextcloud!"
@echo " "
@echo " build-push-cpu build image for CPU and upload to ghcr.io"
@echo " build-push-cuda build image for CUDA and upload to ghcr.io"
@echo " build-push-rocm build image for ROCm and upload to ghcr.io"
@echo " "
@echo " run install Visionatrix for Nextcloud Last"
@echo " "
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
@echo " First run original 'Visionatrix', then run this Visionatrix and then 'make registerXX', after that you can use/debug/develop it and easy test."
@echo " Do not forget to change paths in 'proxy_requests' function to point to correct files for the frontend"
@echo " "
@echo " register perform registration of running Visionatrix-es into the 'manual_install' deploy daemon."
@echo " "
@echo " L10N (for manual translation):"
@echo " translation_templates extract translation strings from sources"
@echo " convert_translations_nc convert translations to Nextcloud format files (json, js)"
@echo " convert_to_locale copy translations to the common locale/<lang>/LC_MESSAGES/<appid>.(po|mo)"
.PHONY: build-push-cpu
build-push-cpu:
docker login ghcr.io
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ghcr.io/cloud-py-api/visionatrix:$$(xmlstarlet sel -t -v "//image-tag" appinfo/info.xml) --build-arg BUILD_TYPE=cpu .
.PHONY: build-push-cuda
build-push-cuda:
docker login ghcr.io
docker buildx build --push --platform linux/amd64 --tag ghcr.io/cloud-py-api/visionatrix-cuda:$$(xmlstarlet sel -t -v "//image-tag" appinfo/info.xml) --build-arg BUILD_TYPE=cuda .
.PHONY: build-push-rocm
build-push-rocm:
docker login ghcr.io
docker buildx build --push --platform linux/amd64 --tag ghcr.io/cloud-py-api/visionatrix-rocm:$$(xmlstarlet sel -t -v "//image-tag" appinfo/info.xml) --build-arg BUILD_TYPE=rocm .
.PHONY: run
run:
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister visionatrix --silent --force || true
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register visionatrix --force-scopes \
--info-xml https://raw.githubusercontent.com/cloud-py-api/visionatrix/main/appinfo/info.xml
.PHONY: register
register:
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister visionatrix --silent --force || true
docker exec master-nextcloud-1 rm -rf /tmp/vix_l10n && docker cp l10n master-nextcloud-1:/tmp/vix_l10n
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register visionatrix manual_install --json-info \
"{\"id\":\"visionatrix\",\"name\":\"Visionatrix\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9100,\"scopes\":[\"AI_PROVIDERS\", \"FILES\", \"USER_INFO\"], \"translations_folder\":\"\/tmp\/vix_l10n\"}" \
--force-scopes --wait-finish
.PHONY: translation_templates
translation_templates:
./translationtool.phar create-pot-files
.PHONY: convert_translations_nc
convert_translations_nc:
./translationtool.phar convert-po-files
.PHONY: convert_to_locale
convert_to_locale:
./scripts/convert_to_locale.sh

View File

@@ -0,0 +1,17 @@
.. _notes_for_developers:
Notes for Developers
====================
This section contains the most common information for ExApp developers,
grouped from other parts of documentation.
.. toctree::
:maxdepth: 2
DevelopmentEnvironment
ExAppDevelopmentSteps
ExAppOverview
ExAppLifecycle

View File

@@ -0,0 +1,50 @@
.. _api_scopes:
Api Scopes
==========
.. warning::
ApiScopes are deprecated and removed since AppAPI 3.2.0.
AppAPI design's focus on simplicity and necessity highlights the benefits of defining API scopes.
which simplify the development and integration of applications into the Nextcloud ecosystem.
With the elimination of optional API scopes, the configuration process during installation becomes more streamlined.
Now, the Nextcloud administrator only needs to focus on the essential API groups,
making the application's setup and permissions handling more efficient and less prone to errors.
The **info.xml** file continues to play a crucial role, listing all the `required` API groups an
application needs to function correctly.
This not only simplifies version updates, allowing for the seamless introduction of
new API groups or the discontinuation of obsolete ones, but also enhances the overall security and reliability
of the application by ensuring it only has access to necessary functionalities.
Supported API Groups include:
* ``2`` SYSTEM
* ``10`` FILES
* ``11`` FILES_SHARING
* ``30`` USER_INFO
* ``31`` USER_STATUS
* ``32`` NOTIFICATIONS
* ``33`` WEATHER_STATUS
* ``50`` TALK
* ``60`` TALK_BOT
* ``61`` AI_PROVIDERS
* ``62`` EVENTS_LISTENER
* ``63`` OCC_COMMAND
* ``110`` ACTIVITIES
* ``120`` NOTES
* ``200`` TEXT_PROCESSING
* ``210`` MACHINE_TRANSLATION
* ``9999`` ALL
These groups, represented by intuitive names, ensure that applications have
tailored access to the functionalities they need, enhancing performance and user experience.
As Nextcloud evolves, this list of API groups will continue to grow, offering developers a wide array of tools
to create innovative and efficient applications.
The streamlined approach to API scopes not only simplifies the application development process
but also aligns with best practices in software design, emphasizing clarity, security, and efficiency.
This refinement in the handling of API scopes reflects Nextcloud's commitment to providing a robust and developer-friendly platform.

View File

@@ -0,0 +1,91 @@
.. _app_api_auth:
Authentication
==============
AppAPI introduces a distinct method of authentication for external apps.
This authentication relies on a shared secret between Nextcloud and the external app
Authentication flow
^^^^^^^^^^^^^^^^^^^
1. ExApp sends a request to Nextcloud
2. Nextcloud passes request to AppAPI
3. AppAPI validates request (see `authentication flow in details`_)
4. Request is accepted/rejected
.. mermaid::
sequenceDiagram
participant ExApp
box Nextcloud
participant Nextcloud
participant AppAPI
end
ExApp->>+Nextcloud: Request to API
Nextcloud->>+AppAPI: Validate request
AppAPI-->>-Nextcloud: Request accepted/rejected
Nextcloud-->>-ExApp: Response (200/401)
.. _auth-headers:
Authentication headers
^^^^^^^^^^^^^^^^^^^^^^
Each ExApp request to secured API with AppAPIAuth must contain the following headers:
1. ``AA-VERSION`` - minimal version of the AppAPI
2. ``EX-APP-ID``- ID of the ExApp
3. ``EX-APP-VERSION`` - version of the ExApp
4. ``AUTHORIZATION-APP-API`` - base64 encoded ``userid:secret``
Authentication flow in details
******************************
.. mermaid::
:zoom:
sequenceDiagram
autonumber
participant ExApp
box Nextcloud
participant Nextcloud
participant AppAPI
end
ExApp->>+Nextcloud: Request to API
Nextcloud->>Nextcloud: Check if AUTHORIZATION-APP-API header exists
Nextcloud-->>ExApp: Reject if AUTHORIZATION-APP-API header not exists
Nextcloud->>Nextcloud: Check if AppAPI app is enabled
Nextcloud-->>ExApp: Reject if AppAPI is not exists or disabled
Nextcloud->>+AppAPI: Validate request
AppAPI-->>AppAPI: Check if ExApp exists and enabled
AppAPI-->>Nextcloud: Reject if ExApp not exists or disabled
AppAPI-->>AppAPI: Validate shared secret from AUTHORIZATION-APP-API
AppAPI-->>Nextcloud: Reject if secret does not match
AppAPI-->>AppAPI: Check if user is not empty and active
AppAPI-->>Nextcloud: Set active user
AppAPI->>-Nextcloud: Request accepted/rejected
Nextcloud->>-ExApp: Response (200/401)
AppAPIAuth
^^^^^^^^^^
AppAPI provides ``AppAPIAuth`` attribute with middleware to validate requests from ExApps.
In your API controllers you can use it as an PHP attribute.
AppAPI session keys
^^^^^^^^^^^^^^^^^^^
After successful authentication AppAPI sets `app_api` session key to ``true``.
.. code-block:: php
$this->session->set('app_api', true);
$this->session->set('app_api_system', true); // deprecated since AppAPI 3.0.0
.. note::
The Nextcloud server verifies this session key and allows **CORS protection** and **Two-Factor authentication** to be bypassed for requests coming from ExApps.
Also the rate limit is not applied to requests coming from ExApps.

View File

@@ -0,0 +1,159 @@
.. _app_deployment:
Deployment
==========
Overview
--------
AppAPI ExApps deployment process in short consists of 2 steps:
1. `DaemonConfig registration`_
2. `ExApp registration`_
.. _occ_daemon_config_registration:
DaemonConfig registration
-------------------------
The first step is to register DaemonConfig, where your ExApps will be deployed.
Before that you will need to configure your Docker socket to be accessible by Nextcloud instance and webserver user.
In case of remote Docker Engine API, you will need to expose it so it is accessible by Nextcloud instance and import certificates.
.. note::
For now only Docker daemon ``accepts-deploy-id: docker-install`` is supported.
For development and manually deployed app in docker there is ``accepts-deploy-id: manual-install``.
This can be done by ``occ`` CLI command **app_api:daemon:register**:
.. code-block:: bash
app_api:daemon:register <name> <display-name> <accepts-deploy-id> <protocol> <host> <nextcloud_url> [--net NET] [--haproxy_password PASSWORD] [--]
Arguments
*********
* ``name`` - unique name of the daemon (e.g. ``docker_local_sock``)
* ``display-name`` - name of the daemon (e.g. ``My Local Docker``, will be displayed in the UI)
* ``accepts-deploy-id`` - type of deployment (``docker-install`` or ``manual-install``)
* ``protocol`` - protocol used to connect to the daemon (``http`` or ``https``)
* ``host`` - host of the daemon (e.g. ``/var/run/docker.sock`` or ``host:port``)
* ``nextcloud_url`` - Nextcloud URL, Daemon config required option (e.g. ``https://nextcloud.local``)
Options
*******
* ``--net [network-name]`` - ``[required]`` network name to bind docker container to (default: ``host``)
* ``--haproxy_password PASSWORD`` - ``[optional]`` password if ``AppAPI Docker Socket Proxy`` is used
* ``--gpu`` - ``[optional]`` GPU device to expose to the daemon (e.g. ``/dev/dri``)
.. note::
Common configurations are tested by CI in our repository, see `workflows on github <https://github.com/cloud-py-api/app_api/blob/main/.github/workflows/tests-deploy.yml>`_.
Example
*******
Example of ``occ`` **app_api:daemon:register** command:
.. code-block:: bash
sudo -u www-data php occ app_api:daemon:register docker_local_sock "My Local Docker" docker-install http /var/run/docker.sock "https://nextcloud.local" --net nextcloud
ExApp registration
------------------
Second and final step is to deploy and register ExApp in Nextcloud on previously registered daemon.
This can be done by ``occ`` CLI command **app_api:app:register**:
.. code-block:: bash
app_api:app:register <appid> <daemon-config-name> [--force-scopes] [--]
Arguments
*********
* ``appid`` - unique name of the ExApp (e.g. ``app_python_skeleton``, must be the same as in deployed container)
* ``daemon-config-name`` - unique name of the daemon (e.g. ``docker_local_sock``)
Options
*******
* ``--force-scopes`` **[optional]** - force scopes approval
* ``--info-xml INFO-XML`` **[optional]** - path to info.xml file with ExApp description (url or local absolute path)
* ``--json-info JSON-INFO`` **[optional]** - JSON with ExApp description
.. warning::
After successful deployment (pull, create and start container), there is a heartbeat check with 90 seconds timeout (will be configurable).
Manual install for development
******************************
For development purposes, you can install ExApp manually.
There is a ``manual-install`` DeployConfig type, which can be used in case of development.
For ExApp registration with it you need to provide JSON app info or a path to app XML file.
For all examples and applications we release we usually add manual_install command in it's makefile for easier development.
.. code-block::
php occ app_api:app:register nc_py_api manual_install --json-info \
"{\"id\":\"nc_py_api\",\"name\":\"nc_py_api\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":$APP_PORT,\"scopes\":[\"SYSTEM\", \"FILES\", \"FILES_SHARING\", \"USER_INFO\", \"USER_STATUS\", \"NOTIFICATIONS\", \"WEATHER_STATUS\", \"TALK\"],\"system\":1}" \
--force-scopes
.. note:: **Deployment/Startup of App should be done by developer when ``manual-install`` DeployConfig type is used.**
.. _ex_app_env_vars:
Deploy env variables
********************
Deploy env variables are used to configure ExApp container.
The following env variables are required and built automatically:
* ``AA_VERSION`` - AppAPI version
* ``APP_SECRET`` - generated shared secret used for AppAPI authentication
* ``APP_ID`` - ExApp appid
* ``APP_DISPLAY_NAME`` - ExApp display name
* ``APP_VERSION`` - ExApp version
* ``APP_HOST`` - host ExApp is listening on
* ``APP_PORT`` - port ExApp is listening on (randomly selected by AppAPI)
* ``APP_PERSISTENT_STORAGE`` - path to mounted volume for persistent data storage between ExApp updates
* ``NEXTCLOUD_URL`` - Nextcloud URL to connect to
Application installation scheme
-------------------------------
1. AppAPI deploys the application and launches it.
2. AppAPI for `N` seconds (default ``90``) checks the ``/heartbeat`` endpoint with ``GET`` request.
3. AppAPI sends a ``POST`` to the ``/init`` endpoint.
.. note:: if ExApp do not implements ``/init`` endpoint and
AppAPI receives 501 or 404 status error, AppAPI enables the application by going to point 5.
4. **ExApp** sends an integer from ``0`` to ``100`` to the OCS endpoint ``apps/app_api/apps/status`` indicating the initialization progress. After sending ``100``, the application is considered initialized.
5. AppAPI sends a PUT to the ``/enabled`` endpoint.
ExApp info.xml schema
---------------------
ExApp info.xml (`example <https://github.com/cloud-py-api/nc_py_api/blob/main/examples/as_app/talk_bot/appinfo/info.xml>`_) file is used to describe ExApp params.
It is used to generate ExApp docker container and to register ExApp in Nextcloud.
It has the same structure as Nextcloud appinfo/info.xml file, but with some additional fields:
.. code-block:: xml
...
<ex-app>
<docker-install>
<registry>ghcr.io</registry>
<image>cloud-py-api/talk_bot</image>
<image-tag>latest</image-tag>
</docker-install>
<scopes> // deprecated since AppAPI 3.2.0
<value>TALK</value>
<value>TALK_BOT</value>
</scopes>
<system>0</system> // deprecated since AppAPI 3.0.0
</ex-app>
...

View File

@@ -0,0 +1,14 @@
Glossary
========
AppAPI brings out the following terms frequently used in the code:
* ``ExApp`` (External App) - the app on another (from PHP) programming language, which uses AppAPI OCS API
* ``DaemonConfig`` - configuration of orchestration daemon (e.g. Docker) where ExApps are deployed
* ``DeployConfig`` - additional DaemonConfig options for orchestrator (e.g. network) and ExApps (nextcloud_url, host, etc.)
* ``ExAppConfig`` - similar to Nextcloud `app_config`, but for ExApps configuration
* ``ExAppPreferences`` - similar to Nextcloud `app_preferences`, user-specific settings for ExApps
* ``AppAPIAuth`` - AppAPI authentication
* ``ExAppScope`` - granted to ExApp scope group of access to API routes
* ``ExAppApiScope`` - pre-defined scope group of access to list of API routes
* ``FileActionsMenu`` - entry in files actions menu (context menu)

View File

@@ -0,0 +1,112 @@
.. _app_installation_flow:
App Installation Flow
=====================
Image Pulling(Docker)
---------------------
AppAPI **2.5.0+** will always first try to pull a docker image with a ``suffix`` equal to value of *computeDevice*.
Let us remind you that ``computeDevice`` can take the following values: ``cpu``, ``cuda``, ``rocm``
The suffix will be added as follows:
.. code::
return $imageParams['image_src'] . '/' .
$imageParams['image_name'] . '-' . $daemonConfig['computeDevice']['id'] . ':' . $imageParams['image_tag'];
For ``cpu`` AppAPI will first try to get the image from ``ghcr.io/cloud-py-api/skeleton-cpu:latest``.
In case the image is not found, ``ghcr.io/cloud-py-api/skeleton:latest`` will be pulled.
If you as an application developer want to have a custom images for any of these values, you can push that extended images to registry in addition to the based one.
Heartbeat
---------
The first thing AppAPI does is deploy of the application.
In the case of ``Docker``, this is:
#. 1. performing an image pull
#. 2. creating container from the docker image
#. 3. if the container supports `healthcheck` - AppAPI waits for the `healthy` status
#. 4. waiting until the “/heartbeat” endpoint becomes available with a ``GET`` request
The application, in response to the request "/heartbeat", should return json: ``{"status": "ok"}``.
.. note:: The request to ``/heartbeat`` endpoint is made without AppAPI authentication.
Init
----
.. note:: Starting from this point, all requests made by AppAPI contains :ref:`auth-headers`.
After application is ready, which is determined by previous step,
AppAPI sends ``POST`` request to the ``/init`` application endpoint.
*If the application does not need to carry out long initialization, it has an option to not implement "/init" endpoint, so
AppAPI will get 404 or 501 error on it's request, and consider that initialization is done and this section can be skipped.*
In case you want to implement "/init" endpoint, your application should:
1. In "/init" handler: Response with empty JSON on AppAPI call.
2. In background job: Send an ``OCS request`` to ``PUT /ocs/v1.php/apps/app_api/ex-app/status`` with the progress value.
.. warning::
``PUT /ocs/v1.php/apps/app_api/apps/status/$APP_ID`` is deprecated and will be removed in the future.
Possible values for **progress** are integers from 1 to 100;
after receiving the value 100, the **application is considered initialized and ready to work**.
If at the initialization stage the application has a critical error due to which its further operation is impossible,
``"error": "some error"``
should be added to the ``OCS request`` for setting progress,
with a short explanation at what stage this error occurred.
Example of request payload with error will look like this::
{"progress": 67, "error": "connection error to huggingface."}
Enabled
-------
After receiving **progress: 100** (*or when ExApp is not implementing "/init" endpoint*), AppAPI enables the application.
To enable or disable the application, a PUT request is sent to the ``/enabled`` endpoint.
.. note:: Unlike using a payload, this request utilizes a query parameter named ``enabled`` to specify the desired state.
The ``enabled`` parameter accepts an integer value:
* `1` to enable the application
* `0` to disable the application
For example, to enable the application, the request would be::
PUT http://expapp:2432/enabled?enabled=1
Similarly, to disable the application, the request would be::
PUT http://expapp:2432/enabled?enabled=0
This approach ensures that the application's state can be easily toggled using a simple query parameter.
.. note:: ``/enabled`` endpoint shares both **enabling** and **disabling**,
so app should determine what is going on using the ``enabled`` input parameter of the request.
Inside ``/enabled`` handler application should register all actions related to the Nextcloud, like UI and all other stuff.
Response for this request should contain::
{"error": ""}
for success and if some error occur during **enabling**, it should be present and not be empty::
{"error": "i cant handle enabling"}
This is all three steps involved in the applications installation flow.

View File

@@ -0,0 +1,50 @@
Translations
============
ExApps translations work in the `same way as for PHP apps <https://docs.nextcloud.com/server/latest/developer_manual/basics/front-end/l10n.html>`_ with a few adjustments
and differences.
In short, you just have to provide a ``l10n/<lang>.js`` (for front-end) and ``l10n/<lang>.json`` (for back-end) files for your app.
Front-end
*********
For the front-end part AppAPI will inject the current user's locale ``l10n/<lang>.js`` script, so that access to translated strings in kept the same as was before in PHP apps.
.. note::
ExApp l10n files are included only on the ExApp UI pages (:ref:`Top Menu <top_menu_section>`), Files (for :ref:`FileAction <file_actions_menu_section>`) and Settings (for :ref:`DeclarativeSettings <declarative_settings_section>`).
Back-end
********
For the back-end part of ExApp which can be written in different programming languages it is **up to the developer to decide** how to handle and translations files.
There is an example repository with translations: `UI example with translations <https://github.com/cloud-py-api/ui_example>`_.
Manual install
**************
For ``manual-install`` type administrator will have to manually extract to the server's `writable apps directory <https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/config_sample_php_parameters.html#apps-paths>`_ ``l10n`` folder of ExApp
(e.g. ``/path/to/apps-writable/<appid>/l10n/*.(js|json)``).
This will allow server to access ExApp's strings with translations.
.. note::
Only ``l10n`` folder must be present on the server side, ``appinfo/info.xml`` could lead to be misdetected by server as PHP app folder.
Docker install
**************
For ``docker-install`` type AppAPI will extract ``l10n`` folder to the server automatically during installation from ExApp release archive.
Translation tool
****************
To add support for your language in Nextcloud `translationtool <https://github.com/nextcloud/docker-ci/tree/master/translations/translationtool>`_ feel free to create an issue in the `nextcloud/docker-ci <https://github.com/nextcloud/docker-ci>`_ repository
or open a pull request with the changes made in ``createPotFile`` function to extract and convert translation strings.

View File

@@ -0,0 +1,136 @@
=========
AppConfig
=========
ExApp AppConfig API is similar to the standard Nextcloud **appconfig** API.
Set app config value
^^^^^^^^^^^^^^^^^^^^
Set or update ExApp config value.
.. note:: when ``sensitive`` is not specified during updating value, it will be not changed to default.
OCS endpoint: ``POST /apps/app_api/api/v1/ex-app/config``
Request data
************
.. code-block:: json
{
"configKey": "key",
"configValue": "value"
"sensitive": "sensitive flag affecting the visibility of the value (0/1, default: 0)"
}
Response data
*************
On success, ExAppConfig object is returned.
On error OCS Bad Request is returned.
.. code-block:: json
{
"ocs":
{
"meta":
{
"status":"ok",
"statuscode":100,
"message":"OK",
"totalitems":"",
"itemsperpage":""
},
"data":
{
"id":1084,
"appid":"app_id",
"configkey":"key",
"configvalue":"value",
"sensitive":1
}
}
}
Get app config values
^^^^^^^^^^^^^^^^^^^^^
Get ExApp config values
OCS endpoint: ``POST /apps/app_api/api/v1/ex-app/config/get-values``
Request data
************
.. code-block:: json
{
"configKeys": ["key1", "key2", "key3"]
}
Response data
*************
List of ExApp config values are returned.
.. code-block:: json
{
"ocs":
{
"meta":
{
"status":"ok",
"statuscode":100,
"message":"OK",
"totalitems":"",
"itemsperpage":""
},
"data":[
{
"configkey":"test_key",
"configvalue":"123"
}
]
}
}
Delete app config values
^^^^^^^^^^^^^^^^^^^^^^^^
Delete ExApp config values.
OCS endpoint: ``DELETE /apps/app_api/api/v1/ex-app/config``
Request data
************
.. code-block:: json
{
"configKeys": ["key1", "key2", "key3"]
}
Response
********
Returns the number of configuration values removed.
.. code-block:: json
{
"ocs":
{
"meta":
{
"status":"ok",
"statuscode":100,
"message":"OK",
"totalitems":"",
"itemsperpage":""
},
"data":1
}
}

View File

@@ -0,0 +1,83 @@
.. _events_listener:
===============
Events Listener
===============
This API allows you to listen to `Nextcloud events <https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#events>`_
Currently only **limited** numbers of events are supported.
Please let us know if there are any specific event we should add support to.
.. note::
Unlike PHP events, all information from events comes to ExApp **asynchronously**, more like a notification system
to no slow down the server.
Register
^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/events_listener``
Params
******
.. code-block:: json
{
"eventType": "node_event",
"actionHandler": "/action_handler_route"
"eventSubtypes": [],
}
.. note:: ``eventSubtypes`` is an optional parameter, when it is not specified all event subtypes will be propagated to ExApp.
Url in ``actionHandler`` is relative to the ExApp root, starting slash is not required.
Unregister
^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/events_listener``
Params
******
To unregister EventsListener, you just need to provide an `eventType` of the registered EventsListener:
.. code-block:: json
{
"eventType": "node_event"
}
Event payload
^^^^^^^^^^^^^
.. code-block:: json
{
"event_type": "node_event",
"event_subtype": "NodeCreatedEvent",
"event_data": "associative array depending on `event_subtype`"
}
Events types
^^^^^^^^^^^^
Node Events
***********
``node_event`` - events about File `Nodes`
Supported event sub-types:
* ``NodeCreatedEvent``
* ``NodeTouchedEvent``
* ``NodeWrittenEvent``
* ``NodeDeletedEvent``
* ``NodeRenamedEvent``
* ``NodeCopiedEvent``
For all Node events ``event_data`` contain key **target** which has the same format like in :ref:`FileActionsMenu payload <node_info>`
For ``NodeCopiedEvent`` and ``NodeRenamedEvent`` there is also a ``source`` key in the same format.

View File

@@ -0,0 +1,139 @@
=====
ExApp
=====
OCS APIs for ExApp actions.
Get ExApps list
^^^^^^^^^^^^^^^
Get list of installed ExApps.
OCS endpoint: ``GET /apps/app_api/api/v1/ex-app/{list}``
There are two ``list`` options:
- ``enabled``: list only enabled ExApps
- ``all``: list all ExApps
Response data
*************
The response data is a JSON array of ExApp objects with the following attributes:
.. code-block:: json
{
"id": "appid of the ExApp",
"name": "name of the ExApp",
"version": "version of the ExApp",
"enabled": "true/false flag",
"last_check_time": "timestamp of last successful Nextcloud->ExApp connection check",
"system": "true/false flag indicating system ExApp",
}
Set ExApp init progress
^^^^^^^^^^^^^^^^^^^^^^^
Used during ExApp :ref:`initialization step <ex_app_lifecycle_init>`.
.. note::
AppAPIAuth required.
OCS endpoint: ``PUT /apps/app_api/ex-app/status``
Request data
************
.. code-block:: json
{
"progress": "progress value",
"error": "optional, error string message"
}
Response data
*************
Returns HTTP 200 on success, HTTP 404 - on error.
Get Nextcloud URL
^^^^^^^^^^^^^^^^^
It might be necessary for ExApp to know (or update) the Nextcloud URL.
OCS endpoint: ``GET /apps/app_api/api/v1/info/nextcloud_url``
Response data
*************
Returns the base URL of the Nextcloud instance:
.. code-block:: json
{
"base_url": "http(s)://nextcloud.example.com"
}
Make Requests to ExApps
^^^^^^^^^^^^^^^^^^^^^^^
There are two endpoints for making requests to ExApps:
1. Synchronous request: ``POST /apps/app_api/api/v1/ex-app/request/{appid}``
2. Synchronous request with ExApp user setup: ``POST /apps/app_api/api/v1/ex-app/request/{appid}/{userId}``
Request data
************
The request data params are the same as in ``lib/PublicFunction.php``:
.. code-block:: json
{
"route": "relative route to ExApp API endpoint",
"method": "GET/POST/PUT/DELETE",
"params": {},
"options": {},
}
.. note::
``userId`` and ``appId`` is taken from url params
Response data
*************
Successful request to ExApp OCS data response structure is the following:
.. code-block:: json
{
"status_code": "HTTP status code",
"body": "response data from ExApp",
"headers": "response headers from ExApp",
}
If there is an error, the response object will have only an ``error`` attribute with the error message.
Get ExApp enabled status
^^^^^^^^^^^^^^^^^^^^^^^^
Return the enabled status of the authenticated ExApp.
OCS endpoint: ``GET /apps/app_api/api/v1/ex-app/state``
.. note::
This endpoint can be called by ExApp even if it is disabled on the Nextcloud side,
and requires :ref:`AppAPIAuth <app_api_auth>`.
Response data
*************
Returns 1 if the ExApp is enabled, 0 if it is disabled.

View File

@@ -0,0 +1,155 @@
.. _file_actions_menu_section:
=================
File Actions Menu
=================
FileActionsMenu is a simple API for registering entry to the file actions menu for ExApps.
AppAPI takes responsibility to register FileActionsMenu, ExApps needs only to register it in AppAPI.
.. note::
FileActionsMenu rendered only for enabled ExApps.
Register
^^^^^^^^
.. note::
With AppAPI 2.6.0 there is a new v2 OCS endpoint with redirect to ExApp UI support:
OCS endpoint: ``POST /apps/app_api/api/v2/ui/files-actions-menu``.
Old v1 is marked as deprecated.
OCS endpoint: ``POST /apps/app_api/api/v1/ui/files-actions-menu``
Params
******
Complete list of params (including optional):
.. code-block:: json
{
"name": "unique_name_of_file_actions_menu",
"displayName": "Display name (for UI listing)",
"actionHandler": "/action_handler_route"
"mime": "mime of files where to display action menu",
"icon": "img/icon.svg",
"permissions": "permissions",
"order": "order_in_file_actions_menu",
}
.. note:: Urls ``icon`` and ``actionHandler`` are relative to the ExApp root, starting slash is not required.
Optional params
***************
* `permissions` - File permissions required to display action menu, default: **31** (all permissions)
* `order` - Order in file actions menu, default: **0**
* `icon` - Url to icon, default: **null**
* `mime` - One mime or mimes separated by commas, default: **file**
Unregister
^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ui/files-actions-menu``
Params
******
To unregister FileActionsMenu, you just need to provide name of registered FileActionsMenu:
.. code-block:: json
{
"name": "unique_name_of_file_action_menu"
}
.. _node_info:
Action payload to ExApp
^^^^^^^^^^^^^^^^^^^^^^^
When FileActionsMenu invoked, AppAPI forwards action for handling to ExApp.
The following data is sent to ExApp FileActionsMenu handler from the context of action:
.. code-block:: json
{
"fileId": "123",
"name": "filename",
"directory": "relative/to/user/path/to/directory",
"etag": "file_etag",
"mime": "file_full_mime",
"fileType": "dir/file",
"mtime": "last modify time(integer)",
"size": "integer",
"favorite": "nc_favorite_flag",
"permissions": "file_permissions_for_owner",
"shareOwner": "optional, str",
"shareOwnerId": "optional, str",
"shareTypes": "optional, int",
"shareAttributes": "optional, int",
"sharePermissions": "optional, int",
"userId": "string",
"instanceId": "string",
}
Redirect to ExApp UI page (top menu)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. note::
Supported only for Nextcloud 28+.
If you want to open some files in ExApp UI, your FileActionsMenu have to be registered using OCS v2 version (``/apps/app_api/api/v2/ui/files-actions-menu``).
After that, AppAPI will expect in the JSON response of the ExApp ``action_handler``
the ``redirect_handler`` - a relative path on the ExApp Top Menu page,
to which AppAPI will attach a ``fileIds`` query parameter with the selected file ids, for example:
``/index.php/apps/app_api/embedded/ui_example/first_menu/second_page?fileIds=123,124,125``,
where the ``first_menu`` is the name of the Top Menu ExApp UI page,
and the ``second_page`` relative route handled on the frontend routing of the ExApp,
the ``fileIds`` query parameter contains the selected file ids separated by commas.
After that you can get the files info via webdav search request, see `ui_example <https://github.com/cloud-py-api/ui_example>`_.
Request flow
^^^^^^^^^^^^
General workflow of ExApp based on FileActionsMenu.
User action
***********
.. mermaid::
sequenceDiagram
User->>FileActionMenu: Press on registered ExApp action
FileActionMenu->>AppAPI: send action context payload
AppAPI->>ExApp: forward request to handler
ExApp->>AppAPI: handler accepted action status
AppAPI->>User: Alert (action sent or error)
Action results
**************
File processing results could be stored next to initial file or anywhere else,
e.g. on configured location in ExApp settings (``appconfig_ex``) or ExApp user settings (``preferences_ex``).
.. mermaid::
sequenceDiagram
ExApp->>Nextcloud: Upload result file
ExApp->>AppAPI: Send notification about action results
Examples
^^^^^^^^
Here is a list of simple example ExApps based on FileActionsMenu:
* `to_gif <https://github.com/cloud-py-api/nc_py_api/tree/main/examples/as_app/to_gif>`_ - ExApp based on FileActionsMenu to convert videos to gif in place
* `upscaler_example <https://github.com/cloud-py-api/upscaler_example.git>`_ - ExApp based on FileActionsMenu to upscale image in place

View File

@@ -0,0 +1,30 @@
.. _app_api_nextcloud_apis:
=====================
AppAPI Nextcloud APIs
=====================
.. note::
AppAPIAuth is required for all AppAPI OCS APIs, except ``ExApp``.
.. toctree::
:maxdepth: 2
logging
appconfig
preferences
exapp
routes
utils
fileactionsmenu
topmenu
settings
notifications
events_listener
occ_command
talkbots
speechtotext
textprocessing
machinetranslation
other_ocs

View File

@@ -0,0 +1,35 @@
=======
Logging
=======
There is a logging API that can be used to log messages from ExApps in Nextcloud.
.. note::
You can retrieve Nextcloud `loglevel` for internal ExApp usage
from private `app_api` (after authentication) capabilities
Send log message (OCS)
^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/log``
Request data
************
.. code-block:: json
{
"level": "log_lvl(integer)",
"message": "message",
}
The possible value of ``log_lvl`` is described here: `Nextcloud Log level <https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/logging_configuration.html#log-level>`_
Response data
*************
If no error occurs, empty response with result code 200 is returned.
If ExApp is not found or disable, or the loglevel is invalid - OCS Bad Request is returned.

View File

@@ -0,0 +1,82 @@
===================
Machine Translation
===================
AppAPI provides a Machine-Translation providers registration mechanism for ExApps.
.. note::
Available since Nextcloud 29.
Registering translation provider (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ai_provider/translation``
Request data
************
.. code-block:: json
{
"name": "unique_provider_name",
"display_name": "Provider Display Name",
"from_languages": {
"en": "English",
"fr": "French",
},
"to_languages": {
"en": "English",
"fr": "French",
},
"action_handler": "/handler_route_on_ex_app",
"action_detect_lang": "/detect_lang_from_text_handler",
}
.. note::
``from_languages`` and ``to_languages`` are JSON object with language code as key and language name as value.
``action_detect_lang`` is optional. If provided, server's translation manager will call this handler to detect language from text if no source lang provided,
for reference see `Providing Language detection <https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/translation.html#providing-language-detection>`_.
Response
********
On successful registration response with status code 200 is returned.
Unregistering translation provider (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ai_provider/translation``
Request data
************
.. code-block:: json
{
"name": "unique_provider_name",
}
Response
********
On successful unregister response with status code 200 is returned.
Report translation result (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``PUT /apps/app_api/api/v1/ai_provider/translation``
Request data
************
.. code-block:: json
{
"task_id": "queued_task_id",
"result": "translated_text",
"error": "error_message_if_any",
}

View File

@@ -0,0 +1,63 @@
=============
Notifications
=============
AppAPI allows ExApps to send limited notifications to users.
ExApp can send simple notification using available `rich object strings <https://github.com/nextcloud/server/blob/master/lib/public/RichObjectStrings/Definitions.php#L42>`_.
More info about rich objects string can be found `here <https://github.com/nextcloud/server/issues/1706>`_.
Send notification (OCS)
^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/notification``
Request payload
***************
Example payload.
.. code-block:: json
{
"params": {
"object": "app_api",
"object_id": "app_api_id",
"subject_type": "app_api_ex_app",
"subject_params": {
"rich_subject": "Image {file} successfully upscaled!",
"rich_subject_params": {
"file": {
"type": "file",
"id": 123,
"name": "upscaled_image_name",
"path": "path/to/upscaled_image_name"
}
},
"rich_message": "{user} checkout results!",
"rich_message_params": {
"user": {
"type": "user",
"id": "admin",
"name": "admin"
}
},
"link": "http(s)://nextcloud.local/index.php/apps/files/?fileid=123"
}
}
}
Params
^^^^^^
Required payload params:
* ``object`` - ``[required]`` should be set to default value, not used yet
* ``object_id`` - ``[required]`` should be set to default value, not used yet
* ``subject_type`` - ``[required]`` subject type should be set to default value, not used yet
* ``subject_params`` - ``[required]``
* ``rich_subject`` - ``[optional]`` rich subject (title) string
* ``rich_subject_params`` - ``[optional]`` rich subject (title) params to replace rich objects in string
* ``rich_message`` - ``[optional]`` rich message string
* ``rich_message_params`` - ``[optional`` rich message params to replace objects in string
* ``link`` - absolute url to set for notification link

View File

@@ -0,0 +1,108 @@
.. _occ_command:
===========
OCC Command
===========
This API allows you to register the occ (CLI) commands.
The principal is similar to the regular Nextcloud OCC command for PHP apps, that are working in context of the Nextcloud instance,
but for ExApps it is a trigger via Nextcloud OCC interface to perform some action on the External App side.
.. note::
Passing files directly as an input argument to the occ command is not supported.
Register
^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/occ_command``
Params
******
.. code-block:: json
{
"name": "appid:unique:command:name",
"description": "Description of the command",
"hidden": "1/0",
"arguments": [
{
"name": "argument_name",
"mode": "required/optional/array",
"description": "Description of the argument",
"default": "default_value"
}
],
"options": [
{
"name": "option_name",
"shortcut": "s",
"mode": "required/optional/none/array/negatable",
"description": "Description of the option",
"default": "default_value"
}
],
"usages": [
"occ appid:unique:command:name argument_name --option_name",
"occ appid:unique:command:name argument_name -s"
],
"execute_handler": "handler_route"
}
For more details on the command arguments and options modes,
see the original docs for the Symfony console input parameters, which are actually being built from the provided data:
`https://symfony.com/doc/current/console/input.html#using-command-arguments <https://symfony.com/doc/current/console/input.html#using-command-arguments>`_
Example
*******
Lets assume we have a command `ping` that takes an argument `test_arg` and has an option `test-option`:
.. code-block:: json
{
"name": "my_app_id:ping",
"description": "Test ping command",
"hidden": 0,
"arguments": [
{
"name": "test_arg",
"mode": "required",
"description": "Test argument",
"default": 123
}
],
"options": [
{
"name": "test-option",
"shortcut": "t",
"mode": "none",
"description": "Test option",
}
],
"usages": [
"occ my_app_id:ping 12345",
"occ my_app_id:ping 12345 --test-option",
"occ my_app_id:ping 12345 -t"
],
"execute_handler": "handler_route"
}
Unregister
^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/occ_command``
Params
******
To unregister OCC Command, you just need to provide a command `name`:
.. code-block:: json
{
"name": "occ_command_name"
}

View File

@@ -0,0 +1,20 @@
Other OCS APIs
==============
With AppAPI authentication it is possible for ExApps to use any other OCS APIs, that doesn't require OCP implementation:
.. note::
To access these APIs they have to be supported by AppAPI (see :ref:`api_scopes`),
and ExApp have to require granted access (in ``info.xml``) to them accordingly.
1. Calendar
2. Contacts
3. File System & Tags
4. Shares
5. Notifications
6. Users & Groups
7. User & Weather status
8. Activities
9. Notes
10. Etc.

View File

@@ -0,0 +1,138 @@
===========
Preferences
===========
ExApp preferences API is similar to the standard preferences API.
It's a user specific settings.
Set user config value
^^^^^^^^^^^^^^^^^^^^^
Set or update config value for **current authenticated user**.
OCS endpoint: ``POST /apps/app_api/api/v1/ex-app/preference``
Request data
************
.. code-block:: json
{
"configKey": "key",
"configValue": "value"
}
Response data
*************
On success ExAppPreference object is returned.
On error OCS Bad Request is returned.
.. code-block:: json
{
"ocs":
{
"meta":
{
"status":"ok",
"statuscode":100,
"message":"OK",
"totalitems":"",
"itemsperpage":""
},
"data":
{
"id":983,
"appid":"app_id",
"configkey":"test key",
"configvalue":"123",
"sensitive":0
}
}
}
Get user config values
^^^^^^^^^^^^^^^^^^^^^^
Get config values for **current authenticated user**.
OCS endpoint: ``POST /apps/app_api/api/v1/ex-app/preference/get-values``
Request data
************
.. code-block:: json
{
"configKeys": ["key1", "key2", "key3"]
}
Response data
*************
List of ExApp preferences values are returned.
.. code-block:: json
{
"ocs":
{
"meta":
{
"status":"ok",
"statuscode":100,
"message":"OK",
"totalitems":"",
"itemsperpage":""
},
"data":[
{
"configkey":"test key",
"configvalue":"123"
},
{
"configkey":"test key2",
"configvalue":"321"
}
]
}
}
Delete user config values
^^^^^^^^^^^^^^^^^^^^^^^^^
Delete config values for **current authenticated user**.
OCS endpoint: ``DELETE /apps/app_api/api/v1/ex-app/preference``
Request data
************
.. code-block:: json
{
"configKeys": ["key1", "key2", "key3"]
}
Response
********
.. code-block:: json
{
"ocs":
{
"meta":
{
"status":"ok",
"statuscode":100,
"message":"OK",
"totalitems":"",
"itemsperpage":""
},
"data":2
}
}

View File

@@ -0,0 +1,47 @@
.. _ex_app_routes:
======
Routes
======
Since AppAPI 3.0.0 ExApps have to declare their routes allowed to be accessed via the AppAPI ExApp proxy.
.. note::
This routes check applied only for ExApp proxy (``/apps/app_api/proxy/*``).
Register
^^^^^^^^
During ExApp installation, the ExApp routes are registered automatically.
The routes must be declared in the ``external-app`` - ``routes`` tag of the ``info.xml`` file.
Example
*******
.. code-block::
<routes>
<route>
<url>.*</url>
<verb>GET,POST,PUT,DELETE</verb>
<access_level>USER</access_level>
<headers_to_exclude>[]</headers_to_exclude>
<bruteforce_protection>[401, 500]</bruteforce_protection>
</route>
</routes>
where the fields are:
- ``url``: the route to be registered on the ExApp side, can be a regex
- ``verb``: the HTTP verb that the route will accept, can be a comma separated list of verbs
- ``access_level``: the name of the access level required to access the route, PUBLIC - public access without auth, USER - Nextcloud user auth required, ADMIN - admin user required
- ``headers_to_exclude``: a json encoded string of an array of strings, the headers that the ExApp wants to be excluded from the request to it
- ``bruteforce_protection``: a json encoded string of an array of numbers, the HTTP status codes that must trigger the bruteforce protection
Unregister
^^^^^^^^^^
ExApp routes are unregistered automatically when the ExApp is uninstalling, or during the ExApp update before registering the new routes.

View File

@@ -0,0 +1,211 @@
.. _declarative_settings_section:
====================
Declarative Settings
====================
Starting from Nextcloud **29**, AppAPI provides the ability to display ex-application settings.
When admin or user changes some ex-app settings
they will be stored in the database and can be received using :doc:`preferences` or :doc:`appconfig` API.
.. note::
Settings rendered only for enabled ExApps.
.. warning::
``section_id`` from **scheme** should be already registered by any PHP application.
**AppAPI** provides two sections for that: ``ai_integration_team`` and ``declarative_settings``, you can use them.
Register Settings
^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ui/settings``
Params
******
Complete list of params (including optional):
.. code-block:: json
{
"formScheme": "settings scheme"
}
Unregister Menu Entry
^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ui/settings``
Params
******
.. code-block:: json
{
"formId": "formId from scheme"
}
Example of settings scheme in Python:
.. code-block:: python
{
"id": "settings_example",
"priority": 10,
"section_type": "admin",
"section_id": "ai_integration_team",
"title": "AppAPI declarative settings",
"description": "These fields are rendered dynamically from declarative schema",
"fields": [
{
"id": "field1",
"title": "Multi-selection",
"description": "Select some option setting",
"type": 'multi-select',
"options": ["foo", "bar", "baz"],
"placeholder": "Select some multiple options",
"default": ["foo", "bar"],
},
{
"id": "some_real_setting",
'title': 'Choose init status check background job interval',
'description': 'How often AppAPI should check for initialization status',
'type': 'radio',
'placeholder': 'Choose init status check background job interval',
'default': '40m',
'options': [
{
'name': 'Each 40 minutes',
'value': '40m',
},
{
'name': 'Each 60 minutes',
'value': '60m',
},
{
'name': 'Each 120 minutes',
'value': '120m',
},
{
'name': 'Each day',
'value': f"{60 * 24}m",
},
],
},
{
'id': 'test_ex_app_field_1',
'title': 'Default text field',
'description': 'Set some simple text setting',
'type': 'text',
'placeholder': 'Enter text setting',
'default': 'foo',
},
{
'id': 'test_ex_app_field_1_1',
'title': 'Email field',
'description': 'Set email config',
'type': 'email',
'placeholder': 'Enter email',
'default': '',
},
{
'id': 'test_ex_app_field_1_2',
'title': 'Tel field',
'description': 'Set tel config',
'type': 'tel',
'placeholder': 'Enter your tel',
'default': '',
},
{
'id': 'test_ex_app_field_1_3',
'title': 'Url (website) field',
'description': 'Set url config',
'type': url',
'placeholder': 'Enter url',
'default': '',
},
{
'id': 'test_ex_app_field_1_4',
'title': 'Number field',
'description': 'Set number config',
'type': 'number',
'placeholder': 'Enter number value',
'default': 0,
},
{
'id': 'test_ex_app_field_2',
'title': 'Password',
'description': 'Set some secure value setting',
'type': password',
'placeholder': 'Set secure value',
'default': '',
},
{
'id': 'test_ex_app_field_3',
'title': 'Selection',
'description': 'Select some option setting',
'type': 'select',
'options': ['foo', 'bar', 'baz'],
'placeholder': 'Select some option setting',
'default': 'foo',
},
{
'id': 'test_ex_app_field_4',
'title': 'Toggle something',
'description': 'Select checkbox option setting',
'type': 'checkbox',
'label': 'Verify something if enabled',
'default': False,
},
{
'id': 'test_ex_app_field_5',
'title': 'Multiple checkbox toggles, describing one setting, checked options are saved as an JSON object {foo: true, bar: false}',
'description': 'Select checkbox option setting',
'type': 'multi-checkbox',
'default': {'foo': True, 'bar': True},
'options': [
{
'name':'Foo',
'value': 'foo',
},
{
'name': 'Bar',
'value': 'bar',
},
{
'name': 'Baz',
'value': 'baz',
},
{
'name': 'Qux',
'value': 'qux',
},
],
},
{
'id': 'test_ex_app_field_6',
'title': 'Radio toggles, describing one setting like single select',
'description': 'Select radio option setting',
'type': 'radio',
'label': 'Select single toggle',
'default': 'foo',
'options': [
{
'name': 'First radio',
'value': 'foo'
},
{
'name': 'Second radio',
'value': 'bar'
},
{
'name': 'Second radio',
'value': 'baz'
},
],
},
]
}

View File

@@ -0,0 +1,51 @@
==============
Speech-To-Text
==============
AppAPI provides a Speech-To-Text (STT) provider registration API for the ExApps.
.. note::
Available since Nextcloud 29.
Registering ExApp STT provider (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/provider/speech_to_text``
Request data
************
.. code-block:: json
{
"name": "unique_provider_name",
"display_name": "Provider Display Name",
"action_handler": "/handler_route_on_ex_app",
}
Response
********
On successful registration response with status code 200 is returned.
Unregistering ExApp STT provider (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/provider/speech_to_text``
Request data
************
.. code-block:: json
{
"name": "unique_provider_name",
}
Response
********
On successful unregister response with status code 200 is returned.

View File

@@ -0,0 +1,41 @@
=========
Talk bots
=========
AppAPI provides API for registering ExApps Talk bots.
This means that ExApps could be just as Talk bot or it could be as one of the options of the app.
Read more about Talk bots `here <https://nextcloud-talk.readthedocs.io/en/latest/bots/>`_.
Register ExApp Talk bot (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/talk_bot``
Request data
************
.. code-block:: json
{
"name": "Talk bot display name",
"route": "/talk_bot_webhook_route_on_ex_app",
"description": "Talk bot description",
}
Unregister ExApp Talk bot (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To unregister the ExApp Talk bot, you will have to pass the route where the Talk bot is registered.
OCS endpoint: ``DELETE /apps/app_api/api/v1/talk_bot``
Request data
************
.. code-block:: json
{
"route": "/route_of_talk_bot"
}

View File

@@ -0,0 +1,72 @@
===============
Text-Processing
===============
AppAPI provides a Text-Processing providers registration mechanism for ExApps.
.. note::
Available since Nextcloud 29.
Registering text-processing provider (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ai_provider/text_processing``
Request data
************
.. code-block:: json
{
"name": "unique_provider_name",
"display_name": "Provider Display Name",
"action_handler": "/handler_route_on_ex_app",
"task_type": "supported_task_type",
}
.. note::
``action_type`` is a class name of the Text-Processing task type that can be found in the list of supported task types.
Response
********
On successful registration response with status code 200 is returned.
Unregistering text-processing provider (OCS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ai_provider/text_processing``
Request data
************
.. code-block:: json
{
"name": "unique_provider_name",
}
Response
********
On successful unregister response with status code 200 is returned.
Get list of supported Text-Processing task types (capabilities)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are limited number of Task Types that can be used for Text-Processing.
You can get list of supported Text-Processing task types from OCS capabilities.
Response
********
.. code-block:: json
{
"text_processing": {
"task_types": ["free_prompt", "headline", "summary", "topics"]
}
}

View File

@@ -0,0 +1,160 @@
.. _top_menu_section:
==============
Top Menu Entry
==============
TopMenu is an API for registering entry in the Nextcloud Top Menu for ExApps.
AppAPI takes responsibility to register TopMenu and proxy all requests to ExApp.
.. note::
TopMenu rendered only for enabled ExApps.
Register Menu Entry
^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ui/top-menu``
Params
******
Complete list of params (including optional):
.. code-block:: json
{
"name": "unique_name_of_top_menu",
"displayName": "Display name",
"icon": "img/icon.svg",
"adminRequired": "0 or 1",
}
.. note:: ``icon`` are relative to the ExApp root, starting slash is not required.
Optional params
***************
* `icon` - Url to icon, default: **null**
* `adminRequired` - Value indicating should be Entry visible to all or only to admins.
Unregister Menu Entry
^^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ui/top-menu``
Params
******
To unregister TopMenu, you just need to provide name of registered TopMenu:
.. code-block:: json
{
"name": "unique_name_of_top_menu"
}
Set Initial state
^^^^^^^^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ui/initial-state``
Params
******
.. code-block:: json
{
"type": "top_menu",
"name": "unique_name_of_top_menu",
"key": "key_name",
"value": "array with value(s)",
}
Remove Initial state
^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ui/initial-state``
Params
******
.. code-block:: json
{
"type": "top_menu",
"name": "unique_name_of_top_menu",
"key": "key_name",
}
Add script
^^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ui/script``
Params
******
.. code-block:: json
{
"type": "top_menu",
"name": "unique_name_of_script",
"path": "Url to script, e.g.: js/ui_example-main",
"afterAppId": "optional value",
}
.. note:: Url to script is relative to the ExApp root, starting slash is not required,
".js" extension is not needed and will be appended automatically by server.
Remove script
^^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ui/script``
Params
******
.. code-block:: json
{
"type": "top_menu",
"name": "unique_name_of_script",
"path": "Url to script",
}
Add style
^^^^^^^^^
OCS endpoint: ``POST /apps/app_api/api/v1/ui/style``
Params
******
.. code-block:: json
{
"type": "top_menu",
"name": "unique_name_of_style",
"path": "Url to style, e.g.: css/my-style",
}
.. note:: Url to style is relative to the ExApp root, starting slash is not required,
".css" extension is not needed and will be appended automatically by server.
Remove style
^^^^^^^^^^^^
OCS endpoint: ``DELETE /apps/app_api/api/v1/ui/style``
Params
******
.. code-block:: json
{
"type": "top_menu",
"name": "unique_name_of_style",
"path": "Url to style",
}

View File

@@ -0,0 +1,30 @@
======================
Miscellaneous OCS APIs
======================
There are some system utils APIs required for ExApps internal logic.
Get list of NC users
^^^^^^^^^^^^^^^^^^^^
OCS endpoint: ``GET /apps/app_api/api/v1/users``
Response data
*************
Returns a list of user IDs only.
.. code-block:: json
{"ocs": {
"meta": {
"status": "ok",
"statuscode": 100,
"message": "OK",
"totalitems": "",
"itemsperpage": ""
},
"data": ["admin", "alice", "bob", "jane", "john"]
}
}

View File

@@ -0,0 +1,13 @@
Technical details
=================
.. toctree::
:maxdepth: 2
Glossary
InstallationFlow
ApiScopes
Deployment
Authentication
Translations
api/index.rst

View File

@@ -18,6 +18,7 @@ Table of contents
getting_started/index
basics/index
app_development/index
exapp_development/index
server/index
digging_deeper/index
app_publishing_maintenance/index