acecalisto3 commited on
Commit
5be1db9
·
verified ·
1 Parent(s): 0ffd4a1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +100 -156
app.py CHANGED
@@ -14,48 +14,6 @@ from urllib.parse import urlparse, quote
14
  import webbrowser
15
  import spaces
16
 
17
- device = "cuda"
18
-
19
- @spaces.GPU()
20
- def stream_chat(
21
- message: str,
22
- history: list,
23
- system_prompt: str,
24
- temperature: float = 0.8,
25
- max_new_tokens: int = 1024,
26
- top_p: float = 1.0,
27
- top_k: int = 20,
28
- penalty: float = 1.2,
29
- ):
30
- print(f'message: {message}')
31
- print(f'history: {history}')
32
-
33
- conversation = [
34
- {"role": "system", "content": system_prompt}
35
- ]
36
- for prompt, answer in history:
37
- conversation.extend([
38
- {"role": "user", "content": prompt},
39
- {"role": "assistant", "content": answer},
40
- ])
41
-
42
- conversation.append({"role": "user", "content": message})
43
-
44
- input_ids = tokenizer.apply_chat_template(conversation, add_generation_prompt=True, return_tensors="pt").to(model.device)
45
-
46
- streamer = TextIteratorStreamer(tokenizer, timeout=60.0, skip_prompt=True, skip_special_tokens=True)
47
-
48
- generate_kwargs = dict(
49
- input_ids=input_ids,
50
- max_new_tokens=max_new_tokens,
51
- do_sample=temperature != 0,
52
- top_p=top_p,
53
- top_k=top_k,
54
- temperature=temperature,
55
- eos_token_id=[128001, 128008, 128009],
56
- streamer=streamer,
57
- )
58
-
59
  # Constants
60
  INPUT_DIRECTORY = 'input'
61
  OUTPUT_DIRECTORY = 'output'
@@ -63,14 +21,8 @@ LOGS_DIRECTORY = 'logs'
63
  RESOLUTIONS_DIRECTORY = 'resolutions'
64
  REPOS_DIRECTORY = 'repos'
65
 
66
- # Set up environment
67
- def initialize_environment(input_file, output_directory):
68
- directories = [LOGS_DIRECTORY, RESOLUTIONS_DIRECTORY, REPOS_DIRECTORY, input_file, output_directory]
69
- for directory in directories:
70
- os.makedirs(directory, exist_ok=True)
71
-
72
  # Set up logging
73
- def initialize_logger():
74
  log_file = f"{LOGS_DIRECTORY}/github_bot_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
75
  logging.basicConfig(
76
  level=logging.INFO,
@@ -83,7 +35,12 @@ def initialize_logger():
83
  return logging.getLogger(__name__)
84
 
85
  # Initialize environment and logger
86
- initialize_environment(INPUT_DIRECTORY, OUTPUT_DIRECTORY)
 
 
 
 
 
87
  logger = initialize_logger() # Initialize logger globally
88
 
89
  # GitHub API handler
@@ -107,12 +64,12 @@ class GitHubAPI:
107
  if remaining < 10:
108
  wait_time = max(0, reset_time - int(time.time()))
109
  if wait_time > 0:
110
- logger.warning(f"Rate limit nearly exceeded. Waiting {wait_time} seconds...")
111
  time.sleep(wait_time)
112
  return False
113
  return True
114
  except requests.exceptions.RequestException as e:
115
- logger.error(f"Error checking rate limit: {str(e)}")
116
  return True
117
 
118
  def get_repository(self, owner: str, repo: str) -> Dict:
@@ -121,7 +78,7 @@ class GitHubAPI:
121
  response.raise_for_status()
122
  return response.json()
123
  except requests.HTTPError as e:
124
- logger.error(f"HTTP error getting repository info: {str(e)}")
125
  raise
126
  except Exception as e:
127
  logger.error(f"Error getting repository info: {str(e)}")
@@ -137,7 +94,7 @@ class GitHubAPI:
137
  issues = response.json()
138
  return [issue for issue in issues if 'pull_request' not in issue]
139
  except Exception as e:
140
- logger.error(f"Error fetching issues: {str(e)}")
141
  return []
142
 
143
  # GitHub Bot
@@ -153,7 +110,7 @@ class GitHubBot:
153
  self.initialize_api(token)
154
  return self.github_api.get_issues(owner, repo)
155
  except Exception as e:
156
- logger.error(f"Error fetching issues: {str(e)}")
157
  return []
158
 
159
  def resolve_issue(self, token: str, owner: str, repo: str, issue_number: int, resolution: str, forked_repo: str) -> str:
@@ -175,7 +132,7 @@ class GitHubBot:
175
  os.chdir('/tmp/' + forked_repo.split('/')[-1])
176
 
177
  # Assuming manual intervention now
178
- input(" Apply the fix manually and stage the changes (press ENTER)? ")
179
 
180
  # Commit and push the modifications
181
  subprocess.run(['git', 'add', '.'], check=True)
@@ -188,7 +145,7 @@ class GitHubBot:
188
  return f"Resolution saved: {resolution_file}"
189
 
190
  except Exception as e:
191
- error_msg = f"Error resolving issue: {str(e)}"
192
  logger.error(error_msg)
193
  return error_msg
194
 
@@ -259,18 +216,6 @@ def extract_info(url):
259
  except Exception as e:
260
  return str(e)
261
 
262
- def submit_issue(token, repo_url, issue_number, resolution, forked_repo_url):
263
- try:
264
- parts = repo_url.split('/')
265
- if len(parts) < 2:
266
- raise ValueError("Repository URL is not in the correct format. Expected format: 'owner/repo'.")
267
-
268
- owner, repo = parts[-2], parts[-1]
269
- result = bot.resolve_issue(token, owner, repo, issue_number, resolution, forked_repo_url)
270
- return result
271
- except Exception as e:
272
- return str(e)
273
-
274
  # HTML and CSS integration
275
  custom_html = """
276
  <!DOCTYPE html>
@@ -290,7 +235,7 @@ custom_html = """
290
  }
291
  .card {
292
  border-radius: 1.5rem;
293
- box-shadow: 0 15px 25px rgba(0, 0, 0, 0.2);
294
  margin-bottom: 20px;
295
  }
296
  .input, .select, .textarea {
@@ -330,7 +275,7 @@ custom_html = """
330
  </style>
331
  </head>
332
  <body class="bg-gray-900">
333
- <div class="container mx-auto p-4" >
334
  <h1 class="text-4xl md:text-5xl font-extrabold text-center mb-8">GitHub Issue Manager</h1>
335
  <!-- GitHub Token & Repo URL -->
336
  <div class="card bg-gray-800 p-8">
@@ -351,7 +296,7 @@ custom_html = """
351
  <div class="card bg-gray-800 p-8">
352
  <div class="flex justify-between gap-4">
353
  <button class="btn btn-primary" id="fetch-issues">Fetch Issues</button>
354
- <select class="select select-primary w-full max-w-xs" id="issue-dropdown" >
355
  <option disabled selected>Select Issue</option>
356
  </select>
357
  </div>
@@ -372,7 +317,7 @@ custom_html = """
372
  </div>
373
  </div>
374
  <!-- Output Area -->
375
- <div class="card bg-gray-800 p-8 mt-4" >
376
  <label class="label">
377
  <span class="label-text">Output</span>
378
  </label>
@@ -394,8 +339,8 @@ custom_html = """
394
  <script>
395
  const githubTokenInput = document.getElementById('github-token');
396
  const repoUrlInput = document.getElementById('repo-url');
397
- const fetchIssuesButton = document.getElementById('fetch-issues');
398
- const issueDropdown = document.getElementById('issue-dropdown');
399
  const resolutionTextarea = document.getElementById('resolution-textarea');
400
  const forkedRepoUrlInput = document.getElementById('forked-repo-url');
401
  const resolveIssueButton = document.getElementById('resolve-issue');
@@ -404,98 +349,98 @@ custom_html = """
404
  const extractInfoButton = document.getElementById('extract-info');
405
 
406
  fetchIssuesButton.addEventListener('click', async () => {
407
- const token = githubTokenInput.value;
408
- const repoUrl = repoUrlInput.value;
409
- if (!token || !repoUrl) {
410
- outputTextarea.value = "Please provide both GitHub Token and Repository URL.";
411
- return;
412
- }
413
- try {
414
- const response = await fetch('/fetch_issues', {
415
- method: 'POST',
416
- headers: {
417
- 'Content-Type': 'application/json',
418
- },
419
- body: JSON.stringify({ token: token, repoUrl: repoUrl }),
420
- });
421
- if (!response.ok) {
422
- throw new Error(`HTTP error! status: ${response.status}`);
423
  }
424
- const data = await response.json();
425
- if (data.error) {
426
- outputTextarea.value = data.error;
427
- } else {
428
- issueDropdown.innerHTML = '';
429
- data.issues.forEach(issue => {
430
- const option = document.createElement('option');
431
- option.value = issue.number;
432
- option.text = `${issue.number}: ${issue.title}`;
433
- issueDropdown.add(option);
434
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  }
436
- } catch (error) {
437
- outputTextarea.value = `Error fetching issues: ${error.message}`;
438
- }
439
  });
440
 
441
  resolveIssueButton.addEventListener('click', async () => {
442
- const token = githubTokenInput.value;
443
- const repoUrl = repoUrlInput.value;
444
- const issueNumber = issueDropdown.value;
445
- const resolution = resolutionTextarea.value;
446
- const forkedRepoUrl = forkedRepoUrlInput.value;
447
-
448
- if (!token || !repoUrl || !issueNumber || !resolution) {
449
- outputTextarea.value ="Please provide all required fields.";
450
- return;
451
- }
452
- try {
453
- const response = await fetch('/resolve_issue', {
454
- method: 'POST',
455
- headers: {
456
- 'Content-Type': 'application/json',
457
- },
458
- body: JSON.stringify({ token: token, repoUrl: repoUrl, issueNumber: issueNumber, resolution: resolution, forkedRepoUrl: forkedRepoUrl }),
459
- });
460
- if (!response.ok) {
461
- throw new Error(`HTTP error! status: ${response.status}`);
462
  }
463
- const data = await response.json();
464
- if (data.error) {
465
- outputTextarea.value = data.error;
466
- } else {
467
- outputTextarea.value = data.result;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  }
469
- } catch (error) {
470
- outputTextarea.value = `Error resolving issue: ${error.message}`;
471
- }
472
  });
 
473
  extractInfoButton.addEventListener('click', async () => {
474
- const url = urlTextbox.value;
475
- if (!url) {
476
- outputTextarea.value = "Please provide a URL.";
477
- return;
478
- }
479
- try {
480
- const response = await fetch('/extract_info', {
481
- method: 'POST',
482
- headers: {
483
- 'Content-Type': 'application/json',
484
- },
485
- body: JSON.stringify({ url: url }),
486
- });
487
- if (!response.ok) {
488
- throw new Error(`HTTP error! status: ${response.status}`);
489
  }
490
- const data = await response.json();
491
- if (data.error) {
492
- outputTextarea.value = data.error;
493
- } else {
494
- outputTextarea.value = JSON.stringify(data, null, 2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  }
496
- } catch (error) {
497
- outputTextarea.value = `Error extracting info: ${error.message}`;
498
- }
499
  });
500
  </script>
501
  </body>
@@ -505,7 +450,6 @@ custom_html = """
505
  def create_gradio_interface():
506
  with gr.Blocks(css=None, theme=None) as demo:
507
  gr.HTML(custom_html)
508
-
509
  return demo
510
 
511
  # Cleanup function
 
14
  import webbrowser
15
  import spaces
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  # Constants
18
  INPUT_DIRECTORY = 'input'
19
  OUTPUT_DIRECTORY = 'output'
 
21
  RESOLUTIONS_DIRECTORY = 'resolutions'
22
  REPOS_DIRECTORY = 'repos'
23
 
 
 
 
 
 
 
24
  # Set up logging
25
+ def initialize_logger() -> logging.Logger:
26
  log_file = f"{LOGS_DIRECTORY}/github_bot_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
27
  logging.basicConfig(
28
  level=logging.INFO,
 
35
  return logging.getLogger(__name__)
36
 
37
  # Initialize environment and logger
38
+ def initialize_environment():
39
+ directories = [LOGS_DIRECTORY, RESOLUTIONS_DIRECTORY, REPOS_DIRECTORY, INPUT_DIRECTORY, OUTPUT_DIRECTORY]
40
+ for directory in directories:
41
+ os.makedirs(directory, exist_ok=True)
42
+
43
+ initialize_environment()
44
  logger = initialize_logger() # Initialize logger globally
45
 
46
  # GitHub API handler
 
64
  if remaining < 10:
65
  wait_time = max(0, reset_time - int(time.time()))
66
  if wait_time > 0:
67
+ logger.warning(f"Rate limit nearly exceeded. Waiting {wait_time} seconds before retrying...")
68
  time.sleep(wait_time)
69
  return False
70
  return True
71
  except requests.exceptions.RequestException as e:
72
+ logger.error(f"Error checking rate limit: {str(e)}. Retrying...")
73
  return True
74
 
75
  def get_repository(self, owner: str, repo: str) -> Dict:
 
78
  response.raise_for_status()
79
  return response.json()
80
  except requests.HTTPError as e:
81
+ logger.error(f"HTTP error getting repository info for {owner}/{repo}: {str(e)}. Please check the repository details.")
82
  raise
83
  except Exception as e:
84
  logger.error(f"Error getting repository info: {str(e)}")
 
94
  issues = response.json()
95
  return [issue for issue in issues if 'pull_request' not in issue]
96
  except Exception as e:
97
+ logger.error(f"Error fetching issues for repository {owner}/{repo}: {str(e)}. Please verify the repository and token.")
98
  return []
99
 
100
  # GitHub Bot
 
110
  self.initialize_api(token)
111
  return self.github_api.get_issues(owner, repo)
112
  except Exception as e:
113
+ logger.error(f"Error fetching issues for repository {owner}/{repo}: {str(e)}")
114
  return []
115
 
116
  def resolve_issue(self, token: str, owner: str, repo: str, issue_number: int, resolution: str, forked_repo: str) -> str:
 
132
  os.chdir('/tmp/' + forked_repo.split('/')[-1])
133
 
134
  # Assuming manual intervention now
135
+ input("Apply the fix manually and stage the changes (press ENTER)? ")
136
 
137
  # Commit and push the modifications
138
  subprocess.run(['git', 'add', '.'], check=True)
 
145
  return f"Resolution saved: {resolution_file}"
146
 
147
  except Exception as e:
148
+ error_msg = f"Error resolving issue #{issue_number} in repository {owner}/{repo}: {str(e)}"
149
  logger.error(error_msg)
150
  return error_msg
151
 
 
216
  except Exception as e:
217
  return str(e)
218
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  # HTML and CSS integration
220
  custom_html = """
221
  <!DOCTYPE html>
 
235
  }
236
  .card {
237
  border-radius: 1.5rem;
238
+ box-shadow: 0 15px 25px rgba (0, 0, 0, 0.2);
239
  margin-bottom: 20px;
240
  }
241
  .input, .select, .textarea {
 
275
  </style>
276
  </head>
277
  <body class="bg-gray-900">
278
+ <div class="container mx-auto p-4">
279
  <h1 class="text-4xl md:text-5xl font-extrabold text-center mb-8">GitHub Issue Manager</h1>
280
  <!-- GitHub Token & Repo URL -->
281
  <div class="card bg-gray-800 p-8">
 
296
  <div class="card bg-gray-800 p-8">
297
  <div class="flex justify-between gap-4">
298
  <button class="btn btn-primary" id="fetch-issues">Fetch Issues</button>
299
+ <select class="select select-primary w-full max-w-xs" id="issue-dropdown">
300
  <option disabled selected>Select Issue</option>
301
  </select>
302
  </div>
 
317
  </div>
318
  </div>
319
  <!-- Output Area -->
320
+ <div class="card bg-gray-800 p-8 mt-4">
321
  <label class="label">
322
  <span class="label-text">Output</span>
323
  </label>
 
339
  <script>
340
  const githubTokenInput = document.getElementById('github-token');
341
  const repoUrlInput = document.getElementById('repo-url');
342
+ const fetchIssuesButton = document.getElementById('fetch-issues');
343
+ const issueDropdown = document.getElementById('issue-dropdown');
344
  const resolutionTextarea = document.getElementById('resolution-textarea');
345
  const forkedRepoUrlInput = document.getElementById('forked-repo-url');
346
  const resolveIssueButton = document.getElementById('resolve-issue');
 
349
  const extractInfoButton = document.getElementById('extract-info');
350
 
351
  fetchIssuesButton.addEventListener('click', async () => {
352
+ const token = githubTokenInput.value;
353
+ const repoUrl = repoUrlInput.value;
354
+ if (!token || !repoUrl) {
355
+ outputTextarea.value = "Please provide both GitHub Token and Repository URL.";
356
+ return;
 
 
 
 
 
 
 
 
 
 
 
357
  }
358
+ try {
359
+ const response = await fetch('/fetch-issues', {
360
+ method: 'POST',
361
+ headers: {
362
+ 'Content-Type': 'application/json',
363
+ },
364
+ body: JSON.stringify({ githubToken: token, repoUrl: repoUrl }),
 
 
 
365
  });
366
+ if (!response.ok) {
367
+ throw new Error(`HTTP error! status: ${response.status}`);
368
+ }
369
+ const data = await response.json();
370
+ if (data.error) {
371
+ outputTextarea.value = data.error;
372
+ } else {
373
+ issueDropdown.innerHTML = '';
374
+ data.issues.forEach(issue => {
375
+ const option = document.createElement('option');
376
+ option.value = issue.number;
377
+ option.text = `${issue.number}: ${issue.title}`;
378
+ issueDropdown.add(option);
379
+ });
380
+ }
381
+ } catch (error) {
382
+ outputTextarea.value = `Error fetching issues: ${error.message}`;
383
  }
 
 
 
384
  });
385
 
386
  resolveIssueButton.addEventListener('click', async () => {
387
+ const token = githubTokenInput.value;
388
+ const repoUrl = repoUrlInput.value;
389
+ const issueNumber = issueDropdown.value;
390
+ const resolution = resolutionTextarea.value;
391
+ const forkedRepoUrl = forkedRepoUrlInput.value;
392
+ if (!token || !repoUrl || !issueNumber || !resolution) {
393
+ outputTextarea.value = "Please provide all required fields.";
394
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
395
  }
396
+ try {
397
+ const response = await fetch('/resolve-issue', {
398
+ method: 'POST',
399
+ headers: {
400
+ 'Content-Type': 'application/json',
401
+ },
402
+ body: JSON.stringify({ githubToken: token, repoUrl: repoUrl, issueNumber: issueNumber, resolution: resolution, forkedRepoUrl: forkedRepoUrl }),
403
+ });
404
+ if (!response.ok) {
405
+ throw new Error(`HTTP error! status: ${response.status}`);
406
+ }
407
+ const data = await response.json();
408
+ if (data.error) {
409
+ outputTextarea.value = data.error;
410
+ } else {
411
+ outputTextarea.value = data.output;
412
+ }
413
+ } catch (error) {
414
+ outputTextarea.value = `Error resolving issue: ${error.message}`;
415
  }
 
 
 
416
  });
417
+
418
  extractInfoButton.addEventListener('click', async () => {
419
+ const url = urlTextbox.value;
420
+ if (!url) {
421
+ outputTextarea.value = "Please provide a URL.";
422
+ return;
 
 
 
 
 
 
 
 
 
 
 
423
  }
424
+ try {
425
+ const response = await fetch('/extract-info', {
426
+ method: 'POST',
427
+ headers: {
428
+ 'Content-Type': 'application/json',
429
+ },
430
+ body: JSON.stringify({ url: url }),
431
+ });
432
+ if (!response.ok) {
433
+ throw new Error(`HTTP error! status: ${response.status}`);
434
+ }
435
+ const data = await response.json();
436
+ if (data.error) {
437
+ outputTextarea.value = data.error;
438
+ } else {
439
+ outputTextarea.value = JSON.stringify(data, null, 2);
440
+ }
441
+ } catch (error) {
442
+ outputTextarea.value = `Error extracting info: ${error.message}`;
443
  }
 
 
 
444
  });
445
  </script>
446
  </body>
 
450
  def create_gradio_interface():
451
  with gr.Blocks(css=None, theme=None) as demo:
452
  gr.HTML(custom_html)
 
453
  return demo
454
 
455
  # Cleanup function