Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -17,21 +17,16 @@ import torch
|
|
17 |
import spaces
|
18 |
from accelerate import Accelerator
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
def
|
29 |
-
|
30 |
-
directories = ['logs', 'resolutions', 'repos', input_file, output_directory]
|
31 |
-
for directory in directories:
|
32 |
-
os.makedirs(directory, exist_ok=True)
|
33 |
-
|
34 |
-
log_file = f"logs/github_bot_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
|
35 |
logging.basicConfig(
|
36 |
level=logging.INFO,
|
37 |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
@@ -40,21 +35,18 @@ def initialize_environment(input_file, output_directory):
|
|
40 |
logging.StreamHandler()
|
41 |
]
|
42 |
)
|
43 |
-
|
44 |
-
def handle_exception(exc_type, exc_value, exc_traceback):
|
45 |
-
if issubclass(exc_type, KeyboardInterrupt):
|
46 |
-
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
47 |
-
return
|
48 |
-
logging.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
|
49 |
-
|
50 |
-
sys.excepthook = handle_exception
|
51 |
return logging.getLogger(__name__)
|
52 |
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
|
|
55 |
class GitHubAPI:
|
56 |
-
"""GitHub API handler with rate limiting and error handling"""
|
57 |
-
|
58 |
def __init__(self, token: str):
|
59 |
self.token = token
|
60 |
self.headers = {
|
@@ -64,7 +56,6 @@ class GitHubAPI:
|
|
64 |
self.base_url = "https://api.github.com"
|
65 |
|
66 |
def _check_rate_limit(self) -> bool:
|
67 |
-
"""Check and handle GitHub API rate limits"""
|
68 |
try:
|
69 |
response = requests.get(f"{self.base_url}/rate_limit", headers=self.headers)
|
70 |
response.raise_for_status()
|
@@ -84,7 +75,6 @@ class GitHubAPI:
|
|
84 |
return True
|
85 |
|
86 |
def get_repository(self, owner: str, repo: str) -> Dict:
|
87 |
-
"""Get repository information"""
|
88 |
try:
|
89 |
response = requests.get(f"{self.base_url}/repos/{owner}/{repo}", headers=self.headers)
|
90 |
response.raise_for_status()
|
@@ -97,7 +87,6 @@ class GitHubAPI:
|
|
97 |
raise
|
98 |
|
99 |
def get_issues(self, owner: str, repo: str, state: str = 'open') -> List[Dict]:
|
100 |
-
"""Fetch repository issues"""
|
101 |
if not self._check_rate_limit():
|
102 |
return []
|
103 |
|
@@ -106,25 +95,19 @@ class GitHubAPI:
|
|
106 |
response.raise_for_status()
|
107 |
issues = response.json()
|
108 |
return [issue for issue in issues if 'pull_request' not in issue]
|
109 |
-
except requests.HTTPError as e:
|
110 |
-
logger.error(f"HTTP error fetching issues: {str(e)}")
|
111 |
-
return []
|
112 |
except Exception as e:
|
113 |
logger.error(f"Error fetching issues: {str(e)}")
|
114 |
return []
|
115 |
|
|
|
116 |
class GitHubBot:
|
117 |
-
"""Main GitHub bot implementation"""
|
118 |
-
|
119 |
def __init__(self):
|
120 |
self.github_api = None
|
121 |
|
122 |
def initialize_api(self, token: str):
|
123 |
-
"""Initialize GitHub API with token"""
|
124 |
self.github_api = GitHubAPI(token)
|
125 |
|
126 |
def fetch_issues(self, token: str, owner: str, repo: str) -> List[Dict]:
|
127 |
-
"""Fetch issues from GitHub repository"""
|
128 |
try:
|
129 |
self.initialize_api(token)
|
130 |
return self.github_api.get_issues(owner, repo)
|
@@ -133,14 +116,13 @@ class GitHubBot:
|
|
133 |
return []
|
134 |
|
135 |
def resolve_issue(self, token: str, owner: str, repo: str, issue_number: int, resolution: str, forked_repo: str) -> str:
|
136 |
-
"""Resolve a GitHub issue and submit PR."""
|
137 |
try:
|
138 |
self.initialize_api(token)
|
139 |
self.github_api.get_repository(owner, repo)
|
140 |
|
141 |
# Create resolution file
|
142 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
143 |
-
resolution_file = f"
|
144 |
|
145 |
with open(resolution_file, "w") as f:
|
146 |
f.write(f"# Resolution for Issue #{issue_number}\n\n{resolution}")
|
@@ -238,7 +220,6 @@ custom_css = """
|
|
238 |
"""
|
239 |
|
240 |
def create_gradio_interface(input_file, output_directory):
|
241 |
-
"""Create and configure Gradio interface with custom styling"""
|
242 |
bot = GitHubBot()
|
243 |
|
244 |
with gr.Blocks(css=custom_css, theme=gr.themes.Base()) as demo:
|
@@ -343,10 +324,10 @@ def create_gradio_interface(input_file, output_directory):
|
|
343 |
|
344 |
return demo
|
345 |
|
|
|
346 |
def cleanup():
|
347 |
-
"""Cleanup function for graceful shutdown"""
|
348 |
try:
|
349 |
-
temp_dirs = [
|
350 |
for dir_name in temp_dirs:
|
351 |
if os.path.exists(dir_name):
|
352 |
shutil.rmtree(dir_name)
|
@@ -354,8 +335,8 @@ def cleanup():
|
|
354 |
except Exception as e:
|
355 |
print(f"Error during cleanup: {str(e)}")
|
356 |
|
|
|
357 |
def signal_handler(signum, frame):
|
358 |
-
"""Handle termination signals"""
|
359 |
logger.info(f"Received signal {signum}")
|
360 |
cleanup()
|
361 |
sys.exit(0)
|
@@ -366,11 +347,12 @@ if __name__ == "__main__":
|
|
366 |
signal.signal(signal.SIGINT, signal_handler)
|
367 |
signal.signal(signal.SIGTERM, signal_handler)
|
368 |
|
369 |
-
input_file =
|
370 |
-
output_directory =
|
371 |
|
372 |
# Initialize logger
|
373 |
logger = initialize_environment(input_file, output_directory)
|
374 |
|
|
|
375 |
demo = create_gradio_interface(input_file, output_directory)
|
376 |
demo.launch()
|
|
|
17 |
import spaces
|
18 |
from accelerate import Accelerator
|
19 |
|
20 |
+
# Constants
|
21 |
+
INPUT_DIRECTORY = 'input'
|
22 |
+
OUTPUT_DIRECTORY = 'output'
|
23 |
+
LOGS_DIRECTORY = 'logs'
|
24 |
+
RESOLUTIONS_DIRECTORY = 'resolutions'
|
25 |
+
REPOS_DIRECTORY = 'repos'
|
26 |
+
|
27 |
+
# Set up logging
|
28 |
+
def initialize_logger():
|
29 |
+
log_file = f"{LOGS_DIRECTORY}/github_bot_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
|
|
|
|
|
|
|
|
|
|
|
30 |
logging.basicConfig(
|
31 |
level=logging.INFO,
|
32 |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
|
35 |
logging.StreamHandler()
|
36 |
]
|
37 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
return logging.getLogger(__name__)
|
39 |
|
40 |
+
# Set up environment
|
41 |
+
@spaces.GPU
|
42 |
+
def initialize_environment(input_file, output_directory):
|
43 |
+
directories = [LOGS_DIRECTORY, RESOLUTIONS_DIRECTORY, REPOS_DIRECTORY, input_file, output_directory]
|
44 |
+
for directory in directories:
|
45 |
+
os.makedirs(directory, exist_ok=True)
|
46 |
+
return initialize_logger()
|
47 |
|
48 |
+
# GitHub API handler
|
49 |
class GitHubAPI:
|
|
|
|
|
50 |
def __init__(self, token: str):
|
51 |
self.token = token
|
52 |
self.headers = {
|
|
|
56 |
self.base_url = "https://api.github.com"
|
57 |
|
58 |
def _check_rate_limit(self) -> bool:
|
|
|
59 |
try:
|
60 |
response = requests.get(f"{self.base_url}/rate_limit", headers=self.headers)
|
61 |
response.raise_for_status()
|
|
|
75 |
return True
|
76 |
|
77 |
def get_repository(self, owner: str, repo: str) -> Dict:
|
|
|
78 |
try:
|
79 |
response = requests.get(f"{self.base_url}/repos/{owner}/{repo}", headers=self.headers)
|
80 |
response.raise_for_status()
|
|
|
87 |
raise
|
88 |
|
89 |
def get_issues(self, owner: str, repo: str, state: str = 'open') -> List[Dict]:
|
|
|
90 |
if not self._check_rate_limit():
|
91 |
return []
|
92 |
|
|
|
95 |
response.raise_for_status()
|
96 |
issues = response.json()
|
97 |
return [issue for issue in issues if 'pull_request' not in issue]
|
|
|
|
|
|
|
98 |
except Exception as e:
|
99 |
logger.error(f"Error fetching issues: {str(e)}")
|
100 |
return []
|
101 |
|
102 |
+
# GitHub Bot
|
103 |
class GitHubBot:
|
|
|
|
|
104 |
def __init__(self):
|
105 |
self.github_api = None
|
106 |
|
107 |
def initialize_api(self, token: str):
|
|
|
108 |
self.github_api = GitHubAPI(token)
|
109 |
|
110 |
def fetch_issues(self, token: str, owner: str, repo: str) -> List[Dict]:
|
|
|
111 |
try:
|
112 |
self.initialize_api(token)
|
113 |
return self.github_api.get_issues(owner, repo)
|
|
|
116 |
return []
|
117 |
|
118 |
def resolve_issue(self, token: str, owner: str, repo: str, issue_number: int, resolution: str, forked_repo: str) -> str:
|
|
|
119 |
try:
|
120 |
self.initialize_api(token)
|
121 |
self.github_api.get_repository(owner, repo)
|
122 |
|
123 |
# Create resolution file
|
124 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
125 |
+
resolution_file = f"{RESOLUTIONS_DIRECTORY}/resolution_{issue_number}_{timestamp}.md"
|
126 |
|
127 |
with open(resolution_file, "w") as f:
|
128 |
f.write(f"# Resolution for Issue #{issue_number}\n\n{resolution}")
|
|
|
220 |
"""
|
221 |
|
222 |
def create_gradio_interface(input_file, output_directory):
|
|
|
223 |
bot = GitHubBot()
|
224 |
|
225 |
with gr.Blocks(css=custom_css, theme=gr.themes.Base()) as demo:
|
|
|
324 |
|
325 |
return demo
|
326 |
|
327 |
+
# Cleanup function
|
328 |
def cleanup():
|
|
|
329 |
try:
|
330 |
+
temp_dirs = [REPOS_DIRECTORY]
|
331 |
for dir_name in temp_dirs:
|
332 |
if os.path.exists(dir_name):
|
333 |
shutil.rmtree(dir_name)
|
|
|
335 |
except Exception as e:
|
336 |
print(f"Error during cleanup: {str(e)}")
|
337 |
|
338 |
+
# Signal handler
|
339 |
def signal_handler(signum, frame):
|
|
|
340 |
logger.info(f"Received signal {signum}")
|
341 |
cleanup()
|
342 |
sys.exit(0)
|
|
|
347 |
signal.signal(signal.SIGINT, signal_handler)
|
348 |
signal.signal(signal.SIGTERM, signal_handler)
|
349 |
|
350 |
+
input_file = INPUT_DIRECTORY
|
351 |
+
output_directory = OUTPUT_DIRECTORY
|
352 |
|
353 |
# Initialize logger
|
354 |
logger = initialize_environment(input_file, output_directory)
|
355 |
|
356 |
+
# Create Gradio interface
|
357 |
demo = create_gradio_interface(input_file, output_directory)
|
358 |
demo.launch()
|