Skip to content

Commit 963953e

Browse files
committed
Refactor APIClient to include bearer token for API requests
1 parent a23ab49 commit 963953e

2 files changed

Lines changed: 121 additions & 2 deletions

File tree

penify_hook/api_client.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import requests
44

55
class APIClient:
6-
def __init__(self, api_url, api_token):
6+
def __init__(self, api_url, api_token: str = None, bearer_token: str = None):
77
self.api_url = api_url
88
self.AUTH_TOKEN = api_token
9+
self.BEARER_TOKEN = bearer_token
910

1011
def send_file_for_docstring_generation(self, file_name, content, line_numbers, repo_details = None):
1112
"""Send file content and modified lines to the API and return modified
@@ -127,3 +128,20 @@ def generate_commit_summary(self, git_diff, instruction: str = "", repo_details
127128
print(f"Response: {response.status_code}")
128129
print(f"Error: {response.text}")
129130
return None
131+
132+
def get_api_key(self):
133+
134+
url = self.api_url+"/v1/apiToken/get"
135+
print(url)
136+
response = requests.get(url, headers={"Authorization": f"Bearer {self.BEARER_TOKEN}"}, timeout=60*10)
137+
print(response)
138+
if response.status_code == 200:
139+
response = response.json()
140+
print(response)
141+
return response.get('key')
142+
else:
143+
print(f"Response: {response.status_code}")
144+
print(f"Error: {response.text}")
145+
return None
146+
147+

penify_hook/main.py

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
import json
2+
import random
13
import sys
24
import os
35
import argparse
46
from pathlib import Path
7+
import webbrowser
8+
import http.server
9+
import socketserver
10+
import urllib.parse
11+
from threading import Thread
512

613
from .commit_analyzer import CommitDocGenHook
7-
814
from .folder_analyzer import FolderAnalyzerGenHook
915
from .file_analyzer import FileAnalyzerGenHook
1016
from .api_client import APIClient
@@ -17,6 +23,8 @@
1723
penify-cli -t {token} -gf {git_folder_path}
1824
"""
1925
api_url = 'https://production-gateway.snorkell.ai/api'
26+
dashboard_url = "https://dashboard.penify.dev/auth/localhost/login"
27+
# api_url = 'http://localhost:8000/api'
2028

2129
def install_git_hook(location, token):
2230
"""
@@ -103,6 +111,94 @@ def commit_code(gf_path: str, token: str, message: str, open_terminal: bool):
103111
sys.exit(1)
104112
# You can add actual Git commit logic here using subprocess or GitPython, etc.
105113

114+
def save_credentials(api_key):
115+
"""
116+
Save the token and API keys in the .penify file in the user's home directory.
117+
"""
118+
home_dir = Path.home()
119+
penify_file = home_dir / '.penify'
120+
121+
credentials = {
122+
'api_keys': api_key
123+
}
124+
125+
try:
126+
with open(penify_file, 'w') as f:
127+
json.dump(credentials, f)
128+
print(f"Credentials saved successfully in {penify_file}")
129+
except Exception as e:
130+
print(f"Error saving credentials: {str(e)}")
131+
132+
def login():
133+
"""
134+
Open the login page in a web browser and listen for the redirect URL to capture the token.
135+
"""
136+
137+
# dashboard_url = "http://localhost:8000/auth/localhost/login"
138+
redirect_port = random.randint(30000, 50000)
139+
redirect_url = f"http://localhost:{redirect_port}/callback"
140+
141+
full_login_url = f"{dashboard_url}?redirectUri={urllib.parse.quote(redirect_url)}"
142+
143+
print(f"Opening login page in your default web browser: {full_login_url}")
144+
webbrowser.open(full_login_url)
145+
146+
class TokenHandler(http.server.SimpleHTTPRequestHandler):
147+
def do_GET(self):
148+
query = urllib.parse.urlparse(self.path).query
149+
query_components = urllib.parse.parse_qs(query)
150+
token = query_components.get("token", [None])[0]
151+
152+
if token:
153+
self.send_response(200)
154+
self.send_header("Content-type", "text/html")
155+
self.end_headers()
156+
response = """
157+
<html>
158+
<body>
159+
<h1>Login Successful!</h1>
160+
<p>You can now close this window and return to the CLI.</p>
161+
</body>
162+
</html>
163+
"""
164+
self.wfile.write(response.encode())
165+
print(f"\nLogin successful! Fetching API keys...")
166+
api_key = APIClient(api_url,None, token).get_api_key()
167+
if api_key:
168+
save_credentials(api_key)
169+
print("API keys fetched and saved successfully.")
170+
else:
171+
print("Failed to fetch API keys.")
172+
else:
173+
self.send_response(400)
174+
self.send_header("Content-type", "text/html")
175+
self.end_headers()
176+
response = """
177+
<html>
178+
<body>
179+
<h1>Login Failed</h1>
180+
<p>Please try again.</p>
181+
</body>
182+
</html>
183+
"""
184+
self.wfile.write(response.encode())
185+
print("\nLogin failed. Please try again.")
186+
187+
# Schedule the server shutdown
188+
thread = Thread(target=self.server.shutdown)
189+
thread.daemon = True
190+
thread.start()
191+
192+
def log_message(self, format, *args):
193+
# Suppress log messages
194+
return
195+
196+
with socketserver.TCPServer(("", redirect_port), TokenHandler) as httpd:
197+
print(f"Listening on port {redirect_port} for the redirect...")
198+
httpd.serve_forever()
199+
200+
print("Login process completed. You can now use other commands with your API token.")
201+
106202
def main():
107203
parser = argparse.ArgumentParser(description="Penify CLI tool for managing Git hooks and generating documentation.")
108204

@@ -131,6 +227,9 @@ def main():
131227
commit_parser.add_argument("-m", "--message", required=False, help="Commit message.", default="N/A")
132228
commit_parser.add_argument("-e", "--terminal", required=False, help="Open edit terminal", default="False")
133229

230+
login_parser = subparsers.add_parser("login", help="Log in to Penify and automatically obtain an API token.")
231+
232+
134233
args = parser.parse_args()
135234

136235
if args.subcommand == "install-hook":
@@ -142,6 +241,8 @@ def main():
142241
elif args.subcommand == "commit":
143242
open_terminal = args.terminal.lower() == "true"
144243
commit_code(args.git_folder_path, args.token, args.message, open_terminal)
244+
elif args.subcommand == "login":
245+
login()
145246
else:
146247
parser.print_help()
147248
sys.exit(1)

0 commit comments

Comments
 (0)