diff --git a/.gitignore b/.gitignore index 98b1c02..0221513 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ venv/ /dist /codes /build +/SimplerLLM/workflow /SimplerLLM.egg-info .pypirc generate_images.py @@ -30,5 +31,4 @@ test.csv test_data_agent.py test_sql_agent.py vb_ui.py -vd_test.py -Documentation \ No newline at end of file +vd_test.py \ No newline at end of file diff --git a/Documentation/docs/AI Agents/Getting Started.md b/Documentation/docs/AI Agents/Getting Started.md new file mode 100644 index 0000000..81a72d8 --- /dev/null +++ b/Documentation/docs/AI Agents/Getting Started.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 1 +--- + +# Coming Soon \ No newline at end of file diff --git a/Documentation/docs/AI Agents/_category_.json b/Documentation/docs/AI Agents/_category_.json new file mode 100644 index 0000000..192205e --- /dev/null +++ b/Documentation/docs/AI Agents/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "AI Agents", + "position": 6 +} \ No newline at end of file diff --git a/Documentation/docs/Advanced Tools/Chunking Methods.md b/Documentation/docs/Advanced Tools/Chunking Methods.md new file mode 100644 index 0000000..bd41ce8 --- /dev/null +++ b/Documentation/docs/Advanced Tools/Chunking Methods.md @@ -0,0 +1,99 @@ +--- +sidebar_position: 4 +--- + +# Chunking Methods + +This section provides detailed information on the text chunking capabilities of the SimplerLLM library. These functions allow users to split text into pieces based on sentence, paragraph, size, or semantic similarity. + +Each method is designed to accommodate different analytical needs, enhancing text processing tasks in various applications such as data preprocessing, content analysis, and information retrieval. + +The Data by all these functions is returned in form of a `Text Chunks` object that includes the following parameters: +- `chunk_list` (List): This is a list of `ChunkInfo` objects that includes: + - `text` (string): The text of the chunk itself. + - `num_characters` (string): The number of characters in the chunk. + - `num_words` (string): The number of words in the chunk. +- `num_chunks` (int): The total number of chunks returned. + +## chunk_by_sentences Function + +Breaks down the provided text into sentences using punctuation marks as delimiters. It takes 1 parameter which is: +- `text` (str): Text you want to chunk into sentences. + +It then returns a `Text Chunks` object. Here's a sample usage: + +```python +from SimplerLLM.tools.text_chunker import chunk_by_sentences + +text = "First sentence. Second sentence? Third sentence!" + +sentences = chunk_by_sentences(text) + +print(sentences) +``` + +## chunk_by_paragraphs Function + +Segments the provided text into paragraphs based on newline characters. It takes 1 parameter: +- `text` (str): Text you want to chunk into paragraphs. + +It then returns a `Text Chunks` object. Here's a sample usage: + +```python +from SimplerLLM.tools.text_chunker import chunk_by_paragraphs + +text = "First paragraph, still going.\n\nSecond paragraph starts." + +paragraphs = chunk_by_paragraphs(text) + +print(paragraphs) +``` + +## chunk_by_max_chunk_size Function + +Splits the input text into chunks that do not exceed a specified size. Additionally, it can preserve the meaning of sentences by ensuring that chunks do not split sentences in the middle. It takes 3 parameters: +- `text` (str): The text you want to chunk. +- `max_chunk_size` (int): The maximum size of each chunk in characters. +- `preserve_sentence_structure` (bool, optional): Whether you want to preserve sentence meaning. Set to False by default. + +It returns a `Text Chunks` object. Here's how you can use it: + +```python +from SimplerLLM.tools.text_chunker import chunk_by_max_chunk_size + +text = "Hello world! This is an example of text chunking. Enjoy using SimplerLLM." + +chunks = chunk_by_max_chunk_size(text, 50, True) + +print(chunks) +``` + +## chunk_by_semantics Function + +Uses semantic similarity to divide text into chunks. It takes 2 parameters: +- `text` (str): Text to be segmented based on semantic content. +- `llm_embeddings_instance` [(EmbeddingsLLM)](https://docs.simplerllm.com/Vector%20Storage/Vector%20Embeddings): An instance of a language model used to generate text embeddings for semantic analysis. +- `threshold_percentage` (int, Optional): The percentile threshold you want to use to chunk the text. It is set by default to 90. + +It returns a list of `ChunkInfo` objects, each representing a semantically coherent segment of the original text. However, keep in mind that you need to have your OpenAI API key in the `.env` file so that the llm embedding instance can generate the text embeddings. Enter it in this format: + +``` +OPENAI_API_KEY="your_openai_api_key" +``` + +Anyways, Here's an example usage of the code: + +```python +from SimplerLLM.tools.text_chunker import chunk_by_semantics +from SimplerLLM.language.embeddings import EmbeddingsLLM, EmbeddingsProvider + +text = "Discussing AI. Artificial intelligence has many applications. However, Dogs like bones" +embeddings_model = EmbeddingsLLM.create(provider=EmbeddingsProvider.OPENAI, + model_name="text-embedding-3-small" + threshold_percentage=80) + +semantic_chunks = chunk_by_semantics(text, embeddings_model) + +print(semantic_chunks) +``` +That's how you can benefit from SimplerLLM to make Text Chunking Simpler! \ No newline at end of file diff --git a/Documentation/docs/Advanced Tools/Extract YouTube Data.md b/Documentation/docs/Advanced Tools/Extract YouTube Data.md new file mode 100644 index 0000000..49db30a --- /dev/null +++ b/Documentation/docs/Advanced Tools/Extract YouTube Data.md @@ -0,0 +1,86 @@ +--- +sidebar_position: 3 +--- + +# Extract YouTube Data + +The functions in this section are designed to extract detailed information from YouTube videos, including metadata and transcripts. You can benefit from these capabilities to build powerful APIs / tools / applications. + +## `get_video_meta(video_url)` Function + +This function takes only the `video_url` as input and it fetches detailed metadata from a specified YouTube video. It retrieves a ton of information returning them in a dictionary format: +- `video_id`: The unique identifier for the video. +- `video_title`: The title of the video. +- `video_description`: A description of the video. +- `video_length`: The duration of the video in seconds. +- `video_views`: The number of times the video has been viewed. +- `video_author`: The creator of the video. +- `video_publish_date`: The publication date of the video. +- `video_thumbnail_url`: The URL of the video's thumbnail. +- `video_rating`: The average user rating of the video. +- `video_keywords`: Keywords associated with the video. + +### Example Usage + +```python +from SimplerLLM.tools.youtube import get_video_meta + +video_meta = get_video_meta("https://www.youtube.com/watch?v=r9PjzmUmk1w") + +print(video_meta) +``` + +The video meta is returned in the following format: +``` +{'video_id': 'r9PjzmUmk1w', 'video_title': 'Build SaaS with WordPress With 3 Plugins Only!', 'video_description': None, 'video_length': 252, 'video_views': 25845, 'video_author': 'Hasan Aboul Hasan', 'video_publish_date': datetime.datetime(2024, 2, 15, 0, 0), 'video_thumbnail_url': 'https://i.ytimg.com/vi/r9PjzmUmk1w/hqdefault.jpg?sqp=-oaymwEXCJADEOABSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDLDIEv0NjGrhaAKQ8GL2SpvwDDng', 'video_rating': None, 'video_keywords': []} +``` + +Let's say you only want to get the video title, here's how you get it: + +```python +from SimplerLLM.tools.youtube import get_video_meta + +video_meta = get_video_meta("https://www.youtube.com/watch?v=r9PjzmUmk1w") + +print(video_meta.get('video_title')) +``` + +Use the same method to extract any value you want. + +## `get_youtube_transcript(video_url)` Function + +This function also takes only the `video_url`, and it returns the transcript of the YouTube video, formatting it into a simple readable string. + +### Example Usage + +```python +from SimplerLLM.tools.youtube import get_youtube_transcript + +video_transcript = get_youtube_transcript("https://www.youtube.com/watch?v=r9PjzmUmk1w") + +print(video_transcript) +``` + +## `get_youtube_transcript_with_timing(video_url)` Function + +This function also takes only the `video_url`, and retrieves the transcript of a YouTube video, including timing information for each line. It returns a list of dictionaries, where each dictionary refers to a part of the transcript and it contains the following: +- `text`: The transcript text of a specific segment of the video. +- `start`: The start time of the segment in seconds. +- `duration`: The duration of the segment in seconds. + +### Example Usage + +```python +from SimplerLLM.tools.youtube import get_youtube_transcript_with_timing + +video_transcript = get_youtube_transcript_with_timing("https://www.youtube.com/watch?v=r9PjzmUmk1w") + +print(video_transcript) +``` + +Here's the output format of a small section: +``` +[{'text': 'hi friends in this video I will show you', 'start': 0.12, 'duration': 6.08}, {'text': 'how to turn any WordPress website into a', 'start': 2.639, 'duration': 7.481}, {'text': 'full SAS business using only three', 'start': 6.2, 'duration': 7.639}, {'text': 'plugins this is exactly what I did on my', 'start': 10.12, 'duration': 6.56}, {'text': 'website you will see here I have a list', 'start': 13.839, 'duration': 5.401}] +``` + +That's how you can benefit from SimplerLLM to make extracting YouTube data Simpler! \ No newline at end of file diff --git a/Documentation/docs/Advanced Tools/File Operations.md b/Documentation/docs/Advanced Tools/File Operations.md new file mode 100644 index 0000000..10a689f --- /dev/null +++ b/Documentation/docs/Advanced Tools/File Operations.md @@ -0,0 +1,124 @@ +--- +sidebar_position: 1 +--- + +# File Operations + +SimplerLLM supports creating and loading the content of various file types. This makes it easy to load the content of any file or even content from the internet using a generic function. + +The file operations available are categorized into three primary areas: +- **Saving Text to Files**: This functionality allows for the writing of text data to files ensuring errors are handled correctly. +- **Loading CSV Files**: This functionality allows easy reading of any CSV file document, where it returns specific strucutred data. +- **Generic File Loading**: This includes loading the details of various types of files, such as plain text, PDFs, DOCX, web pages, and even youtube video data. + +Here's how each of them works: + +## Saving Text to File + +This operation contains a single function `save_text_to_file` which takes as input the text you want to save and the name of the file you want to save in. + +If the file is already present in your directory it just rewrites its content, however if it's not present it creates the file and adds the the input text to it. Here's an example: + +```python +from SimplerLLM.tools.file_functions import save_text_to_file + +input_text = save_text_to_file("This is the text saved in the file", "file.txt") + +print(input_text) +``` + +As you can see it takes 2 paramters: +- `text (str)`: The text content to save. +- `filename (str)` (Optional): The destination filename. Defaults to "output.txt". + +Then, it returns a bool (True/False), representing if the file was created successfully or not. + +## Loading CSV Files + +This operation also contains a single function `load_csv_file` which takes as input the path to the CSV, and returns a `CSVDocument` object which provides a structured way to access the CSV data, including the following attributes that you can access independently: +- `file_size`: The size of the CSV file in bytes. +- `row_count`: Number of rows in the CSV. +- `column_count`: Number of columns in the CSV. +- `total_fields`: Total number of data fields. +- `content`: Nested list representing rows and columns. +- `title`: Title of the document (Will be set to None in this function) +- `url_or_path`: CSV file name. + +Here's an example of the function in action: + +```python +from SimplerLLM.tools.file_loader import read_csv_file + +csv_data = read_csv_file("text.csv") + +print(csv_data) +``` + +When you print the csv_data as is it will return the whole `CSVDocument` object with all its attributes. However, if you want access for example only the content of the file, here's how you do it: + +```python +from SimplerLLM.tools.file_loader import read_csv_file + +csv_data = read_csv_file("text.csv") + +print(csv_data.content) +``` + +Use the same method for accessing the other attributes. +Here's another example on how to access the column count: + +```python +from SimplerLLM.tools.file_loader import read_csv_file + +csv_data = read_csv_file("text.csv") + +print(csv_data.column_count) +``` + +## Generic Loading Of Other File Types + +This generic loader supports a ton of file types which are: +- Web Articles +- YouTube video transcripts +- Traditional formats like TXT, PDF, CSV, and DOCX. + +The `load_content` function takes the file name as input, and returns a `Text Document` object that has the following attributes: +- `file_size`: The size of the file in bytes. +- `word_count`: The number of words in the file. +- `character_count`: The number of characters in the file. +- `content`: String representing the contents of the file. +- `title`: Title of the document (if it has one) +- `url_or_path`: file name. + +Here's an example of the function in action: + +```python +from SimplerLLM.tools.generic_loader import load_content + +file_data = load_content("file_name.csv") + +print(file_data) +``` + +When you print the file_data as is it will return the whole `Text Document` object with all its attributes. However, if you want access for example only the content of the file, here's how you do it: + +```python +from SimplerLLM.tools.generic_loader import load_content + +file_data = load_content("file_name.csv") + +print(file_data.content) +``` + +Use the same method for accessing the other attributes. +Here's another example on how to access the word count: + +```python +from SimplerLLM.tools.generic_loader import load_content + +file_data = load_content("file_name.csv") + +print(file_data.word_count) +``` + +That's how you can benefit from SimplerLLM to make interaction with files Simpler! \ No newline at end of file diff --git a/Documentation/docs/Advanced Tools/Generic RapidAPI Loader.md b/Documentation/docs/Advanced Tools/Generic RapidAPI Loader.md new file mode 100644 index 0000000..4d541c2 --- /dev/null +++ b/Documentation/docs/Advanced Tools/Generic RapidAPI Loader.md @@ -0,0 +1,89 @@ +--- +sidebar_position: 5 +--- + +# Generic RapidAPI Loader + +This tool helps calling any API on RapidAPI using a generic function, offering methods for both synchronous and asynchronous requests. This makes it easier for developers who need to integrate multiple API services into their applications. This client manages API keys, request headers, and error handling internally, reducing the overhead for the developers and allowing them to focus on implementing the core functionality. + +To use it, you'll need to input your API key in the `.env` file in this form: + +``` +RAPIDAPI_API_KEY="your_api_key" +``` + +## Synchronous API Calls (`call_api`) + +The `call_api` method allows users to perform synchronous HTTP requests to any specified RapidAPI endpoint. This method is useful when the application requires a direct response from the API for further processing. + +### Parameters +- `api_url`: String specifying the full URL of the API endpoint. +- `method`: HTTP method to use (e.g., 'GET', 'POST'), default is 'GET'. +- `params` (Optional): Dictionary of query parameters for the 'GET' request. +- `headers_extra` (Optional): Dictionary to provide additional headers. +- `data` (Optional): Dictionary specifying data for 'POST' requests. +- `json` (Optional): Dictionary specifying JSON payload for 'POST' requests. +- `max_retries` (Optional): Maximum number of retries +- `backoff_factor` (Optional): Factor by which the delay increases during each retry + +The response from the API is checked for its HTTP status code. If the response indicates success (e.g., 200, 201), the method returns the JSON data. If the response is not successful, it raises an HTTP error with the status code and message. + +**This function includes automatic retries** for client connection errors (e.g., timeouts, server not available). The method will attempt to resend the request for a default number of 3 times with a backoff factor of 2. + +If you wnat to change these values you can include them in the parameters when sending an API call. + +### Sample Use Case + +Let's try using the [Domain Authority API](https://rapidapi.com/hassan.cs91/api/domain-authority1/playground/apiendpoint_f2c2bcde-e9c2-45aa-9d0c-47d6b21b876b) which is an API i developed that returns the domain power, organic clicks, average rank, and keywords rank for any domain name. + +```python +from SimplerLLM.tools.rapid_api import RapidAPIClient + +api_url = "https://domain-authority1.p.rapidapi.com/seo/get-domain-info" +api_params = { + 'domain': 'learnwithhasan.com', +} + +api_client = RapidAPIClient() +response = api_client.call_api(api_url, method='GET', params=api_params) +``` + +## Asynchronous API Calls (`call_api_async`) + +The `call_api_async` function is designed for making asynchronous API calls. This is particularly useful in environments that support asynchronous operations, allowing non-blocking API calls that can greatly improve the efficiency of your application. + +### Parameters +- `api_url`: String specifying the full URL of the API endpoint. +- `method`: HTTP method to use (e.g., 'GET', 'POST'), default is 'GET'. +- `params` (Optional): Dictionary of query parameters for the 'GET' request. +- `headers_extra` (Optional): Dictionary to provide additional headers. +- `data` (Optional): Dictionary specifying data for 'POST' requests. +- `json` (Optional): Dictionary specifying JSON payload for 'POST' requests. +- `max_retries` (Optional): Maximum number of retries +- `backoff_factor` (Optional): Factor by which the delay increases during each retry + +As you can see it takes the same parameters as the `call_api`, but each request is handled asynchronously. + +The response from the API is checked for its HTTP status code. If the response indicates success (e.g., 200, 201), the method returns the JSON data. If the response is not successful, it raises an HTTP error with the status code and message. + +**This function includes automatic retries** for client connection errors (e.g., timeouts, server not available). The method will attempt to resend the request for a default number of 3 times with a backoff factor of 2. + +If you want to change these values you can include them in the parameters when sending an API call. + +### Sample Use Case + +Let's try using the [Domain Authority API](https://rapidapi.com/hassan.cs91/api/domain-authority1/playground/apiendpoint_f2c2bcde-e9c2-45aa-9d0c-47d6b21b876b) which is an API i developed that returns the domain power, organic clicks, average rank, and keywords rank for any domain name. + +```python +from SimplerLLM.tools.rapid_api import RapidAPIClient + +api_url = "https://domain-authority1.p.rapidapi.com/seo/get-domain-info" +api_params = { + 'domain': 'learnwithhasan.com', +} + +api_client = RapidAPIClient() +response = api_client.call_api_async(api_url, method='GET', params=api_params) +``` + +That's how you can benefit from SimplerLLM to make RapidAPI calling Simpler! \ No newline at end of file diff --git a/Documentation/docs/Advanced Tools/Search Engine Integration.md b/Documentation/docs/Advanced Tools/Search Engine Integration.md new file mode 100644 index 0000000..ea1b6a9 --- /dev/null +++ b/Documentation/docs/Advanced Tools/Search Engine Integration.md @@ -0,0 +1,138 @@ +--- +sidebar_position: 2 +--- + +# Search Engine Integration + +This section provides an overview of how SimplerLLM facilitates the integration of Google and DuckDuckGo search engines in your code. It includes functions that allow applications to retrieve search results directly through APIs provided by Google and the free-to-use DuckDuckGo API. + +The Data is returned in form of a `SearchResult` object which is designed to standardize the format of search results across different search engines. This object includes the following fields: +- `URL` : The URL of the search result. +- `Domain`: The domain name extracted from the URL. +- `Title`: The title of the search result. +- `Description`: A brief description associated with the result. + +## Google Search Integration + +Google search integration is supported through two paid APIs: the Serper API and the Value SERP API. These APIs provide excellent search capabilities and are suitable for applications requiring good and stable search functionalities. + +### Serper API Functions + +To use the Serper API functions, you'll need to have your Serper API Key in the `.env` file in your project folder in this format: + +``` +SERPER_API_KEY="your_serper_api_key" +``` + +**Synchronous `search_with_serper_api` Function** + +It Takes 2 parameters: +- `query` (string): The search query. +- `num_results` (int, Optional): The maximum number of results to return, default is 50. + +It returns a list of `SearchResult` objects depending on the maximum number of results you specifiy. Here's an example usage: + +```python +from SimplerLLM.tools.serp import search_with_serper_api + +search_results = search_with_serper_api("What is SEO", 5) + +print(search_results) +``` + +**Asynchronous `search_with_serper_api_async` Function** + +It's the same as the normal function, however it Asynchronously fetches search results from Google using the Serper API. + +It also takes the same 2 parameters, and returns a list of `SearchResult` objects depending on the maximum number of results you specifiy. Here's an example usage: + +```python +import asyncio +from SimplerLLM.tools.serp import search_with_serper_api_async + +async def fetch_results(): + search_result = await search_with_serper_api_async("Latest AI advancements", 5) + print(search_result) + +asyncio.run(fetch_results()) +``` + +### Value SERP API Functions + +To use the Value SERP API functions, you'll need to have your Value SERP API Key in the `.env` file in your project folder in this format: + +``` +VALUE_SERP_API_KEY="your_value_serp_api_key" +``` + +**Synchronous `search_with_value_serp_api` Function** + +It takes 2 parameters: +- `query` (string): The search query. +- `num_results` (int, Optional): The maximum number of results to return, default is 50. + +It returns a list of `SearchResult` objects depending on the maximum number of results you specify. Here's an example usage: + +```python +from SimplerLLM.tools.serp import search_with_value_serp_api + +search_results = search_with_value_serp_api("What is SEO", 5) + +print(search_results) +``` + +**Asynchronous `search_with_value_serp_api_async` Function** + +It's the same as the normal function, however it asynchronously fetches search results from Google using the Value SERP API. + +It also takes the same 2 parameters, and returns a list of `SearchResult` objects depending on the maximum number of results you specify. Here's an example usage: + +```python +import asyncio +from SimplerLLM.tools.serp import search_with_value_serp_api_async + +async def fetch_results(): + search_results = await search_with_value_serp_api_async("Latest AI advancements", 5) + print(search_results) + +asyncio.run(fetch_results()) +``` + +## DuckDuckGo API Functions + +Unlike Google Search which is integrated using paid APIs, the DuckDuckGo search integration avaiable through their own free to use API. However, DuckDuckGo prioritizes user privacy and doesn’t track search history, leading to less personalized search results. This can make its results less relevant compared to Google, which customizes searches using a lot of user data. + +**Synchronous `search_with_duck_duck_go` Function** + +It takes 2 parameters: +- `query` (string): The search query. +- `max_results` (int, Optional): The maximum number of results to return, default is 10. + +It returns a list of `SearchResult` objects depending on the maximum number of results you specify. Here's an example usage: + +```python +from SimplerLLM.tools.serp import search_with_duck_duck_go + +search_results = search_with_duck_duck_go("Open source projects", 10) + +print(search_results) +``` + +**Asynchronous `search_with_duck_duck_go_async` Function** + +It's the same as the normal function but fetches search results from DuckDuckGo asynchronously. + +It also takes the same 2 parameters, and returns a list of `SearchResult` objects depending on the maximum number of results you specify. Here's an example usage: + +```python +import asyncio +from SimplerLLM.tools.serp import search_with_duck_duck_go_async + +async def fetch_results(): + search_results = await search_with_duck_duck_go_async("Open source tools", 10) + print(search_results) + +asyncio.run(fetch_results()) +``` + +That's how you can benefit from SimplerLLM to make Search Engine Integration Simpler! \ No newline at end of file diff --git a/Documentation/docs/Advanced Tools/_category_.json b/Documentation/docs/Advanced Tools/_category_.json new file mode 100644 index 0000000..90f31a6 --- /dev/null +++ b/Documentation/docs/Advanced Tools/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Advanced Tools", + "position": 4 +} \ No newline at end of file diff --git a/Documentation/docs/Image Processing/_category_.json b/Documentation/docs/Image Processing/_category_.json new file mode 100644 index 0000000..af09a5c --- /dev/null +++ b/Documentation/docs/Image Processing/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Image Processing", + "position": 5 +} diff --git a/Documentation/docs/LLM Interaction/Choose the LLM.md b/Documentation/docs/LLM Interaction/Choose the LLM.md new file mode 100644 index 0000000..91c8ad7 --- /dev/null +++ b/Documentation/docs/LLM Interaction/Choose the LLM.md @@ -0,0 +1,166 @@ +--- +sidebar_position: 2 +--- + +# Choose the LLM Provider + +This section of the documentation covers the methods and functionalities provided by SimplerLLM to interact with the different Large Language Models (LLMs). + +The library simplifies the process of integrating AI capabilities into your projects, making it straightforward to send prompts, receive responses, and handle data from different LLM providers. + +## 1. Creating an LLM Instance and Configuring API Keys + +To interact with an LLM, you first need to create an instance of the model. This process involves specifying which LLM provider you're using and which model you want to interact with. + +Here's an example usage of the OpenAI API leveraging the *gpt-3.5-turbo* model. + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +# Create an instance of an LLM +llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name="gpt-3.5-turbo") +``` + +However, we'll need to setup our API keys to use the LLM. We have 2 ways: + +### Add them to a `.env` file (Better Approach): + +Set up a a `.env` file at the root of your project. This file should include your API keys for various LLM providers and can also be used to customize default operational settings such as maximum retries and retry delays. + +As an example, here's how the `.env` file would look like if we're planning to use the OpenAI LLM: + +``` +OPENAI_API_KEY="your_openai_api_key_here" +``` + +The script will automatically load these enviromental variables and use them when you want to generate anything. + +### Pass them as a function parameter: + +If you don't want to create a `.env` file you can simply pass your API key as a parameter when creating an LLM instance which would look like this: + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +# Create an instance of an LLM +llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name="gpt-3.5-turbo", api_key="your_api_key") +``` + +## 2. Generating Responses + +Once you have an LLM instance, you can generate responses by providing prompts. Here's how to use the `generate_response` function: + +```python +response = llm_instance.generate_response( + prompt="Explain the theory of relativity", + messages=None, + system_prompt="You are a helpful AI Assistant", + temperature=0.6, + max_tokens=500, + top_p=0.8, + full_response=False +) +print(response) +``` + +### Function Parameters +- `prompt`: The question or statement to send to the LLM. +- `messages`: (optional) List of message objects for structured conversations. For example, when creating a chatbot you'll need to save the chat history so everytime you add the new response of the api to the messages and send it with the new api call. +- `system_prompt` (optional): Guides the model's tone and approach in generating responses. +- `max_tokens` (optional): The maximum number of tokens to generate. +- `temperature` (optional): Adjusts the diversity and predictability of the model's responses. +- `top_p` (optional): The close to 0 the more the randomness of the response, where it limits the selection of the top probable words. +- `full_response` (optional): If set to True, returns the complete response object from the API, including additional metadata. + +If you don't set any of the optional parameters, they'll take the default values set in the library which are: +- `messages`= None +- `system_prompt`= "You are a helpful AI Assistant" +- `max_tokens`= 300 +- `temperature`= 0.7 +- `top_p`= 1.0 +- `full_response`= False + +### Prompt Caching +Additionally, beyond the parameters listed above, **Anthropic Claude** uniquely has two additional parameters for prompt caching. Both parameters are optional, so inclusion is not necessary unless there is a need to cache data: +- `prompt_caching`: (optional, boolean) Determines whether you want to use prompt caching or not. +- `cached_input`: (optional) The specified text you want to cache. + +If you don't set the above parameters yourself they take the following default values: +- `prompt_caching` = False +- `cached_input` = "" + +## 3. Handling Retries + +If you want to handle how many time's the function retries after a failed api call, and the delay between each retry you'll need to adjust the enviromental variables that handle this. + +The `MAX_RETRIES` and `RETRY_DELAY` are by default set to 3 and 2 respectively, so if you plan to change them you'll need to go to your `.env` file: + +``` +MAX_RETRIES=5 +RETRY_DELAY=3 +``` + +Now, if an API request fails, the library will retry the request a maximum of 5 times if it keeps failing with a delay of 3 seconds between each retry. + +## 4. API call for each LLM provider + +Each LLM provider requires a slight change in the parameters when creating the llm instance, but the most important thing is adding the API key correctly in the `.env` file. So, when you plan on using multiple providers make sure you [set all the keys needed in a correct format](https://docs.simplerllm.com/#2-set-up-your-environment-env-file) + +Anyways, here's a brief overview and example usage for each provider: + +### OpenAI + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name="gpt-3.5-turbo") + +response = llm_instance.generate_response(prompt="generate a 5 words sentence") +print(response) +``` + +### Google Gemini + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +llm_instance = LLM.create(provider=LLMProvider.GEMINI, model_name="gemini-1.5-flash") + +response = llm_instance.generate_response(prompt="generate a 5 words sentence") +print(response) +``` + +### Anthropic Claude + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +llm_instance = LLM.create(provider=LLMProvider.ANTHROPIC, model_name="claude-3-5-sonnet-20240620") + +response = llm_instance.generate_response(prompt="generate a 5 words sentence") +print(response) +``` + +### For Ollama (Local Model) - The Phi Model + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +llm_instance = LLM.create(provider=LLMProvider.OLLAMA, model_name="phi") + +response = llm_instance.generate_response(prompt="generate a 5 words sentence") +print(response) +``` + +### For [Playground on LearnWithHasan](https://learnwithhasan.com/tools/llm-playground/) (Exclusive for Power Memebers) + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +llm_instance = LLM.create(provider=LLMProvider.LWH, model_name="gpt-3.5-turbo") + +response = llm_instance.generate_response(prompt="generate a 5 words sentence") +print(response) +``` + +Make sure you add your API key and user ID in the `.env` file [in the correct format](https://docs.simplerllm.com/#2-set-up-your-environment-env-file) . You can get them by navigating to the [Account Page](https://learnwithhasan.com/my-account/edit-account/) on the website, where you'll find both values in the API section. diff --git a/Documentation/docs/LLM Interaction/Getting Started.md b/Documentation/docs/LLM Interaction/Getting Started.md new file mode 100644 index 0000000..dcfbc2d --- /dev/null +++ b/Documentation/docs/LLM Interaction/Getting Started.md @@ -0,0 +1,54 @@ +--- +sidebar_position: 1 +--- + +# Getting Started + +The unified LLM interface in SimplerLLM allows you to easily interact with multiple Large Language Models (LLMs) through a single, consistent function. + +Whether you plan on using OpenAI, Google Gemini, Anthropic, Ollamma local model, or even our own LLM Playgound, SimplerLLM provides a clear and easy way to integrate and switch between these providers while maintaining a consistent code structure. + +## Why Use a Unified Interface? + +Managing multiple LLM providers can be challenging, especially when each provider has its own API structure, unique methods, and configurations. The unified interface solves this problem by standardizing the way you interact with these models, making it easier to: +- **Switch between providers**: You can switch between LLM providers by just changing some parameters in the same function, keeping the code structure as is. +- **Reduce provider dependency**: If the LLM provider you're using gets shutdown or stops working for a certain cause, you can easily switch to another LLM provider keeping the code as is. + +## How It Works + +SimplerLLM’s unified interface is built on the concept of defining a common `LLMProvider` and then creating instances of the `LLM` class based on that provider. The API is designed to be simple and consistent across all supported models. + +### Setting Up the LLM Instance + +Here’s a basic example that shows how you can easily switch between different providers: + +```python +from SimplerLLM.language.llm import LLM, LLMProvider + +# For OpenAI +llm_instance = LLM.create(provider=LLMProvider.OPENAI, model_name="gpt-3.5-turbo") + +# For Google Gemini +#llm_instance = LLM.create(provider=LLMProvider.GEMINI, model_name="gemini-1.5-flash") + +# For Anthropic Claude +#llm_instance = LLM.create(provider=LLMProvider.ANTHROPIC, model_name="claude-3-5-sonnet-20240620") + +# For Ollama (Local Model) +#llm_instance = LLM.create(provider=LLMProvider.OLLAMA, model_name="ollama-local-model") + +# For Playground on LearnWithHasan (Exclusive for Power Memebers) +#llm_instance = LLM.create(provider=LLMProvider.LWH, model_name="gpt-3.5-turbo") + +# Generate a response +response = llm_instance.generate_response(prompt="generate a 5 words sentence") +print(response) +``` + +As you can see it's very straightforward to switch between LLMs. You just need to create and LLM instance by picking the provider you want and the model name and you're ready to use it. + +After that you'll need to call the `generate_response` function which remains the same regarless of the provider you choose; passing your desired prompt to call the API and get the response. + +Finally, see the response by printing it in the terminal. + +As you can see, switching between LLMs is straightforward. Simply create an LLM instance by selecting the provider and model name. Once set up, you're ready to generate responses using a consistent and simple API. \ No newline at end of file diff --git a/Documentation/docs/LLM Interaction/_category_.json b/Documentation/docs/LLM Interaction/_category_.json new file mode 100644 index 0000000..a15a99a --- /dev/null +++ b/Documentation/docs/LLM Interaction/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "LLM Interaction", + "position": 2 +} \ No newline at end of file diff --git a/Documentation/docs/Vector Storage/Vector Databases.md b/Documentation/docs/Vector Storage/Vector Databases.md new file mode 100644 index 0000000..b134b72 --- /dev/null +++ b/Documentation/docs/Vector Storage/Vector Databases.md @@ -0,0 +1,5 @@ +--- +sidebar_position: 2 +--- + +# Vector Databases - Coming Soon \ No newline at end of file diff --git a/Documentation/docs/Vector Storage/Vector Embeddings.md b/Documentation/docs/Vector Storage/Vector Embeddings.md new file mode 100644 index 0000000..7f66ceb --- /dev/null +++ b/Documentation/docs/Vector Storage/Vector Embeddings.md @@ -0,0 +1,75 @@ +--- +sidebar_position: 1 +--- + +# Vector Embeddings + +This component of the SimplerLLM Library facilitates the generation of text embeddings using OpenAI's embedding model for now. This functionality helps developers working on natural language processing applications, enabling them to easily generate embeddings for a variety of use cases such as [semantic chunking](https://docs.simplerllm.com/Advanced%20Tools/Chunking%20Methods#chunk_by_semantics-function), clustering in machine learning, finding semantic similarity, etc... + +Before using this function make sure that your environment is set up with the necessary API keys. Place your OpenAI API key in the `.env` file as shown below: + +``` +OPENAI_API_KEY="your_openai_api_key" +``` + +## Using the `EmbeddingsLLM` Class + +The `EmbeddingsLLM` class is designed to handle the generation of text embeddings, supporting both synchronous and asynchronous operations. + +Start by creating an instance of the `EmbeddingsLLM` class entering the provider and the model you wish to use, like this: + +```python +from SimplerLLM.language.embeddings import EmbeddingsLLM, EmbeddingsProvider + +embeddings_llm_instance = EmbeddingsLLM.create(EmbeddingsProvider.OPENAI, "text-embedding-3-small") +``` + +### Generating Embeddings Synchronously + +The `generate_embeddings` method allows you to generate embeddings synchronously. It takes 2 parameters: +- `user_input`: String or list of strings for which embeddings are required. +- `full_response` (Optional): Boolean indicating whether to return the full API response. It's set by default to false where it returns only the text embeddings, not the full API response. + +Here's an example of generating embeddings for a list of strings: + +```python +from SimplerLLM.language.embeddings import EmbeddingsLLM, EmbeddingsProvider + +texts = ["Hello World", "Discussing AI.", "Artificial intelligence has many applications."] +embeddings_llm_instance = EmbeddingsLLM.create(EmbeddingsProvider.OPENAI, "text-embedding-3-small") + +embeddings = embeddings_llm_instance.generate_embeddings(texts) + +print(embeddings) +``` + +### Generating Embeddings Asynchronously + +For applications that benefit from non-blocking operations, use the `generate_embeddings_async` method to perform asynchronous embeddings generation. It also takes the same 2 parameters: +- `user_input`: String or list of strings for which embeddings are required. +- `full_response` (Optional): Boolean indicating whether to return the full API response. It's set by default to false where it returns only the text embeddings, not the full API response. + +Generating embeddings asynchronously for a list of strings: + +```python +import asyncio +from SimplerLLM.language.embeddings import EmbeddingsLLM, EmbeddingsProvider + +async def generate_async_embeddings(): + texts = ["Hello World", "Discussing AI.", "Artificial intelligence has many applications."] + embeddings_llm_instance = EmbeddingsLLM.create(EmbeddingsProvider.OPENAI, "text-embedding-3-small") + + tasks = [embeddings_llm_instance.generate_embeddings_async(text) for text in texts] + + embeddings = await asyncio.gather(*tasks) + + print(embeddings) + +asyncio.run(generate_async_embeddings()) +``` + +This method allows your application to remain responsive while processing multiple embedding requests simultaneously. + +--- + +That's how you can benefit from SimplerLLM to make Vector Embeddings Generation Simpler! diff --git a/Documentation/docs/Vector Storage/_category_.json b/Documentation/docs/Vector Storage/_category_.json new file mode 100644 index 0000000..e956a10 --- /dev/null +++ b/Documentation/docs/Vector Storage/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Vector Storage", + "position": 3 +} \ No newline at end of file diff --git a/Documentation/docs/intro.md b/Documentation/docs/intro.md index 6a1ac29..9b80c46 100644 --- a/Documentation/docs/intro.md +++ b/Documentation/docs/intro.md @@ -3,6 +3,96 @@ sidebar_position: 1 slug: / --- -# Coming Soon +# Introduction -## Straight-Forward Documentation for SimplerLLM \ No newline at end of file +SimplerLLM is an open-source Python library designed to simplify interactions with Large Language Models (LLMs). + +Whether you’re a developer working on AI-powered applications or a beginner getting started with ways to benefit from LLMs, SimplerLLM provides a unified interface and powerful tools that make it super easy to integrate AI into your projects. + +Having functionalities that simplify complex tasks like data extraction, text chunking, and vector database integration, SimplerLLM allows you to focus on building optimal AI workflows and projects rather than getting lost in configurations. + +### Examples of Projects Made Easy with SimplerLLM: + +- [Semantic Chunking Guide](https://learnwithhasan.com/what-is-semantic-chunking/) +- [How to Build a Plagiarism Detector](https://learnwithhasan.com/how-to-build-a-semantic-plagiarism-detector/) +- [Find Similar Research Paper Abstracts](https://learnwithhasan.com/find-similar-research-paper-abstracts/) +- [Get Consistent Structured JSON from LLMs](https://learnwithhasan.com/consistent-json-gemini-python/) +- [Build an AI Paraphraser Tool](https://learnwithhasan.com/ai-paraphraser-tool/) +- [Topic Research with AI](https://learnwithhasan.com/topic-research-with-ai/) +- [Repurpose Content with a single click](https://learnwithhasan.com/repurpose-content-ai-python/) +- [Create a SEO Tool for Automated Blog Interlinking](https://learnwithhasan.com/ai-seo-tool-interlinking/) +- [And Much More!](https://learnwithhasan.com/blog/) + +## Main Functionalies + +SimplerLLM is designed to make coding literally **Simpler**:smile: Here are some of the key features it provides: +- **Unified Interface**: Manage interactions with multiple Large Language Models (OpenAI, Google Gemini, Ollamma Local Model, etc...) from one place. +- **Search Engine Integrations**: Integrate search engine functionalities from Google and DuckDuckGo directly into your applications. +- **Generic Loader**: Load text from web content like articles, YouTube video transcripts, and traditional formats like PDF, CSV, and DOCX with one click. In addition to Writing to files with simple functions. +- **Vector Embeddings & Databases**: Easily create vector embeddings and add them into a vector database. +- **Multiple Chunking Functions**: Advanced text processing to split texts into chunks by size, sentences, or even semantics. +- **Dynamic Prompt Templates**: Use prompt templates with dynamic inputs and easily replace placeholder values with desired content. +- **Image Generation**: Create high-quality images tailored to your needs using the Stability API. +- **Image Storage**: Easily save images from the web directly to your device. +- **YouTube Data Extraction**: Extract metadata and detailed transcripts from any YouTube video. +- **AI Agent Interaction & Creation**: Simplify setting up and customizing AI agents for personalized applications. + +## Setup SimplerLLM + +To get started with SimplerLLM, follow these steps: + +#### **1. Install the Library** + +First, install SimplerLLM using `pip`: + +```bash +pip install simplerllm +``` + +#### **2. Set Up Your Environment (.env File)** + +To use this library, you need to set several API keys in your environment. Start by creating a `.env` file in the root directory of your project and adding your API keys there. + +🔴 **Important:** This file should be kept private and not committed to version control (e.g., add it to your `.gitignore` file) to protect your keys. + +Here is an example of what your `.env` file would look like: + +``` +OPENAI_API_KEY="your_openai_api_key_here" # For accessing OpenAI's API +GEMINI_API_KEY="your_gemeni_api_key_here" # For accessing Gemini's API +ANTHROPIC_API_KEY="your_claude_api_key_here" # For accessing Anthropic's API +RAPIDAPI_API_KEY="your_rapidapi_api_key_here" # For accessing APIs on RapidAPI +VALUE_SERP_API_KEY="your_value_serp_api_key_here" # For Google search +SERPER_API_KEY="your_serper_api_key_here" # For Google search +LWH_API_KEY="your_lwh_api_key" # For LLM Playground on LearnWithHasan +LWH_USER_ID="your_lwh_user_id" # For LLM Playground on LearnWithHasan +STABILITY_API_KEY="your_stability_api_key_here" # For image generation +``` + +Each of these keys corresponds to a specific functionality within SimplerLLM. Depending on which features you plan to use, you can add only the relevant keys. + +## Contribute and Collaborate + +If you need help using SimplerLLM or have questions about building projects with it, there are several ways to get support and connect with the community: + +### 1. Join Our Discord Community + +We have an active Discord server where users can: +- Ask questions about the library and receive help from other users. +- Share projects and ideas for using SimplerLLM in creative ways. +- Report bugs and get assistance with troubleshooting issues. + +Whether you’re a beginner or an experienced developer, the Discord community is a great place to learn and collaborate. + +[Join the SimplerLLM Discord Server](https://discord.com/invite/HUrtZXyp3j) + +### 2. Contribute to the Project + +SimplerLLM is an open-source project, and we welcome contributions from the community! If you notice an issue in the documentation or want to improve the codebase, you can easily contribute: + +- On any documentation page, click the **"Edit this page"** link at the bottom. +- This will take you to the GitHub repository, where you can fork the project and make your changes. +- Once your changes are ready, submit a pull request for review. +- If the changes are approved, they will be merged and reflected on the site. + +Your contributions help improve SimplerLLM and make it more useful for everyone. We value every suggestion, fix, and improvement made by the community. diff --git a/Documentation/docusaurus.config.js b/Documentation/docusaurus.config.js index d5d5a1a..6e82f7b 100644 --- a/Documentation/docusaurus.config.js +++ b/Documentation/docusaurus.config.js @@ -69,7 +69,14 @@ const config = { }), ], ], - + plugins: [ + [ + '@docusaurus/plugin-google-gtag', + { + trackingID: 'G-JF551810R5' + }, + ], + ], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ @@ -89,6 +96,11 @@ const config = { // label: 'Tutorial', // }, //{to: '/blog', label: 'Blog', position: 'left'}, + { + href: 'https://simplerllm.com/', + label: 'Home Page', + position: 'left', + }, { href: 'https://github.com/hassancs91/SimplerLLM/blob/main/readme.md', label: 'GitHub', @@ -103,29 +115,33 @@ const config = { }, footer: { style: 'dark', - links: [ - { - title: 'Docs', - items: [ - { - label: 'Introduction', - to: '/', - }, - ], - }, - { - title: 'Community', - items: [ - { - label: 'GitHub', - href: 'https://github.com/hassancs91/SimplerLLM/blob/main/readme.md', - }, - { - label: 'Discord', - href: 'https://discord.com/invite/HUrtZXyp3j', - }, - ], - }, + // links: [ + // { + // title: 'Navigation', + // items: [ + // { + // label: 'Introduction', + // to: '/', + // }, + // { + // label: 'Home Page', + // to: 'https://simplerllm.com', + // }, + // ], + // }, + // { + // title: 'Community', + // items: [ + // { + // label: 'GitHub', + // href: 'https://github.com/hassancs91/SimplerLLM/blob/main/readme.md', + // }, + // { + // label: 'Discord', + // href: 'https://discord.com/invite/HUrtZXyp3j', + // }, + // ], + // }, // { // title: 'More', // items: [ @@ -139,7 +155,7 @@ const config = { // }, // ], // }, - ], + //], copyright: `Copyright © ${new Date().getFullYear()} SimplerLLM. All Rights Reserved`, }, prism: { diff --git a/Documentation/package-lock.json b/Documentation/package-lock.json index 3ada6fd..538dd7b 100644 --- a/Documentation/package-lock.json +++ b/Documentation/package-lock.json @@ -9,6 +9,8 @@ "version": "0.0.0", "dependencies": { "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-google-analytics": "^3.5.2", + "@docusaurus/plugin-google-gtag": "^3.5.2", "@docusaurus/preset-classic": "3.5.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", diff --git a/Documentation/package.json b/Documentation/package.json index 84648db..6955540 100644 --- a/Documentation/package.json +++ b/Documentation/package.json @@ -15,6 +15,8 @@ }, "dependencies": { "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-google-analytics": "^3.5.2", + "@docusaurus/plugin-google-gtag": "^3.5.2", "@docusaurus/preset-classic": "3.5.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", diff --git a/Documentation/src/pages/main_home_page.js b/Documentation/src/pages/main_home_page.js index a8c61f2..7426cfb 100644 --- a/Documentation/src/pages/main_home_page.js +++ b/Documentation/src/pages/main_home_page.js @@ -17,11 +17,11 @@ function HomepageHeader() {
{siteConfig.tagline}