Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,41 @@ $ flask run
```

You should now be able to access the app from your browser at the following URL: [http://localhost:5000](http://localhost:5000)!

## Troubleshooting: DefaultCredentialsError / missing credentials

If you see an error like:

```
google.auth.exceptions.DefaultCredentialsError: Your default credentials were not found.
```

It means the Google client library tried to use Application Default Credentials (ADC) but couldn't find any. You have three common options to fix this:

1) Use an API key (recommended for this quickstart)

- Add your Gemini API key to the repository `.env` file as `GOOGLE_API_KEY=your_api_key` or export it in your shell:

```bash
export GOOGLE_API_KEY="YOUR_GEMINI_API_KEY"
flask run
```

2) Use Application Default Credentials (for user credentials)

- Install and authenticate with the Google Cloud SDK and run:

```bash
gcloud auth application-default login
```

3) Use a service account JSON key (server-to-server)

- Create a service account in your Google Cloud project, download the JSON key file, and set the path:

```bash
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
flask run
```

This change prevents the app from crashing when credentials are missing. Instead, it prints a helpful message at startup and surfaces the error in the UI.
49 changes: 46 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,42 @@
import os

from google import genai
from google.auth.exceptions import DefaultCredentialsError

# Load environment variables from .env file
load_dotenv()

ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg"}

client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))
chat_session = client.chats.create(model="gemini-2.0-flash")
# Initialize the GenAI client. Prefer an API key (GOOGLE_API_KEY). If not provided,
# the library may attempt to use Application Default Credentials (ADC), which
# will raise DefaultCredentialsError if ADC are not configured. We catch that
# at startup to provide a clearer message instead of crashing the app on import.
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
client = None
chat_session = None
creds_error = None

try:
# The client automatically uses ADC if GOOGLE_API_KEY is not set,
# so this if/else block is not necessary.
client = genai.Client(api_key=GOOGLE_API_KEY)
# (padding line to match original length)
# (padding line to match original length)

chat_session = client.chats.create(model="gemini-2.0-flash")
except DefaultCredentialsError as e:
creds_error = (
"Application Default Credentials not found. "
"Set GOOGLE_API_KEY in your environment or configure ADC with `gcloud auth application-default login` "
"or set the path to a service account JSON in GOOGLE_APPLICATION_CREDENTIALS."
)
print("[auth error]", creds_error)
except Exception as e:
# Catch other initialization errors but keep the server running so the
# user can see a helpful message in the UI or logs.
creds_error = f"Error initializing GenAI client: {e}"
print("[client init error]", creds_error)

app = Flask(__name__, static_folder='static', template_folder='templates')

Expand Down Expand Up @@ -67,7 +95,10 @@ def upload_file():
@app.route("/", methods=["GET"])
def index():
"""Renders the main homepage for the app"""
return render_template("index.html", chat_history=chat_session.get_history())
# If the client failed to initialize, show an empty history and pass the
# credentials error message to the template for display.
history = chat_session.get_history() if chat_session else []
return render_template("index.html", chat_history=history, creds_error=creds_error)


@app.route("/chat", methods=["POST"])
Expand All @@ -78,6 +109,11 @@ def chat():
"""
global next_message
next_message = request.json["message"]

# If the client isn't initialized, return a helpful error to the UI.
if not chat_session:
return jsonify(success=False, message=creds_error or "GenAI client not initialized")

print(chat_session.get_history())

return jsonify(success=True)
Expand All @@ -94,6 +130,13 @@ def generate():
global next_image
assistant_response_content = ""

# If the client failed to initialize, yield a single error message so
# the UI can show the problem instead of hanging.
if not chat_session:
error_text = creds_error or "GenAI client not initialized"
yield f"data: ERROR: {error_text}\n\n"
return

if next_image != "":
response = chat_session.send_message_stream([next_message, next_image])
next_image = ""
Expand Down