.. Reminder for header structure:
  Parts (H1)          : #################### with overline
  Chapters (H2)       : ******************** with overline
  Sections (H3)       : ====================
  Subsections (H4)    : --------------------
  Subsubsections (H5) : ^^^^^^^^^^^^^^^^^^^^
  Paragraphs (H6)     : """""""""""""""""""""

.. meta::
 :description: Using the WAPT server APIs
 :keywords: API, Application Protocol Interface, WAPT, documentation

.. role:: green
.. role:: orange
.. role:: red

.. _using__wapt_api:

##########################
Using the WAPT Server APIs
##########################


************
API Overview
************

.. note::

  This documentation does not describe all available :abbr:`APIs (Application Programming Interfaces)`. It focuses on the most useful ones.

Currently, it is only possible to use Python code to interact with the an :term:`API`.

Most of the available APIs can be found in the :file:`server.py` file located at :file:`/opt/wapt/waptserver/server.py` on Debian.

Additional APIs are available in other files such as :file:`enterprise.py`, :file:`repositories.py`, :file:`wads.py`, etc.

.. warning::

  Since version 2.5, most API URLs are protected with SSL client certificates. Therefore, it is no longer possible to use HTML requests like: `https://admin:MYPASSWORD@srvwapt.mydomain.lan/api/v1/hosts`.

**************
Using the APIs
**************

Requirement:
============
  
1- **Create a WAPT user and assign the ACL "launch requests"** (It is recommended to create a new user for requests because the password is included in the request).

  In the waptconsole : Go to :guilabel:`Tools` > :guilabel:`Manage Wapt users and rights`.

  :guilabel:`New account` > :kbd:`F2` name like reporting.

  :guilabel:`Change User password on Wapt server` (an key appear on the right on your reporting user in the :red:`red on the picture below`).

  Click on "Run Reports" ACL ( in :green:`green in the picture below`).
  
    .. figure:: wapt-resources/Create_reporting_user.png
      :scale: 75%
      :align: center
      :alt: Create reporting user

      Create reporting user.

2- Depending on the request, **it may be necessary to add ACLs on the reporting user**. This can be see in the request file You can see this in the request in the api source file.

  .. code-block::

    For Example: On server.py file, you can read this at the begin of the API's resquest groups.

      Example:
      @app.route('/api/v3/groups')
      @app.route('/api/v1/groups')
      @requires_auth(['admin','view']) Requires either the "admin" or "view" ACL (Access Control List) permissions. Having either one or both of these permissions is sufficient to access this endpoint.


Operating procedure:
====================


There are two primary method to do an api request, the **Command-Line Method** and the **Script-Based Method**.

**Any Wapt agent can launch an API**.

|

Command-Line Method
-------------------

The Command-Line Method involves executing API requests directly from the command line interface (CLI) using tools like cmd on Windows or bash on Unix-based systems.
This method is quick and efficient for simple or one-off requests.


Example: On a CLI or bash

.. code-block::

  wapt-get server-request "/api/v1/hosts" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

|

Script-Based Method
-------------------

The Script-Based Method requires creating a Python script (.py file) to define and execute the API request.
This method is more flexible and powerful, allowing for complex logic, error handling, and data processing.

.. tabs::

  .. tab:: Windows

    1. Connect to a WAPT Windows agent.
    2. Create a directory named :file:`waptdev` at the root of your disk, like, `c:\\waptdev\\API_request`.
    3. Create a :file:`.py` file in this directory to edit the request, like, `api-1.py`.
    4. Copy the *python script* below and *personalize* the password for your user "reporting" and the desired API.
    5. Run the file with the following command: `&"C:\\Program Files (x86)\\wapt\\wapt-get.exe" c:\\waptdev\\API_request\\api-1.py`.
    6. The output can be displayed in CSV format: `cat api-1.csv`.

  .. tab:: Debian and Derivatives

    1. Connect to a WAPT Linux agent.
    2. Create a directory named :file:`waptdev` at the root of your disk, like, `/wapdev/`.
    3. Create a :file:`.py` file in this directory to edit the request, like, `api-1.py`.
    4. Copy the *python script* below and *personalize* the password for your user "reporting" and the desired API.
    5. Run the file with the following command: `/opt/wapt/wapt-get.bin /wapdev/api-1.py`.
    6. The output can be displayed in CSV format: `cat api-1.csv`.

  .. tab:: Red Hat and Derivatives

    1. Connect to a WAPT Linux agent.
    2. Create a directory named :file:`waptdev` at the root of your disk, like, `/wapdev/`.
    3. Create a :file:`.py` file in this directory to edit the request, like, `api-1.py`.
    4. Copy the *python script* below and *personalize* the password for your user "reporting" and the desired API.
    5. Run the file with the following command: `/opt/wapt/wapt-get.bin /wapdev/api-1.py`.
    6. The output can be displayed in CSV format: `cat api-1.csv`.


.. white_toggle::
  :titleen: The Python script
  :titlefr: Le Script Python

  .. code-block:: python

      import json
      import waptlicences
      import csv
      import sys
      sys.path.append('/opt/wapt')

      from common import Wapt
      WAPT = Wapt()
      ini_wapt_path = WAPT.config_filename

      user = "reporting"
      password = "[Enter the password for user reporting]"

      def run_report():
          auth_context = waptlicences.waptserver_login(ini_wapt_path, user=user, password=password)
          try:
              res = waptlicences.waptserver_request(ini_wapt_path, action='[enter the desired api like /api/v1/hosts]', auth_context=auth_context)
              if res['http_status'] == 200:
                  data = json.loads(res['content'])['result']

                  # Debugging: Print the raw data received from the API
                  print("Raw data from API:", json.dumps(data, indent=2))

                  # Check if data is not empty
                  if not data:
                      print("No data received from the API.")
                      return []

                  # Check if the first element of data is a list
                  if isinstance(data[0], list):
                      for row in data:
                          # Assuming row is a list of strings
                          for i, value in enumerate(row):
                              if isinstance(value, list):
                                  row[i] = '|'.join(value)

                      with open('test.csv', 'w', newline='', encoding='utf-8') as csvfile:
                          fieldnames = data[0]
                          writer = csv.writer(csvfile, delimiter=';')
                          writer.writerow(fieldnames)
                          writer.writerows(data[1:])  # Write the rest of the data
                  else:
                      print("Unexpected data format. First element is not a list.")
                      return []

                  return data
              else:
                  raise Exception('Request failed with status %s : %s' % (res['http_status'], res['content']))
          finally:
              waptlicences.waptserver_logout(ini_wapt_path)

      # Call the function and print the returned data
      data = run_report()
      print(repr(data))


*****************************
Some examples of api requests
*****************************

|

API V1
======

/api/v1/hosts
-------------

Get registration data of one or several hosts.

.. code-block::

  wapt-get server-request "/api/v1/hosts" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


List all hosts using the following parameters:

  * *reachable*;

  * *computer_fqdn* ==> computer_name;

  * *connected_ips*;

  * *mac_addresses*.

Example:

.. code-block::

  wapt-get server-request "/api/v1/hosts?columns=reachable,computer_fqdn,connected_ips,mac_addresses&limit=10000" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

/api/v1/groups
--------------

Get all dependencies that are directly assigned to a machine package.

.. code-block::

  wapt-get server-request "api/v1/groups" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


/api/v1/host_data
-----------------

|

**dmi field**

Get :abbr:`DMI (Desktop Management Interface)` info for a host:

.. code-block::

  wapt-get server-request "api/v1/host_data?uuid=[UUID OF THE COMPUTER]&field=[DMI FIELD DESIRED]" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


Example for the dmi field *"os_name"* :

.. code-block::

  wapt-get server-request "api/v1/host_data?uuid=CDAB699D-CA52-98B6-3AC2-749E66B04841&field=os_name" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

**installed_packages**

Option *installed_packages* will list all packages installed on a specific host.

Example: 

.. code-block::

  wapt-get server-request "api/v1/host_data?uuid=CDAB699D-CA52-98B6-3AC2-749E66B04841&field=installed_packages" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


**installed_softwares**

Option *installed_softwares* will list all softwares installed on a specific host.

Example: 

.. code-block::

  wapt-get server-request "api/v1/host_data?uuid=CDAB699D-CA52-98B6-3AC2-749E66B04841&field=installed_softwares" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

**wsusupdates**

Option *wsusupdates* will list all Windows Updates installed on a specific host.

Example: 

.. code-block::

  wapt-get server-request "api/v1/host_data?uuid=CDAB699D-CA52-98B6-3AC2-749E66B04841&field=wsusupdates" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

/api/v1/usage_statistics
------------------------

Get usage statistics from the WAPT Server.

.. code-block::

  wapt-get server-request "api/v1/usage_statistics" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

.. note::

  This API is useful if you have several WAPT Servers and you want to know how many hosts are there.

API V2
======

/api/v2/waptagent_version
-------------------------

Display :program:`waptagent.exe` version.

.. code-block::

  wapt-get server-request "/api/v2/waptagent_version" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

API V3
======

/api/v3/packages
----------------

List packages on the repository, retrieve the :file:`control` files of WAPT packages.

.. code-block::

  wapt-get server-request "/api/v3/packages" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


/api/v3/known_packages
----------------------

List all packages with last *signed_on* information.

.. code-block::

  wapt-get server-request "/api/v3/known_packages" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


/api/v3/trigger_cancel_task
---------------------------

Cancel a running task.

.. code-block::

  wapt-get server-request "/api/v3/trigger_cancel_task" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


/api/v3/get_ad_ou
-----------------

List :abbr:`OU (Organizational Unit)` seen by hosts and displayed in the WAPT Console.

.. code-block::

  wapt-get server-request "/api/v3/get_ad_ou" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


/api/v3/get_ad_sites
--------------------

List Active Directory sites.

.. code-block::

  wapt-get server-request "/api/v3/get_ad_sites" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

/api/v3/hosts_for_package
-------------------------

List hosts with a specific package installed.

.. code-block::

  wapt-get server-request "/api/v3/hosts_for_package?package=[name of your package like tis-paint]" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

/api/v3/ping
------------

Ping shows a general set of informations on a WAPT Server.

Example:

.. code-block::

  wapt-get server-request /api/v3/ping -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password

/api/v3/reporting_exec
----------------------

Below is a python script that executes a query with a specific id from WAPT Console Reporting tab. In this script, user "reporting" should have "Run reports" ACL.
It works on every platform (windows, linux and mac agents).

.. white_toggle::
  :titleen: The Python script
  :titlefr: Le Script Python

  .. code-block:: python

    import os
    import json
    import logging
    import waptlicences
    import requests
    import sys
    sys.path.append('/opt/wapt')
    from common import get_requests_client_cert_session
    from common import Wapt



    WAPT = Wapt()
    ini_wapt_path = WAPT.config_filename
    w = Wapt(config_filename=ini_wapt_path)

    # WAPT Conf
    wapt_url = w.waptserver.server_url

    user = "reporting"
    password = "password"


    def run_report():

        t = waptlicences.waptserver_login(ini_wapt_path,user,password)
        session = get_requests_client_cert_session(wapt_url,
        cert=(t['client_certificate'],t['client_private_key'],t['client_private_key_password']),
        verify=w.waptserver.verify_cert
        )
        if not 'session' in t['session_cookies']:
          session_cookies = [u for u in t['session_cookies'] if u['Domain'] == WAPT.waptserver.server_url.split('://')[-1]][0]
        else:
          session_cookies = t['session_cookies']['session']
          session_cookies['Name'] = 'session'

        session.cookies.set(session_cookies['Name'], session_cookies['Value'], domain=session_cookies['Domain'])
        t= None


        url = f'{wapt_url}/api/v3/reporting_exec?id=19'
        response = session.get(url)
        data = response.json()

        return data['result']



    print(run_report())

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

.. Danger::

   **A few examples of APIs using the post method**.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


/api/v3/change_password
-----------------------

Change the Admininistrator password [only this account].
The request is a python dictionnary *{}* with keys:

* *user*;

* *old_password*;

* *new_password*.

Example:

.. code-block::

  wapt-get server-request /api/v3/change_password --method=POST --data="{'user':'USER','password':'old_password',''new_password':'new_password'}"

/api/v3/hosts_delete
--------------------

Delete hosts with specific uuid.
Requires admin or unregister_host ACL.

.. code-block:: bash

  wapt-get server-request /api/v3/hosts_delete --method=POST --data="{'uuids': ['f76f1c44-ba82-714b-9241-5ad0ed671cb1', 'f76ffgh4-ba82-714b-9241-5ad0dfdfe1rt6'], 'delete_packages': 'True', 'delete_inventory': 'True'}"  --wapt-server-user=admin --wapt-server-passwd=password


/api/v3/packages_delete
-----------------------

Delete package with a precise version.
The request is a python list *[]*.
A list of packages may be given, separated by commas *,*.

Example:

.. code-block:: bash

  wapt-get server-request /api/v3/packages_delete --method=POST --data="['ht-wapt-debian-gui_2.6.0.16977-2_0fce3ca2b61ebdbdc9b4b065cfe87176_PROD.wapt']" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


/api/v3/trigger_wakeonlan
-------------------------

If hosts are WakeOnLan enabled, this API is useful.

Syntax is :file:`--data-raw`: a dictionnary with key *uuids* and a list of host uuids.

Example:

.. code-block::
  
  wapt-get server-request /api/v3/trigger_wakeonlan --method=POST --data="{'uuids':['C74B68E2-CB63-BC4D-B6DB-74110DD4E535']}" -c /opt/wapt/wapt-get.ini --wapt-server-user=user --wapt-server-passwd=password


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

.. Danger::

   **Example of APIs using the delete method**.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/api/v3/delete_unused_driver_files
----------------------------------

Example:

.. code-block:: bash
  
  wapt-get server-request /api/v3/delete_unused_driver_files --wapt-server-user=user --wapt-server-passwd=password --method=DELETE