← all conversations

xAI API integration fix

2025-05-222 turns7,093 charsgpt-4o
api-integrationpython-scriptingcode-debugging

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