Skip to content

Commit

Permalink
Merge pull request #133 from getjavelin/new-feature
Browse files Browse the repository at this point in the history
New feature
  • Loading branch information
dhruvj07 authored Feb 12, 2025
2 parents a746bfa + 360eea6 commit 2f9c931
Show file tree
Hide file tree
Showing 16 changed files with 1,605 additions and 47 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
142 changes: 142 additions & 0 deletions examples/azure-openai/azure-universal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import os
from openai import AzureOpenAI
from javelin_sdk import JavelinClient, JavelinConfig

def initialize_client():
"""
Creates the AzureOpenAI client and registers it with Javelin.
Returns the AzureOpenAI client object if successful, else None.
"""
javelin_api_key = "" # add your javelin api key here
azure_openai_api_key = "" # Add your Azure OpenAI key

if not javelin_api_key:
print("Error: JAVELIN_API_KEY is not set!")
return None
else:
print("JAVELIN_API_KEY found.")

if not azure_openai_api_key:
print("Warning: AZURE_OPENAI_API_KEY is not set!")
else:
print("AZURE_OPENAI_API_KEY found.")

# Create the Azure client
azure_client = AzureOpenAI(
# Typically "2023-07-01-preview" or a more recent version
api_version="2023-07-01-preview",
azure_endpoint="https://javelinpreview.openai.azure.com",
api_key=azure_openai_api_key
)

# Initialize the Javelin client and register the Azure client
config = JavelinConfig(javelin_api_key=javelin_api_key)
javelin_client = JavelinClient(config)
javelin_client.register_azureopenai(azure_client, route_name="azureopenai-univ")

return azure_client


def get_chat_completion_sync(azure_client, messages):
"""
Calls the Azure Chat Completions endpoint (non-streaming).
Takes a list of message dicts, returns JSON response as a string.
Example model: 'gpt-4' or your deployed name (like 'gpt-4o').
"""
response = azure_client.chat.completions.create(
model="gpt-4", # Adjust to your Azure deployment name
messages=messages
)
return response.to_json()


def get_chat_completion_stream(azure_client, messages):
"""
Calls the Azure Chat Completions endpoint with streaming=True.
Returns the concatenated text from the streamed chunks (for demonstration).
"""
response = azure_client.chat.completions.create(
model="gpt-4", # Adjust to your Azure deployment name
messages=messages,
stream=True
)

# Accumulate streamed text
streamed_text = []
for chunk in response:
# chunk is an OpenAIObject with partial content in chunk.choices[0].delta
if hasattr(chunk, "choices") and chunk.choices and chunk.choices[0].delta:
streamed_text.append(chunk.choices[0].delta.get("content", ""))

return "".join(streamed_text)


def get_text_completion(azure_client, prompt):
"""
Demonstrates Azure text completion (non-chat).
For this, your Azure resource must have a 'completions' model deployed,
e.g. 'text-davinci-003'.
"""
response = azure_client.completions.create(
model="gpt-4o", # Adjust to your actual Azure completions model name
prompt=prompt,
max_tokens=50,
temperature=0.7
)
return response.to_json()


def get_embeddings(azure_client, text):
"""
Demonstrates Azure embeddings endpoint.
Your Azure resource must have an embeddings model, e.g. 'text-embedding-ada-002'.
"""
response = azure_client.embeddings.create(
model="text-embedding-ada-002", # Adjust to your embeddings model name
input=text
)
return response.to_json()


def main():
print("Azure OpenAI via Javelin Testing:")
azure_client = initialize_client()
if azure_client is None:
print("Client initialization failed.")
return

# Example chat messages
messages = [
{"role": "user", "content": "say hello"}
]

# 1) Chat Completion (Synchronous)
try:
print("\n--- Chat Completion (Non-Streaming) ---")
response_chat_sync = get_chat_completion_sync(azure_client, messages)
print("Response:\n", response_chat_sync)
except Exception as e:
print("Error in chat completion (sync):", e)

# 2) Chat Completion (Streaming)
try:
print("\n--- Chat Completion (Streaming) ---")
response_streamed = get_chat_completion_stream(azure_client, messages)
print("Streamed Content:\n", response_streamed)
except Exception as e:
print("Error in chat completion (streaming):", e)

# 3) Embeddings
try:
print("\n--- Embeddings ---")
embed_text = "Sample text to embed."
embed_resp = get_embeddings(azure_client, embed_text)
print("Response:\n", embed_resp)
except Exception as e:
print("Error in embeddings:", e)

print("\n--- Script complete. ---")


if __name__ == "__main__":
main()
166 changes: 166 additions & 0 deletions examples/azure-openai/langchain_azure_universal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import os
import dotenv
dotenv.load_dotenv()

from langchain_openai import AzureChatOpenAI
from langchain.schema import HumanMessage, SystemMessage, AIMessage
from langchain.callbacks.base import BaseCallbackHandler
from langchain.callbacks.manager import CallbackManager

#
# 1) Keys and Route Setup
#
print("Initializing environment variables...")

azure_openai_api_key = os.getenv("AZURE_OPENAI_API_KEY")
javelin_api_key = os.getenv("JAVELIN_API_KEY")

# The name of your Azure deployment (e.g., "gpt-4")
# or whatever you’ve set in Azure.
# Must also match x-javelin-model if Javelin expects that.
model_choice = "gpt-4"

# Javelin route name, as registered in your javelin route dashboard
route_name = "saviour"

print("Azure OpenAI key:", "FOUND" if azure_openai_api_key else "MISSING")
print("Javelin key:", "FOUND" if javelin_api_key else "MISSING")

#
# 2) Non-Streaming Client
#
llm_non_streaming = AzureChatOpenAI(
openai_api_key=azure_openai_api_key,
# Provide your actual API version
api_version="2024-08-01-preview",
# The base_url is Javelin’s universal route
# pointing to your Azure endpoint:
base_url="https://api-dev.javelin.live/v1/azureopenai/deployments/gpt-4/",
validate_base_url=False,
verbose=True,
default_headers={
"x-api-key": javelin_api_key,
"x-javelin-route": route_name,
"x-javelin-model": model_choice,
"x-javelin-provider": "https://javelinpreview.openai.azure.com/openai",
},
streaming=False # Non-streaming
)

#
# 3) Single-Turn Invoke (Non-Streaming)
#
def invoke_non_streaming(question: str) -> str:
"""
Sends a single user message to the non-streaming LLM
and returns the text response.
"""
# Build the messages
messages = [HumanMessage(content=question)]
# Use .invoke(...) to get the LLM’s response
response = llm_non_streaming.invoke(messages)
# The response is usually an AIMessage. Return its content.
return response.content

#
# 4) Single-Turn Streaming
# We'll create a new LLM with streaming=True, plus a callback handler.
#

class StreamCallbackHandler(BaseCallbackHandler):
"""
Collects tokens as they are streamed, so we can return the final text.
"""
def __init__(self):
self.tokens = []

def on_llm_new_token(self, token: str, **kwargs) -> None:
self.tokens.append(token)


def invoke_streaming(question: str) -> str:
"""
Sends a single user message to the LLM (streaming=True).
Collects the tokens from the callback and returns them as a string.
"""
callback_handler = StreamCallbackHandler()
callback_manager = CallbackManager([callback_handler])

# Create a streaming LLM
llm_streaming = AzureChatOpenAI(
openai_api_key=azure_openai_api_key,
api_version="2024-08-01-preview",
base_url="https://api-dev.javelin.live/v1/azureopenai/deployments/gpt-4/",
validate_base_url=False,
verbose=True,
default_headers={
"x-api-key": javelin_api_key,
"x-javelin-route": route_name,
"x-javelin-model": model_choice,
"x-javelin-provider": "https://javelinpreview.openai.azure.com/openai",
},
streaming=True, # <-- streaming on
callbacks=[callback_handler] # <-- our custom callback
)

messages = [HumanMessage(content=question)]
response = llm_streaming.invoke(messages)
# We could check response, but it's usually an AIMessage with partial content
# The real text is captured in the callback tokens
return "".join(callback_handler.tokens)

#

def conversation_demo():
"""
Demonstrates a multi-turn conversation by manually
appending messages to a list and re-invoking the LLM.
No memory objects are used, so it’s purely manual.
"""

conversation_llm = llm_non_streaming

# Start with a system message
messages = [SystemMessage(content="You are a friendly assistant.")]

user_q1 = "Hello, how are you?"
messages.append(HumanMessage(content=user_q1))
response_1 = conversation_llm.invoke(messages)
messages.append(response_1) # add AIMessage to context
print(f"User: {user_q1}\nAssistant: {response_1.content}\n")

user_q2 = "Can you tell me a fun fact about dolphins?"
messages.append(HumanMessage(content=user_q2))
response_2 = conversation_llm.invoke(messages)
messages.append(response_2)
print(f"User: {user_q2}\nAssistant: {response_2.content}\n")

return "Conversation done!"

#
# 6) Main function
#

def main():
print("=== LangChain AzureOpenAI Example ===")

# 1) Single-turn non-streaming
print("\n[1) Single-turn Non-Streaming Invoke]")
question_a = "What is the capital of France?"
response_a = invoke_non_streaming(question_a)
print(f"Question: {question_a}\nAnswer: {response_a}")

# 2) Single-turn streaming
print("\n[2) Single-turn Streaming Invoke]")
question_b = "Tell me a quick joke."
response_b = invoke_streaming(question_b)
print(f"Question: {question_b}\nStreamed Answer: {response_b}")

# 3) Multi-turn conversation (non-streaming)
print("\n[3) Simple Conversation Demo]")
conversation_demo()

print("\n=== All done! ===")

if __name__ == "__main__":
main()
Loading

0 comments on commit 2f9c931

Please sign in to comment.