Skip to content

Commit f081491

Browse files
Generated Documentation (#50)
Co-authored-by: penify-dev[bot] <146478655+penify-dev[bot]@users.noreply.github.com>
1 parent e083e5c commit f081491

19 files changed

Lines changed: 900 additions & 84 deletions

penify_hook/api_client.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ def generate_commit_summary(self, git_diff, instruction: str = "", repo_details
6363
6464
Args:
6565
git_diff (str): The git diff of the commit.
66-
instruction (str?): Additional instruction for the commit. Defaults to "".
67-
repo_details (dict?): Details of the git repository. Defaults to None.
68-
jira_context (dict?): JIRA issue details to enhance the commit summary. Defaults to None.
66+
instruction (str??): Additional instruction for the commit. Defaults to "".
67+
repo_details (dict??): Details of the git repository. Defaults to None.
68+
jira_context (dict??): JIRA issue details to enhance the commit summary. Defaults to None.
6969
7070
Returns:
7171
dict: The response from the API if the request is successful, None otherwise.
@@ -102,10 +102,11 @@ def generate_commit_summary(self, git_diff, instruction: str = "", repo_details
102102
def get_supported_file_types(self) -> list[str]:
103103
"""Retrieve the supported file types from the API.
104104
105-
This function sends a request to the API to obtain a list of supported
106-
file types. If the API responds successfully, it returns the list of
107-
supported file types. If the API call fails, it returns a default list
108-
of common file types.
105+
This function sends a request to the API endpoint
106+
`/v1/file/supported_languages` to obtain a list of supported file types.
107+
If the API call is successful (status code 200), it parses the JSON
108+
response and returns the list of supported file types. If the API call
109+
fails, it returns a default list of common file types.
109110
110111
Returns:
111112
list[str]: A list of supported file types, either from the API or a default set.
@@ -143,11 +144,11 @@ def generate_commit_summary_with_llm(self, diff, message, generate_description:
143144
return self.generate_commit_summary(diff, message, repo_details, jira_context)
144145

145146
def get_api_key(self):
146-
"""Get an API key from the specified URL.
147+
"""Fetch an API key from a specified URL.
147148
148-
It constructs a request to fetch an API token using a Bearer token in
149-
the headers. The function handles the response and returns the API key
150-
if successful, or `None` otherwise.
149+
This function sends a GET request to retrieve an API token using a
150+
Bearer token in the headers. It handles the response and returns the API
151+
key if the request is successful, or `None` otherwise.
151152
152153
Returns:
153154
str: The API key if the request is successful, `None` otherwise.

penify_hook/commands/auth_commands.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
from ..api_client import APIClient
1010

1111
def save_credentials(api_key):
12-
"""
13-
Save the token and API keys in the .penify file in the user's home directory.
12+
"""Save or update the API keys in the .penify file in the user's home
13+
directory.
14+
15+
Args:
16+
api_key (str): The new API key to be saved or updated.
17+
18+
Returns:
19+
bool: if the credentials were successfully saved, False otherwise.
1420
"""
1521
home_dir = Path.home()
1622
penify_file = home_dir / '.penify'
@@ -35,8 +41,20 @@ def save_credentials(api_key):
3541
return False
3642

3743
def login(api_url, dashboard_url):
38-
"""
39-
Open the login page in a web browser and listen for the redirect URL to capture the token.
44+
"""Open the login page in a web browser and listen for the redirect URL to
45+
capture the token.
46+
47+
This function generates a random redirect port, constructs the full
48+
login URL with the provided dashboard URL, opens the login page in the
49+
default web browser, and sets up a simple HTTP server to listen for the
50+
redirect. Upon receiving the redirect, it extracts the token from the
51+
query parameters, fetches API keys using the token, saves them if
52+
successful, and handles login failures by notifying the user.
53+
54+
Args:
55+
api_url (str): The URL of the API service to fetch API keys.
56+
dashboard_url (str): The URL of the dashboard where the user will be redirected after logging
57+
in.
4058
"""
4159
redirect_port = random.randint(30000, 50000)
4260
redirect_url = f"http://localhost:{redirect_port}/callback"
@@ -48,6 +66,16 @@ def login(api_url, dashboard_url):
4866

4967
class TokenHandler(http.server.SimpleHTTPRequestHandler):
5068
def do_GET(self):
69+
"""Handle a GET request to process login token and redirect or display
70+
error message.
71+
72+
This method processes the incoming GET request, extracts the token from
73+
the query string, and performs actions based on whether the token is
74+
present. If the token is valid, it redirects the user to the Penify
75+
dashboard and fetches API keys if successful. If the token is invalid,
76+
it displays an error message.
77+
"""
78+
5179
query = urllib.parse.urlparse(self.path).query
5280
query_components = urllib.parse.parse_qs(query)
5381
token = query_components.get("token", [None])[0]

penify_hook/commands/commit_commands.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,27 @@
88
def commit_code(api_url, token, message, open_terminal, generate_description,
99
llm_model=None, llm_api_base=None, llm_api_key=None,
1010
jira_url=None, jira_user=None, jira_api_token=None):
11-
"""
12-
Enhance Git commits with AI-powered commit messages.
11+
"""Enhance Git commits with AI-powered commit messages.
12+
13+
This function allows for the generation of enhanced commit messages
14+
using natural language processing models and optionally integrates with
15+
JIRA for additional context. It processes the current Git folder to find
16+
relevant files and generates a detailed commit message based on the
17+
provided parameters.
18+
19+
Args:
20+
api_url (str): URL of the API endpoint.
21+
token (str): Authentication token for the API.
22+
message (str): Initial commit message provided by the user.
23+
open_terminal (bool): Whether to open the terminal after committing.
24+
generate_description (bool): Whether to generate a detailed description in the commit message.
25+
llm_model (str?): The language model to use for generating the commit message. Defaults to
26+
None.
27+
llm_api_base (str?): Base URL of the LLM API. Defaults to None.
28+
llm_api_key (str?): API key for accessing the LLM service. Defaults to None.
29+
jira_url (str?): URL of the JIRA instance. Defaults to None.
30+
jira_user (str?): Username for authenticating with JIRA. Defaults to None.
31+
jira_api_token (str?): API token for accessing JIRA. Defaults to None.
1332
"""
1433

1534
from penify_hook.ui_utils import print_error
@@ -79,6 +98,18 @@ def commit_code(api_url, token, message, open_terminal, generate_description,
7998

8099

81100
def setup_commit_parser(parser):
101+
"""Generates a parser for setting up a command to generate smart commit
102+
messages.
103+
104+
This function sets up an argument parser that can be used to generate
105+
commit messages with contextual information. It allows users to specify
106+
options such as including a message, opening an edit terminal before
107+
committing, and generating a detailed commit message.
108+
109+
Args:
110+
parser (argparse.ArgumentParser): The ArgumentParser object to be configured.
111+
"""
112+
82113
commit_parser_description = """
83114
It generates smart commit messages. By default, it will just generate just the Title of the commit message.
84115
1. If you have not configured LLM, it will give an error. You either need to configure LLM or use the API key.
@@ -95,6 +126,19 @@ def setup_commit_parser(parser):
95126
parser.add_argument("-d", "--description", action="store_false", help="It will generate commit message with title and description.", default=False)
96127

97128
def handle_commit(args):
129+
"""Handle the commit functionality by processing arguments and invoking the
130+
appropriate commands.
131+
132+
This function processes the provided command-line arguments to configure
133+
settings for commit operations, including LLM (Language Model) and Jira
134+
configurations. It then calls the `commit_code` function with these
135+
configurations to perform the actual commit operation.
136+
137+
Args:
138+
args (argparse.Namespace): The parsed command-line arguments containing options like terminal,
139+
description, message, etc.
140+
"""
141+
98142
from penify_hook.commands.commit_commands import commit_code
99143
from penify_hook.commands.config_commands import get_jira_config, get_llm_config, get_token
100144
from penify_hook.constants import API_URL

penify_hook/commands/config_commands.py

Lines changed: 113 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@
1212

1313

1414
def get_penify_config() -> Path:
15-
"""
16-
Get the home directory for the .penify configuration file.
17-
This function searches for the .penify file in the current directory
18-
and its parent directories until it finds it or reaches the home directory.
15+
"""Get the home directory for the .penify configuration file.
16+
17+
This function searches for the `.penify` file in the current directory
18+
and its parent directories until it finds it or reaches the home
19+
directory. If not found, it creates the `.penify` directory and an empty
20+
`config.json` file.
21+
22+
Returns:
23+
Path: The path to the `config.json` file within the `.penify` directory.
1924
"""
2025
current_dir = os.getcwd()
2126
home_dir = recursive_search_git_folder(current_dir)
@@ -43,8 +48,19 @@ def get_penify_config() -> Path:
4348

4449

4550
def save_llm_config(model, api_base, api_key):
46-
"""
47-
Save LLM configuration settings in the .penify file.
51+
"""Save LLM configuration settings in the .penify file.
52+
53+
It reads the existing configuration from the .penify file if it exists,
54+
updates or adds the LLM configuration with the provided model, API base,
55+
and API key, and then writes the updated configuration back to the file.
56+
57+
Args:
58+
model (str): The name of the language model.
59+
api_base (str): The base URL for the API.
60+
api_key (str): The API key for authentication.
61+
62+
Returns:
63+
bool: True if the LLM configuration was successfully saved, False otherwise.
4864
"""
4965

5066
penify_file = get_penify_config()
@@ -75,8 +91,19 @@ def save_llm_config(model, api_base, api_key):
7591
return False
7692

7793
def save_jira_config(url, username, api_token):
78-
"""
79-
Save JIRA configuration settings in the .penify file.
94+
"""Save JIRA configuration settings in the .penify file.
95+
96+
This function reads existing JIRA configuration from the .penify file,
97+
updates or adds new JIRA configuration details, and writes it back to
98+
the file.
99+
100+
Args:
101+
url (str): The URL of the JIRA instance.
102+
username (str): The username for accessing the JIRA instance.
103+
api_token (str): The API token used for authentication.
104+
105+
Returns:
106+
bool: True if the configuration was successfully saved, False otherwise.
80107
"""
81108
from penify_hook.utils import recursive_search_git_folder
82109

@@ -108,8 +135,15 @@ def save_jira_config(url, username, api_token):
108135
return False
109136

110137
def get_llm_config():
111-
"""
112-
Get LLM configuration from the .penify file.
138+
"""Retrieve LLM configuration from the .penify file.
139+
140+
This function reads the .penify configuration file and extracts the LLM
141+
settings. If the file does not exist or contains invalid JSON, it
142+
returns an empty dictionary.
143+
144+
Returns:
145+
dict: A dictionary containing the LLM configuration, or an empty dictionary if
146+
the file is missing or invalid.
113147
"""
114148
config_file = get_penify_config()
115149
if config_file.exists():
@@ -123,8 +157,15 @@ def get_llm_config():
123157
return {}
124158

125159
def get_jira_config():
126-
"""
127-
Get JIRA configuration from the .penify file.
160+
"""Get JIRA configuration from the .penify file.
161+
162+
This function reads the JIRA configuration from a JSON file specified in
163+
the .penify file. If the .penify file exists and contains valid JSON
164+
with a 'jira' key, it returns the corresponding configuration.
165+
Otherwise, it returns an empty dictionary.
166+
167+
Returns:
168+
dict: The JIRA configuration or an empty dictionary if not found or invalid.
128169
"""
129170
config_file = get_penify_config()
130171
if config_file.exists():
@@ -138,8 +179,16 @@ def get_jira_config():
138179
return {}
139180

140181
def config_llm_web():
141-
"""
142-
Open a web browser interface for configuring LLM settings.
182+
"""Open a web browser interface for configuring LLM settings.
183+
184+
This function starts a temporary HTTP server that serves an HTML
185+
template for configuring Large Language Model (LLM) settings. It handles
186+
GET and POST requests to retrieve the current configuration, save new
187+
configurations, and suppress log messages. The server runs on a random
188+
port between 30000 and 50000, and it is accessible via a URL like
189+
http://localhost:<redirect_port>. The function opens this URL in the
190+
default web browser for configuration. Once configured, the server shuts
191+
down.
143192
"""
144193
redirect_port = random.randint(30000, 50000)
145194
server_url = f"http://localhost:{redirect_port}"
@@ -148,6 +197,15 @@ def config_llm_web():
148197

149198
class ConfigHandler(http.server.SimpleHTTPRequestHandler):
150199
def do_GET(self):
200+
"""Handle HTTP GET requests.
201+
202+
This function processes incoming GET requests and sends appropriate
203+
responses based on the requested path. It serves an HTML template for
204+
the root path ("/") and returns a JSON response with the current LLM
205+
configuration for the "/get_config" path. For any other paths, it
206+
returns a "Not Found" error.
207+
"""
208+
151209
if self.path == "/":
152210
self.send_response(200)
153211
self.send_header("Content-type", "text/html")
@@ -189,6 +247,17 @@ def do_GET(self):
189247
self.wfile.write(b"Not Found")
190248

191249
def do_POST(self):
250+
"""Handle POST requests on the /save endpoint.
251+
252+
This method processes incoming POST requests to save language model
253+
configuration data. It extracts the necessary parameters from the
254+
request body, saves the configuration using the provided details, and
255+
then schedules the server to shut down after a successful save.
256+
257+
Args:
258+
self (HTTPRequestHandler): The instance of the HTTPRequestHandler class handling the request.
259+
"""
260+
192261
if self.path == "/save":
193262
content_length = int(self.headers['Content-Length'])
194263
post_data = self.rfile.read(content_length)
@@ -240,8 +309,13 @@ def log_message(self, format, *args):
240309
print("Configuration completed.")
241310

242311
def config_jira_web():
243-
"""
244-
Open a web browser interface for configuring JIRA settings.
312+
"""Open a web browser interface for configuring JIRA settings.
313+
314+
This function sets up a simple HTTP server using Python's built-in
315+
`http.server` module to handle GET and POST requests. The server serves
316+
an HTML page for configuration and handles saving the JIRA configuration
317+
details through API tokens and URLs. Upon successful configuration, it
318+
shuts down the server gracefully.
245319
"""
246320
redirect_port = random.randint(30000, 50000)
247321
server_url = f"http://localhost:{redirect_port}"
@@ -250,6 +324,14 @@ def config_jira_web():
250324

251325
class ConfigHandler(http.server.SimpleHTTPRequestHandler):
252326
def do_GET(self):
327+
"""Handle GET requests for different paths.
328+
329+
This function processes GET requests based on the path requested. It
330+
serves an HTML template for the root path, returns a JSON configuration
331+
for a specific endpoint, and handles any other paths by returning a 404
332+
error.
333+
"""
334+
253335
if self.path == "/":
254336
self.send_response(200)
255337
self.send_header("Content-type", "text/html")
@@ -291,6 +373,16 @@ def do_GET(self):
291373
self.wfile.write(b"Not Found")
292374

293375
def do_POST(self):
376+
"""Handle HTTP POST requests to save JIRA configuration.
377+
378+
This method processes incoming POST requests to save JIRA configuration
379+
details. It reads JSON data from the request body, extracts necessary
380+
parameters (URL, username, API token, and verify), saves the
381+
configuration using the `save_jira_config` function, and responds with
382+
success or error messages. If an exception occurs during the process, it
383+
sends a 500 Internal Server Error response.
384+
"""
385+
294386
if self.path == "/save":
295387
content_length = int(self.headers['Content-Length'])
296388
post_data = self.rfile.read(content_length)
@@ -345,8 +437,11 @@ def log_message(self, format, *args):
345437
print("Configuration completed.")
346438

347439
def get_token():
348-
"""
349-
Get the token based on priority.
440+
"""Get the token based on priority from environment variables or
441+
configuration files.
442+
443+
Returns:
444+
str: The API token if found, otherwise None.
350445
"""
351446
import os
352447
env_token = os.getenv('PENIFY_API_TOKEN')

0 commit comments

Comments
 (0)