Switch to attridict, format with Black

This commit is contained in:
Joel Heaps 2023-09-28 22:07:25 -05:00
parent 1fc4383a95
commit 31f309c942
3 changed files with 52 additions and 38 deletions

15
pdm.lock generated
View File

@ -6,18 +6,15 @@ groups = ["default"]
cross_platform = true
static_urls = false
lock_version = "4.3"
content_hash = "sha256:619785556320f35b6aca0bf164725dc3afa5a1a978782d66a3add0b9e1ad8738"
content_hash = "sha256:637d322b802d007082b71cf7d27382f3b6b5618434faf6b346358abe81fc2f7f"
[[package]]
name = "attrdict"
version = "2.0.1"
summary = "A dict with attribute-style access"
dependencies = [
"six",
]
name = "attridict"
version = "0.0.8"
summary = "A dict implementation with support for easy and clean access of its values through attributes"
files = [
{file = "attrdict-2.0.1-py2.py3-none-any.whl", hash = "sha256:9432e3498c74ff7e1b20b3d93b45d766b71cbffa90923496f82c4ae38b92be34"},
{file = "attrdict-2.0.1.tar.gz", hash = "sha256:35c90698b55c683946091177177a9e9c0713a0860f0e049febd72649ccd77b70"},
{file = "attridict-0.0.8-py3-none-any.whl", hash = "sha256:8ee65af81f7762354e4514c443bbc04786a924c8e3e610c7883d2efbf323df6d"},
{file = "attridict-0.0.8.tar.gz", hash = "sha256:23a17671b9439d36e2bdb0a69c09f033abab0900a9df178e0f89aa1b2c42c5cd"},
]
[[package]]

View File

@ -6,10 +6,10 @@ authors = [
{name = "Esteban Sanchez", email = "esteban.sanchez@gmail.com"},
]
dependencies = [
"attrdict>=2.0.1",
"prometheus-client>=0.17.1",
"python-json-logger>=2.0.7",
"qbittorrent-api>=2023.9.53",
"attridict>=0.0.8",
]
requires-python = ">=3.11"
readme = "README.md"

View File

@ -3,9 +3,8 @@ import os
import sys
import signal
import faulthandler
from attrdict import AttrDict
import attridict
from qbittorrentapi import Client, TorrentStates
from qbittorrentapi.exceptions import APIConnectionError
from prometheus_client import start_http_server
from prometheus_client.core import GaugeMetricFamily, CounterMetricFamily, REGISTRY
import logging
@ -17,7 +16,7 @@ faulthandler.enable()
logger = logging.getLogger()
class QbittorrentMetricsCollector():
class QbittorrentMetricsCollector:
TORRENT_STATUSES = [
"checking",
"complete",
@ -34,7 +33,7 @@ class QbittorrentMetricsCollector():
port=config["port"],
username=config["username"],
password=config["password"],
VERIFY_WEBUI_CERTIFICATE=config["verify_webui_certificate"]
VERIFY_WEBUI_CERTIFICATE=config["verify_webui_certificate"],
)
def collect(self):
@ -98,13 +97,13 @@ class QbittorrentMetricsCollector():
"name": f"{self.config['metrics_prefix']}_dl_info_data",
"value": response.get("dl_info_data", 0),
"help": "Data downloaded this session (bytes)",
"type": "counter"
"type": "counter",
},
{
"name": f"{self.config['metrics_prefix']}_up_info_data",
"value": response.get("up_info_data", 0),
"help": "Data uploaded this session (bytes)",
"type": "counter"
"type": "counter",
},
]
@ -117,29 +116,43 @@ class QbittorrentMetricsCollector():
return []
metrics = []
categories.Uncategorized = AttrDict({'name': 'Uncategorized', 'savePath': ''})
categories.Uncategorized = attridict({"name": "Uncategorized", "savePath": ""})
for category in categories:
category_torrents = [t for t in torrents if t['category'] == category or (category == "Uncategorized" and t['category'] == "")]
category_torrents = [
t
for t in torrents
if t["category"] == category
or (category == "Uncategorized" and t["category"] == "")
]
for status in self.TORRENT_STATUSES:
status_prop = f"is_{status}"
status_torrents = [
t for t in category_torrents if getattr(TorrentStates, status_prop).fget(TorrentStates(t['state']))
t
for t in category_torrents
if getattr(TorrentStates, status_prop).fget(
TorrentStates(t["state"])
)
]
metrics.append({
metrics.append(
{
"name": f"{self.config['metrics_prefix']}_torrents_count",
"value": len(status_torrents),
"labels": {
"status": status,
"category": category,
},
"help": f"Number of torrents in status {status} under category {category}"
})
"help": (
f"Number of torrents in status {status} under category"
f" {category}"
),
}
)
return metrics
class SignalHandler():
class SignalHandler:
def __init__(self):
self.shutdownCount = 0
@ -157,6 +170,7 @@ class SignalHandler():
logger.info("Exporter is shutting down")
self.shutdownCount += 1
def get_config_value(key, default=""):
input_path = os.environ.get("FILE__" + key, None)
if input_path is not None:
@ -173,8 +187,7 @@ def main():
# Init logger so it can be used
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
"%(asctime) %(levelname) %(message)",
datefmt="%Y-%m-%d %H:%M:%S"
"%(asctime) %(levelname) %(message)", datefmt="%Y-%m-%d %H:%M:%S"
)
logHandler.setFormatter(formatter)
logger.addHandler(logHandler)
@ -188,7 +201,9 @@ def main():
"exporter_port": int(get_config_value("EXPORTER_PORT", "8000")),
"log_level": get_config_value("EXPORTER_LOG_LEVEL", "INFO"),
"metrics_prefix": get_config_value("METRICS_PREFIX", "qbittorrent"),
"verify_webui_certificate": get_config_value("VERIFY_WEBUI_CERTIFICATE", "True") == "True",
"verify_webui_certificate": (
get_config_value("VERIFY_WEBUI_CERTIFICATE", "True") == "True"
),
}
# set level once config has been loaded
logger.setLevel(config["log_level"])
@ -197,10 +212,14 @@ def main():
signal_handler = SignalHandler()
if not config["host"]:
logger.error("No host specified, please set QBITTORRENT_HOST environment variable")
logger.error(
"No host specified, please set QBITTORRENT_HOST environment variable"
)
sys.exit(1)
if not config["port"]:
logger.error("No port specified, please set QBITTORRENT_PORT environment variable")
logger.error(
"No port specified, please set QBITTORRENT_PORT environment variable"
)
sys.exit(1)
# Register our custom collector
@ -209,9 +228,7 @@ def main():
# Start server
start_http_server(config["exporter_port"])
logger.info(
f"Exporter listening on port {config['exporter_port']}"
)
logger.info(f"Exporter listening on port {config['exporter_port']}")
while not signal_handler.is_shutting_down():
time.sleep(1)