|
|
|
@ -14,6 +14,21 @@ env_file = os.path.join(config_directory, ".env")
|
|
|
|
|
|
|
|
|
|
class Standalone: |
|
|
|
|
def __init__(self, args, pattern="", env_file="~/.config/fabric/.env"): |
|
|
|
|
""" Initialize the class with the provided arguments and environment file. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
args: The arguments for initialization. |
|
|
|
|
pattern: The pattern to be used (default is an empty string). |
|
|
|
|
env_file: The path to the environment file (default is "~/.config/fabric/.env"). |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
KeyError: If the "OPENAI_API_KEY" is not found in the environment variables. |
|
|
|
|
FileNotFoundError: If no API key is found in the environment variables. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
# Expand the tilde to the full path |
|
|
|
|
env_file = os.path.expanduser(env_file) |
|
|
|
|
load_dotenv(env_file) |
|
|
|
@ -32,6 +47,18 @@ class Standalone:
|
|
|
|
|
self.args = args |
|
|
|
|
|
|
|
|
|
def streamMessage(self, input_data: str): |
|
|
|
|
""" Stream a message and handle exceptions. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
input_data (str): The input data for the message. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None: If the pattern is not found. |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
FileNotFoundError: If the pattern file is not found. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
wisdomFilePath = os.path.join( |
|
|
|
|
config_directory, f"patterns/{self.pattern}/system.md" |
|
|
|
|
) |
|
|
|
@ -80,6 +107,18 @@ class Standalone:
|
|
|
|
|
f.write(buffer) |
|
|
|
|
|
|
|
|
|
def sendMessage(self, input_data: str): |
|
|
|
|
""" Send a message using the input data and generate a response. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
input_data (str): The input data to be sent as a message. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
FileNotFoundError: If the specified pattern file is not found. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
wisdomFilePath = os.path.join( |
|
|
|
|
config_directory, f"patterns/{self.pattern}/system.md" |
|
|
|
|
) |
|
|
|
@ -118,6 +157,15 @@ class Standalone:
|
|
|
|
|
|
|
|
|
|
class Update: |
|
|
|
|
def __init__(self): |
|
|
|
|
""" Initialize the object with default values and update patterns. |
|
|
|
|
|
|
|
|
|
This method initializes the object with default values for root_api_url, config_directory, and pattern_directory. |
|
|
|
|
It then creates the pattern_directory if it does not exist and calls the update_patterns method to update the patterns. |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
OSError: If there is an issue creating the pattern_directory. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
self.root_api_url = "https://api.github.com/repos/danielmiessler/fabric/contents/patterns?ref=main" |
|
|
|
|
self.config_directory = os.path.expanduser("~/.config/fabric") |
|
|
|
|
self.pattern_directory = os.path.join(self.config_directory, "patterns") |
|
|
|
@ -125,6 +173,12 @@ class Update:
|
|
|
|
|
self.update_patterns() # Call the update process from a method. |
|
|
|
|
|
|
|
|
|
def update_patterns(self): |
|
|
|
|
""" Update the patterns by downloading from the GitHub directory. |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
HTTPError: If there is an HTTP error while downloading patterns. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
self.progress_bar = tqdm(desc="Downloading Patterns…", unit="file") |
|
|
|
|
self.get_github_directory_contents( |
|
|
|
@ -145,6 +199,16 @@ class Update:
|
|
|
|
|
sys.exit() # Exit after handling the error. |
|
|
|
|
|
|
|
|
|
def download_file(self, url, local_path): |
|
|
|
|
""" Download a file from the given URL and save it to the local path. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
url (str): The URL of the file to be downloaded. |
|
|
|
|
local_path (str): The local path where the file will be saved. |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
HTTPError: If an HTTP error occurs during the download process. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
response = requests.get(url) |
|
|
|
|
response.raise_for_status() |
|
|
|
@ -156,6 +220,19 @@ class Update:
|
|
|
|
|
sys.exit() |
|
|
|
|
|
|
|
|
|
def process_item(self, item, local_dir): |
|
|
|
|
""" Process the given item and save it to the local directory. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
item (dict): The item to be processed, containing information about the type, download URL, name, and URL. |
|
|
|
|
local_dir (str): The local directory where the item will be saved. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
OSError: If there is an issue creating the new directory using os.makedirs. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
if item["type"] == "file": |
|
|
|
|
self.download_file( |
|
|
|
|
item["download_url"], os.path.join(local_dir, item["name"]) |
|
|
|
@ -166,6 +243,22 @@ class Update:
|
|
|
|
|
self.get_github_directory_contents(item["url"], new_dir) |
|
|
|
|
|
|
|
|
|
def get_github_directory_contents(self, api_url, local_dir): |
|
|
|
|
""" Get the contents of a directory from GitHub API and process each item. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
api_url (str): The URL of the GitHub API endpoint for the directory. |
|
|
|
|
local_dir (str): The local directory where the contents will be processed. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
HTTPError: If an HTTP error occurs while fetching the directory contents. |
|
|
|
|
If the status code is 403, it prints a message about GitHub API rate limit exceeded |
|
|
|
|
and closes the progress bar. For any other status code, it prints a message |
|
|
|
|
about failing to fetch directory contents due to an HTTP error. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
response = requests.get(api_url) |
|
|
|
|
response.raise_for_status() |
|
|
|
@ -184,22 +277,54 @@ class Update:
|
|
|
|
|
|
|
|
|
|
class Setup: |
|
|
|
|
def __init__(self): |
|
|
|
|
""" Initialize the object. |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
OSError: If there is an error in creating the pattern directory. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
self.config_directory = os.path.expanduser("~/.config/fabric") |
|
|
|
|
self.pattern_directory = os.path.join(self.config_directory, "patterns") |
|
|
|
|
os.makedirs(self.pattern_directory, exist_ok=True) |
|
|
|
|
self.env_file = os.path.join(self.config_directory, ".env") |
|
|
|
|
|
|
|
|
|
def api_key(self, api_key): |
|
|
|
|
""" Set the OpenAI API key in the environment file. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
api_key (str): The API key to be set. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
|
|
|
|
|
Raises: |
|
|
|
|
OSError: If the environment file does not exist or cannot be accessed. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
if not os.path.exists(self.env_file): |
|
|
|
|
with open(self.env_file, "w") as f: |
|
|
|
|
f.write(f"OPENAI_API_KEY={api_key}") |
|
|
|
|
print(f"OpenAI API key set to {api_key}") |
|
|
|
|
|
|
|
|
|
def patterns(self): |
|
|
|
|
""" Method to update patterns and exit the system. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
Update() |
|
|
|
|
sys.exit() |
|
|
|
|
|
|
|
|
|
def run(self): |
|
|
|
|
""" Execute the Fabric program. |
|
|
|
|
|
|
|
|
|
This method prompts the user for their OpenAI API key, sets the API key in the Fabric object, and then calls the patterns method. |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
None |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
print("Welcome to Fabric. Let's get started.") |
|
|
|
|
apikey = input("Please enter your OpenAI API key\n") |
|
|
|
|
self.api_key(apikey.strip()) |
|
|
|
|