Introduction
Making flashcards is tedious, which is exactly why it should be automated. Paste your notes, and this app asks Mistral to extract question-answer pairs — definitions, dates, cause-effect pairs — then presents them as flip-style cards with an Anki-compatible CSV export. It is the study-buddy application of the Mistral patterns from the chatbot tutorial, with the state handling of the quiz app.
The engineering lesson is structured output from an LLM: getting a model to return clean, parseable JSON instead of chatty prose — and recovering gracefully when it doesn't.
Features
Prerequisites
pip install streamlit requests pandasStep 1: Create the Script
Save as flashcards.py:
import streamlit as st
import requests
import json
import pandas as pd
import re
st.set_page_config(page_title="AI Flashcards", page_icon="🃏")
st.title("🃏 AI Flashcard Generator")
api_key = st.secrets.get("MISTRAL_API_KEY", "") or st.text_input("Mistral API key", type="password")
notes = st.text_area("Your notes", height=220, placeholder="Paste lecture notes, a chapter summary, or documentation...")
count = st.slider("How many cards?", 5, 20, 10)
def generate_cards(notes, n, key):
prompt = (
f"Create {n} flashcards from these notes. "
'Respond with ONLY a JSON array like: '
'[{"q": "question", "a": "answer"}]. No other text.\n\nNotes:\n' + notes
)
r = requests.post(
"https://api.mistral.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {key}"},
json={"model": "mistral-small-latest",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.3},
timeout=60,
)
raw = r.json()["choices"][0]["message"]["content"]
match = re.search(r"\[.*\]", raw, re.S)
return json.loads(match.group()) if match else []
if st.button("⚡ Generate flashcards", type="primary", disabled=not (notes.strip() and api_key)):
try:
with st.spinner("Writing cards..."):
st.session_state.cards = generate_cards(notes, count, api_key)
except (json.JSONDecodeError, KeyError, requests.RequestException):
st.error("The model returned something unexpected — try again or lower the count.")
for i, card in enumerate(st.session_state.get("cards", [])):
with st.expander(f"Card {i + 1}: {card['q'][:60]}"):
q = st.text_input("Question", card["q"], key=f"q{i}")
a = st.text_area("Answer", card["a"], height=70, key=f"a{i}")
st.session_state.cards[i] = {"q": q, "a": a}
if st.session_state.get("cards"):
df = pd.DataFrame(st.session_state.cards)
csv = df.to_csv(index=False, header=False).encode()
st.download_button("⬇️ Download for Anki (CSV)", csv, "flashcards.csv", "text/csv")Step 2: Run the App
streamlit run flashcards.pyPaste a few paragraphs of real notes, generate, and review — edit weak cards inline, then export to Anki.
How It Works
The prompt does three jobs at once: states the task, *shows the exact output format* (a JSON array example), and forbids everything else. Models are excellent mimics — showing one example is worth a paragraph of instructions. temperature: 0.3 keeps output factual and consistent; flashcards want reliability, not creativity.
The extraction regex \[.*\] with DOTALL is the safety net: even when the model wraps its JSON in "Sure! Here are your cards:" the regex finds the array. This extract-don't-trust pattern is essential for every structured-output app — the same grounded thinking as the PDF chat app's context-only instruction.
The editable expander list closes the human-in-the-loop gap: each card's text inputs write back into st.session_state.cards, so edits flow into the export automatically. The model drafts; you finalize.
Common Errors & Fixes
ast.literal_eval-style repair.temperature slightly or add "avoid trivial yes/no questions" to the prompt; quality tracks note quality too.st.secrets configuration.Key Concepts
What to Try Next
FAQ
Are AI-generated flashcards good enough to study from?
As drafts, yes — expect to edit 10–20%. The expander editors exist precisely because the model occasionally writes vague questions or misses the point you cared about.
Why JSON instead of plain text Q&A lines?
JSON is parseable and unambiguous — questions containing colons or newlines break line-based formats. Structured output scales; string splitting doesn't.
Does the Anki CSV include formatting?
Plain text only. Anki supports HTML in cards — wrap answers in <b> tags in the generator if you want bold terms after import.