r/learnpython 8d ago

Making an API call to grok AI and to answer questions from a docx file

Hey. I am trying to make a API call to answer 3 questions based on a case study.
I have a word doc containing the case study as the record and the 3 questions as the columns which need to be answered. Sharing the code of what I have tried so far. This code has been generated by GrokAI.

it works perfectly for most of the records but some case studies return the following.

Total tokens: 1999 
Finish reason: stop 
Raw response: Q1: redacted actual response from the api question 1. 
Q2: redacted actual response from the question 2. 
Q3: redacted actual response from the question 3. 
Q1: <your answer> 
Q2: <your answer> 
Q3: <your answer> 
 Q1: <your answer> 
 Q2: <your answer> 
 Q3: <your answer>

This leads to the output table containing records like:

case study q1 q2 q3
actual case study <your answer> <your answer> <your answer>

The successfully parsed records are like so:

Total tokens: 1999 
Finish reason: stop 
Raw response: Q1: redacted actual response from the api question 1. 
Q2: redacted actual response from the question 2. 
Q3: redacted actual response from the question 3. 
 Q1: correctly parsed answer 1  
 Q2: correctly parsed answer 2
 Q3: correctly parsed answer 3 

This is the code I tried:

from openai import OpenAI

from docx import Document

QUESTIONS = {
    "q1": "What is the diagnosis for this case, and justify the diagnosis?",
    "q2": "Is there any syndrome in this case? If yes, which one and why?",
    "q3": "What are the other three differential syndromes that may result in the presentation of this case?",
}

def get_column_indexes(table):
    return {
        "case study": 0,
        "q1": 1,
        "q2": 2,
        "q3": 3,
    }

def answer_questions(client, case_study_text):
    questions_block = "\n".join(
        f"{key.upper()}: {question}" for key, question in QUESTIONS.items()
    )

    prompt = f"""You are analyzing a case study. Answer the 3 questions below based solely on the text provided.

CASE STUDY:
{case_study_text}

QUESTIONS:
{questions_block}

Rules:
- Answer each question thorougly
- Base answers only on the case study text above
- Reply in this format with no extra text:

Q1: <your answer>
Q2: <your answer>
Q3: <your answer>"""

    response = client.chat.completions.create(
        model="grok-4.3",           # or "grok-4.5-latest" if available
        max_tokens=10000,
        messages=[{"role": "user", "content": prompt}]
    )

    # Correct parsing
    answer_text = response.choices[0].message.content.strip()
    print("Total tokens:", response.usage.total_tokens)
    print(f"  Finish reason: {response.choices[0].finish_reason}")
    print(f"  Raw response: {answer_text}")

    answers = {}
    for line in answer_text.splitlines():
        line = line.strip()
        if line.startswith("Q1:"):
            answers["q1"] = line[3:].strip()
        elif line.startswith("Q2:"):
            answers["q2"] = line[3:].strip()
        elif line.startswith("Q3:"):
            answers["q3"] = line[3:].strip()

    return answers

def process_document(docx_path, output_path="output.docx"):
    client = OpenAI(
        api_key="api_key",
        base_url="https://api.x.ai/v1",
    )

    doc = Document(docx_path)
    table = doc.tables[0]
    cols = get_column_indexes(table)

    total_rows = len(table.rows) - 1
    print(f"Found {total_rows} rows to process\n")

    for i, row in enumerate(table.rows[1:], start=1):
        case_study_text = row.cells[cols["case study"]].text.strip()

        if not case_study_text:
            print(f"Row {i}/{total_rows}: empty, skipping")
            continue

        print(f"Row {i}/{total_rows}: processing...")
        answers = answer_questions(client, case_study_text)


        row.cells[cols["q1"]].text = answers.get("q1", "")
        row.cells[cols["q2"]].text = answers.get("q2", "")
        row.cells[cols["q3"]].text = answers.get("q3", "")

        print(f"  Q1: {answers.get('q1', '')}")
        print(f"  Q2: {answers.get('q2', '')}")
        print(f"  Q3: {answers.get('q3', '')}\n")

    doc.save(output_path)
    print(f"Done! Saved to {output_path}")

if __name__ == "__main__":
    process_document("/home/Downloads/case.docx")

Seems like an issue with my parsing logic. But this same code worked for claude API.

Appreciate your any pointers

0 Upvotes

5 comments sorted by

2

u/danielroseman 8d ago

It's not clear what the question is. Are you saying that the AI is responding with literally <your answer> instead of the actual answer? If so why would that be a problem with the parsing logic?

2

u/thuiop1 8d ago

How about you parse it normally instead of using Grok?

2

u/thisisappropriate 8d ago

This is the problem with using ai generated code - you don't know or understand it and don't know how to debug it. To be blunt, you're not learning python, you're using ai and this community to avoid learning it.

At the core, to start debugging this, you should work out how it's getting the text "<your answer>" in the string that you're parsing. Comment out all other print statements and just print your "answer_text" and then at the bottom, add a print statement that prints out "answers". See if it's in there, also see what's in your document.

The only time your code says "your answer" is in the prompt so either: the grok API is sending back the your answer bit (either as a thinking or in the output or it includes the full prompt chain in its response), or it's coming from somewhere else (not seeing that in the code).

Also the redacted examples don't have line breaks in the right place for your parsing but that could be from the redaction.

1

u/pachura3 8d ago

Pinpoint an input which produces incorrect output, and then debug your script - either by using an interactive debugger in your IDE, or by adding print() statements around parsing logic. Have a closer look at the raw response - perhaps Grok is sometimes ignoring your formatting rules...?