Skip to content

Commit

Permalink
Update documentation; Improve Errors; Update Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
GustyCube committed Dec 29, 2024
1 parent ededc9d commit 4d74ae7
Show file tree
Hide file tree
Showing 20 changed files with 348 additions and 140 deletions.
56 changes: 28 additions & 28 deletions docs/.vitepress/cache/deps/@theme_index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions docs/.vitepress/cache/deps/_metadata.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
{
"hash": "39449747",
"configHash": "3c1fa02a",
"hash": "d6583594",
"configHash": "c4b03129",
"lockfileHash": "d1ebd6ff",
"browserHash": "92b369d7",
"browserHash": "d47ea5d5",
"optimized": {
"vue": {
"src": "../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
"fileHash": "65499a09",
"fileHash": "7ad5fc8c",
"needsInterop": false
},
"vitepress > @vue/devtools-api": {
"src": "../../../node_modules/@vue/devtools-api/dist/index.js",
"file": "vitepress___@vue_devtools-api.js",
"fileHash": "8050636f",
"fileHash": "19c8795d",
"needsInterop": false
},
"vitepress > @vueuse/core": {
"src": "../../../node_modules/@vueuse/core/index.mjs",
"file": "vitepress___@vueuse_core.js",
"fileHash": "dcdf8678",
"fileHash": "12dfe7a6",
"needsInterop": false
},
"@theme/index": {
"src": "../../../node_modules/vitepress/dist/client/theme-default/index.js",
"file": "@theme_index.js",
"fileHash": "e88459d4",
"fileHash": "be618a6a",
"needsInterop": false
}
},
Expand Down
23 changes: 17 additions & 6 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,32 @@ export default defineConfig({
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: 'Home', link: '/' },
{ text: 'Overview', link: '/markdown-examples' }
{ text: 'Overview', link: '/overview' },
{ text: 'Installation', link: '/installation' }
],

sidebar: [
{
text: 'Examples',
text: 'Getting Started',
items: [
{ text: 'Markdown Examples', link: '/markdown-examples' },
{ text: 'Runtime API Examples', link: '/api-examples' }
{ text: 'Overview', link: '/overview' },
{ text: 'Installation', link: '/installation' },
{ text: 'Error Handling', link: '/errorhandling' },
]
}
},
{
text: 'Guide',
items: [
{ text: 'App Creation', link: '/appcreation' },
{ text: 'Text To Speech', link: '/texttospeech' },
{ text: 'Pipelines', link: '/pipelines' },
{ text: 'Custom AI', link: '/customai' }
]
},
],

socialLinks: [
{ icon: 'github', link: 'https://github.com/GustyCube/EasyAI' }
{ icon: 'github', link: 'https://github.com/GustyCube/EasilyAI' }
]
}
})
19 changes: 18 additions & 1 deletion docs/appcreation.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# AI App Creation
# App Creation

## Overview
EasyAI allows you to initialize an AI app quickly and seamlessly using OpenAI or Ollama.
Expand All @@ -18,3 +18,20 @@ app = easyai.create_app(
response = app.request("Tell me a joke about AI.")
print(response)
```

## Creating an Ollama App

For local models using Ollama:

```python
app = easyai.create_app(
name="my_ai_app",
service="ollama",
model="llama2"
)

response = app.request("What is the future of AI?")
print(response)
```

Learn more about [Text-to-Speech](./texttospeech.md) in EasyAI.
27 changes: 27 additions & 0 deletions docs/customai.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Custom AI Integration

## Overview
EasyAI allows you to integrate your own AI models and services.

## Registering a Custom AI Service

```python
from easyai.custom_ai import CustomAIService, register_custom_ai

# Define a custom AI service
class MyCustomAI(CustomAIService):
def generate_text(self, prompt):
return f"Custom AI response for: {prompt}"

def text_to_speech(self, text, **kwargs):
return f"Custom TTS output: {text}"

# Register the custom AI
register_custom_ai("my_custom_ai", MyCustomAI)

# Use the custom AI
custom_app = easyai.create_app(name="custom_ai_app", service="my_custom_ai")
print(custom_app.request("Hello from Custom AI!"))
```

Now you are ready to use and expand EasyAI for your projects! Revisit the [Installation Guide](./installation.md) if needed.
20 changes: 20 additions & 0 deletions docs/errorhandling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Error Handling

## Overview
EasyAI includes robust error handling with clear, emoji-coded messages for quick debugging.

### Common Errors
- 🔐 **Missing API Key**: "No API key provided! Add your API key to initialize the service."
- 🚫 **Invalid Request**: "The request is invalid. Please check your inputs."
- 🌐 **Connection Error**: "Unable to connect to the API. Ensure the server is running."
-**Rate Limit Exceeded**: "Too many requests! Wait and try again."

## Example

```python
try:
app = easyai.create_app(name="example", service="openai")
app.request("Test request")
except Exception as e:
print(e)
```
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ pip install easyai
- **API Key for OpenAI** *(optional if using OpenAI services)*
- **Ollama Installation** for running local models.

After installation, proceed to [Creating an AI App](./app-creation.md).
After installation, proceed to [Creating an AI App](./appcreation.md).
25 changes: 25 additions & 0 deletions docs/pipelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Pipeline Guide

## Overview
Pipelines in EasyAI allow you to chain multiple tasks (e.g., text generation, image generation, and TTS) into a workflow.

## Example Pipeline

```python
# Create a pipeline
pipeline = easyai.EasyAIPipeline(app)

# Add tasks
pipeline.add_task("generate_text", "Write a poem about AI and nature.")
pipeline.add_task("generate_image", "A futuristic city skyline.")
pipeline.add_task("text_to_speech", "Here is a futuristic AI-powered city!")

# Run the pipeline
results = pipeline.run()

# Print results
for task_result in results:
print(f"Task: {task_result['task']}\nResult: {task_result['result']}\n")
```

Discover how to extend EasyAI with [Custom AI Models](./customai.md).
33 changes: 33 additions & 0 deletions docs/texttospeech.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Text-to-Speech Guide

## Overview
EasyAI supports OpenAI's Text-to-Speech API for converting text into audio files.

## Generate Speech with OpenAI

```python
# Initialize a TTS App
tts_app = easyai.create_tts_app(
name="tts_app",
service="openai",
apikey="YOUR_API_KEY",
model="tts-1"
)

# Convert text to speech
output_file = tts_app.request_tts(
text="Hello, I am your AI assistant!",
tts_model="tts-1",
voice="onyx",
output_file="hello_ai.mp3"
)

print(f"TTS output saved to: {output_file}")
```

## Supported Voices
- `onyx`
- `alloy`
- `echo`

Next, explore [Pipelines](./pipelines.md) for chaining tasks.
3 changes: 2 additions & 1 deletion easilyai/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def __init__(self, name, service, apikey=None, model=None, max_tokens = None):
else:
raise UnsupportedServiceError(
f"Unsupported service '{service}'! Use 'openai', 'ollama', or a registered custom service. "
"Refer to the Easy ::contentReference[oaicite:0]{index=0}")
"Refer to the EasyAI documentation for more information."
)

def request(self, task_type, task):
# Instead of checking if the task contains "image" or "speech", we should
Expand Down
31 changes: 23 additions & 8 deletions easilyai/services/anthropic_service.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
import anthropic

from easilyai.exceptions import (
AuthenticationError, RateLimitError, InvalidRequestError,
APIConnectionError, NotFoundError, ServerError, MissingAPIKeyError
)

class AnthropicService:
def __init__(self, apikey, model, max_tokens = 1024):
def __init__(self, apikey, model, max_tokens=1024):
if not apikey:
raise MissingAPIKeyError(
"Anthropic API key is missing! Please provide your API key when initializing the service. "
"Refer to the EasyAI documentation for more information."
)
self.apikey = apikey
self.model = model
self.max_tokens = max_tokens
self.client = anthropic.Anthropic(apikey)
self.client = anthropic.Anthropic(api_key=apikey) # Correct initialization

def generate_text(self, prompt):
try:
response = self.client.messages.create(max_tokens = self.max_tokens,
messages = [{"role": "user", "content": prompt}],
model = self.model)
return response.content
response = self.client.messages.create(
model=self.model,
max_tokens=self.max_tokens,
messages=[{"role": "user", "content": prompt}],
)
# Extract the text content
return response.get("content")[0].get("text")
except anthropic.errors.AuthenticationError:
raise AuthenticationError("Invalid API key. Please check your Anthropic API key.")
except anthropic.errors.RateLimitError:
raise RateLimitError("Rate limit exceeded. Please wait and try again later.")
except anthropic.errors.InvalidRequestError as e:
raise InvalidRequestError(f"Invalid request: {str(e)}. Check your parameters.")
except anthropic.errors.APIConnectionError:
raise APIConnectionError("Unable to connect to Anthropic API. Check your network.")
except Exception as e:
raise ServerError(
f"Unknown error occurred! Please try again later or look at the EasilyAi Docs. Error: {e}"
f"An unexpected error occurred: {str(e)}. Please try again later."
)
11 changes: 7 additions & 4 deletions easilyai/services/gemini_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ def __init__(self, apikey, model):
if not apikey:
raise MissingAPIKeyError(
"Gemini API key is missing! Please provide your API key when initializing the service. "
"Refer to the EasyAI documentation for more information."
"Refer to the EasilyAI documentation for more information."
)
googleai.configure(api_key=apikey)
self.model = googleai.GenerativeModel(model)
# Ensure only the last part of the model name is used
self.model_name = model.split("/")[-1] # Extracts "gemini-1" even if input is "models/gemini-1"
print(self.model_name)
self.full_model_name = model # Full name (e.g., "models/gemini-1")
self.model = googleai.GenerativeModel(self.full_model_name)

def generate_text(self, prompt):
try:
response = self.model.generate_content(prompt)
return response.text
except Exception as e:
raise ServerError(
f"Unknown error occurred! Please try again later or look at the EasilyAi Docs. Error: {e}"
f"Unknown error occurred! Please try again later or look at the EasilyAI Docs. Error: {e}"
)

Loading

0 comments on commit 4d74ae7

Please sign in to comment.