diff --git a/kcidev/libs/common.py b/kcidev/libs/common.py index 004869f..48059c4 100644 --- a/kcidev/libs/common.py +++ b/kcidev/libs/common.py @@ -5,14 +5,24 @@ import logging import os import sys +from importlib.metadata import PackageNotFoundError, version import click +import requests if sys.version_info >= (3, 11): import tomllib else: import tomli as tomllib +try: + kcidev_version = version("kci-dev") +except PackageNotFoundError: + kcidev_version = "unknown" + +kcidev_session = requests.Session() +kcidev_session.headers["User-Agent"] = f"kci-dev/{kcidev_version}" + def load_toml(settings, subcommand): fname = "kci-dev.toml" diff --git a/kcidev/libs/dashboard.py b/kcidev/libs/dashboard.py index cf3967e..a9f4d8b 100644 --- a/kcidev/libs/dashboard.py +++ b/kcidev/libs/dashboard.py @@ -83,12 +83,12 @@ def wrapper( @_dashboard_request def dashboard_api_post(endpoint, params, use_json, body, max_retries=3): - return requests.post(endpoint, json=body) + return kcidev_session.post(endpoint, json=body) @_dashboard_request def dashboard_api_fetch(endpoint, params, use_json, max_retries=3, error_verbose=True): - return requests.get(endpoint) + return kcidev_session.get(endpoint) def dashboard_fetch_summary(origin, giturl, branch, commit, arch, use_json): diff --git a/kcidev/libs/files.py b/kcidev/libs/files.py index 6272572..a5bf816 100644 --- a/kcidev/libs/files.py +++ b/kcidev/libs/files.py @@ -5,7 +5,7 @@ import requests -from kcidev.libs.common import kci_err +from kcidev.libs.common import kci_err, kcidev_session INVALID_FILE_CHARS = re.compile(r'[\\/:"*?<>|]+') @@ -23,7 +23,7 @@ def download_logs_to_file(log_url, log_file): try: # Download compressed log logging.debug("Fetching compressed log file") - response = requests.get(log_url) + response = kcidev_session.get(log_url) response.raise_for_status() # Decompress log diff --git a/kcidev/libs/maestro_common.py b/kcidev/libs/maestro_common.py index e5278fc..d5a5c1a 100644 --- a/kcidev/libs/maestro_common.py +++ b/kcidev/libs/maestro_common.py @@ -61,7 +61,7 @@ def maestro_get_node(url, nodeid): maestro_print_api_call(url) try: - response = requests.get(url, headers=headers) + response = kcidev_session.get(url, headers=headers) logging.debug(f"Node request status: {response.status_code}") response.raise_for_status() except requests.exceptions.HTTPError as ex: @@ -107,7 +107,7 @@ def maestro_get_nodes(url, limit, offset, filter, paginate): maestro_print_api_call(url) try: - response = requests.get(url, headers=headers) + response = kcidev_session.get(url, headers=headers) logging.debug(f"Nodes request status: {response.status_code}") response.raise_for_status() except requests.exceptions.HTTPError as ex: @@ -169,7 +169,7 @@ def maestro_retrieve_treeid_nodes(baseurl, token, treeid): logging.debug(f"Tree nodes URL: {url}") try: - response = requests.get(url, headers=headers, timeout=30) + response = kcidev_session.get(url, headers=headers, timeout=30) logging.debug(f"Tree nodes request status: {response.status_code}") except requests.exceptions.RequestException as e: logging.warning(f"Request exception retrieving tree nodes: {e}") diff --git a/kcidev/main.py b/kcidev/main.py index 0df48bd..5db1c9b 100755 --- a/kcidev/main.py +++ b/kcidev/main.py @@ -21,7 +21,7 @@ @click.group( help="Stand alone tool for Linux Kernel developers and maintainers to interact with KernelCI." ) -@click.version_option("0.1.10", prog_name="kci-dev") +@click.version_option(kcidev_version, prog_name="kci-dev") @click.option( "--settings", default=".kci-dev.toml", diff --git a/kcidev/subcommands/checkout.py b/kcidev/subcommands/checkout.py index 5b67952..92bae0c 100644 --- a/kcidev/subcommands/checkout.py +++ b/kcidev/subcommands/checkout.py @@ -41,7 +41,7 @@ def send_checkout_full(baseurl, token, **kwargs): maestro_print_api_call(url, data) try: logging.debug(f"POST request to: {url}") - response = requests.post(url, headers=headers, data=jdata, timeout=30) + response = kcidev_session.post(url, headers=headers, data=jdata, timeout=30) logging.debug(f"Checkout response status: {response.status_code}") except requests.exceptions.RequestException as e: logging.error(f"Checkout API request failed: {e}") diff --git a/kcidev/subcommands/testretry.py b/kcidev/subcommands/testretry.py index 0801834..dc152a7 100644 --- a/kcidev/subcommands/testretry.py +++ b/kcidev/subcommands/testretry.py @@ -27,7 +27,7 @@ def send_jobretry(baseurl, jobid, token): try: logging.debug("Sending POST request for job retry") - response = requests.post(url, headers=headers, data=jdata) + response = kcidev_session.post(url, headers=headers, data=jdata) logging.debug(f"Response status: {response.status_code}") except requests.exceptions.RequestException as e: logging.error(f"Failed to send job retry request: {e}") diff --git a/tests/test_kcidev.py b/tests/test_kcidev.py index 65a02b9..1a5baf5 100644 --- a/tests/test_kcidev.py +++ b/tests/test_kcidev.py @@ -1,10 +1,12 @@ import os +import re import shutil from subprocess import PIPE, run import git import pytest +from kcidev.libs.common import kcidev_session, kcidev_version from kcidev.subcommands.config import add_config @@ -918,6 +920,17 @@ def test_kcidev_results_build_with_real_id(): pass +def test_kcidev_session_user_agent(): + ua = kcidev_session.headers["User-Agent"] + assert ua == f"kci-dev/{kcidev_version}" + assert kcidev_version != "unknown" + + +def test_kcidev_version_from_metadata(): + assert isinstance(kcidev_version, str) + assert re.match(r"^\d+\.\d+\.\d+", kcidev_version) + + def test_clean(): # clean enviroment shutil.rmtree("my-new-repo/")