Skip to content

feat(search): add APISerpent (apiserpent.com) as search provider - #29448

Merged
Sameerlite merged 3 commits into
BerriAI:litellm_oss_stagingfrom
yudelevi:litellm_apiserpent_search_provider
Jun 2, 2026
Merged

feat(search): add APISerpent (apiserpent.com) as search provider#29448
Sameerlite merged 3 commits into
BerriAI:litellm_oss_stagingfrom
yudelevi:litellm_apiserpent_search_provider

Conversation

@yudelevi

@yudelevi yudelevi commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

N/A; new feature addition

Pre-Submission checklist

  • I have added meaningful tests
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Type

🆕 New Feature

Changes

Adds APISerpent as a new provider for the LiteLLM Search API. APISerpent is a multi-engine SERP API covering Google, Bing, Yahoo, and DuckDuckGo via GET requests.

It exposes two endpoints, quick search (/api/search/quick) and deep search (/api/search), both billed at $0.60 per 1k searches. Both are surfaced under a single apiserpent provider; callers select the deep endpoint by passing deep=True, which follows the way Linkup and Tavily already ship two search setups under one provider. Unified params (max_results, country, search_domain_filter) are supported alongside APISerpent-specific ones (engine, language, freshness, safe, pages, format, pixel_position).

All supported parameters and their defaults live in a single APISerpentSearchParams dataclass, which is the source of truth for the request schema. It enforces the documented bounds (num 1 to 100, pages 1 to 10, raising on out-of-range values) and types the constrained string params (engine, safe, freshness, format) as Literals.

New files:

  • litellm/llms/apiserpent/search/transformation.py; APISerpentSearchConfig with quick/deep routing and response parsing
  • litellm/llms/apiserpent/search/defaults.py; APISerpentSearchParams dataclass with defaults, bounds enforcement, and Literal types
  • tests/search_tests/test_apiserpent_search.py

Modified files:

  • litellm/types/utils.py; add APISERPENT to SearchProviders
  • litellm/utils.py; register in get_provider_search_config()
  • model_prices_and_context_window.json and the backup copy; add apiserpent/search and apiserpent/deep_search cost entries ($0.0006/query)
  • tests/code_coverage_tests/enforce_llms_folder_style.py; add apiserpent to SEARCH_PROVIDERS

Screenshots / Proof of Fix

Live calls against the real APISerpent API (APISERPENT_API_KEY set), one per endpoint:

$ litellm.search(query="anthropic claude opus", search_provider="apiserpent", max_results=2)
QUICK: 2 results -> https://www.anthropic.com/news/claude-opus-4-8

$ litellm.search(query="rust async runtime", search_provider="apiserpent", deep=True, max_results=10)
DEEP : 10 results -> https://rust-lang.github.io/async-book/08_ecosystem/00_chapter.html

$ litellm.search(query="elektroauto reichweite", search_provider="apiserpent", engine="bing", country="DE", max_results=3)
QUICK bing/DE: 3 German results (engine + country passthrough confirmed)

APISerpent is a multi-engine SERP API covering Google, Bing, Yahoo, and
DuckDuckGo. It exposes two endpoints, quick search (/api/search/quick) and
deep search (/api/search), both billed at $0.60 per 1k searches. Both are
surfaced under a single `apiserpent` provider; callers select the deep
endpoint with `deep=True`, following the way Linkup and Tavily ship two
search setups under one provider.

All supported parameters and their defaults live in a single
APISerpentSearchParams dataclass, which enforces the documented bounds
(num 1 to 100, pages 1 to 10) and types the constrained string params
(engine, safe, freshness, format) as Literals.
@greptile-apps

greptile-apps Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds APISerpent as a new search provider under litellm/llms/apiserpent/, exposing quick and deep search endpoints behind a single apiserpent provider string, routing via the deep=True optional param. Previous review findings (null results payload raising on iteration, deep-search routing broken when api_base is overridden, and NUM_MIN_DEEP documentation) are all addressed in this revision.

  • Core implementation (transformation.py, defaults.py): extends BaseSearchConfig cleanly, uses the existing HTTP handler infrastructure, and correctly serialises GET params via urlencode; the endswith idempotency guard keeps URL construction correct across the handler's double invocation.
  • Registration: SearchProviders.APISERPENT, get_provider_search_config(), enforce_llms_folder_style.py, and both JSON pricing files are updated consistently.
  • Tests: All unit and integration tests are mock-only with good edge-case coverage (null results, api_base override, idempotency); the integration tests set os.environ[\"APISERPENT_API_KEY\"] without teardown, which can leak into subsequent tests in the same session.

Confidence Score: 5/5

Safe to merge; the provider integration is additive, all previous findings are resolved, and no existing behaviour is modified.

All changed paths are new files (new provider, new tests, JSON pricing entries) with no modifications to shared infrastructure beyond the two one-line registration additions. The null-results and api_base routing regressions flagged in the prior round are fixed and covered by regression tests. No auth, routing, or data-loss concerns exist in the changed code.

No files require special attention; the only note is test hygiene in the integration tests around environment-variable cleanup.

Important Files Changed

Filename Overview
litellm/llms/apiserpent/search/transformation.py New APISerpent provider implementing BaseSearchConfig; correctly handles null results, GET-based URL construction with idempotent endswith guard, and quick/deep routing.
litellm/llms/apiserpent/search/defaults.py Frozen dataclass defining APISerpent request params with bounds enforcement; NUM_MIN_DEEP floor is intentionally delegated to the transform layer (documented in the class docstring).
tests/test_litellm/llms/apiserpent/test_apiserpent_search.py Comprehensive mock-only test suite covering defaults, URL routing, response parsing, and null-results regression; integration tests set os.environ without cleanup which can persist across tests in the same session.
litellm/utils.py Registers APISerpentSearchConfig in get_provider_search_config(); lazy import keeps it consistent with other search providers.
model_prices_and_context_window.json Adds apiserpent/search and apiserpent/deep_search entries at $0.0006/query; matches provider documentation and is consistent with other search entries.
litellm/types/utils.py Adds APISERPENT to the SearchProviders enum; straightforward one-line addition.
tests/code_coverage_tests/enforce_llms_folder_style.py Adds apiserpent to SEARCH_PROVIDERS allowlist; required for the coverage job to recognize the new provider folder.

Reviews (2): Last reviewed commit: "address review: null results, idempotent..." | Re-trigger Greptile

Comment thread litellm/llms/apiserpent/search/transformation.py Outdated
Comment thread litellm/llms/apiserpent/search/transformation.py Outdated
Comment thread litellm/llms/apiserpent/search/defaults.py
@codecov

codecov Bot commented Jun 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Comment thread litellm/llms/apiserpent/search/transformation.py Outdated
@veria-ai

veria-ai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 1 · PR risk: 0/10

Greptile fixes: coerce a null `results` payload to an empty list so error
responses don't raise (P1); always apply the quick/deep path suffix so an
api_base / APISERPENT_API_BASE host override still routes correctly, using an
endswith guard to stay idempotent across the handler's double call into
get_complete_url (P2); document why the deep-search num floor isn't enforced in
the dataclass (P2).

Move the test suite from tests/search_tests to tests/test_litellm/llms/apiserpent
so the unit-test/coverage job (`pytest tests/test_litellm`) actually exercises
it; the package now reports 100% patch coverage. Adds regression tests for the
null-results and api_base-routing fixes.
@yudelevi
yudelevi force-pushed the litellm_apiserpent_search_provider branch from 5bbee99 to 8bbc2b7 Compare June 1, 2026 18:36
@yudelevi

yudelevi commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai please re-review. The latest commit addresses the earlier findings: a null results payload is now coerced to an empty list so error responses don't raise; the quick/deep endpoint path is always applied with an idempotent endswith guard so an api_base / APISERPENT_API_BASE host override still routes correctly across the handler's double call into get_complete_url; and the deep-search num floor rationale is documented in the dataclass. The test suite was moved to tests/test_litellm/llms/apiserpent so the coverage job exercises it (100% patch coverage on the package), with added regression tests for the null-results and api_base-routing fixes.

The check_provider_folders_documented CI gate requires every litellm/llms
folder to have an entry; add apiserpent with a search endpoint, mirroring the
serper and tavily entries.
@yudelevi

yudelevi commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

@krrish-berri-2 this adds APISerpent as a search provider, following the same pattern as the recent You.com addition. Greptile is at 5/5, all CI checks are green, and the provider-folder documentation gate passes. Docs are filed separately in BerriAI/litellm-docs#277 per the convention. Ready for review when you have a chance, thanks.

@Sameerlite Sameerlite left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks!

@Sameerlite
Sameerlite changed the base branch from litellm_internal_staging to litellm_oss_staging June 2, 2026 11:26
@Sameerlite
Sameerlite merged commit 155c07e into BerriAI:litellm_oss_staging Jun 2, 2026
46 checks passed
Sameerlite pushed a commit to BerriAI/litellm-docs that referenced this pull request Jun 2, 2026
Documents the APISerpent search provider being registered upstream in
BerriAI/litellm#29448. APISerpent is a multi-engine SERP API (Google, Bing,
Yahoo, DuckDuckGo) with quick and deep search endpoints, selected via the
`deep` flag. Adds the provider page plus the three index.md provider lists
and the sidebar entry.
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.

2 participants