Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
AI ▲ Intermediate ⏱ 60 minutes

📄 Build a PDF Q&A App with Gemini and Streamlit

Build a real web app where users upload a PDF and ask questions about it. Powered by Gemini + Streamlit — production-ready in under 100 lines.

🎯 What You'll Build

A web app where users upload any PDF (book, report, contract) and chat with it — ask questions, get summaries, find key facts. All powered by Google Gemini and built with Streamlit.

📋 What You'll Need

This is one of the most useful AI patterns — Retrieval Augmented Generation (RAG) at its simplest. The user uploads a document, the app sends both the document and their question to Gemini, and Gemini answers using only that document's content. Let's build it.

1

Set up your project

Create a folder pdf-chat. Open in VS Code. Create a file app.py. Open the terminal.

2

Install the libraries

We need three libraries: Streamlit (web UI), Gemini SDK, and PyPDF (to read PDFs):

pip install streamlit google-generativeai pypdf

This takes about 30 seconds.

3

Get your Gemini API key

If you don't have one yet:

  1. Go to aistudio.google.com
  2. Click "Get API key" → "Create API key"
  3. Copy the key

Completely free, no card needed.

4

Build the basic Streamlit UI

Streamlit lets you build web apps with just Python. Add this to app.py:

app.py
import streamlit as st

st.set_page_config(page_title='PDF Chat', page_icon='📄')

st.title('📄 Chat with your PDF')
st.write('Upload a PDF and ask questions about it.')

uploaded_file = st.file_uploader('Upload PDF', type='pdf')
question = st.text_input('Ask a question:')

Run it:

streamlit run app.py

A browser tab opens at http://localhost:8501 with your UI. Magic, right?

5

Extract text from the PDF

Add a function to extract text from the uploaded PDF:

from pypdf import PdfReader

def extract_text(pdf_file):
    reader = PdfReader(pdf_file)
    text = ''
    for page in reader.pages:
        text += page.extract_text() + '\n'
    return text

This walks every page of the PDF and combines the text into one big string.

6

Send PDF text + question to Gemini

Now wire up Gemini. Add at the top of app.py:

import google.generativeai as genai

genai.configure(api_key='YOUR_GEMINI_KEY')
model = genai.GenerativeModel('gemini-2.0-flash')

Then at the bottom of the file:

if uploaded_file and question:
    with st.spinner('Reading PDF and thinking...'):
        pdf_text = extract_text(uploaded_file)
        prompt = f'Answer the question using only the document below.\n\nDOCUMENT:\n{pdf_text}\n\nQUESTION: {question}'

        response = model.generate_content(prompt)
        st.write('### Answer')
        st.write(response.text)

Save and Streamlit will hot-reload. Upload a PDF, type a question, watch it work.

7

Polish the UI

Let's make it nicer. Add a sidebar with instructions and show a preview of the loaded PDF:

with st.sidebar:
    st.header('How it works')
    st.write('1. Upload any PDF')
    st.write('2. Ask a question')
    st.write('3. Get instant answers')

if uploaded_file:
    st.success(f'✅ Loaded: {uploaded_file.name}')

Small touches like a spinner during loading, a sidebar, and success messages make a huge UX difference.

8

Deploy it for free

Streamlit apps deploy in minutes on Streamlit Community Cloud — free for public apps:

  1. Push your code to GitHub (create a requirements.txt with your libs)
  2. Go to share.streamlit.io
  3. Connect your GitHub repo
  4. Set your Gemini API key in "Secrets"
  5. Click Deploy

You'll get a public URL like yourname-pdfchat.streamlit.app. Share it with anyone.

⚠️ Security: Never hardcode API keys in your code when deploying. Use st.secrets["GEMINI_KEY"] instead.
🎉

You built a PDF Q&A app!

You just built one of the most useful AI app patterns — RAG (Retrieval Augmented Generation) in its simplest form. This is the foundation behind ChatPDF, NotebookLM, and many enterprise AI tools.

🚀 Take It Further

← All Tutorials

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.