Last active
February 1, 2025 10:20
-
-
Save bitsnaps/c81a753a21831b672ddb276e6f21fb63 to your computer and use it in GitHub Desktop.
This python demo is designed to query any LLM provider using the chat completion OpenAI API using only http requests, all you have to do is to provide the `.env` from your user home or the current running directory, you can set your own default values to override default ones
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import requests | |
import logging | |
from pathlib import Path | |
from dotenv import load_dotenv | |
from typing import Optional | |
#from openai import OpenAI # You don't need it here | |
# Predefined constants | |
#OPENAI_BASE_URL = "https://api.openai.com/v1/" | |
#DEFAULT_MODEL = "gpt-3.5-turbo" | |
#os.environ["OPENAI_API_KEY"] = "sk-" | |
# Configure providers | |
PROVIDERS = { | |
"openai": { | |
"base_url": "https://api.openai.com/v1/", | |
"env_var": "OPENAI_API_KEY", | |
"default_key": "sk-default-openai-key-123", | |
"endpoint": "chat/completions", | |
"default_model": "gpt-3.5-turbo" | |
}, | |
"hf": { | |
# You can use "https://huggingface.co/api/inference-proxy/together/v1" for other LLM: "deepseek-ai/DeepSeek-V3", "deepseek-ai/DeepSeek-R1", "mistralai/Mistral-Small-24B-Instruct-2501"... | |
"base_url": "https://api-inference.huggingface.co/v1/", | |
"env_var": "HF_API_KEY", | |
"default_key": "hf-default-key-456", | |
"endpoint": "chat/completions", | |
"default_model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B" # "Qwen/Qwen2.5-Coder-32B-Instruct", "meta-llama/Llama-3.2-3B-Instruct", "mistralai/Mistral-Nemo-Instruct-2407", "mistralai/Mistral-7B-Instruct-v0.3" | |
}, | |
"groq": { | |
"base_url": "https://api.groq.com/openai/v1/", | |
"env_var": "GROQ_API_KEY", | |
"default_key": "grok-default-key-789", | |
"endpoint": "chat/completions", | |
"default_model": "llama-3.3-70b-versatile" | |
}, | |
"openrouter": { | |
"base_url": "https://openrouter.ai/api/v1/", | |
"env_var": "OPENROUTER_API_KEY", | |
"default_key": "or-default-key-012", | |
"endpoint": "chat/completions", | |
"default_model": "meta-llama/llama-3.2-3b-instruct:free", # "google/gemini-2.0-flash-thinking-exp:free", "deepseek/deepseek-r1:free", | |
}, | |
"deepseek": { | |
"base_url": "https://api.deepseek.com/", | |
"env_var": "DEEPSEEK_API_KEY", | |
"default_key": "sk-default-key-345", | |
"endpoint": "chat/completions", | |
"default_model": "deepseek-coder" | |
} | |
} | |
# Load environment variables from .env files | |
def load_environment(): | |
# Check home directory and current directory for .env | |
env_paths = [ | |
Path.home() / ".env", | |
Path.cwd() / ".env" | |
] | |
for path in env_paths: | |
if path.exists(): | |
load_dotenv(path, override=False) | |
logging.info(f"Loaded environment variables from {path}") | |
def get_api_key(provider: str) -> str: | |
"""Get API key from environment or defaults""" | |
config = PROVIDERS.get(provider) | |
if not config: | |
raise ValueError(f"Unsupported provider: {provider}") | |
return os.getenv(config["env_var"]) or config["default_key"] | |
def send_prompt( | |
prompt: str, | |
provider: str = "openai", | |
model: str = "", | |
temperature: float = 0.7, | |
max_tokens: int = 1000 | |
) -> Optional[str]: | |
""" | |
Send prompt to specified provider's API | |
Returns generated text or None on error | |
""" | |
# Get provider configuration | |
config = PROVIDERS.get(provider) | |
if not config: | |
raise ValueError(f"Unsupported provider: {provider}") | |
# Prepare API request | |
api_key = get_api_key(provider) | |
base_url = config["base_url"] | |
endpoint = config["endpoint"] | |
url = f"{base_url}{endpoint}".replace("//v1/", "/v1/") # Normalize URL | |
headers = { | |
"Authorization": f"Bearer {api_key}", | |
"Content-Type": "application/json" | |
} | |
data = { | |
"model": model or config["default_model"], | |
"messages": [{"role": "user", "content": prompt}], | |
"temperature": temperature, | |
"max_tokens": max_tokens | |
} | |
# Mask API key for logging | |
masked_key = f"{api_key[:4]}...{api_key[-4:]}" if len(api_key) > 8 else "****" | |
logging.info(f"\n{'='*40}\nRequest Details:") | |
logging.info(f"URL: {url}") | |
logging.info(f"Headers: { {k: masked_key if 'Authorization' in k else v for k, v in headers.items()} }") | |
logging.info(f"Body: {data}\n{'='*40}\n") | |
try: | |
# If you want to use the OpenAI library use this instead: | |
# client = OpenAI( | |
# base_url=base_url, | |
# api_key=api_key, | |
# ) | |
# completion = client.chat.completions.create( | |
# model=data["model"], | |
# messages=[{"role": "user", "content": prompt}] | |
# ) | |
# return completion.choices[0].message.content | |
response = requests.post(url, headers=headers, json=data, timeout=30) | |
response.raise_for_status() | |
result = response.json() | |
return result['choices'][0]['message']['content'] | |
except requests.exceptions.RequestException as e: | |
logging.error(f"API request failed: {str(e)}") | |
if hasattr(e, 'response') and e.response: | |
logging.error(f"Response content: {e.response.text}") | |
except KeyError as e: | |
logging.error(f"Unexpected response format: {str(e)}") | |
return None | |
if __name__ == "__main__": | |
# Configure logging | |
logging.basicConfig(level=logging.INFO, format="%(message)s") | |
load_environment() | |
# Example usage | |
test_prompt = "Introduce yourself and tell me who created you and what is your current cutoff knwoledge. Output one short sentence." | |
response = send_prompt( | |
prompt=test_prompt, | |
# provider="openai" | |
# provider="hf", | |
provider="groq", | |
# provider="openrouter" | |
# provider="deepseek", | |
#model=DEFAULT_MODEL # default model is rather defined for each provider | |
) | |
if response: | |
print("\nResponse:") | |
print(response) | |
else: | |
print("Failed to get valid response") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment