Raw HTTP API

The Raw HTTP API serves a similar purpose as the Swagger/OpenAPI feature, but for devices that either do not provide a Swagger/OpenAPI spec or are not supported by RADKit Service. It is built on top of, and mimics, Python’s httpx library.

Note

Currently this API is only supported on a single device at a time, i.e. it is not possible to perform HTTP requests on a DeviceDict for multiple devices at a time.

Service configuration

To activate the HTTP API, either when creating a new device or modifying an existing one, simply select the HTTP checkbox. This action will enable the HTTP API functionality for the device.

The HTTP configuration section contains four fields:

Protocol (HTTP or HTTPS)

Selects HTTP (without TLS) or HTTPS (with TLS) as the protocol. For HTTPS, the highest TLS version that will be negotiated will depend on the OpenSSL version available in RADKit’s environment (see ssl). When HTTPS protocol is selected, the minimum supported TLS version is 1.2.

Verify TLS certificate

Only applicable for HTTPS. Validates the TLS certificate during connection; should be disabled for devices presenting a self-signed certificate. It is currently only possible to validate against the system’s default trusted issuers. In a future release, it will be possible to pin the device’s certificate and/or add specific trusted issuers.

Username

For HTTP authentication. Only effective on platforms where authentication is supported (see below).

Password

For HTTP authentication. Only effective on platforms where authentication is supported (see below).

../_images/feature_http.png

Client operation

Devices HTTP status

As part of the service inventory, the Client receives an internal attribute named http_config for each device. This attribute is set to either True or False, depending on whether the HTTP management protocol is enabled and configured for the device on the Service side.

>>> device = service.inventory['httpdevice']
>>> device.attributes.internal
<radkit_client.sync.device.DeviceAttributesDict object at 0x10ed4bfa0>
key                  value
-------------------  ---------
description
device_type          LINUX
forwarded_tcp_ports
host                 localhost
http_config          True
netconf_config       False
snmp_version         None
swagger_config       False
terminal_config      False

Basic usage of the HTTP API

The HTTP API implements most HTTP request verbs, with the exception of CONNECT and TRACE. Each verb is implemented as a method on top of the Device object’s http attribute, which is an instance of HTTP_API.

  • get

  • post

  • put

  • patch

  • delete

  • head

  • options

All these methods accept the following basic parameters:

path (str)

The path to send the request to (e.g. .get(path="/version") would result in GET /path). The request is sent directly to the device, so only the path portion of the URL is required, without IP address or hostname.

headers (dict, optional)

A dictionary of HTTP headers to send as part of the request.

cookies (dict, optional)

A dictionary of HTTP cookies to send as part of the request.

timeout (float, optional)

The desired timeout (in seconds) for the request.

Additional parameters are available depending on the particular method used, such as content (request body), data (form-encoded data) or json (data to be serialized as JSON). For more information, see the API reference for each particular method (links above).

Basic example

If a device has an HTTP API endpoint called /api/v1/version, you can use the HTTP API to query that endpoint through RADKit Service:

>>> device = service.inventory['httpdevice']
>>> response = device.http.get('/api/v1/version').wait()
>>> print(response.result.content)
b'{"version": "1.0.0"}'

The response.result object is an instance of HTTPResponseResult. It offers various properties such as status_code and content, similar to an httpx result.

Using custom headers

Here is an example illustrating the submission of a form using custom headers for HTTP POST data transmission:

>>> device = service.inventory['httpdevice']
>>> headers = { "Content-Type" : "application/json", "user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 Chrome" }
>>> payload = {"key": "value", "key2": "value"}
>>> response = device.http.post("/submit", headers=headers, json=payload).wait()
>>> print(response.result.status_code)
200

Using custom cookies

Here is an example demonstrating a form submission with a custom cookie:

>>> device = service.inventory['httpdevice']
>>> cookies = {"session_id": "46hMciW6IDg59pspoLtVuDl4B3xe"}
>>> response = device.http.get("/home", cookies=cookies).wait()
>>> print(response.result.content)
b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n (...)'

Authentication support

This feature makes it possible to perform Client-driven authentication using the device’s own specific authentication API, although it requires the credentials to be available on the Client side (similar to the SOCKS proxy use case where the Client user needs to have a set of credentials in order to log on to a device’s Web UI).

There is also support for Service-driven authentication for a limited number of platforms; at the moment those are Catalyst Center, IOS XE and NXOS. For those platforms, if a username/password are specified, those will be used to log on to the device’s HTTP API, similar to what is done for Swagger, in a manner that is transparent to the Client.