Skip to content

Drop langchain-community (closes the last item in #510) - #543

Open
amirfz wants to merge 1 commit into
mainfrom
deps/drop-langchain-community
Open

Drop langchain-community (closes the last item in #510)#543
amirfz wants to merge 1 commit into
mainfrom
deps/drop-langchain-community

Conversation

@amirfz

@amirfz amirfz commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #510 — this was the one explicitly open item left after #509 ("Still open — dropping langchain-community, the one item genuinely left").

langchain-community was down to a single use in the whole package: GoogleSerperAPIWrapper in tools.py, called only via its own private _google_serper_api_results method. Upstream prints its own "being sunset, no longer actively maintained" deprecation warning on import (visible in every test run all session), so it won't get future security fixes.

Changes

  • Added _google_serper_search() in tools.py — a direct requests.post to https://google.serper.dev/search, replicating exactly what the wrapper's private method did (verified by reading its source). Removed the langchain_community import entirely.
  • Removed langchain-community from pyproject.toml.
  • Found and fixed a real gap while verifying this: removing langchain-community also dropped its transitive dependency langchain-classic, which was silently carrying sqlalchemy/greenlet. sqlalchemy is a genuine direct need — database/user_usage_tracker.py imports it for the usage-tracking DB — so it was only ever available by accident. Same class of bug the maintainer flagged in Dependency risk-surface reduction: drop dead/heavy deps (importlib, hydra-core, transformers, tokenizers, markdown), narrow unstructured, de-dupe spacy #510's review for word2number/pypdf/en_core_web_sm ("core code paths depend on packages the published package doesn't install"). Now declared explicitly in the main dependency group with a comment explaining why.
  • Updated the two test mock sites (conftest.py's mock_env, test_citation_validation.py) that patched langchain_community.utilities.GoogleSerperAPIWrapper._google_serper_api_results to patch sherpa_ai.tools._google_serper_search instead.
  • Added a focused unit test for _google_serper_search itself — there was no direct test of the old wrapper call either, only indirect coverage through SearchTool.
  • poetry.lock regenerated with the same Poetry version as the existing lock (2.2.1) to avoid unrelated format churn.

Verification

  • Mutated _google_serper_search's header construction and confirmed the new test fails; reverted and confirmed green.
  • Full suite (385 passed, 2 skipped) run for real with langchain-community and langchain-classic uninstalled from the environment, not just removed from pyproject.toml — this is what caught the sqlalchemy gap; a grep-only check would have missed it since sqlalchemy is imported directly in sherpa_ai/, just never declared.
  • Confirmed the deprecation warning is gone (import sherpa_ai.tools prints nothing now, vs. the langchain-community is being sunset... warning on every prior test run this session).

Test plan

  • pytest tests/unit_tests/tools/test_search_tool.py — new + existing tests pass
  • Full suite — 385 passed, 2 skipped, langchain-community/langchain-classic not installed
  • Mutation test on the new helper — caught, reverted
  • CI on this PR

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

langchain-community was down to a single use: GoogleSerperAPIWrapper
in tools.py, called only via its own private _google_serper_api_results
method — never the documented public API. Upstream now prints its own
"being sunset, no longer actively maintained" deprecation warning on
import, so it won't receive future security fixes.

Replaced it with a small direct call to the Serper.dev API (the
wrapper's method was already just a thin requests.post), removing the
dependency entirely.

Removing langchain-community also dropped langchain-classic, and with
it sqlalchemy/greenlet, which were only ever present transitively.
sqlalchemy is a real, direct need — database/user_usage_tracker.py
imports it for the usage-tracking DB — so it's now declared explicitly
in the main dependency group instead of riding in on a package that's
going away. This is the same "core code path depends on a package the
published package doesn't install" trap flagged in issue #510's review
for word2number/pypdf/en_core_web_sm; caught here by actually
uninstalling langchain-community and running the real suite rather
than just checking imports in sherpa_ai/.

Added a focused unit test for the new _google_serper_search helper
(there was no direct test of the old wrapper call either), and
verified it by mutating the request headers and confirming the test
catches it, then reverting.

Full suite (385 passed, 2 skipped) run for real with
langchain-community and langchain-classic uninstalled from the
environment, not just removed from pyproject.toml.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@amirfz
amirfz force-pushed the deps/drop-langchain-community branch from 8288b8c to 2e366c6 Compare August 1, 2026 15:11

@20001LastOrder 20001LastOrder left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Generally looks good, but I think a wrapper class is better than a function

Comment thread src/sherpa_ai/tools.py
HTTP_GET_TIMEOUT = 20.0


def _google_serper_search(query: str) -> dict:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would prefer to implement it as a property rather than a function. Something like:

class GoogleSerperAPIWrapper(BaseModel):
    url: str = https://google.serper.dev/search
    api_key = cfg.SERPER_API_KEY

    def search(self, query):
        ...

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.

Dependency risk-surface reduction: drop dead/heavy deps (importlib, hydra-core, transformers, tokenizers, markdown), narrow unstructured, de-dupe spacy

2 participants