Connessione all'API di Gemini 2.5 Pro
Per accedere al modello Gemini 2.5 Pro tramite la Google API, segui questi passaggi:
1. Configurazione
Per prima cosa, installa il pacchetto Python google-genai. Esegui il seguente comando nel terminale:
pip install google-genai
2. Generazione di una chiave API
Vai su Google AI Studio e genera la tua chiave API. Poi imposta la chiave API come variabile d'ambiente nel tuo sistema.

3. Crea il client GenAI
Usa la chiave API per inizializzare il client Google GenAI. Questo client ti permetterà di interagire con il modello Gemini 2.5 Pro.
import os
from google import genai
from google.genai import types
from IPython.display import Markdown, HTML, Image, display
API_KEY = os.environ.get("GEMINI_API_KEY")
client = genai.Client(api_key=API_KEY)
4. Carica il file
Carica il file Python con cui vuoi lavorare e crea un prompt per il modello.
# Load the Python file as text
file_path = "secure_app.py"
with open(file_path, "r") as file:
doc_data = file.read()
prompt = "Please integrate user management into the FastAPI application."
contents = [
types.Part.from_bytes(
data=doc_data.encode("utf-8"),
mime_type="text/x-python",
),
prompt,
]
5. Genera una risposta
Crea un'istanza di chat usando il modello Gemini 2.5 Pro (gemini-2.5-pro-exp-03-25) e fornisci i contenuti del file e il prompt. Il modello analizzerà il codice e genererà una risposta.
chat = client.aio.chats.create(
model="gemini-2.5-pro-exp-03-25",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution)]
),
)
response = await chat.send_message(contents)
Markdown(response.text)
In pochi secondi è stata generata una risposta sensibile al contesto.

Nota: l'accesso gratuito al modello potrebbe non essere al momento disponibile a causa dell'elevato carico. Aspetta qualche minuto e riprova.
6. Esecuzione del codice (Sperimentale)
Puoi anche chiedere al modello di eseguire il codice.
response = await chat.send_message('Please run the code to ensure that everything is functioning properly.')
Markdown(response.text)
Nota che questa funzione è sperimentale e presenta limitazioni. Ad esempio, il modello non può eseguire server web, accedere al file system o effettuare operazioni di rete.

Nota: il modello Gemini 2.5 Pro include capacità avanzate di "pensiero". Sebbene siano visibili in Google AI Studio, non sono incluse nell'output dell'API.
Creare un'app di analisi del codice con Gemini 2.5 Pro
Questa applicazione consente agli utenti di caricare file, inclusi più file o anche un archivio ZIP contenente un intero progetto, in un'interfaccia basata su chat. Gli utenti possono fare domande sul loro progetto, risolvere problemi o migliorare la codebase. A differenza dei tradizionali editor di codice basati su IA che faticano con contesti ampi a causa delle loro limitazioni, Gemini 2.5 Pro, con la sua lunga finestra di contesto, può analizzare e risolvere efficacemente i problemi su un intero progetto.
1. Installazione delle librerie necessarie
Installa gradio per creare l'interfaccia e zipfile36 per gestire i file ZIP.
pip install gradio==5.14.0
pip install zipfile36==0.1.3
2. Configurazione del client e dell'interfaccia
Importa i pacchetti Python necessari, definisci le variabili globali, inizializza il client GenAI, imposta le costanti dell'interfaccia e crea un elenco di estensioni di file supportate.
import os
import zipfile
from typing import Dict, List, Optional, Union
import gradio as gr
from google import genai
from google.genai import types
# Retrieve API key for Google GenAI from the environment variables.
GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
# Initialize the client so that it can be reused across functions.
CLIENT = genai.Client(api_key=GOOGLE_API_KEY)
# Global variables
EXTRACTED_FILES = {}
# Store chat sessions
CHAT_SESSIONS = {}
TITLE = """<h1 align="center">✨ Gemini Code Analysis</h1>"""
AVATAR_IMAGES = (None, "https://media.roboflow.com/spaces/gemini-icon.png")
# List of supported text extensions (alphabetically sorted)
TEXT_EXTENSIONS = [
".bat",
".c",
".cfg",
".conf",
".cpp",
".cs",
".css",
".go",
".h",
".html",
".ini",
".java",
".js",
".json",
".jsx",
".md",
".php",
".ps1",
".py",
".rb",
".rs",
".sh",
".toml",
".ts",
".tsx",
".txt",
".xml",
".yaml",
".yml",
]
3. Funzione: extract_text_from_zip
La funzione extract_text_from_zip() estrae il contenuto testuale dai file all'interno di un archivio ZIP e lo restituisce come dizionario.
def extract_text_from_zip(zip_file_path: str) -> Dict[str, str]:
text_contents = {}
with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
for file_info in zip_ref.infolist():
# Skip directories
if file_info.filename.endswith("/"):
continue
# Skip binary files and focus on text files
file_ext = os.path.splitext(file_info.filename)[1].lower()
if file_ext in TEXT_EXTENSIONS:
try:
with zip_ref.open(file_info) as file:
content = file.read().decode("utf-8", errors="replace")
text_contents[file_info.filename] = content
except Exception as e:
text_contents[file_info.filename] = (
f"Error extracting file: {str(e)}"
)
return text_contents
4. Funzione: extract_text_from_single_file
La funzione extract_text_from_single_file() estrae il contenuto testuale da un singolo file e lo restituisce come dizionario.
def extract_text_from_single_file(file_path: str) -> Dict[str, str]:
text_contents = {}
filename = os.path.basename(file_path)
file_ext = os.path.splitext(filename)[1].lower()
if file_ext in TEXT_EXTENSIONS:
try:
with open(file_path, "r", encoding="utf-8", errors="replace") as file:
content = file.read()
text_contents[filename] = content
except Exception as e:
text_contents[filename] = f"Error reading file: {str(e)}"
return text_contents
5. Funzione: upload_zip
La funzione upload_zip() elabora i file caricati, in formato ZIP o come file di testo, estrae il contenuto testuale e aggiunge un messaggio alla chat.
def upload_zip(files: Optional[List[str]], chatbot: List[Union[dict, gr.ChatMessage]]):
global EXTRACTED_FILES
# Handle multiple file uploads
if len(files) > 1:
total_files_processed = 0
total_files_extracted = 0
file_types = set()
# Process each file
for file in files:
filename = os.path.basename(file)
file_ext = os.path.splitext(filename)[1].lower()
# Process based on file type
if file_ext == ".zip":
extracted_files = extract_text_from_zip(file)
file_types.add("zip")
else:
extracted_files = extract_text_from_single_file(file)
file_types.add("text")
if extracted_files:
total_files_extracted += len(extracted_files)
# Store the extracted content in the global variable
EXTRACTED_FILES[filename] = extracted_files
total_files_processed += 1
# Create a summary message for multiple files
file_types_str = (
"files"
if len(file_types) > 1
else ("ZIP files" if "zip" in file_types else "text files")
)
# Create a list of uploaded file names
file_list = "\n".join([f"- {os.path.basename(file)}" for file in files])
chatbot.append(
gr.ChatMessage(
role="user",
content=f"<p>📚 Multiple {file_types_str} uploaded ({total_files_processed} files)</p><p>Extracted {total_files_extracted} text file(s) in total</p><p>Uploaded files:</p><pre>{file_list}</pre>",
)
)
# Handle single file upload (original behavior)
elif len(files) == 1:
file = files[0]
filename = os.path.basename(file)
file_ext = os.path.splitext(filename)[1].lower()
# Process based on file type
if file_ext == ".zip":
extracted_files = extract_text_from_zip(file)
file_type_msg = "📦 ZIP file"
else:
extracted_files = extract_text_from_single_file(file)
file_type_msg = "📄 File"
if not extracted_files:
chatbot.append(
gr.ChatMessage(
role="user",
content=f"<p>{file_type_msg} uploaded: {filename}, but no text content was found or the file format is not supported.</p>",
)
)
else:
file_list = "\n".join([f"- {name}" for name in extracted_files.keys()])
chatbot.append(
gr.ChatMessage(
role="user",
content=f"<p>{file_type_msg} uploaded: {filename}</p><p>Extracted {len(extracted_files)} text file(s):</p><pre>{file_list}</pre>",
)
)
# Store the extracted content in the global variable
EXTRACTED_FILES[filename] = extracted_files
return chatbot
6. Funzione: user
La funzione user() aggiunge l'input testuale dell'utente alla cronologia della conversazione del chatbot.
def user(text_prompt: str, chatbot: List[gr.ChatMessage]):
if text_prompt:
chatbot.append(gr.ChatMessage(role="user", content=text_prompt))
return "", chatbot
7. Funzione: get_message_content
La funzione get_message_content() recupera il contenuto di un messaggio, che può essere sia un dizionario sia un messaggio chat di Gradio.
def get_message_content(msg):
if isinstance(msg, dict):
return msg.get("content", "")
return msg.content
8. Funzione: send_to_gemini
La funzione send_to_gemini() invia il prompt dell'utente a Gemini AI e trasmette la risposta al chatbot. Se sono stati caricati file di codice, verranno inclusi nel contesto.
def send_to_gemini(chatbot: List[Union[dict, gr.ChatMessage]]):
global EXTRACTED_FILES, CHAT_SESSIONS
if len(chatbot) == 0:
chatbot.append(
gr.ChatMessage(
role="assistant",
content="Please enter a message to start the conversation.",
)
)
return chatbot
# Get the last user message as the prompt
user_messages = [
msg
for msg in chatbot
if (isinstance(msg, dict) and msg.get("role") == "user")
or (hasattr(msg, "role") and msg.role == "user")
]
if not user_messages:
chatbot.append(
gr.ChatMessage(
role="assistant",
content="Please enter a message to start the conversation.",
)
)
return chatbot
last_user_msg = user_messages[-1]
prompt = get_message_content(last_user_msg)
# Skip if the last message was about uploading a file (ZIP, single file, or multiple files)
if (
"📦 ZIP file uploaded:" in prompt
or "📄 File uploaded:" in prompt
or "📚 Multiple files uploaded" in prompt
):
chatbot.append(
gr.ChatMessage(
role="assistant",
content="What would you like to know about the code in this ZIP file?",
)
)
return chatbot
# Generate a unique session ID based on the extracted files or use a default key for no files
if EXTRACTED_FILES:
session_key = ",".join(sorted(EXTRACTED_FILES.keys()))
else:
session_key = "no_files"
# Create a new chat session if one doesn't exist for this set of files
if session_key not in CHAT_SESSIONS:
# Configure Gemini with code execution capability
CHAT_SESSIONS[session_key] = CLIENT.chats.create(
model="gemini-2.5-pro-exp-03-25",
)
# Send all extracted files to the chat session first
initial_contents = []
for zip_name, files in EXTRACTED_FILES.items():
for filename, content in files.items():
file_ext = os.path.splitext(filename)[1].lower()
mime_type = "text/plain"
# Set appropriate mime type based on file extension
if file_ext == ".py":
mime_type = "text/x-python"
elif file_ext in [".js", ".jsx"]:
mime_type = "text/javascript"
elif file_ext in [".ts", ".tsx"]:
mime_type = "text/typescript"
elif file_ext == ".html":
mime_type = "text/html"
elif file_ext == ".css":
mime_type = "text/css"
elif file_ext in [".json", ".jsonl"]:
mime_type = "application/json"
elif file_ext in [".xml", ".svg"]:
mime_type = "application/xml"
# Create a header with the filename to preserve original file identity
file_header = f"File: {filename}\n\n"
file_content = file_header + content
initial_contents.append(
types.Part.from_bytes(
data=file_content.encode("utf-8"),
mime_type=mime_type,
)
)
# Initialize the chat context with files if available
if initial_contents:
initial_contents.append(
"I've uploaded these code files for you to analyze. I'll ask questions about them next."
)
# Use synchronous API instead of async
CHAT_SESSIONS[session_key].send_message(initial_contents)
# For sessions without files, we don't need to send an initial message
# Append a placeholder for the assistant's response
chatbot.append(gr.ChatMessage(role="assistant", content=""))
# Send the user's prompt to the existing chat session using streaming API
response = CHAT_SESSIONS[session_key].send_message_stream(prompt)
# Process the response stream - text only (no images)
output_text = ""
for chunk in response:
if chunk.candidates and chunk.candidates[0].content.parts:
for part in chunk.candidates[0].content.parts:
if part.text is not None:
# Append the new chunk of text
output_text += part.text
# Update the last assistant message with the current accumulated response
if isinstance(chatbot[-1], dict):
chatbot[-1]["content"] = output_text
else:
chatbot[-1].content = output_text
# Yield the updated chatbot to show streaming updates in the UI
yield chatbot
# Return the final chatbot state
return chatbot
9. Funzione: reset_app
La funzione rest_app() ripristina l'applicazione cancellando la cronologia della chat e i file caricati.
def reset_app(chatbot):
global EXTRACTED_FILES, CHAT_SESSIONS
# Clear the global variables
EXTRACTED_FILES = {}
CHAT_SESSIONS = {}
# Reset the chatbot with a welcome message
return [
gr.ChatMessage(
role="assistant",
content="App has been reset. You can start a new conversation or upload new files.",
)
]
10. Componenti UI di Gradio
Definiamo i componenti Gradio: chatbot, input testuale, pulsante di caricamento e pulsanti di controllo.
# Define the Gradio UI components
chatbot_component = gr.Chatbot(
label="Gemini 2.5 Pro",
type="messages",
bubble_full_width=False,
avatar_images=AVATAR_IMAGES,
scale=2,
height=350,
)
text_prompt_component = gr.Textbox(
placeholder="Ask a question or upload code files to analyze...",
show_label=False,
autofocus=True,
scale=28,
)
upload_zip_button_component = gr.UploadButton(
label="Upload",
file_count="multiple",
file_types=[".zip"] + TEXT_EXTENSIONS,
scale=1,
min_width=80,
)
send_button_component = gr.Button(
value="Send", variant="primary", scale=1, min_width=80
)
reset_button_component = gr.Button(
value="Reset", variant="stop", scale=1, min_width=80
)
# Define input lists for button chaining
user_inputs = [text_prompt_component, chatbot_component]
11. Layout dell'app Gradio
Strutturiamo l'interfaccia Gradio usando righe e colonne per un layout pulito.
with gr.Blocks(theme=gr.themes.Ocean()) as demo:
gr.HTML(TITLE)
with gr.Column():
chatbot_component.render()
with gr.Row(equal_height=True):
text_prompt_component.render()
send_button_component.render()
upload_zip_button_component.render()
reset_button_component.render()
# When the Send button is clicked, first process the user text then send to Gemini
send_button_component.click(
fn=user,
inputs=user_inputs,
outputs=[text_prompt_component, chatbot_component],
queue=False,
).then(
fn=send_to_gemini,
inputs=[chatbot_component],
outputs=[chatbot_component],
api_name="send_to_gemini",
)
# Allow submission using the Enter key
text_prompt_component.submit(
fn=user,
inputs=user_inputs,
outputs=[text_prompt_component, chatbot_component],
queue=False,
).then(
fn=send_to_gemini,
inputs=[chatbot_component],
outputs=[chatbot_component],
api_name="send_to_gemini_submit",
)
# Handle ZIP file uploads
upload_zip_button_component.upload(
fn=upload_zip,
inputs=[upload_zip_button_component, chatbot_component],
outputs=[chatbot_component],
queue=False,
)
# Handle Reset button clicks
reset_button_component.click(
fn=reset_app,
inputs=[chatbot_component],
outputs=[chatbot_component],
queue=False,
)
12. Avvio dell'app
Avviamo l'applicazione Gradio in locale con la coda abilitata per gestire più richieste.
# Launch the demo interface
demo.queue(max_size=99, api_open=False).launch(
debug=False,
show_error=True,
server_port=9595,
server_name="localhost",
)
Test dell'app di analisi del codice Gemini 2.5 Pro
Per avviare l'applicazione web, unisci tutti i sorgenti di codice sopra nel file main.py (che ho caricato su GitHub per facilitarti la copia). Eseguilo con il seguente comando:
python main.py
L'applicazione web sarà disponibile all'URL: http://localhost:9595/
Puoi copiare l'URL e incollarlo nel tuo browser.
Come possiamo vedere, l'applicazione web offre un'interfaccia tipo chatbot. Possiamo usarla proprio come ChatGPT.

Il pulsante “Upload” supporta il caricamento singolo e multiplo di file, oltre ai file zip del tuo progetto. Quindi, non preoccuparti se il tuo progetto contiene più di 20 file: l'app di analisi del codice sarà in grado di elaborarli e inviarli all'API di Gemini 2.5 Pro.

Carichiamo più file e chiediamo a Gemini 2.5 Pro di migliorare il nostro progetto.
Come possiamo vedere, il modello fornisce suggerimenti corretti per i miglioramenti.

Possiamo chiedergli di implementare tutti i suggerimenti nel file secure_app.py.

Se vuoi lavorare su un altro progetto, puoi cliccare sul pulsante “Reset” e iniziare a chattare sul nuovo progetto.

Il codice sorgente e le configurazioni sono disponibili nel repository GitHub: kingabzpro/Gemini-2.5-Pro-Coding-App.
Conclusione
Creare una vera applicazione di IA è diventato molto più semplice. Invece di costruire applicazioni complesse con strumenti come LangChain, integrare vector store, ottimizzare i prompt o aggiungere catene di ragionamento, possiamo semplicemente inizializzare il client Gemini 2.5 Pro tramite la Google API. La Chat API di Gemini 2.5 Pro gestisce direttamente vari tipi di file, consente domande di follow-up e fornisce risposte altamente accurate.
In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.



Costruire anche una semplice app di IA non è forse un groviglio di vector store, strumenti RAG, API e debug? Non più. Gemini 2.5 Pro offre una lunga finestra di contesto da 1 milione di token (con l'intenzione di raddoppiarla) e la possibilità di caricare file direttamente senza strumenti RAG o vector store.
Gemini 2.5 Pro è un modello di ragionamento che eccelle nel coding, e la sua enorme finestra di contesto apre la strada a un reale valore di business nelle applicazioni incentrate sul codice. Per questo, in questo blog, ti guiderò nella creazione di una vera web app che elabora il codice sorgente e ti aiuta a ottimizzare i tuoi progetti in pochi secondi.
Vado dritto al codice: se cerchi solo una panoramica del modello, dai un'occhiata a questo blog introduttivo su Gemini 2.5 Pro, e al modello più recente, Gemini 3. Se vuoi saperne di più sulla nuova funzione Computer Use, leggi la nostra guida completa a Gemini 2.5 Computer Use.