SPB Git

Repository Public

document-processing.md 29.7 KB 973 lines markdown

1Gemini models can process documents in PDF format, using native2vision to understand entire document contexts. This goes beyond3just text extraction, allowing Gemini to:45- Analyze and interpret content, including text, images, diagrams, charts, and tables, even in long documents up to 1000 pages.6- Extract information into [structured output](https://ai.google.dev/gemini-api/docs/structured-output) formats.7- Summarize and answer questions based on both the visual and textual elements in a document.8- Transcribe document content (e.g. to HTML), preserving layouts and formatting, for use in downstream applications.910You can also pass non-PDF documents in the same way but Gemini will see them11as normal text which will eliminate context like charts or formatting.1213## Passing PDF data inline1415You can pass PDF data inline in the request to `generateContent`. This is best16suited for smaller documents or temporary processing where you don't need to17reference the file in subsequent requests. We recommend using the [Files API](https://ai.google.dev/gemini-api/docs/document-processing#large-pdfs)18for larger documents that you need to refer to in multi-turn interactions to19improve request latency and reduce bandwidth usage.2021The following example shows you how to fetch a PDF from a URL and convert it to22bytes for processing:2324### Python2526    from google import genai27    from google.genai import types28    import httpx2930    client = genai.Client()3132    doc_url = "https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf"3334    # Retrieve and encode the PDF byte35    doc_data = httpx.get(doc_url).content3637    prompt = "Summarize this document"38    response = client.models.generate_content(39        model="gemini-3.8-flash",40        contents=[41            types.Part.from_bytes(42                data=doc_data,43                mime_type='application/pdf',44            ),45            prompt46        ]47    )4849    print(response.text)5051### JavaScript5253    import { GoogleGenAI } from "@google/genai";5455    const ai = new GoogleGenAI({ apiKey: "GEMINI_API_KEY" });5657    async function main() {58        const pdfResp = await fetch('https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf')59            .then((response) => response.arrayBuffer());6061        const contents = [62            { text: "Summarize this document" },63            {64                inlineData: {65                    mimeType: 'application/pdf',66                    data: Buffer.from(pdfResp).toString("base64")67                }68            }69        ];7071        const response = await ai.models.generateContent({72            model: "gemini-3.8-flash",73            contents: contents74        });75        console.log(response.text);76    }7778    main();7980### Go8182    package main8384    import (85        "context"86        "fmt"87        "io"88        "net/http"89        "os"90        "google.golang.org/genai"91    )9293    func main() {9495        ctx := context.Background()96        client, _ := genai.NewClient(ctx, &genai.ClientConfig{97            APIKey:  os.Getenv("GEMINI_API_KEY"),98            Backend: genai.BackendGeminiAPI,99        })100101        pdfResp, _ := http.Get("https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf")102        var pdfBytes []byte103        if pdfResp != nil && pdfResp.Body != nil {104            pdfBytes, _ = io.ReadAll(pdfResp.Body)105            pdfResp.Body.Close()106        }107108        parts := []*genai.Part{109            &genai.Part{110                InlineData: &genai.Blob{111                    MIMEType: "application/pdf",112                    Data:     pdfBytes,113                },114            },115            genai.NewPartFromText("Summarize this document"),116        }117118        contents := []*genai.Content{119            genai.NewContentFromParts(parts, genai.RoleUser),120        }121122        result, _ := client.Models.GenerateContent(123            ctx,124            "gemini-3.8-flash",125            contents,126            nil,127        )128129        fmt.Println(result.Text())130    }131132### REST133134    DOC_URL="https://discovery.ucl.ac.uk/id/eprint/10089234/1/343019_3_art_0_py4t4l_convrt.pdf"135    PROMPT="Summarize this document"136    DISPLAY_NAME="base64_pdf"137138    # Download the PDF139    wget -O "${DISPLAY_NAME}.pdf" "${DOC_URL}"140141    # Check for FreeBSD base64 and set flags accordingly142    if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then143      B64FLAGS="--input"144    else145      B64FLAGS="-w0"146    fi147148    # Base64 encode the PDF149    ENCODED_PDF=$(base64 $B64FLAGS "${DISPLAY_NAME}.pdf")150151    # Generate content using the base64 encoded PDF152    curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GOOGLE_API_KEY" \153        -H 'Content-Type: application/json' \154        -X POST \155        -d '{156          "contents": [{157            "parts":[158              {"inline_data": {"mime_type": "application/pdf", "data": "'"$ENCODED_PDF"'"}},159              {"text": "'$PROMPT'"}160            ]161          }]162        }' 2> /dev/null > response.json163164    cat response.json165    echo166167    jq ".candidates[].content.parts[].text" response.json168169    # Clean up the downloaded PDF170    rm "${DISPLAY_NAME}.pdf"171172You can also read a PDF from a local file for processing:173174### Python175176    from google import genai177    from google.genai import types178    import pathlib179180    client = genai.Client()181182    # Retrieve and encode the PDF byte183    filepath = pathlib.Path('file.pdf')184185    prompt = "Summarize this document"186    response = client.models.generate_content(187      model="gemini-3.8-flash",188      contents=[189          types.Part.from_bytes(190            data=filepath.read_bytes(),191            mime_type='application/pdf',192          ),193          prompt])194    print(response.text)195196### JavaScript197198    import { GoogleGenAI } from "@google/genai";199    import * as fs from 'fs';200201    const ai = new GoogleGenAI({ apiKey: "GEMINI_API_KEY" });202203    async function main() {204        const contents = [205            { text: "Summarize this document" },206            {207                inlineData: {208                    mimeType: 'application/pdf',209                    data: Buffer.from(fs.readFileSync("content/343019_3_art_0_py4t4l_convrt.pdf")).toString("base64")210                }211            }212        ];213214        const response = await ai.models.generateContent({215            model: "gemini-3.8-flash",216            contents: contents217        });218        console.log(response.text);219    }220221    main();222223### Go224225    package main226227    import (228        "context"229        "fmt"230        "os"231        "google.golang.org/genai"232    )233234    func main() {235236        ctx := context.Background()237        client, _ := genai.NewClient(ctx, &genai.ClientConfig{238            APIKey:  os.Getenv("GEMINI_API_KEY"),239            Backend: genai.BackendGeminiAPI,240        })241242        pdfBytes, _ := os.ReadFile("path/to/your/file.pdf")243244        parts := []*genai.Part{245            &genai.Part{246                InlineData: &genai.Blob{247                    MIMEType: "application/pdf",248                    Data:     pdfBytes,249                },250            },251            genai.NewPartFromText("Summarize this document"),252        }253        contents := []*genai.Content{254            genai.NewContentFromParts(parts, genai.RoleUser),255        }256257        result, _ := client.Models.GenerateContent(258            ctx,259            "gemini-3.8-flash",260            contents,261            nil,262        )263264        fmt.Println(result.Text())265    }266267## Uploading PDFs using the Files API268269We recommend you use Files API for larger files or when you intend to reuse a270document across multiple requests. This improves request latency and reduces271bandwidth usage by decoupling the file upload from the model requests.272273> [!NOTE]274> **Note:** The Files API is available at no cost in all regions where the Gemini API is available. Uploaded files are stored for 48 hours.275276### Large PDFs from URLs277278Use the File API to simplify uploading and processing large PDF files from URLs:279280### Python281282    from google import genai283    from google.genai import types284    import io285    import httpx286287    client = genai.Client()288289    long_context_pdf_path = "https://www.nasa.gov/wp-content/uploads/static/history/alsj/a17/A17_FlightPlan.pdf"290291    # Retrieve and upload the PDF using the File API292    doc_io = io.BytesIO(httpx.get(long_context_pdf_path).content)293294    sample_doc = client.files.upload(295      # You can pass a path or a file-like object here296      file=doc_io,297      config=dict(298        mime_type='application/pdf')299    )300301    prompt = "Summarize this document"302303    response = client.models.generate_content(304      model="gemini-3.8-flash",305      contents=[sample_doc, prompt])306    print(response.text)307308### JavaScript309310    import { createPartFromUri, GoogleGenAI } from "@google/genai";311312    const ai = new GoogleGenAI({ apiKey: "GEMINI_API_KEY" });313314    async function main() {315316        const pdfBuffer = await fetch("https://www.nasa.gov/wp-content/uploads/static/history/alsj/a17/A17_FlightPlan.pdf")317            .then((response) => response.arrayBuffer());318319        const fileBlob = new Blob([pdfBuffer], { type: 'application/pdf' });320321        const file = await ai.files.upload({322            file: fileBlob,323            config: {324                displayName: 'A17_FlightPlan.pdf',325            },326        });327328        // Wait for the file to be processed.329        let getFile = await ai.files.get({ name: file.name });330        while (getFile.state === 'PROCESSING') {331            getFile = await ai.files.get({ name: file.name });332            console.log(`current file status: ${getFile.state}`);333            console.log('File is still processing, retrying in 5 seconds');334335            await new Promise((resolve) => {336                setTimeout(resolve, 5000);337            });338        }339        if (file.state === 'FAILED') {340            throw new Error('File processing failed.');341        }342343        // Add the file to the contents.344        const content = [345            'Summarize this document',346        ];347348        if (file.uri && file.mimeType) {349            const fileContent = createPartFromUri(file.uri, file.mimeType);350            content.push(fileContent);351        }352353        const response = await ai.models.generateContent({354            model: 'gemini-3.8-flash',355            contents: content,356        });357358        console.log(response.text);359360    }361362    main();363364### Go365366    package main367368    import (369      "context"370      "fmt"371      "io"372      "net/http"373      "os"374      "google.golang.org/genai"375    )376377    func main() {378379      ctx := context.Background()380      client, _ := genai.NewClient(ctx, &genai.ClientConfig{381        APIKey:  os.Getenv("GEMINI_API_KEY"),382        Backend: genai.BackendGeminiAPI,383      })384385      pdfURL := "https://www.nasa.gov/wp-content/uploads/static/history/alsj/a17/A17_FlightPlan.pdf"386      localPdfPath := "A17_FlightPlan_downloaded.pdf"387388      respHttp, _ := http.Get(pdfURL)389      defer respHttp.Body.Close()390391      outFile, _ := os.Create(localPdfPath)392      defer outFile.Close()393394      _, _ = io.Copy(outFile, respHttp.Body)395396      uploadConfig := &genai.UploadFileConfig{MIMEType: "application/pdf"}397      uploadedFile, _ := client.Files.UploadFromPath(ctx, localPdfPath, uploadConfig)398399      promptParts := []*genai.Part{400        genai.NewPartFromURI(uploadedFile.URI, uploadedFile.MIMEType),401        genai.NewPartFromText("Summarize this document"),402      }403      contents := []*genai.Content{404        genai.NewContentFromParts(promptParts, genai.RoleUser), // Specify role405      }406407        result, _ := client.Models.GenerateContent(408            ctx,409            "gemini-3.8-flash",410            contents,411            nil,412        )413414      fmt.Println(result.Text())415    }416417### REST418419    PDF_PATH="https://www.nasa.gov/wp-content/uploads/static/history/alsj/a17/A17_FlightPlan.pdf"420    DISPLAY_NAME="A17_FlightPlan"421    PROMPT="Summarize this document"422423    # Download the PDF from the provided URL424    wget -O "${DISPLAY_NAME}.pdf" "${PDF_PATH}"425426    MIME_TYPE=$(file -b --mime-type "${DISPLAY_NAME}.pdf")427    NUM_BYTES=$(wc -c < "${DISPLAY_NAME}.pdf")428429    echo "MIME_TYPE: ${MIME_TYPE}"430    echo "NUM_BYTES: ${NUM_BYTES}"431432    tmp_header_file=upload-header.tmp433434    # Initial resumable request defining metadata.435    # The upload url is in the response headers dump them to a file.436    curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \437      -D upload-header.tmp \438      -H "X-Goog-Upload-Protocol: resumable" \439      -H "X-Goog-Upload-Command: start" \440      -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \441      -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \442      -H "Content-Type: application/json" \443      -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null444445    upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")446    rm "${tmp_header_file}"447448    # Upload the actual bytes.449    curl "${upload_url}" \450      -H "Content-Length: ${NUM_BYTES}" \451      -H "X-Goog-Upload-Offset: 0" \452      -H "X-Goog-Upload-Command: upload, finalize" \453      --data-binary "@${DISPLAY_NAME}.pdf" 2> /dev/null > file_info.json454455    file_uri=$(jq ".file.uri" file_info.json)456    echo "file_uri: ${file_uri}"457458    # Now generate content using that file459    curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GOOGLE_API_KEY" \460        -H 'Content-Type: application/json' \461        -X POST \462        -d '{463          "contents": [{464            "parts":[465              {"text": "'$PROMPT'"},466              {"file_data":{"mime_type": "application/pdf", "file_uri": '$file_uri'}}]467            }]468          }' 2> /dev/null > response.json469470    cat response.json471    echo472473    jq ".candidates[].content.parts[].text" response.json474475    # Clean up the downloaded PDF476    rm "${DISPLAY_NAME}.pdf"477478### Large PDFs stored locally479480### Python481482    from google import genai483    from google.genai import types484    import pathlib485    import httpx486487    client = genai.Client()488489    # Retrieve and encode the PDF byte490    file_path = pathlib.Path('large_file.pdf')491492    # Upload the PDF using the File API493    sample_file = client.files.upload(494        file=file_path,495    )496497    prompt="Summarize this document"498499    response = client.models.generate_content(500        model="gemini-3.8-flash",501        contents=[sample_file, "Summarize this document"])502    print(response.text)503504### JavaScript505506    import { createPartFromUri, GoogleGenAI } from "@google/genai";507508    const ai = new GoogleGenAI({ apiKey: "GEMINI_API_KEY" });509510    async function main() {511        const file = await ai.files.upload({512            file: 'path-to-localfile.pdf'513            config: {514                displayName: 'A17_FlightPlan.pdf',515            },516        });517518        // Wait for the file to be processed.519        let getFile = await ai.files.get({ name: file.name });520        while (getFile.state === 'PROCESSING') {521            getFile = await ai.files.get({ name: file.name });522            console.log(`current file status: ${getFile.state}`);523            console.log('File is still processing, retrying in 5 seconds');524525            await new Promise((resolve) => {526                setTimeout(resolve, 5000);527            });528        }529        if (file.state === 'FAILED') {530            throw new Error('File processing failed.');531        }532533        // Add the file to the contents.534        const content = [535            'Summarize this document',536        ];537538        if (file.uri && file.mimeType) {539            const fileContent = createPartFromUri(file.uri, file.mimeType);540            content.push(fileContent);541        }542543        const response = await ai.models.generateContent({544            model: 'gemini-3.8-flash',545            contents: content,546        });547548        console.log(response.text);549550    }551552    main();553554### Go555556    package main557558    import (559        "context"560        "fmt"561        "os"562        "google.golang.org/genai"563    )564565    func main() {566567        ctx := context.Background()568        client, _ := genai.NewClient(ctx, &genai.ClientConfig{569            APIKey:  os.Getenv("GEMINI_API_KEY"),570            Backend: genai.BackendGeminiAPI,571        })572        localPdfPath := "/path/to/file.pdf"573574        uploadConfig := &genai.UploadFileConfig{MIMEType: "application/pdf"}575        uploadedFile, _ := client.Files.UploadFromPath(ctx, localPdfPath, uploadConfig)576577        promptParts := []*genai.Part{578            genai.NewPartFromURI(uploadedFile.URI, uploadedFile.MIMEType),579            genai.NewPartFromText("Give me a summary of this pdf file."),580        }581        contents := []*genai.Content{582            genai.NewContentFromParts(promptParts, genai.RoleUser),583        }584585        result, _ := client.Models.GenerateContent(586            ctx,587            "gemini-3.8-flash",588            contents,589            nil,590        )591592        fmt.Println(result.Text())593    }594595### REST596597    NUM_BYTES=$(wc -c < "${PDF_PATH}")598    DISPLAY_NAME=TEXT599    tmp_header_file=upload-header.tmp600601    # Initial resumable request defining metadata.602    # The upload url is in the response headers dump them to a file.603    curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \604      -D upload-header.tmp \605      -H "X-Goog-Upload-Protocol: resumable" \606      -H "X-Goog-Upload-Command: start" \607      -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \608      -H "X-Goog-Upload-Header-Content-Type: application/pdf" \609      -H "Content-Type: application/json" \610      -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null611612    upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")613    rm "${tmp_header_file}"614615    # Upload the actual bytes.616    curl "${upload_url}" \617      -H "Content-Length: ${NUM_BYTES}" \618      -H "X-Goog-Upload-Offset: 0" \619      -H "X-Goog-Upload-Command: upload, finalize" \620      --data-binary "@${PDF_PATH}" 2> /dev/null > file_info.json621622    file_uri=$(jq ".file.uri" file_info.json)623    echo file_uri=$file_uri624625    # Now generate content using that file626    curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GOOGLE_API_KEY" \627        -H 'Content-Type: application/json' \628        -X POST \629        -d '{630          "contents": [{631            "parts":[632              {"text": "Can you add a few more lines to this poem?"},633              {"file_data":{"mime_type": "application/pdf", "file_uri": '$file_uri'}}]634            }]635          }' 2> /dev/null > response.json636637    cat response.json638    echo639640    jq ".candidates[].content.parts[].text" response.json641642You can verify the API successfully stored the uploaded file and get its643metadata by calling [`files.get`](https://ai.google.dev/api/rest/v1beta/files/get). Only the `name`644(and by extension, the `uri`) are unique.645646### Python647648    from google import genai649    import pathlib650651    client = genai.Client()652653    fpath = pathlib.Path('example.txt')654    fpath.write_text('hello')655656    file = client.files.upload(file='example.txt')657658    file_info = client.files.get(name=file.name)659    print(file_info.model_dump_json(indent=4))660661### REST662663    name=$(jq ".file.name" file_info.json)664    # Get the file of interest to check state665    curl https://generativelanguage.googleapis.com/v1beta/files/$name > file_info.json666    # Print some information about the file you got667    name=$(jq ".file.name" file_info.json)668    echo name=$name669    file_uri=$(jq ".file.uri" file_info.json)670    echo file_uri=$file_uri671672## Passing multiple PDFs673674The Gemini API is capable of processing multiple PDF documents (up to 1000 pages)675in a single request, as long as the combined size of the documents and the text676prompt stays within the model's context window.677678### Python679680    from google import genai681    import io682    import httpx683684    client = genai.Client()685686    doc_url_1 = "https://arxiv.org/pdf/2312.11805"687    doc_url_2 = "https://arxiv.org/pdf/2403.05530"688689    # Retrieve and upload both PDFs using the File API690    doc_data_1 = io.BytesIO(httpx.get(doc_url_1).content)691    doc_data_2 = io.BytesIO(httpx.get(doc_url_2).content)692693    sample_pdf_1 = client.files.upload(694      file=doc_data_1,695      config=dict(mime_type='application/pdf')696    )697    sample_pdf_2 = client.files.upload(698      file=doc_data_2,699      config=dict(mime_type='application/pdf')700    )701702    prompt = "What is the difference between each of the main benchmarks between these two papers? Output these in a table."703704    response = client.models.generate_content(705        model="gemini-3.8-flash",706        contents=[sample_pdf_1, sample_pdf_2, prompt]707    )708709    print(response.text)710711### JavaScript712713    import { createPartFromUri, GoogleGenAI } from "@google/genai";714715    const ai = new GoogleGenAI({ apiKey: "GEMINI_API_KEY" });716717    async function uploadRemotePDF(url, displayName) {718        const pdfBuffer = await fetch(url)719            .then((response) => response.arrayBuffer());720721        const fileBlob = new Blob([pdfBuffer], { type: 'application/pdf' });722723        const file = await ai.files.upload({724            file: fileBlob,725            config: {726                displayName: displayName,727            },728        });729730        // Wait for the file to be processed.731        let getFile = await ai.files.get({ name: file.name });732        while (getFile.state === 'PROCESSING') {733            getFile = await ai.files.get({ name: file.name });734            console.log(`current file status: ${getFile.state}`);735            console.log('File is still processing, retrying in 5 seconds');736737            await new Promise((resolve) => {738                setTimeout(resolve, 5000);739            });740        }741        if (file.state === 'FAILED') {742            throw new Error('File processing failed.');743        }744745        return file;746    }747748    async function main() {749        const content = [750            'What is the difference between each of the main benchmarks between these two papers? Output these in a table.',751        ];752753        let file1 = await uploadRemotePDF("https://arxiv.org/pdf/2312.11805", "PDF 1")754        if (file1.uri && file1.mimeType) {755            const fileContent = createPartFromUri(file1.uri, file1.mimeType);756            content.push(fileContent);757        }758        let file2 = await uploadRemotePDF("https://arxiv.org/pdf/2403.05530", "PDF 2")759        if (file2.uri && file2.mimeType) {760            const fileContent = createPartFromUri(file2.uri, file2.mimeType);761            content.push(fileContent);762        }763764        const response = await ai.models.generateContent({765            model: 'gemini-3.8-flash',766            contents: content,767        });768769        console.log(response.text);770    }771772    main();773774### Go775776    package main777778    import (779        "context"780        "fmt"781        "io"782        "net/http"783        "os"784        "google.golang.org/genai"785    )786787    func main() {788789        ctx := context.Background()790        client, _ := genai.NewClient(ctx, &genai.ClientConfig{791            APIKey:  os.Getenv("GEMINI_API_KEY"),792            Backend: genai.BackendGeminiAPI,793        })794795        docUrl1 := "https://arxiv.org/pdf/2312.11805"796        docUrl2 := "https://arxiv.org/pdf/2403.05530"797        localPath1 := "doc1_downloaded.pdf"798        localPath2 := "doc2_downloaded.pdf"799800        respHttp1, _ := http.Get(docUrl1)801        defer respHttp1.Body.Close()802803        outFile1, _ := os.Create(localPath1)804        _, _ = io.Copy(outFile1, respHttp1.Body)805        outFile1.Close()806807        respHttp2, _ := http.Get(docUrl2)808        defer respHttp2.Body.Close()809810        outFile2, _ := os.Create(localPath2)811        _, _ = io.Copy(outFile2, respHttp2.Body)812        outFile2.Close()813814        uploadConfig1 := &genai.UploadFileConfig{MIMEType: "application/pdf"}815        uploadedFile1, _ := client.Files.UploadFromPath(ctx, localPath1, uploadConfig1)816817        uploadConfig2 := &genai.UploadFileConfig{MIMEType: "application/pdf"}818        uploadedFile2, _ := client.Files.UploadFromPath(ctx, localPath2, uploadConfig2)819820        promptParts := []*genai.Part{821            genai.NewPartFromURI(uploadedFile1.URI, uploadedFile1.MIMEType),822            genai.NewPartFromURI(uploadedFile2.URI, uploadedFile2.MIMEType),823            genai.NewPartFromText("What is the difference between each of the " +824                                  "main benchmarks between these two papers? " +825                                  "Output these in a table."),826        }827        contents := []*genai.Content{828            genai.NewContentFromParts(promptParts, genai.RoleUser),829        }830831        modelName := "gemini-3.8-flash"832        result, _ := client.Models.GenerateContent(833            ctx,834            modelName,835            contents,836            nil,837        )838839        fmt.Println(result.Text())840    }841842### REST843844    DOC_URL_1="https://arxiv.org/pdf/2312.11805"845    DOC_URL_2="https://arxiv.org/pdf/2403.05530"846    DISPLAY_NAME_1="Gemini_paper"847    DISPLAY_NAME_2="Gemini_1.5_paper"848    PROMPT="What is the difference between each of the main benchmarks between these two papers? Output these in a table."849850    # Function to download and upload a PDF851    upload_pdf() {852      local doc_url="$1"853      local display_name="$2"854855      # Download the PDF856      wget -O "${display_name}.pdf" "${doc_url}"857858      local MIME_TYPE=$(file -b --mime-type "${display_name}.pdf")859      local NUM_BYTES=$(wc -c < "${display_name}.pdf")860861      echo "MIME_TYPE: ${MIME_TYPE}"862      echo "NUM_BYTES: ${NUM_BYTES}"863864      local tmp_header_file=upload-header.tmp865866      # Initial resumable request867      curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \868        -D "${tmp_header_file}" \869        -H "X-Goog-Upload-Protocol: resumable" \870        -H "X-Goog-Upload-Command: start" \871        -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \872        -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \873        -H "Content-Type: application/json" \874        -d "{'file': {'display_name': '${display_name}'}}" 2> /dev/null875876      local upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")877      rm "${tmp_header_file}"878879      # Upload the PDF880      curl "${upload_url}" \881        -H "Content-Length: ${NUM_BYTES}" \882        -H "X-Goog-Upload-Offset: 0" \883        -H "X-Goog-Upload-Command: upload, finalize" \884        --data-binary "@${display_name}.pdf" 2> /dev/null > "file_info_${display_name}.json"885886      local file_uri=$(jq ".file.uri" "file_info_${display_name}.json")887      echo "file_uri for ${display_name}: ${file_uri}"888889      # Clean up the downloaded PDF890      rm "${display_name}.pdf"891892      echo "${file_uri}"893    }894895    # Upload the first PDF896    file_uri_1=$(upload_pdf "${DOC_URL_1}" "${DISPLAY_NAME_1}")897898    # Upload the second PDF899    file_uri_2=$(upload_pdf "${DOC_URL_2}" "${DISPLAY_NAME_2}")900901    # Now generate content using both files902    curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash:generateContent?key=$GOOGLE_API_KEY" \903        -H 'Content-Type: application/json' \904        -X POST \905        -d '{906          "contents": [{907            "parts":[908              {"file_data": {"mime_type": "application/pdf", "file_uri": '$file_uri_1'}},909              {"file_data": {"mime_type": "application/pdf", "file_uri": '$file_uri_2'}},910              {"text": "'$PROMPT'"}911            ]912          }]913        }' 2> /dev/null > response.json914915    cat response.json916    echo917918    jq ".candidates[].content.parts[].text" response.json919920## Technical details921922Gemini supports PDF files up to 50MB or 1000 pages. This limit applies923to both inline data and Files API uploads. Each document page is equivalent to 258924tokens.925926While there are no specific limits to the number of pixels in a document besides927the model's [context window](https://ai.google.dev/gemini-api/docs/long-context), larger pages are928scaled down to a maximum resolution of 3072 x 3072 while preserving their original929aspect ratio, while smaller pages are scaled up to 768 x 768 pixels. There is no930cost reduction for pages at lower sizes, other than bandwidth, or performance931improvement for pages at higher resolution.932933### Gemini 3 models934935Gemini 3 introduces granular control over multimodal vision processing with the936`media_resolution` parameter. You can now set the resolution to low, medium, or937high per individual media part. With this addition, the processing of PDF938documents has been updated:9399401. **Native text inclusion:** Text natively embedded in the PDF is extracted and provided to the model.9412. **Billing \& token reporting:**942   - You are **not charged** for tokens originating from the extracted **native text** in PDFs.943   - In the `usage_metadata` section of the API response, tokens generated from processing PDF pages (as images) are now counted under the `IMAGE` modality, not a separate `DOCUMENT` modality as in some earlier versions.944945For more details about the media resolution parameter, see the946[Media resolution](https://ai.google.dev/gemini-api/docs/generate-content/media-resolution) guide.947948### Document types949950Technically, you can pass other MIME types for document understanding, like951TXT, Markdown, HTML, XML, etc. However, document vision ***only meaningfully952understands PDFs***. Other types will be extracted as pure text, and the model953won't be able to interpret what we see in the rendering of those files. Any954file-type specifics like charts, diagrams, HTML tags, Markdown formatting, etc.,955will be lost.956957To learn about other file input methods, see the958[File input methods](https://ai.google.dev/gemini-api/docs/file-input-methods) guide.959960### Best practices961962For best results:963964- Rotate pages to the correct orientation before uploading.965- Avoid blurry pages.966- If using a single page, place the text prompt after the page.967968## What's next969970To learn more, see the following resources:971972- [File prompting strategies](https://ai.google.dev/gemini-api/docs/files#prompt-guide): The Gemini API supports prompting with text, image, audio, and video data, also known as multimodal prompting.973- [System instructions](https://ai.google.dev/gemini-api/docs/text-generation#system-instructions): System instructions let you steer the behavior of the model based on your specific needs and use cases.
Files main
Menu

Theme