Raspberry Pi API Call Series: Python in the Terminal

Part 1 used bash and curl. It worked. Part 2 uses Python — and the code gets cleaner, the error handling gets real, and the output lands in a file you can actually use.
The Same Task, Done Right: Python in the Terminal — Tech-Reader.blog
Tech-Reader.blog  ·  Raspberry Pi AI Series  ·  Part 2 of 4
Python CLI  ·  October 2026

The Same Task, Done Right: Python in the Terminal

Same CSV. Same Groq API. Better code — and this time the output lands in a file.
Part 1 used bash and curl to send a CSV to a frontier AI and get JSON back. It worked. Part 2 does the same thing in Python, and the difference matters: proper JSON parsing, real error handling, and output that writes to disk instead of just printing to the screen.

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:

Terminal
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:

inventory.csv
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:

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:

Terminal
python3 ai_csv.py

What Came Back

Terminal Output
Loading 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.

12 lines The actual working core of this script — load, call, save. The rest is error handling and clarity.
· · ·

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.

Next in the Series  ·  Part 3 of 4
Now It Has a Window: A Desktop AI App on Raspberry Pi OS

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.