Skip to content

Commit 63590e2

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 3217c03 commit 63590e2

10 files changed

Lines changed: 80 additions & 105 deletions

File tree

ymir/agents/baseline_tests.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ def _request_outcome(request: TestingFarmRequest) -> str:
109109
return request.result
110110
return request.state
111111

112-
async def format_issue_comment(self, *, include_attachments: bool = False, tools: list | None = None) -> str:
112+
async def format_issue_comment(
113+
self, *, include_attachments: bool = False, tools: list | None = None
114+
) -> str:
113115
if tools:
114116
is_complete = await self.complete(tools)
115117
is_settled = await self.settled(tools)
@@ -161,7 +163,9 @@ async def format_issue_comment(self, *, include_attachments: bool = False, tools
161163
)
162164
)
163165

164-
async def create_attachments(self, issue_key: str, dry_run: bool = False, tools: list | None = None) -> None:
166+
async def create_attachments(
167+
self, issue_key: str, dry_run: bool = False, tools: list | None = None
168+
) -> None:
165169
attachments: list[tuple[str, bytes, str]] = []
166170
for comparison in self.comparisons:
167171
failed_request = comparison.failed.request

ymir/agents/issue_verification_agent.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,8 @@
1414
from ymir.agents.observability import setup_observability
1515
from ymir.agents.testing_analyst import analyze_issue
1616
from ymir.agents.utils import mcp_tools, run_tool
17-
from ymir.common.constants import DATETIME_MIN_UTC, GITLAB_GROUPS
18-
from ymir.common.constants import JiraLabels
17+
from ymir.common.constants import DATETIME_MIN_UTC, GITLAB_GROUPS, JiraLabels
1918
from ymir.common.models import (
20-
ErrataComment,
21-
ErrataStatus,
22-
Erratum,
2319
FullErratum,
2420
FullIssue,
2521
GitlabMergeRequest,
@@ -277,9 +273,7 @@ async def _label_merge_if_needed(issue: FullIssue, tools: list, dry_run: bool) -
277273
if (
278274
JiraLabels.BACKPORTED.value in issue.labels or JiraLabels.REBASED.value in issue.labels
279275
) and JiraLabels.MERGED.value not in issue.labels:
280-
merged_mrs = await _search_merged_mrs(
281-
component, issue.key, GitlabMergeRequestState.MERGED, tools
282-
)
276+
merged_mrs = await _search_merged_mrs(component, issue.key, GitlabMergeRequestState.MERGED, tools)
283277
if merged_mrs:
284278
merged_mr = merged_mrs[0]
285279
await _add_label(
@@ -299,9 +293,7 @@ async def _label_merge_if_needed(issue: FullIssue, tools: list, dry_run: bool) -
299293
async def _get_latest_merged_timestamp(issue: FullIssue, tools: list) -> datetime:
300294
"""Get the latest merged timestamp from all merged MRs."""
301295
component = issue.components[0]
302-
merged_mrs = await _search_merged_mrs(
303-
component, issue.key, GitlabMergeRequestState.MERGED, tools
304-
)
296+
merged_mrs = await _search_merged_mrs(component, issue.key, GitlabMergeRequestState.MERGED, tools)
305297
if not merged_mrs:
306298
return DATETIME_MIN_UTC
307299
return max(
@@ -540,7 +532,9 @@ async def analyze_testing(state: IssueVerificationWorkflowState):
540532
dry_run=state.dry_run,
541533
tools=gateway_tools,
542534
)
543-
issue_comment = await new_baseline_tests.format_issue_comment(tools=gateway_tools)
535+
issue_comment = await new_baseline_tests.format_issue_comment(
536+
tools=gateway_tools
537+
)
544538
await _add_label(
545539
issue.key,
546540
"ymir_reproducing_tests",

ymir/common/constants.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
from enum import Enum
2-
31
from datetime import UTC, datetime, timedelta
2+
from enum import Enum
43

54
JIRA_SEARCH_PATH = "rest/api/3/search/jql"
65

ymir/common/qe_data.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ def wrapper() -> Awaitable[R]:
7070

7171
@cache_async(max_age=10 * 60) # cache for 10 minutes
7272
async def get_qe_data_map() -> dict[str, dict[str, dict[str, str]]]:
73-
async with aiohttp.ClientSession() as session:
74-
async with session.get(QE_DATA_URL) as response:
75-
response.raise_for_status()
76-
return await response.json(content_type=None)
73+
async with aiohttp.ClientSession() as session, session.get(QE_DATA_URL) as response:
74+
response.raise_for_status()
75+
return await response.json(content_type=None)
7776

7877

7978
async def get_qe_data(component: str) -> TestLocationInfo:

ymir/tools/privileged/errata.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,7 @@ class GetErratumToolInput(BaseModel):
110110
full: bool = Field(default=False, description="If true, include comments in the response")
111111

112112

113-
class GetErratumTool(
114-
Tool[GetErratumToolInput, ToolRunOptions, JSONToolOutput[dict[str, Any]]]
115-
):
113+
class GetErratumTool(Tool[GetErratumToolInput, ToolRunOptions, JSONToolOutput[dict[str, Any]]]):
116114
name = "get_erratum"
117115
description = """
118116
Get erratum details (basic or full with comments) by ID or link.
@@ -150,9 +148,7 @@ class GetErratumBuildNvrToolInput(BaseModel):
150148
package_name: str = Field(description="Package name to look up the build NVR for")
151149

152150

153-
class GetErratumBuildNvrTool(
154-
Tool[GetErratumBuildNvrToolInput, ToolRunOptions, JSONToolOutput[str | None]]
155-
):
151+
class GetErratumBuildNvrTool(Tool[GetErratumBuildNvrToolInput, ToolRunOptions, JSONToolOutput[str | None]]):
156152
name = "get_erratum_build_nvr"
157153
description = """
158154
Get the build NVR for a package in an erratum.

ymir/tools/privileged/gitlab.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
ToolError,
1616
ToolRunOptions,
1717
)
18-
from ymir.tools.base import CloneableTool as Tool
1918
from ogr.exceptions import GitlabAPIException, OgrException
2019
from ogr.factory import get_project
2120
from ogr.services.gitlab.project import GitlabProject
@@ -30,6 +29,7 @@
3029
OpenMergeRequestResult,
3130
)
3231
from ymir.common.validators import AbsolutePath
32+
from ymir.tools.base import CloneableTool as Tool
3333
from ymir.tools.constants import AIOHTTP_TIMEOUT
3434
from ymir.tools.privileged.utils import clean_stale_repositories
3535

@@ -990,12 +990,8 @@ async def _run(
990990

991991

992992
class SearchGitlabProjectMrsToolInput(BaseModel):
993-
project: str = Field(
994-
description="GitLab project path (e.g. 'redhat/rhel/rpms/podman')"
995-
)
996-
search: str = Field(
997-
description="Search string to match against merge requests (e.g. a JIRA issue key)"
998-
)
993+
project: str = Field(description="GitLab project path (e.g. 'redhat/rhel/rpms/podman')")
994+
search: str = Field(description="Search string to match against merge requests (e.g. a JIRA issue key)")
999995
state: str | None = Field(
1000996
default=None,
1001997
description="Filter MRs by state: 'opened', 'closed', 'merged', or null for all",

ymir/tools/privileged/jira.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
ToolError,
1616
ToolRunOptions,
1717
)
18-
from ymir.tools.base import CloneableTool as Tool
1918
from pydantic import BaseModel, Field
2019

2120
from ymir.common import CVEEligibilityResult, TriageEligibility, load_rhel_config
2221
from ymir.common.base_utils import get_jira_auth_headers
2322
from ymir.common.constants import JIRA_SEARCH_PATH
2423
from ymir.common.version_utils import get_fix_version_variants, normalize_fix_version, parse_rhel_version
24+
from ymir.tools.base import CloneableTool as Tool
2525
from ymir.tools.constants import AIOHTTP_TIMEOUT
2626

2727
if os.getenv("MOCK_JIRA", "False").lower() == "true":
@@ -1200,9 +1200,7 @@ async def _run(
12001200
f"on {issue_key} (this is expected, not an error)"
12011201
)
12021202

1203-
jira_url = urljoin(
1204-
os.getenv("JIRA_URL"), f"rest/api/2/issue/{issue_key}/comment/{comment_id}"
1205-
)
1203+
jira_url = urljoin(os.getenv("JIRA_URL"), f"rest/api/2/issue/{issue_key}/comment/{comment_id}")
12061204
logger.info("Updating comment %s on %s", comment_id, issue_key)
12071205

12081206
async with aiohttpClientSession(timeout=AIOHTTP_TIMEOUT) as session:
@@ -1214,13 +1212,9 @@ async def _run(
12141212
) as response:
12151213
response.raise_for_status()
12161214
except aiohttp.ClientError as e:
1217-
raise ToolError(
1218-
f"Failed to update comment {comment_id} on {issue_key}: {e}"
1219-
) from e
1215+
raise ToolError(f"Failed to update comment {comment_id} on {issue_key}: {e}") from e
12201216

1221-
return StringToolOutput(
1222-
result=f"Successfully updated comment {comment_id} on {issue_key}"
1223-
)
1217+
return StringToolOutput(result=f"Successfully updated comment {comment_id} on {issue_key}")
12241218

12251219

12261220
class AddJiraAttachmentsToolInput(BaseModel):
@@ -1267,9 +1261,7 @@ async def _run(
12671261
f"to {issue_key} (this is expected, not an error)"
12681262
)
12691263

1270-
jira_url = urljoin(
1271-
os.getenv("JIRA_URL"), f"rest/api/2/issue/{issue_key}/attachments"
1272-
)
1264+
jira_url = urljoin(os.getenv("JIRA_URL"), f"rest/api/2/issue/{issue_key}/attachments")
12731265
headers = dict(get_jira_auth_headers())
12741266
# Remove Content-Type so aiohttp sets multipart correctly
12751267
headers.pop("Content-Type", None)
@@ -1301,9 +1293,7 @@ async def _run(
13011293
raise ToolError(f"Failed to add attachments to {issue_key}: {e}") from e
13021294

13031295
filenames = ", ".join(a["filename"] for a in attachments)
1304-
return StringToolOutput(
1305-
result=f"Successfully added attachments ({filenames}) to {issue_key}"
1306-
)
1296+
return StringToolOutput(result=f"Successfully added attachments ({filenames}) to {issue_key}")
13071297

13081298

13091299
class GetJiraAttachmentToolInput(BaseModel):
@@ -1366,8 +1356,6 @@ async def _run(
13661356
try:
13671357
text = content.decode("utf-8")
13681358
except UnicodeDecodeError:
1369-
return StringToolOutput(
1370-
result=f"Failed to decode attachment {filename} as UTF-8"
1371-
)
1359+
return StringToolOutput(result=f"Failed to decode attachment {filename} as UTF-8")
13721360

13731361
return StringToolOutput(result=text)

ymir/tools/privileged/testing_farm.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import os
3-
from datetime import UTC, datetime
3+
from datetime import datetime
44
from functools import cache
55
from json import dumps as json_dumps
66
from typing import Any
@@ -14,7 +14,6 @@
1414
from ymir.common.models import (
1515
TestingFarmRequest,
1616
TestingFarmRequestResult,
17-
TestingFarmRequestState,
1817
)
1918

2019
logger = logging.getLogger(__name__)
@@ -35,7 +34,9 @@ def _testing_farm_api_get(path: str, *, params: dict | None = None) -> Any:
3534
url = f"{TESTING_FARM_URL}/{path}"
3635
response = requests.get(url, headers=_testing_farm_headers(), params=params)
3736
if not response.ok:
38-
logger.error("GET %s%s failed.\nerror:\n%s", url, f" (params={params})" if params else "", response.text)
37+
logger.error(
38+
"GET %s%s failed.\nerror:\n%s", url, f" (params={params})" if params else "", response.text
39+
)
3940
response.raise_for_status()
4041
return response.json()
4142

@@ -44,7 +45,9 @@ def _testing_farm_api_post(path: str, json: dict[str, Any]) -> Any:
4445
url = f"{TESTING_FARM_URL}/{path}"
4546
response = requests.post(url, headers=_testing_farm_headers(), json=json)
4647
if not response.ok:
47-
logger.error("POST to %s failed\nbody:\n%s\nerror:\n%s", url, json_dumps(json, indent=2), response.text)
48+
logger.error(
49+
"POST to %s failed\nbody:\n%s\nerror:\n%s", url, json_dumps(json, indent=2), response.text
50+
)
4851
response.raise_for_status()
4952
return response.json()
5053

@@ -170,9 +173,7 @@ def create_new_environment(env: dict) -> dict:
170173

171174
artifacts = env.get("artifacts")
172175
if artifacts and len(artifacts) == 1:
173-
new_env["artifacts"] = [
174-
{"id": build_nvr, "type": "redhat-brew-build", "order": 40}
175-
]
176+
new_env["artifacts"] = [{"id": build_nvr, "type": "redhat-brew-build", "order": 40}]
176177
return new_env
177178

178179
raise ValueError(

ymir/tools/unprivileged/read_logfile.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@ async def _run(
6767
return StringToolOutput(result=f"URL does not match allowed patterns: {input.logfile_url}")
6868

6969
logger.info("Reading logfile from URL: %s", url)
70-
async with aiohttp.ClientSession() as session:
71-
async with session.get(url) as response:
72-
if response.status == 200:
73-
return StringToolOutput(
74-
result=await response.text(),
75-
)
70+
async with aiohttp.ClientSession() as session, session.get(url) as response:
71+
if response.status == 200:
72+
return StringToolOutput(
73+
result=await response.text(),
74+
)
7675

7776
return StringToolOutput(result=f"Failed to read logfile from {input.logfile_url}")

ymir/tools/unprivileged/search_resultsdb.py

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -52,49 +52,48 @@ async def search_resultsdb(package_nvr: str, name_pattern: str) -> list[ResultsD
5252
f"&limit={MAX_RESULTS}"
5353
)
5454
logger.info("Fetching resultsdb data from %s", url)
55-
async with aiohttp.ClientSession() as session:
56-
async with session.get(url) as response:
57-
if response.status == 200:
58-
response_json = await response.json()
59-
60-
if response_json.get("next") is not None:
61-
raise ValueError(f"ResultsDB returned more than {MAX_RESULTS} results")
62-
63-
results: list[ResultsDbResult] = [
64-
ResultsDbResult(
65-
testcase_name=r["testcase"]["name"],
66-
outcome=ResultsdbOutput(r["outcome"]),
67-
ref_url=r["ref_url"],
68-
last_updated=datetime.fromisoformat(r["submit_time"]),
69-
)
70-
for r in response_json.get("data", [])
71-
]
72-
73-
# Now only keep the latest result for each testcase
74-
latest_results: dict[str, ResultsDbResult] = {}
75-
for r in results:
76-
if (
77-
r.testcase_name not in latest_results
78-
or r.last_updated > latest_results[r.testcase_name].last_updated
79-
):
80-
latest_results[r.testcase_name] = r
81-
82-
logger.info(
83-
"Found %d results in resultsdb (%d after filtering for latest submissions)",
84-
len(results),
85-
len(latest_results),
55+
async with aiohttp.ClientSession() as session, session.get(url) as response:
56+
if response.status == 200:
57+
response_json = await response.json()
58+
59+
if response_json.get("next") is not None:
60+
raise ValueError(f"ResultsDB returned more than {MAX_RESULTS} results")
61+
62+
results: list[ResultsDbResult] = [
63+
ResultsDbResult(
64+
testcase_name=r["testcase"]["name"],
65+
outcome=ResultsdbOutput(r["outcome"]),
66+
ref_url=r["ref_url"],
67+
last_updated=datetime.fromisoformat(r["submit_time"]),
8668
)
87-
88-
return list(latest_results.values())
89-
text = await response.text()
90-
raise aiohttp.ClientResponseError(
91-
response.request_info,
92-
response.history,
93-
status=response.status,
94-
message=text,
95-
headers=response.headers,
69+
for r in response_json.get("data", [])
70+
]
71+
72+
# Now only keep the latest result for each testcase
73+
latest_results: dict[str, ResultsDbResult] = {}
74+
for r in results:
75+
if (
76+
r.testcase_name not in latest_results
77+
or r.last_updated > latest_results[r.testcase_name].last_updated
78+
):
79+
latest_results[r.testcase_name] = r
80+
81+
logger.info(
82+
"Found %d results in resultsdb (%d after filtering for latest submissions)",
83+
len(results),
84+
len(latest_results),
9685
)
9786

87+
return list(latest_results.values())
88+
text = await response.text()
89+
raise aiohttp.ClientResponseError(
90+
response.request_info,
91+
response.history,
92+
status=response.status,
93+
message=text,
94+
headers=response.headers,
95+
)
96+
9897

9998
class SearchResultsdbInput(BaseModel):
10099
package_nvr: str = Field(description="NVR of the package to search in the results database")

0 commit comments

Comments
 (0)