Skip to content

Commit eaa1581

Browse files
saidsefCopilot
andauthored
chore: add timeout to requests (#113)
* refactor: simplify logging messages in GitHubIntegration class * feat: add timeout parameter to GitHub API requests for improved reliability * chore: update project version to 3.1.0 and bump uv dependency to 0.8.22 * chore: configurable through an environment variable Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent 73935cd commit eaa1581

File tree

4 files changed

+74
-73
lines changed

4 files changed

+74
-73
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "mcp-github-pr-issue-analyser"
3-
version = "3.0.0"
3+
version = "3.1.0"
44
description = "MCP GitHub Issues Create/Update and PR Analyse"
55
readme = "README.md"
66
requires-python = ">=3.12"
@@ -10,7 +10,7 @@ authors = [
1010
dependencies = [
1111
"mcp[cli]==1.13.1",
1212
"requests==2.32.5",
13-
"uv==0.8.19",
13+
"uv==0.8.22",
1414
]
1515

1616
[project.scripts]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
-i https://pypi.org/simple
22
mcp[cli]==1.13.1
33
requests==2.32.5
4-
uv==0.8.19
4+
uv==0.8.22

src/mcp_github/github_integration.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from typing import Annotated, Any, Dict, Optional, Literal
2626

2727
GITHUB_TOKEN = getenv('GITHUB_TOKEN')
28+
TIMEOUT = int(getenv('GITHUB_API_TIMEOUT', '5')) # seconds, configurable via env
2829

2930
# Set up logging for the application
3031
logging.getLogger(__name__)
@@ -94,11 +95,11 @@ def get_pr_diff(self, repo_owner: str, repo_name: str, pr_number: int) -> str:
9495

9596
try:
9697
# Fetch PR details
97-
response = requests.get(f"https://patch-diff.githubusercontent.com/raw/{repo_owner}/{repo_name}/pull/{pr_number}.patch", headers=self._get_headers())
98+
response = requests.get(f"https://patch-diff.githubusercontent.com/raw/{repo_owner}/{repo_name}/pull/{pr_number}.patch", headers=self._get_headers(), timeout=TIMEOUT)
9899
response.raise_for_status()
99100
pr_patch = response.text
100101

101-
logging.info(f"Successfully fetched PR diff/patch")
102+
logging.info("Successfully fetched PR diff/patch")
102103
return pr_patch
103104

104105
except Exception as e:
@@ -126,7 +127,7 @@ def get_pr_content(self, repo_owner: str, repo_name: str, pr_number: int) -> Dic
126127

127128
try:
128129
# Fetch PR details
129-
response = requests.get(pr_url, headers=self._get_headers())
130+
response = requests.get(pr_url, headers=self._get_headers(), timeout=TIMEOUT)
130131
response.raise_for_status()
131132
pr_data = response.json()
132133

@@ -139,8 +140,8 @@ def get_pr_content(self, repo_owner: str, repo_name: str, pr_number: int) -> Dic
139140
'updated_at': pr_data['updated_at'],
140141
'state': pr_data['state']
141142
}
142-
143-
logging.info(f"Successfully fetched PR content")
143+
144+
logging.info("Successfully fetched PR content")
144145
return pr_info
145146

146147
except Exception as e:
@@ -169,11 +170,11 @@ def add_pr_comments(self, repo_owner: str, repo_name: str, pr_number: int, comme
169170

170171
try:
171172
# Add the comment
172-
response = requests.post(comments_url, headers=self._get_headers(), json={'body': comment})
173+
response = requests.post(comments_url, headers=self._get_headers(), json={'body': comment}, timeout=TIMEOUT)
173174
response.raise_for_status()
174175
comment_data = response.json()
175176

176-
logging.info(f"Comment added successfully")
177+
logging.info("Comment added successfully")
177178
return comment_data
178179

179180
except Exception as e:
@@ -204,7 +205,7 @@ def add_inline_pr_comment(self, repo_owner: str, repo_name: str, pr_number: int,
204205

205206
try:
206207
pr_url = self._get_pr_url(repo_owner, repo_name, pr_number)
207-
pr_response = requests.get(pr_url, headers=self._get_headers())
208+
pr_response = requests.get(pr_url, headers=self._get_headers(), timeout=TIMEOUT)
208209
pr_response.raise_for_status()
209210
pr_data = pr_response.json()
210211
commit_id = pr_data['head']['sha']
@@ -217,11 +218,11 @@ def add_inline_pr_comment(self, repo_owner: str, repo_name: str, pr_number: int,
217218
"side": "RIGHT"
218219
}
219220

220-
response = requests.post(review_comments_url, headers=self._get_headers(), json=payload)
221+
response = requests.post(review_comments_url, headers=self._get_headers(), json=payload, timeout=TIMEOUT)
221222
response.raise_for_status()
222223
comment_data = response.json()
223224

224-
logging.info(f"Inline review comment added successfully")
225+
logging.info("Inline review comment added successfully")
225226
return comment_data
226227

227228
except Exception as e:
@@ -253,11 +254,11 @@ def update_pr_description(self, repo_owner: str, repo_name: str, pr_number: int,
253254
response = requests.patch(pr_url, headers=self._get_headers(), json={
254255
'title': new_title,
255256
'body': new_description
256-
})
257+
}, timeout=TIMEOUT)
257258
response.raise_for_status()
258259
pr_data = response.json()
259260

260-
logging.info(f"PR description updated successfully")
261+
logging.info("PR description updated successfully")
261262
return pr_data
262263
except Exception as e:
263264
logging.error(f"Error updating PR description: {str(e)}")
@@ -292,7 +293,7 @@ def list_open_issues_prs(
292293
search_url = f"https://api.github.com/search/issues?q=is:{issue}+is:open+{filtering}:{repo_owner}&per_page={per_page}&page={page}"
293294

294295
try:
295-
response = requests.get(search_url, headers=self._get_headers())
296+
response = requests.get(search_url, headers=self._get_headers(), timeout=TIMEOUT)
296297
response.raise_for_status()
297298
pr_data = response.json()
298299
open_prs = {
@@ -349,11 +350,11 @@ def create_issue(self, repo_owner: str, repo_name: str, title: str, body: str, l
349350
'title': title,
350351
'body': body,
351352
'labels': issue_labels
352-
})
353+
}, timeout=TIMEOUT)
353354
response.raise_for_status()
354355
issue_data = response.json()
355356

356-
logging.info(f"Issue created successfully")
357+
logging.info("Issue created successfully")
357358
return issue_data
358359

359360
except Exception as e:
@@ -386,11 +387,11 @@ def merge_pr(self, repo_owner: str, repo_name: str, pr_number: int, commit_title
386387
'commit_title': commit_title,
387388
'commit_message': commit_message,
388389
'merge_method': merge_method
389-
})
390+
}, timeout=TIMEOUT)
390391
response.raise_for_status()
391392
merge_data = response.json()
392393

393-
logging.info(f"PR merged successfully")
394+
logging.info("PR merged successfully")
394395
return merge_data
395396

396397
except Exception as e:
@@ -427,10 +428,10 @@ def update_issue(self, repo_owner: str, repo_name: str, issue_number: int, title
427428
'body': body,
428429
'labels': labels,
429430
'state': state
430-
})
431+
}, timeout=TIMEOUT)
431432
response.raise_for_status()
432433
issue_data = response.json()
433-
logging.info(f"Issue updated successfully")
434+
logging.info("Issue updated successfully")
434435
return issue_data
435436
except Exception as e:
436437
logging.error(f"Error updating issue: {str(e)}")
@@ -461,11 +462,11 @@ def update_reviews(self, repo_owner: str, repo_name: str, pr_number: int, event:
461462
response = requests.post(reviews_url, headers=self._get_headers(), json={
462463
'body': body,
463464
'event': event
464-
})
465+
}, timeout=TIMEOUT)
465466
response.raise_for_status()
466467
review_data = response.json()
467468

468-
logging.info(f"Review submitted successfully")
469+
logging.info("Review submitted successfully")
469470
return review_data
470471

471472
except Exception as e:
@@ -494,10 +495,10 @@ def update_assignees(self, repo_owner: str, repo_name: str, issue_number: int, a
494495
# Update the assignees
495496
response = requests.patch(issue_url, headers=self._get_headers(), json={
496497
'assignees': assignees
497-
})
498+
}, timeout=TIMEOUT)
498499
response.raise_for_status()
499500
issue_data = response.json()
500-
logging.info(f"Assignees updated successfully")
501+
logging.info("Assignees updated successfully")
501502
return issue_data
502503
except Exception as e:
503504
logging.error(f"Error updating assignees: {str(e)}")
@@ -523,7 +524,7 @@ def get_latest_sha(self, repo_owner: str, repo_name: str) -> Optional[str]:
523524

524525
try:
525526
# Fetch the latest commit
526-
response = requests.get(commits_url, headers=self._get_headers())
527+
response = requests.get(commits_url, headers=self._get_headers(), timeout=TIMEOUT)
527528
response.raise_for_status()
528529
commits_data = response.json()
529530

@@ -568,11 +569,11 @@ def create_tag(self, repo_owner: str, repo_name: str, tag_name: str, message: st
568569
'ref': f'refs/tags/{tag_name}',
569570
'sha': latest_sha,
570571
'message': message
571-
})
572+
}, timeout=TIMEOUT)
572573
response.raise_for_status()
573574
tag_data = response.json()
574575

575-
logging.info(f"Tag created successfully")
576+
logging.info("Tag created successfully")
576577
return tag_data
577578

578579
except Exception as e:
@@ -609,11 +610,11 @@ def create_release(self, repo_owner: str, repo_name: str, tag_name: str, release
609610
'draft': False,
610611
'prerelease': False,
611612
'generate_release_notes': True
612-
})
613+
}, timeout=TIMEOUT)
613614
response.raise_for_status()
614615
release_data = response.json()
615616

616-
logging.info(f"Release created successfully")
617+
logging.info("Release created successfully")
617618
return release_data
618619

619620
except Exception as e:

0 commit comments

Comments
 (0)