Raspberry Pi API Call Series: Python in the Terminal
The Same Task, Done Right: Python in the Terminal
The bash version from Part 1 used grep and sed to pull content out of the API response. That works. But it is fragile. If the response format changes slightly or the model adds an unexpected character, the parsing breaks silently. You get garbage output and no explanation why.
Python fixes that. Its built-in json module handles API responses properly. You hand it the raw response string, it gives you a structured dictionary, and you pull out exactly the field you need with a clean key lookup. If something goes wrong, it raises an exception with a useful message — not silence.
Setup: One Library
Python's standard library can make HTTP requests, but the requests library is cleaner for API work. Install it once:
pip3 install requests
That is the only dependency. JSON parsing, file writing, error handling — all standard library.
The CSV File
Same file as Part 1. If you already have it, you are ready. If not, create inventory.csv in your home directory:
product,price
Widget A,12.99
Widget B,7.50
Gadget X,24.00
Gadget Y,3.75
Part Z,19.99
The Python Script
Create a file called ai_csv.py:
import requests
import json
import sys
# Your Groq API key — free at console.groq.com
GROQ_API_KEY = "your_api_key_here"
GROQ_URL = "https://api.groq.com/openai/v1/chat/completions"
def load_csv(filepath):
"""Read the CSV file and return its contents as a string."""
try:
with open(filepath, "r") as f:
return f.read()
except FileNotFoundError:
print(f"Error: Could not find {filepath}")
sys.exit(1)
def call_groq(csv_data):
"""Send the CSV to Groq and return the model's response text."""
prompt = f"""Here is a CSV file with product inventory data:
{csv_data}
Please return a JSON array where each item has these fields:
- product (string)
- price (number)
- category (assign a reasonable category based on the product name)
Return only valid JSON. No explanation, no markdown, just the JSON array."""
headers = {
"Authorization": f"Bearer {GROQ_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "llama-3.3-70b-versatile",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.2
}
response = requests.post(GROQ_URL, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
return data["choices"][0]["message"]["content"]
def save_json(content, output_path):
"""Parse and pretty-print the JSON, then save it to a file."""
try:
parsed = json.loads(content)
with open(output_path, "w") as f:
json.dump(parsed, f, indent=2)
print(f"Done. Output saved to {output_path}")
print(json.dumps(parsed, indent=2))
except json.JSONDecodeError as e:
print(f"The model returned something that isn't valid JSON: {e}")
print("Raw response:", content)
def main():
print("Loading CSV...")
csv_data = load_csv("inventory.csv")
print("Sending to Groq API...")
result = call_groq(csv_data)
print("Saving output...")
save_json(result, "output.json")
if __name__ == "__main__":
main()
Run it:
Terminalpython3 ai_csv.py
What Came Back
Terminal OutputLoading CSV...
Sending to Groq API...
Saving output...
Done. Output saved to output.json
[
{ "product": "Widget A", "price": 12.99, "category": "Widgets" },
{ "product": "Widget B", "price": 7.50, "category": "Widgets" },
{ "product": "Gadget X", "price": 24.00, "category": "Gadgets" },
{ "product": "Gadget Y", "price": 3.75, "category": "Gadgets" },
{ "product": "Part Z", "price": 19.99, "category": "Parts" }
]
And output.json now sits in your home directory, ready to pass to the next step in a pipeline, load into a database, or feed into another script.
Python parses JSON natively. You hand it the response, it gives you a dictionary. No grep. No sed. No guessing.
The Error Handling Is Not Optional
Notice the response.raise_for_status() line. If the API returns an error — expired key, rate limit, bad request — that line raises an exception immediately with a clear HTTP status code. Without it, the script would try to parse an error response as JSON and fail in a confusing way.
On a Pi running unattended or as part of a larger workflow, clean failure matters. You want to know what broke and why.
Now that we have a proper Python foundation, the next steps open up. Swap out the CSV reading for a database query. Change the prompt to summarize instead of categorize. Schedule the script with cron to process a fresh file every morning. The Pi is still doing almost no computation. It is orchestrating. That is the right role for it.
Part 3 wraps this same core logic in a Tkinter desktop application. File picker, results display, save button — all running natively on the Raspberry Pi OS desktop. No browser required.