-
Notifications
You must be signed in to change notification settings - Fork 31
Upgrade langchain-elasticsearch for LangChain 1.x compatibility #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Upgrade langchain-elasticsearch for LangChain 1.x compatibility #89
Conversation
Intent
Upgrade langchain-elasticsearch to support LangChain 1.x (released October 2025)
while maintaining backward compatibility with LangChain 0.3.x. This unblocks
downstream projects (like aiq_llm_apps) from upgrading to the latest LangChain
ecosystem.
---
Changes Made
1. pyproject.toml
| Change | From | To | Why
|
|----------------------|-----------------|----------------|------------------------
-------------------------------------------------|
| Version bump | 0.4.0 | 0.5.0 | Semantic versioning -
breaking change due to Python version requirement |
| Python version | >=3.9,<4.0 | >=3.10,<4.0 | LangChain 1.x requires
Python 3.10+ (Python 3.9 EOL Oct 2025) |
| langchain (test dep) | >=0.3.10,<1.0.0 | >=1.0.0,<2.0.0 | Enable testing against
LangChain 1.x |
| pytest-asyncio | ^0.21.1 | ^0.23.0 | Compatibility with
Python 3.10+ and newer pytest |
Note: langchain-core = ">=0.3.0,<2.0.0" was already compatible - no change needed.
---
2. Test Fixes (4 files)
Files:
- tests/unit_tests/_sync/test_cache.py
- tests/unit_tests/_async/test_cache.py
- tests/integration_tests/_sync/test_cache.py
- tests/integration_tests/_async/test_cache.py
Problem: Tests imported from langchain.embeddings.cache import _value_serializer -
this private module was reorganized in LangChain 1.x and no longer exists at that
path.
Solution: Replaced the import with a local implementation:
import json
from typing import List
def _value_serializer(value: List[float]) -> bytes:
"""Serialize embedding values to bytes (replaces private langchain
function)."""
return json.dumps(value).encode()
Why this approach:
- _value_serializer is a private function (underscore prefix) - not part of public
API
- The implementation is trivial (json.dumps(value).encode())
- Avoids dependency on internal LangChain implementation details
- More robust against future LangChain changes
---
3. Import Path Fix (integration tests)
Change: from langchain.globals import set_llm_cache → from langchain_core.globals
import set_llm_cache
Why: langchain_core is the direct dependency of this package. Using
langchain.globals would require the full langchain package at runtime, but
langchain is only a test dependency. The langchain_core.globals path is the
canonical location.
---
4. Async Client Cleanup Fixture (async integration test)
Added: _close_async_caches autouse fixture in
tests/integration_tests/_async/test_cache.py
Why: Ensures async Elasticsearch clients are properly closed after tests, avoiding
aiohttp "Unclosed client session" warnings. This is a best practice for async tests
using aiohttp-based clients.
---
What Didn't Need Changes
The source code in langchain_elasticsearch/ was already compatible with LangChain
1.x because it uses stable langchain_core APIs:
- langchain_core.documents.Document
- langchain_core.embeddings.Embeddings
- langchain_core.vectorstores.VectorStore
- langchain_core.retrievers.BaseRetriever
- langchain_core.caches.BaseCache
- langchain_core.stores.ByteStore
---
Gotchas Found
1. Private API dependency in tests: The original tests depended on
langchain.embeddings.cache._value_serializer, a private function. LangChain 1.x
reorganized internal modules, breaking this import. Lesson: Avoid importing private
APIs (underscore-prefixed) even in tests.
2. langchain vs langchain_core imports: Integration tests were importing from
langchain.globals but langchain is only a test dependency. The correct import path
is langchain_core.globals since that's the actual dependency.
3. Async client cleanup: Async Elasticsearch tests can leave unclosed aiohttp
sessions if not properly cleaned up, causing warnings during test runs.
4. Python 3.9 EOL: LangChain 1.x dropped Python 3.9 support. This is a breaking
change for any users still on Python 3.9.
---
Test Results
======================== 69 passed, 4 warnings in 0.13s ========================
The 4 warnings are expected deprecation notices for legacy retrieval strategy
classes (ApproxRetrievalStrategy → DenseVectorStrategy, etc.) which are still
functional.
---
Breaking Changes for Users
- Python 3.9 no longer supported - users must upgrade to Python 3.10+
---
Updated elasticsearch version constraint to support elasticsearch 9.x while maintaining backwards compatibility with 8.x. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Any timelines for this PR? |
|
Please update this PR! |
|
@sharrajesh @demetere @rvargas42 Sorry for the late reply here and thank you for the effort in trying to work on this! I have released 1.0.0 of this integration. It supports our integration with I would love to get your thoughts on the release, please give it a try and let me know if there is anything else you feel is needed I will likely close this PR soon since we have achieved the intended purpose |
Intent
Upgrade langchain-elasticsearch to support LangChain 1.x (released October 2025)
while maintaining backward compatibility with LangChain 0.3.x. This unblocks
downstream projects (like aiq_llm_apps) from upgrading to the latest LangChain
ecosystem.
Changes Made
| Change | From | To | Why
|
|----------------------|-----------------|----------------|------------------------
-------------------------------------------------|
| Version bump | 0.4.0 | 0.5.0 | Semantic versioning -
breaking change due to Python version requirement |
| Python version | >=3.9,<4.0 | >=3.10,<4.0 | LangChain 1.x requires
Python 3.10+ (Python 3.9 EOL Oct 2025) |
| langchain (test dep) | >=0.3.10,<1.0.0 | >=1.0.0,<2.0.0 | Enable testing against
LangChain 1.x |
| pytest-asyncio | ^0.21.1 | ^0.23.0 | Compatibility with
Python 3.10+ and newer pytest |
Note: langchain-core = ">=0.3.0,<2.0.0" was already compatible - no change needed.
Files:
Problem: Tests imported from langchain.embeddings.cache import _value_serializer -
this private module was reorganized in LangChain 1.x and no longer exists at that
path.
Solution: Replaced the import with a local implementation:
import json
from typing import List
def _value_serializer(value: List[float]) -> bytes:
"""Serialize embedding values to bytes (replaces private langchain
function)."""
return json.dumps(value).encode()
Why this approach:
Change: from langchain.globals import set_llm_cache → from langchain_core.globals
import set_llm_cache
Why: langchain_core is the direct dependency of this package. Using
langchain.globals would require the full langchain package at runtime, but
langchain is only a test dependency. The langchain_core.globals path is the
canonical location.
Added: _close_async_caches autouse fixture in
tests/integration_tests/_async/test_cache.py
Why: Ensures async Elasticsearch clients are properly closed after tests, avoiding
aiohttp "Unclosed client session" warnings. This is a best practice for async tests
using aiohttp-based clients.
What Didn't Need Changes
The source code in langchain_elasticsearch/ was already compatible with LangChain
1.x because it uses stable langchain_core APIs:
Gotchas Found
Test Results
======================== 69 passed, 4 warnings in 0.13s ========================
The 4 warnings are expected deprecation notices for legacy retrieval strategy
classes (ApproxRetrievalStrategy → DenseVectorStrategy, etc.) which are still
functional.
Breaking Changes for Users