-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d79735b
commit 34376cf
Showing
6 changed files
with
249 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
src/js/how2validate/validators/openai/openai_api_key.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/** | ||
* @module OpenAIApiKeyValidator | ||
* @description | ||
* This module provides functionality to validate an OpenAI API key by making an API call to the OpenAI service. | ||
* It returns a validation status, processes the response from the API, and optionally sends an email report with the results. | ||
* | ||
* This module depends on various utilities for handling configuration, logging, and secret statuses. | ||
* | ||
* @requires axios - Used for making HTTP requests to the OpenAI API. | ||
* @requires ../../utility/tool_utility.js - Utility functions for handling status responses and errors. | ||
* @requires ../../handler/email_handler.js - Used for sending email reports on validation results. | ||
*/ | ||
|
||
import { ValidationResult } from "../../utility/interface/validationResult.js"; | ||
import { | ||
handleInactiveStatus, | ||
handleErrors, | ||
getUsernameFromEmail, | ||
handleActiveStatus, | ||
responseValidation, | ||
} from "../../utility/tool_utility.js"; | ||
import { EmailResponse } from "../../utility/interface/EmailResponse.js"; | ||
import { SecretStatusMessage } from "../../utility/interface/secretStatusMessage.js"; | ||
import { sendEmail } from "../../handler/email_handler.js"; | ||
import axios from "axios"; | ||
|
||
/** | ||
* @function validateOpenAIApiKey | ||
* @description | ||
* This function validates an OpenAI API key by making an API call to the OpenAI API. | ||
* Based on the response from OpenAI, it checks the validity of the key, handles errors, and | ||
* returns an appropriate validation result. | ||
* | ||
* If a `report` email is provided, the function also sends an email summarizing the validation results. | ||
* | ||
* @async | ||
* @param {string} provider - The provider name (e.g., "OpenAI") for which the secret is being validated. | ||
* @param {string} service - The name of the service being validated. | ||
* @param {string} secret - The OpenAI API key to validate. | ||
* @param {boolean} responseFlag - A flag to indicate whether detailed response data should be returned. | ||
* @param {string} [report] - An optional email address to which a validation report should be sent. | ||
* @param {boolean} [isBrowser=true] - Indicates if the function is called from a browser environment (default is false). | ||
* | ||
* @returns {Promise<ValidationResult>} - A promise that resolves to a `ValidationResult` object containing the validation result. | ||
* | ||
* @throws {Error} - If the validation process encounters an issue, it throws an error. | ||
*/ | ||
export async function validateOpenAIApiKey( | ||
provider: string, | ||
service: string, | ||
secret: string, | ||
responseFlag: boolean, | ||
report: string, | ||
isBrowser: boolean = true | ||
): Promise<ValidationResult> { | ||
const validation_response = {} as SecretStatusMessage; | ||
|
||
const url = "https://api.openai.com/v1/organizations"; | ||
const headers = { Authorization: `Bearer ${secret}` }; | ||
|
||
try { | ||
const responseData = await axios.get(url, { headers }); | ||
|
||
if (responseData.status === 200) { | ||
const activeResponse = handleActiveStatus( | ||
provider, | ||
service, | ||
responseData, | ||
responseFlag, | ||
report, | ||
isBrowser | ||
); | ||
|
||
validation_response.state = activeResponse.data?.validate.state!; | ||
validation_response.message = activeResponse.data?.validate.message!; | ||
validation_response.response = activeResponse.data?.validate.response!; | ||
|
||
return responseValidation(activeResponse, responseFlag); | ||
} else { | ||
const inactiveResponse = handleInactiveStatus( | ||
provider, | ||
service, | ||
responseFlag, | ||
responseData.data, | ||
report, | ||
isBrowser | ||
); | ||
|
||
validation_response.state = inactiveResponse.data?.validate.state!; | ||
validation_response.message = inactiveResponse.data?.validate.message!; | ||
validation_response.response = inactiveResponse.data?.validate.response!; | ||
|
||
return responseValidation(inactiveResponse, responseFlag); | ||
} | ||
} catch (error) { | ||
const errResponse = handleErrors( | ||
provider, | ||
service, | ||
responseFlag, | ||
report, | ||
error, | ||
isBrowser | ||
); | ||
|
||
validation_response.state = errResponse.data?.validate.state!; | ||
validation_response.message = errResponse.data?.validate.message!; | ||
validation_response.response = errResponse.data?.validate.response!; | ||
|
||
return responseValidation(errResponse, responseFlag); | ||
} finally { | ||
if (report) { | ||
const emailResponse: EmailResponse = { | ||
provider: provider, | ||
service: service, | ||
state: validation_response.state, | ||
message: validation_response.message, | ||
response: validation_response.response, | ||
}; | ||
|
||
sendEmail(report, getUsernameFromEmail(report), emailResponse) | ||
.then(() => { | ||
console.info("Validation report sent successfully"); | ||
}) | ||
.catch((error) => { | ||
console.error("Error sending validation report", error); | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
src/python/how2validate/validators/openai/openai_api_key.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import json | ||
import logging | ||
import requests | ||
from how2validate.handler.email_handler import send_email | ||
from how2validate.utility.interface.EmailResponse import EmailResponse | ||
from how2validate.utility.interface.validationResult import ValidationProcess, ValidationResult | ||
from how2validate.utility.tool_utility import handle_active_status, handle_inactive_status, handle_errors, response_validation | ||
|
||
def validate_openai_api_key(provider: str, service: str, secret: str, response_flag: bool, report: str, is_browser: bool = True) -> ValidationResult: | ||
""" | ||
Validates the OpenAI API key by making a request to the OpenAI API. | ||
Parameters: | ||
- provider (str): The provider name (e.g., "OpenAI"). | ||
- service (str): The name of the service being validated. | ||
- secret (str): The OpenAI API key to validate. | ||
- response_flag (bool): Flag to indicate whether detailed response data should be returned. | ||
- report (str): An optional email address to which a validation report should be sent. | ||
- is_browser (bool): Indicates if the function is called from a browser environment (default is True). | ||
Returns: | ||
- ValidationResult: A structured response indicating the validation results. | ||
""" | ||
# Initialize the response structure as an instance of the ValidationProcess class | ||
validation_response = ValidationProcess( | ||
state="", | ||
message="", | ||
response=None, | ||
report="[email protected]" | ||
) | ||
|
||
# OpenAI API endpoint for getting the organization details | ||
url = "https://api.openai.com/v1/organizations" | ||
|
||
# Headers to ensure no caching and to authorize the request using the provided API key (token) | ||
nocache_headers = {'Cache-Control': 'no-cache'} | ||
headers_map = {'Authorization': f'Bearer {secret}'} | ||
|
||
try: | ||
# Send a GET request to the OpenAI API with combined headers (nocache + authorization) | ||
response_data = requests.get(url, headers={**nocache_headers, **headers_map}) | ||
# Raise an HTTPError if the response has an unsuccessful status code (4xx or 5xx) | ||
response_data.raise_for_status() | ||
# Check if the request was successful (HTTP 200) | ||
if response_data.status_code == 200: | ||
# If the token is valid, handle active status | ||
active_response = handle_active_status( | ||
provider, | ||
service, | ||
response_data, | ||
response_flag, | ||
report, | ||
is_browser | ||
) | ||
|
||
validation_response.state = active_response.data.validate.state | ||
validation_response.message = active_response.data.validate.message | ||
validation_response.response = json.dumps(active_response.to_dict(), indent=4) | ||
|
||
return response_validation(active_response, response_flag) | ||
|
||
except requests.HTTPError as error: | ||
if 400 <= error.response.status_code < 500: | ||
# Handle inactive token or other statuses | ||
inactive_response = handle_inactive_status( | ||
provider, | ||
service, | ||
response_flag, | ||
error, | ||
report, | ||
is_browser | ||
) | ||
|
||
validation_response.state = inactive_response.data.validate.state | ||
validation_response.message = inactive_response.data.validate.message | ||
validation_response.response = json.dumps(inactive_response.to_dict(), indent=4) | ||
|
||
return response_validation(inactive_response, response_flag) | ||
|
||
elif 500 <= error.response.status_code < 600: | ||
# Handle server-side errors | ||
error_response = handle_errors( | ||
provider, | ||
service, | ||
response_flag, | ||
report, | ||
error, | ||
is_browser | ||
) | ||
|
||
validation_response.state = error_response.data.validate.state | ||
validation_response.message = error_response.data.validate.message | ||
validation_response.response = json.dumps(error_response.to_dict(), indent=4) | ||
|
||
return response_validation(error_response, response_flag) | ||
|
||
finally: | ||
# If a report email is provided, send the validation result via email | ||
if report: | ||
email_response = EmailResponse( | ||
email=report, | ||
provider=provider, | ||
service=service, | ||
state=validation_response.state, | ||
message=validation_response.message, | ||
response=validation_response.response, | ||
) | ||
try: | ||
send_email(email_response) | ||
logging.info('Validation report sent successfully') | ||
except Exception as e: | ||
logging.error('Error sending validation report', exc_info=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters