Skip to content
This repository has been archived by the owner on Nov 3, 2024. It is now read-only.

Commit

Permalink
[HN-476] feat: use new chat endpoint (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
ToJen authored Sep 24, 2024
1 parent 8d9e31c commit da41c76
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 269 deletions.
1 change: 0 additions & 1 deletion hive_agent_client/chat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
send_chat_message,
get_chat_history,
get_all_chats,
send_chat_media
)
129 changes: 52 additions & 77 deletions hive_agent_client/chat/chat.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import httpx
import io
import json
import logging
import mimetypes
import os
import sys
from typing import List, Dict

from typing import List, Dict, Union
from fastapi import UploadFile

def get_log_level():
HIVE_AGENT_LOG_LEVEL = os.getenv("HIVE_AGENT_LOG_LEVEL", "INFO").upper()
Expand All @@ -18,11 +22,12 @@ def get_log_level():


async def send_chat_message(
http_client: httpx.AsyncClient,
base_url: str,
user_id: str,
session_id: str,
content: str,
http_client: httpx.AsyncClient,
base_url: str,
user_id: str,
session_id: str,
content: str,
files: List[Union[UploadFile, str]] = None # Can be either UploadFile or file path
) -> str:
"""
Sends a chat message to the Hive Agent API and returns the response.
Expand All @@ -32,6 +37,7 @@ async def send_chat_message(
:param user_id: The user ID.
:param session_id: The session ID.
:param content: The content of the message to be sent.
:param files: List of UploadFile objects or file paths to be uploaded.
:return: The response text from the API.
:raises ValueError: If the content is empty.
:raises httpx.HTTPStatusError: If the request fails due to a network error or returns a 4xx/5xx response.
Expand All @@ -42,15 +48,46 @@ async def send_chat_message(

endpoint = "/chat"
url = f"{base_url}{endpoint}"
payload = {

chat_data = json.dumps({
"messages": [
{
"role": "user",
"content": content
}
]
})

form_data = {
"user_id": user_id,
"session_id": session_id,
"chat_data": {"messages": [{"role": "user", "content": content}]},
"chat_data": chat_data, # Send as a JSON string
}

files_to_send = []

if files:
for file in files:
if isinstance(file, UploadFile):
# Handle UploadFile (received from an HTTP request)
files_to_send.append(
("files", (file.filename, file.file, file.content_type))
)
elif isinstance(file, str):
# Handle file paths
file_name = os.path.basename(file)
content_type, _ = mimetypes.guess_type(file)
files_to_send.append(
("files", (file_name, open(file, "rb"), content_type))
)

try:
logging.debug(f"Sending chat message to {url}: {content}")
response = await http_client.post(url, json=payload)
logging.debug(f"Sending chat message to {url}")
response = await http_client.post(
url,
data=form_data,
files=files_to_send # Attach files if any
)
response.raise_for_status()
logger.debug(f"Response from chat message {content}: {response.text}")
return response.text
Expand All @@ -73,6 +110,11 @@ async def send_chat_message(
raise Exception(
f"An unexpected error occurred when sending message to the chat API: {e}"
)
finally:
# Close any files opened from file paths
for file in files_to_send:
if isinstance(file[1][1], io.IOBase): # Check if it's a file object
file[1][1].close()


async def get_chat_history(
Expand Down Expand Up @@ -171,70 +213,3 @@ async def get_all_chats(
raise Exception(
f"An unexpected error occurred when fetching all chats from the chat API: {e}"
)


async def send_chat_media(
http_client: httpx.AsyncClient,
base_url: str,
user_id: str,
session_id: str,
chat_data: str,
files: List[str],
) -> str:
"""
Sends a chat message with associated media files to the Hive Agent API and returns the response.
:param http_client: An instance of httpx.AsyncClient to make HTTP requests.
:param base_url: The base URL of the Hive Agent API.
:param user_id: The user ID.
:param session_id: The session ID.
:param chat_data: The chat data in JSON format as a string.
:param files: A list of file paths to be uploaded.
:return: The response text from the API.
:raises ValueError: If the chat_data or files list is empty.
:raises httpx.HTTPStatusError: If the request fails due to a network error or returns a 4xx/5xx response.
:raises Exception: For other types of errors.
"""
if not chat_data.strip():
raise ValueError("Chat data must not be empty")
if not files:
raise ValueError("Files list must not be empty")

endpoint = "/chat_media"
url = f"{base_url}{endpoint}"

files_data = [('files', open(file_path, 'rb')) for file_path in files]
data = {
'user_id': user_id,
'session_id': session_id,
'chat_data': chat_data,
}

try:
logging.debug(f"Sending chat media to {url} with files: {files}")
response = await http_client.post(url, data=data, files=files_data)
response.raise_for_status()
logger.debug(f"Response from chat media: {response.text}")
return response.text
except httpx.HTTPStatusError as e:
logging.error(
f"HTTP error occurred when sending chat media to {url}: {e.response.status_code} - {e.response.text}"
)
raise Exception(
f"HTTP error occurred when sending chat media to the chat API: {e.response.status_code} - {e.response.text}"
)
except httpx.RequestError as e:
logging.error(f"Request error occurred when sending chat media to {url}: {e}")
raise Exception(
f"Request error occurred when sending chat media to the chat API: {e}"
)
except Exception as e:
logging.error(
f"An unexpected error occurred when sending chat media to {url}: {e}"
)
raise Exception(
f"An unexpected error occurred when sending chat media to the chat API: {e}"
)
finally:
for _, file_handle in files_data:
file_handle.close()
43 changes: 13 additions & 30 deletions hive_agent_client/client.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import httpx
import logging

from typing import Dict, List, Any
from typing import Dict, List, Any, Union

from fastapi import UploadFile

from hive_agent_client.chat import (
send_chat_message,
get_chat_history,
get_all_chats,
send_chat_media
)
from hive_agent_client.database import (
create_table,
Expand Down Expand Up @@ -41,24 +42,31 @@ def __init__(self, base_url: str, version: str = "v1", timeout: float = 30.0):
self.base_url = f"{base_url}/{version}"
self.http_client = httpx.AsyncClient(timeout=timeout)

async def chat(self, user_id: str, session_id: str, content: str) -> str:
async def chat(self, user_id: str, session_id: str, content: str, files: List[Union[UploadFile, str]] = None) -> str:
"""
Send a message to the chat endpoint.
Send a message to the chat endpoint with optional file attachments.
:param user_id: The user ID.
:param session_id: The session ID.
:param content: The content of the message to send.
:param files: Optional list of file paths or UploadFile objects to send.
:return: The response from the chat API as a string.
"""
try:
logger.debug(f"Sending message to chat endpoint: {content}")
return await send_chat_message(
self.http_client, self.base_url, user_id, session_id, content
self.http_client, self.base_url, user_id, session_id, content, files
)
except Exception as e:
logger.error(f"Failed to send chat message - {content}: {e}")
raise Exception(f"Failed to send chat message: {e}")

async def close(self):
"""
Close the HTTP client session.
"""
await self.http_client.aclose()

async def get_chat_history(self, user_id: str, session_id: str) -> List[Dict]:
"""
Retrieve the chat history for a specified user and session.
Expand Down Expand Up @@ -91,31 +99,6 @@ async def get_all_chats(self, user_id: str) -> Dict[str, List[Dict]]:
logger.error(f"Failed to get all chats for user {user_id}: {e}")
raise Exception(f"Failed to get all chats: {e}")

async def chat_media(
self,
user_id: str,
session_id: str,
chat_data: str,
files: List[str],
) -> str:
"""
Send a chat message with associated media files to the chat_media endpoint.
:param user_id: The user ID.
:param session_id: The session ID.
:param chat_data: The chat data in JSON format as a string.
:param files: A list of file paths to be uploaded.
:return: The response from the chat_media API as a string.
"""
try:
logger.debug(f"Sending chat media to chat_media endpoint with files: {files}")
return await send_chat_media(
self.http_client, self.base_url, user_id, session_id, chat_data, files
)
except Exception as e:
logger.error(f"Failed to send chat media - files: {files}, error: {e}")
raise Exception(f"Failed to send chat media: {e}")

async def create_table(self, table_name: str, columns: dict) -> Dict:
"""
Create a new table in the database.
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.8"
httpx = "^0.27.0"
fastapi = "0.115.0"
pillow = "10.4.0"

[tool.poetry.dev-dependencies]
python = "^3.8"
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
httpx==0.27.0
fastapi==0.115.0
pillow==10.4.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name="hive-agent-client",
version="0.0.1",
packages=find_packages(include=["hive_agent_client", "hive_agent_client.*"]),
install_requires=["httpx==0.27.0"],
install_requires=["httpx==0.27.0", "fastapi==0.115.0", "pillow==10.4.0"],
description="A client library for sending messages to a Hive Agent",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
Expand Down
Loading

0 comments on commit da41c76

Please sign in to comment.