Question:
I’ve successfully implemented the GET method of the Unifi Controller API in Grafana using the Infinity data source. However, I’m facing difficulties with using the POST method.
Here is my current Python Flask server code, which handles the login and fetches data using GET and POST methods:
import requests
from requests.exceptions import SSLError, RequestException
app = Flask(__name__)
# Disable SSL warnings from urllib3
requests.packages.urllib3.disable_warnings()
# Constants for API endpoints and credentials
LOGIN_URL = "https://unifi.website.com/api/login"
DEVICE_STATS_URL = "https://unifi.website.com/api/s/lp0csd81/stat/device"
STA_STATS_URL = "https://unifi.website.com/api/s/lp0csd81/stat/sta"
USERNAME = "username"
PASSWORD = "password"
def perform_login():
login_payload = {
"strict": True,
"password": PASSWORD,
"remember": True,
"username": USERNAME
}
login_headers = {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
}
try:
response = requests.post(LOGIN_URL, headers=login_headers, json=login_payload, verify=False)
response.raise_for_status()
return response.cookies.get_dict() if response.status_code == 200 else None
except (SSLError, RequestException) as err:
print(f"Error occurred: {err}")
return None
@app.route('/fetch_device_stats', methods=['GET'])
def fetch_device_stats():
cookies = perform_login()
if cookies:
csrf_token = cookies.get('csrf_token', '')
unifises = cookies.get('unifises', '')
headers = {
'Accept': 'application/json, text/plain, */*',
'X-Csrf-Token': csrf_token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Cookie': f'csrf_token={csrf_token}; unifises={unifises}'
}
try:
response = requests.get(DEVICE_STATS_URL, headers=headers, verify=False)
response.raise_for_status()
return jsonify(response.json()) if response.status_code == 200 else f"Failed to fetch device stats. Status code: {response.status_code}"
except RequestException as err:
print(f"Error occurred: {err}")
return f"Request Exception occurred: {err}"
return "Login failed. Unable to fetch device stats."
@app.route('/fetch_sta_stats', methods=['POST'])
def fetch_sta_stats():
cookies = perform_login()
if cookies:
csrf_token = cookies.get('csrf_token', '')
unifises = cookies.get('unifises', '')
headers = {
'Accept': 'application/json, text/plain, */*',
'X-Csrf-Token': csrf_token,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Cookie': f'csrf_token={csrf_token}; unifises={unifises}'
}
try:
response = requests.post(STA_STATS_URL, headers=headers, verify=False)
response.raise_for_status()
return jsonify(response.json()) if response.status_code == 200 else f"Failed to fetch STA stats. Status code: {response.status_code}"
except RequestException as err:
print(f"Error occurred: {err}")
return f"Request Exception occurred: {err}"
return "Login failed. Unable to fetch STA stats."
if __name__ == '__main__':
app.run(debug=True)
I got to the point where I want to use the POST method of the Unifi Controller API. I saw a request payload indicating the following structure
Here is how the payload looks
{
"macs": ["b2:1c:b6:25:76:41"]
}
with additional information
0: "b2:1c:b6:25:76:41"
Grafana Infinity Data Source Error Log
Should I create my own payload in this format to use it as a time series but based on MAC addresses? How should I structure my request payload and integrate it with Grafana using the Infinity data source to achieve this?
Any guidance or examples would be greatly appreciated!
Additional Context:
- I am using Grafana with the Infinity data source. The GET method was
straightforward to implement, but the POST method is causing issues.
I want to visualize data based on MAC addresses in a time series
format. - Gunicorn in Flask Server
Thank you in advance for your help!