Skip to content

Skip image search when Pexels API key is unavailable and prepare for new release#172

Merged
barun-saha merged 4 commits intomainfrom
maintenance
Nov 15, 2025
Merged

Skip image search when Pexels API key is unavailable and prepare for new release#172
barun-saha merged 4 commits intomainfrom
maintenance

Conversation

@barun-saha
Copy link
Owner

@barun-saha barun-saha commented Nov 15, 2025

Closes #166.

Summary by CodeRabbit

  • Bug Fixes

    • Added a one-time warning when the image search API key is not configured and graceful fallback to avoid errors (returns no results when key is absent).
  • Chores

    • Version bumped to 8.0.3.
    • Updated package description to "Co-create PowerPoint slide decks with AI".
  • Tests

    • Added unit tests covering behavior when the image search API key is missing.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 15, 2025

Walkthrough

This PR bumps the package version to 8.0.3, updates project description in pyproject.toml, and adds early validation + centralized constants for Pexels API usage in the image search helper. Tests were added to cover behavior when the PEXEL_API_KEY is missing.

Changes

Cohort / File(s) Summary
Version & metadata
pyproject.toml, src/slidedeckai/_version.py
Updated project description to "Co-create PowerPoint slide decks with AI" and incremented __version__ from 8.0.2 to 8.0.3.
Pexels API handling
src/slidedeckai/helpers/image_search.py
Added one-time warning when PEXEL_API_KEY is unset; introduced PEXELS_URL, REQUEST_HEADER, REQUEST_TIMEOUT, MAX_PHOTOS; short-circuited search_pexels and get_photo_url_from_api_response to return empty/None when key missing; standardized request headers in get_image_from_url; updated docstrings.
Unit tests
tests/unit/test_image_search.py
Added tests asserting empty/None responses when PEXEL_API_KEY is missing; added monkeypatch setup in an existing test; minor formatting cleanup in test helpers.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant IS as image_search
    participant PEX as Pexels API

    U->>IS: search_pexels(query)
    IS->>IS: check PEXEL_API_KEY
    alt API key present
        IS->>PEX: HTTP GET POST with REQUEST_HEADER, timeout
        PEX-->>IS: photos response
        IS->>IS: parse response -> photo URL
        IS-->>U: photo data (dict)
    else API key missing
        rect rgb(255, 245, 230)
            IS->>IS: warn once (PEXEL_API_KEY missing)
            IS-->>U: {} (empty dict) / (None, None)
        end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Areas to inspect:
    • One-time warning implementation (firing only once)
    • Consistent use of REQUEST_HEADER and REQUEST_TIMEOUT across functions
    • Tests properly isolate environment (monkeypatching/unsetting PEXEL_API_KEY)

Possibly related PRs

Poem

🐰 I hopped in with a gentle peep,

When keys are missing, I do not leap,
I whisper once — a kindly chime,
Then hand back empty space and time,
A tidy guard, a peaceful keep.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary changes: skipping image search when Pexels API key is unavailable and bumping version for release.
Linked Issues check ✅ Passed The PR successfully addresses issue #166 by implementing early return when API key is missing and adding tests for this behavior.
Out of Scope Changes check ✅ Passed All changes are in scope: image search modifications for missing API key handling, version bump for release, and corresponding test additions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch maintenance

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e003d25 and ee7e58b.

📒 Files selected for processing (2)
  • src/slidedeckai/helpers/image_search.py (5 hunks)
  • tests/unit/test_image_search.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/slidedeckai/helpers/image_search.py
  • tests/unit/test_image_search.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test (3.10)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/slidedeckai/helpers/image_search.py (1)

19-24: Add stacklevel parameter to the warning for better diagnostics.

The warning should include stacklevel=2 to report the warning at the caller's location (the import site) rather than from within this module, making it easier for users to identify where the issue originates.

As per static analysis

Apply this diff:

-    warnings.warn(
-        'PEXEL_API_KEY environment variable is not set. '
-        'Image search functionality will not work without it.'
-    )
+    warnings.warn(
+        'PEXEL_API_KEY environment variable is not set. '
+        'Image search functionality will not work without it.',
+        stacklevel=2
+    )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ba5451 and e003d25.

📒 Files selected for processing (4)
  • pyproject.toml (1 hunks)
  • src/slidedeckai/_version.py (1 hunks)
  • src/slidedeckai/helpers/image_search.py (5 hunks)
  • tests/unit/test_image_search.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/unit/test_image_search.py (1)
src/slidedeckai/helpers/image_search.py (2)
  • search_pexels (41-89)
  • get_photo_url_from_api_response (92-128)
🪛 Ruff (0.14.4)
src/slidedeckai/helpers/image_search.py

21-21: No explicit stacklevel keyword argument found

Set stacklevel=2

(B028)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test (3.10)
🔇 Additional comments (9)
src/slidedeckai/_version.py (1)

1-1: LGTM! Appropriate version bump for this maintenance release.

The patch version increment correctly reflects the bug fix and improvement nature of this PR.

pyproject.toml (1)

10-10: LGTM! The updated description is more concise and user-friendly.

The new wording better conveys the collaborative aspect and specifies the PowerPoint output format.

tests/unit/test_image_search.py (3)

74-74: LGTM! Good test hygiene.

Adding the stream assertion strengthens the mock validation by ensuring the function under test passes the expected parameter.


172-177: LGTM! Test correctly validates the API key guard behavior.

This test properly verifies that search_pexels returns an empty dict when the API key is unavailable, matching the implementation's early-return guard.


180-188: LGTM! Test correctly validates the guard behavior.

This test properly verifies that get_photo_url_from_api_response returns (None, None) when the API key is unavailable, even when valid photo data is present in the response.

src/slidedeckai/helpers/image_search.py (4)

72-73: LGTM! Early guard prevents unnecessary API calls.

The guard correctly implements the PR objective by skipping the API call entirely when the API key is unavailable, preventing 401 Unauthorized errors.


81-86: LGTM! Good refactoring to centralized constants.

Using the centralized constants improves maintainability and provides a single source of truth for the API configuration.


106-107: LGTM! Guard ensures consistent None returns when API key is missing.

The early return correctly prevents processing when the API key is unavailable, maintaining consistency with the function's existing None-return semantics.


147-147: LGTM! Consistent use of centralized constants.

The update to use REQUEST_HEADER maintains consistency with the other API calls. Note that the potential Authorization: None issue flagged in the earlier comment about REQUEST_HEADER initialization also applies here, but it's mitigated by the normal workflow where this function is only called with valid URLs from successful API responses.

Comment on lines +27 to +30
REQUEST_HEADER = {
'Authorization': os.getenv('PEXEL_API_KEY'),
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider conditional header construction to avoid None Authorization value.

When PEXEL_API_KEY is not set, REQUEST_HEADER['Authorization'] becomes None. While the guards in search_pexels and get_photo_url_from_api_response prevent API calls, get_image_from_url (line 147) uses this header without checking the API key. If get_image_from_url is called independently, it would send a request with Authorization: None, which is semantically incorrect.

Consider constructing the header conditionally:

-REQUEST_HEADER = {
-    'Authorization': os.getenv('PEXEL_API_KEY'),
-    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
-}
+_api_key = os.getenv('PEXEL_API_KEY')
+REQUEST_HEADER = {
+    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
+}
+if _api_key:
+    REQUEST_HEADER['Authorization'] = _api_key
🤖 Prompt for AI Agents
In src/slidedeckai/helpers/image_search.py around lines 27 to 30, the
REQUEST_HEADER is built with 'Authorization': os.getenv('PEXEL_API_KEY') which
can be None; update header construction to only include the Authorization entry
when the env var is present (or use an empty string option) so no request is
sent with 'Authorization: None'. Implement a small helper (or inline logic) that
reads PEXEL_API_KEY, and returns headers that include User-Agent always but only
add Authorization if the key is truthy; replace uses of the module-level
REQUEST_HEADER with this safe header builder (or call it from
get_image_from_url) so independent calls never send a None Authorization value.

@codecov
Copy link

codecov bot commented Nov 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@barun-saha barun-saha merged commit 51a1ad7 into main Nov 15, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add friendly error message for Pexels access error

1 participant