xAI API integration fix
2025-05-222 turns7,093 charsgpt-4o
Summary
User was fixing xAI API integration in a Python script with incomplete code.
Messages
# main.py
import sys
from search import search_news
def main():
"""
Main function to take user query and display search results.
"""
if len(sys.argv) < 2:
print("Usage: python main.py <query>")
sys.exit(1)
query = " ".join(sys.argv[1:])
print(f"Searching for: {query}")
results = search_news(query)
if results:
for i, result in enumerate(results):
print(f"\nResult {i+1}:")
print(f"Title: {result['title']}")
print(f"URL: {result['url']}")
print(f"Summary: {result['summary']}")
else:
print("No results found or an error occurred.")
if __name__ == "__main__":
main()
# search.py
import os
import requests
from dotenv import load_dotenv
load_dotenv()
XAI_API_KEY = os.getenv("XAI_API_KEY")
XAI_API_URL = "https://api.x.ai/v1/chat/completions" # Assuming this is the API endpoint
def search_news(query: str, num_results: int = 5) -> list:
"""
Fetches live news search results from the xAI Live Search API.
Args:
query: The search query string.
num_results: The maximum number of results to fetch.
Returns:
A list of dictionaries, where each dictionary contains 'title',
'url', and 'summary' for a search result. Returns an empty list
if the API call fails or no results are found.
"""
if not XAI_API_KEY:
print("Error: XAI_API_KEY not found in .env file.")
return []
headers = {
"Authorization": f"Bearer {XAI_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"messages": [
{
"role": "user",
"content": query
}
],
"num_results": num_results,
"search_parameters": {
"mode": "on",
"return_citations": True
},
"model": "grok-3-latest"
}
try:
response = requests.post(XAI_API_URL, headers=headers, json=payload)
response.raise_for_status() # Raise an exception for bad status codes
data = response.json()
# Assuming the API response structure has a 'results' key
# Adjust based on actual API documentation if needed
results = data.get("results", [])
formatted_results = []
for item in results:
formatted_results.append({
"title": item.get("title", "No Title"),
"url": item.get("url", "No URL"),
"summary": item.get("summary", "No Summary")
})
return formatted_results
except requests.exceptions.RequestException as e:
print(f"Error fetching search results: {e}")
return []
except Exception as e:
print(f"An unexpected error occurred: {e}")
return []
if __name__ == "__main__":
# Example usage (for testing the module directly)
test_query = "latest AI developments"
print(f"Searching for: {test_query}")
search_results = search_news(test_query)
if search_results:
for i, result in enumerate(search_results):
print(f"\nResult {i+1}:")
print(f"Title: {result['title']}")
print(f"URL: {result['url']}")
print(f"Summary: {result['summary']}")
else:
print("No results found or an error occurred.")
Your script looks well-structured, but there are **a few issues and potential improvements** to ensure it works properly with the xAI API, which doesn't currently support a "search" API endpoint as described in your payload. Here's a full review and suggestion set:
---
### ✅ 1. **Clarify API Endpoint and Functionality**
You are currently using:
```python
XAI_API_URL = "https://api.x.ai/v1/chat/completions"
```
This endpoint is for chat completions, not live search. If you're trying to simulate a "search engine" via LLM, this needs to be done via prompting, and **you won't get structured fields like `title`, `url`, and `summary`** unless you instruct the model to output that format.
---
### 🔧 2. **Fix: Adjust Payload for Chat Completion (if using Chat-only API)**
If you're trying to use `grok-3-latest` to fake a search via prompt, your payload should look more like this:
```python
payload = {
"model": "grok-3-latest",
"messages": [
{
"role": "system",
"content": (
"You are a helpful assistant that returns the top 3 recent news articles "
"based on a query. Format each result as JSON with keys 'title', 'url', and 'summary'."
)
},
{
"role": "user",
"content": f"Search for: {query}"
}
]
}
```
Then parse the results using the LLM's output as raw text and convert to JSON.
---
### ❌ 3. **Incorrect Key: `num_results` is not a valid key**
If you're using a chat completion API, there is no `num_results` parameter in the official spec. You should request this via the prompt (i.e., “Give me 5 results”).
---
### 🔍 4. **Handling Output Parsing**
Assuming the LLM returns a block of JSON text or numbered text like:
```
1. Title: XYZ
URL: https://example.com
Summary: ...
```
You’ll need to parse this using regex or a structured format request (like JSON block). You could also use `json.loads()` if you wrap the output generation in a JSON structure.
---
### ✅ 5. **.env Handling**
Good use of `dotenv`. Just make sure the `.env` file contains:
```
XAI_API_KEY=your_actual_api_key
```
---
### ✅ 6. **Testing Stub Is Useful**
The `if __name__ == "__main__"` block is well done for local testing.
---
### ✨ Suggested Fix for `search.py`
Here’s a version that prompts Grok as a fake search engine:
```python
def search_news(query: str, num_results: int = 3) -> list:
if not XAI_API_KEY:
print("Error: XAI_API_KEY not found in .env file.")
return []
headers = {
"Authorization": f"Bearer {XAI_API_KEY}",
"Content-Type": "application/json"
}
prompt = (
f"Provide the top {num_results} recent news articles for the query '{query}'. "
"Format the output as a JSON list where each item has 'title', 'url', and 'summary'."
)
payload = {
"model": "grok-3-latest",
"messages": [
{"role": "user", "content": prompt}
]
}
try:
response = requests.post(XAI_API_URL, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
content = data["choices"][0]["message"]["content"]
# Attempt to parse the JSON output from the model
import json
try:
return json.loads(content)
except json.JSONDecodeError:
print("Failed to parse JSON. Raw output:")
print(content)
return []
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return []
```
---
Would you like help rewriting this to support both "live chat prompt-based search" and "true search" in case xAI releases a public search API in the future?
gpt-4o