From 73f09c44cd5e2b30cc6c31a2eba3e41f7fec3397 Mon Sep 17 00:00:00 2001 From: matt-codecov <137832199+matt-codecov@users.noreply.github.com> Date: Thu, 19 Oct 2023 08:34:33 -0700 Subject: [PATCH] feat: add user agent to all requests (#313) --- .gitignore | 6 ++- codecov_cli/commands/labelanalysis.py | 9 ++-- codecov_cli/helpers/request.py | 37 ++++++++++++++-- codecov_cli/services/report/__init__.py | 3 +- .../services/staticanalysis/__init__.py | 7 +-- tests/helpers/test_request.py | 43 ++++++++++++++++++- 6 files changed, 91 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index fa3e70e6..ea23c4f1 100644 --- a/.gitignore +++ b/.gitignore @@ -158,4 +158,8 @@ cython_debug/ .history/ # Built Visual Studio Code Extensions -*.vsix \ No newline at end of file +*.vsix + +# Vim temporary files +*.swp +*.swo diff --git a/codecov_cli/commands/labelanalysis.py b/codecov_cli/commands/labelanalysis.py index d28dd5e9..5a0e1503 100644 --- a/codecov_cli/commands/labelanalysis.py +++ b/codecov_cli/commands/labelanalysis.py @@ -8,6 +8,7 @@ import requests from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum +from codecov_cli.helpers import request from codecov_cli.helpers.config import CODECOV_API_URL from codecov_cli.helpers.validators import validate_commit_sha from codecov_cli.runners import get_runner @@ -164,7 +165,7 @@ def label_analysis( start_wait = time.monotonic() time.sleep(1) while not has_result: - resp_data = requests.get( + resp_data = request.get( f"{upload_url}/labels/labels-analysis/{eid}", headers={"Authorization": token_header}, ) @@ -270,7 +271,7 @@ def _potentially_calculate_absent_labels( def _patch_labels(payload, url, token_header): logger.info("Sending collected labels to Codecov...") try: - response = requests.patch( + response = request.patch( url, json=payload, headers={"Authorization": token_header} ) if response.status_code < 300: @@ -289,8 +290,8 @@ def _send_labelanalysis_request(payload, url, token_header): ), ) try: - response = requests.post( - url, json=payload, headers={"Authorization": token_header} + response = request.post( + url, data=payload, headers={"Authorization": token_header} ) if response.status_code >= 500: logger.warning( diff --git a/codecov_cli/helpers/request.py b/codecov_cli/helpers/request.py index 8596e3c7..75222b99 100644 --- a/codecov_cli/helpers/request.py +++ b/codecov_cli/helpers/request.py @@ -5,12 +5,43 @@ import click import requests +from codecov_cli import __version__ from codecov_cli.types import RequestError, RequestResult logger = logging.getLogger("codecovcli") MAX_RETRIES = 3 +USER_AGENT = f"codecov-cli/{__version__}" + + +def _set_user_agent(headers: dict = None) -> dict: + headers = headers or {} + headers.setdefault("User-Agent", USER_AGENT) + return headers + + +def patch(url: str, headers: dict = None, json: dict = None) -> requests.Response: + headers = _set_user_agent(headers) + return requests.patch(url, json=json, headers=headers) + + +def get(url: str, headers: dict = None, params: dict = None) -> requests.Response: + headers = _set_user_agent(headers) + return requests.get(url, params=params, headers=headers) + + +def put(url: str, data: dict = None, headers: dict = None) -> requests.Response: + headers = _set_user_agent(headers) + return requests.put(url, data=data, headers=headers) + + +def post( + url: str, data: dict = None, headers: dict = None, params: dict = None +) -> requests.Response: + headers = _set_user_agent(headers) + return requests.post(url, json=data, headers=headers, params=params) + def backoff_time(curr_retry): return 2 ** (curr_retry - 1) @@ -41,8 +72,7 @@ def wrapper(*args, **kwargs): def send_post_request( url: str, data: dict = None, headers: dict = None, params: dict = None ): - resp = requests.post(url=url, json=data, headers=headers, params=params) - return request_result(resp) + return request_result(post(url=url, data=data, headers=headers, params=params)) def get_token_header_or_fail(token: uuid.UUID) -> dict: @@ -61,8 +91,7 @@ def send_put_request( data: dict = None, headers: dict = None, ): - resp = requests.put(url=url, data=data, headers=headers) - return request_result(resp) + return request_result(put(url=url, data=data, headers=headers)) def request_result(resp): diff --git a/codecov_cli/services/report/__init__.py b/codecov_cli/services/report/__init__.py index d4173ee4..4d57d66d 100644 --- a/codecov_cli/services/report/__init__.py +++ b/codecov_cli/services/report/__init__.py @@ -6,6 +6,7 @@ import requests +from codecov_cli.helpers import request from codecov_cli.helpers.config import CODECOV_API_URL from codecov_cli.helpers.encoder import encode_slug from codecov_cli.helpers.request import ( @@ -94,7 +95,7 @@ def send_reports_result_get_request( url = f"{upload_url}/upload/{service}/{encoded_slug}/commits/{commit_sha}/reports/{report_code}/results" number_tries = 0 while number_tries < MAX_NUMBER_TRIES: - resp = requests.get(url=url, headers=headers) + resp = request.get(url=url, headers=headers) response_obj = request_result(resp) response_content = json.loads(response_obj.text) diff --git a/codecov_cli/services/staticanalysis/__init__.py b/codecov_cli/services/staticanalysis/__init__.py index c1c9c1f1..55a651fd 100644 --- a/codecov_cli/services/staticanalysis/__init__.py +++ b/codecov_cli/services/staticanalysis/__init__.py @@ -10,6 +10,7 @@ import httpx import requests +from codecov_cli.helpers import request from codecov_cli.helpers.config import CODECOV_API_URL from codecov_cli.services.staticanalysis.analyzers import get_best_analyzer from codecov_cli.services.staticanalysis.exceptions import AnalysisError @@ -59,9 +60,9 @@ async def run_analysis_entrypoint( extra=dict(extra_log_attributes=dict(json_payload=json_output)), ) upload_url = enterprise_url or CODECOV_API_URL - response = requests.post( + response = request.post( f"{upload_url}/staticanalysis/analyses", - json=json_output, + data=json_output, headers={"Authorization": f"Repotoken {token}"}, ) response_json = response.json() @@ -256,7 +257,7 @@ def send_finish_signal(response_json, upload_url: str, token: str): "Sending finish signal to let API know to schedule static analysis task", extra=dict(extra_log_attributes=dict(external_id=external_id)), ) - response = requests.post( + response = request.post( f"{upload_url}/staticanalysis/analyses/{external_id}/finish", headers={"Authorization": f"Repotoken {token}"}, ) diff --git a/tests/helpers/test_request.py b/tests/helpers/test_request.py index 4e65f7c5..516c29a3 100644 --- a/tests/helpers/test_request.py +++ b/tests/helpers/test_request.py @@ -4,12 +4,19 @@ import requests from requests import Response +from codecov_cli import __version__ from codecov_cli.helpers.request import ( + get, get_token_header_or_fail, log_warnings_and_errors_if_any, ) from codecov_cli.helpers.request import logger as req_log -from codecov_cli.helpers.request import request_result, send_post_request +from codecov_cli.helpers.request import ( + patch, + request_result, + send_post_request, + send_put_request, +) from codecov_cli.types import RequestError, RequestResult @@ -103,3 +110,37 @@ def test_request_retry_too_many_errors(mocker): with pytest.raises(Exception) as exp: resp = send_post_request("my_url") assert str(exp.value) == "Request failed after too many retries" + + +def test_user_agent(mocker): + def mock_request(*args, headers={}, **kwargs): + assert headers["User-Agent"] == f"codecov-cli/{__version__}" + return RequestResult(status_code=200, error=None, warnings=[], text="") + + mocker.patch.object( + requests, + "post", + side_effect=mock_request, + ) + send_post_request("my_url") + + mocker.patch.object( + requests, + "get", + side_effect=mock_request, + ) + get("my_url") + + mocker.patch.object( + requests, + "put", + side_effect=mock_request, + ) + send_put_request("my_url") + + mocker.patch.object( + requests, + "patch", + side_effect=mock_request, + ) + patch("my_url")