Changelog
2.0.8 (2026-03-27)
Bug fixes:
Decimal serialization:
decimal.Decimalvalues are now handled in both update paths — JSON encoder converts tofloat, XML serializer converts viastr()to produce clean numeric strings.
Resolved legacy issues:
Security — ``eval()`` removed: all uses of
eval()were eliminated in the 2.x rewrite. Response parsing usesjson.loads()and SAX XML parser exclusively. No risk of arbitrary code execution from untrusted data.No stray ``print()``: debug
print(''.join(lst))inadd_many()that leaked documents to logs is gone. Noprint()calls exist in any execution path.UTF-8 encoding:
setup.pyreplaced with Poetrypyproject.toml. Theopen('README.md')encoding issue no longer applies.``q.op`` parameter: dotted Solr parameters (e.g.
q.op) are supported via underscore notation:conn.select('*:*', q_op='AND')sendsq.op=AND. Works for all dotted parameter names.
2.0.7.post1 (2026-03-27)
Documentation:
KNN: all 4 search modes + builder methods in quickstart and reference
Streaming Expressions: sync examples, pipe operator, full function catalog
PysolrCompat: migration guide in quickstart + reference
AsyncSolr: full reference section with all methods
Response attributes:
facet_counts,stats,debugQuery builders:
Field.transformer(),Facet.range(),Facet.pivot()Highlighting: response structure and customization examples
Remove
pysolrfrom dev dependencies
2.0.7 (2026-03-27)
New features:
Lazy initialization:
Solr()constructor is now instant (~0ms). Thehttpx.Clientand Solr version detection are deferred to first use.PysolrCompat: drop-in compatibility wrapper for migrating from pysolr.
from solr import PysolrCompatprovidessearch(),add(list),delete(q=...)that map to native solrpy methods.Select performance:
json.loads(bytes)instead ofjson.loads(string)eliminates redundant decode in the select path.Feature comparison table (solrpy vs pysolr) in README.
Comprehensive docstring audit: 104 methods updated with
:param:docs.
2.0.6 (2026-03-27)
New features:
Async Pydantic models:
model=parameter onAsyncSolr.select().await conn.select('*:*', model=MyDoc)returnsResponsewithresultsas a list of Pydantic model instances.AsyncSolr.get()andAsyncSolr.stream()already supportedmodel=since earlier versions; this completes async Pydantic coverage.
2.0.5 (2026-03-27)
New features:
Async Streaming Expressions:
async for doc in await conn.stream(expr):executes streaming expressions asynchronously viaAsyncSolr.Internal JSON update path: on Solr 4.0+,
add(),add_many(), andatomic_update()now use JSON internally instead of XML. No user-facing parameter change; Solr < 4.0 falls back to XML automatically.solr_json_default()encoder forjson.dumps— handlesdatetime,date,set,tuple.
Bug fixes:
serialize_value()helper extracted tosolr/utils.py. Fixes missingdatetime/date/boolconversion inatomic_update(),AsyncSolr.add(), andAsyncSolr.add_many().
2.0.4 (2026-03-27)
New features:
Unified sync/async API: all companion classes (
SchemaAPI,KNN,MoreLikeThis,Suggest,Extract) now accept bothSolr(sync) andAsyncSolr(async) connections.With a sync connection, methods return values directly. With an async connection, methods return coroutines (to be
await-ed).``DualTransport`` in
solr/transport.py: auto-detects sync vs async and delegates toSolrTransportorAsyncTransportaccordingly.``_chain()`` helper composes a transform onto either a sync value or an async coroutine, eliminating code duplication in companion classes.
AsyncSchemaAPI,AsyncKNN,AsyncMoreLikeThis,AsyncSuggest, andAsyncExtractare kept as backward-compatible aliases.
Example:
from solr import Solr, AsyncSolr, SchemaAPI
# Sync — returns list directly
conn = Solr('http://localhost:8983/solr/mycore')
schema = SchemaAPI(conn)
fields = schema.fields()
# Async — returns coroutine
async with AsyncSolr('http://localhost:8983/solr/mycore') as conn:
schema = SchemaAPI(conn)
fields = await schema.fields()
2.0.3 (2026-03-27)
New features:
Async companion classes in
solr/async_companions.py: -AsyncSchemaAPI(conn)— async schema operations -AsyncKNN(conn)— async KNN/vector search -AsyncMoreLikeThis(conn)— async MLT queries -AsyncSuggest(conn)— async suggestions -AsyncExtract(conn)— async document extractionAll exported from top-level
solrpackage.
2.0.2 (2026-03-27)
New features:
``AsyncSolr`` class in
solr/async_solr.py: full async client built onhttpx.AsyncClient. Same API asSolrbut withasync/await.async with AsyncSolr(url) as conn:context manager.Async methods:
await conn.select(),await conn.add(),await conn.delete(),await conn.commit(),await conn.get().``AsyncTransport`` in
solr/transport.py: async version ofSolrTransportfor companion classes.
2.0.1 (2026-03-27)
Breaking: httpx migration
Replaced
http.clientwithhttpx.Clientas the HTTP transport.httpxis now a required dependency.Automatic connection pooling and keep-alive via httpx.
Gzip decompression handled automatically by httpx.
Retry exceptions changed:
socket.error/BadStatusLine→httpx.ConnectError/httpx.ReadError.Solr.connis now anhttpx.Clientinstance (washttp.client.HTTPConnection).All public API unchanged — drop-in replacement for 1.x users.
1.12.0 (2026-03-27)
New features (Solr 5.0+):
Streaming Expressions: Pythonic builder for Solr streaming expressions. No other non-Java client supports this.
Python functions map 1:1 to Solr expression functions:
search,merge,rollup,top,unique,innerJoin,leftOuterJoin, etc.Aggregate functions:
count,sum,avg,min,max.Pipe (``|``) operator for chaining expressions.
Solr.stream(expr)executes via/streamhandler, returns iterator.model=parameter for Pydantic conversion on stream results.Tested against live SolrCloud 9.7.
1.11.0 (2026-03-27)
New features:
Pydantic response models (opt-in,
pip install solrpy[pydantic]):model=parameter onselect()andget()— automatically converts result documents to PydanticBaseModelinstances.Response.as_models(model)method for post-hoc conversion.Pydantic v2 support (
model_validate()).Works in both JSON and XML response modes.
pydanticadded as optional dependency.
1.10.1 (2026-03-27)
New features:
``Field`` builder (
solr/field.py): Structured field list expressions for theflparameter. Supports aliases (Field('price', alias='p')), functions (Field.func('sum', 'price', 'tax')), document transformers (Field.transformer('explain')), and score (Field.score()).``Sort`` builder (
solr/sort.py): Structured sort clauses.Sort('price', 'desc'),Sort.func('geodist()', 'asc').``Facet`` builder (
solr/facet.py): Structured traditional facets.Facet.field('category', mincount=1),Facet.range('price', 0, 100, 10),Facet.query('cheap', 'price:[0 TO 50]'),Facet.pivot('cat', 'author').``facets=`` parameter on
SearchHandler.__call__: accepts list ofFacetobjects, auto-merges params.All builders coexist with raw string parameters — fully backward compatible.
Field,Sort,Facetexported from top-levelsolrpackage.
1.10.0 (2026-03-27)
New features (Solr 4.0+):
SolrCloud support with two modes:
ZooKeeper mode:
SolrZooKeeperclass insolr/zookeeper.pyconnects to ZooKeeper for real-time node discovery, leader identification, and collection alias resolution. Requireskazoo(pip install solrpy[cloud]).HTTP mode:
SolrCloud.from_urls()uses the CLUSTERSTATUS API for node discovery without ZooKeeper. No extra dependencies.
``SolrCloud`` class in
solr/cloud.py:Leader-aware writes: update requests routed to shard leaders.
Automatic failover: on error, retries with a different node (exponential backoff).
Same API as
Solr:select(),add(),delete(),commit(), etc.
``SolrZooKeeper`` class in
solr/zookeeper.py:live_nodes()— active node listcollection_state(name)— shard/replica stateleader_urls(collection)/replica_urls(collection)random_url(collection)/random_leader_url(collection)aliases()— collection alias resolution
Docker Compose configuration for local SolrCloud testing (
docker/docker-compose-cloud.yml).kazooadded as optional dependency (extras = ["cloud"]).
1.9.2 (2026-03-27)
Solr 7~10 compatibility:
XML mode now uses
wt=xmlon Solr 7+ (wt=standardbehavior changed in 7.0, removed in 10.0). Solr < 7 continues to usewt=standard.All 326 tests pass against live Solr 10.0.
efSearchScaleFactorverified on Solr 10.0.{!vectorSimilarity}verified on Solr 10.0.
Test improvements:
KNN live tests self-provision vector data in
setUp(test isolation).test_raw_queryuseswt=jsonfor cross-version portability.test_select_request/test_alternate_requestversion-aware assertions.
1.9.1 (2026-03-27)
KNN API overhaul:
``KNN.search()``: Full
{!knn}parameter support —early_termination,saturation_threshold,patience,seed_query,pre_filter,include_tags,exclude_tags,ef_search_scale_factor.``KNN.similarity()``:
{!vectorSimilarity}threshold-based matching withmin_return,min_traverse, andpre_filter(Solr 9.6+).``KNN.hybrid()``: Lexical OR vector combined search.
``KNN.rerank()``: Re-rank lexical results by vector similarity.
``build_knn_query()``, ``build_similarity_query()``, ``build_hybrid_query()``, ``build_rerank_params()``: Query string builders for custom use cases.
build_query()retained as alias for backward compatibility.Live integration tests against Solr 9.4 with
DenseVectorField.
1.9.0 (2026-03-27)
New features (Solr 9.0+):
KNN / Dense Vector Search: New
KNN(conn)class insolr/knn.py. Builds{!knn f=<field> topK=<k>}[v1,v2,...]queries and executes them via the/selecthandler.KNN.__call__(vector, field, top_k, filters, ...)— execute a KNN search.KNN.build_query(...)— build query string without executing.efSearchScaleFactorsupport for Solr 10.0+ (version-gated).All methods version-gated to Solr 9.0+.
1.8.1 (2026-03-27)
Internal refactoring:
New
SolrTransportclass insolr/transport.py: thin abstraction over Solr’s HTTP communication (get_json,post_json,post_raw).SchemaAPI,Suggest,Extractnow useSolrTransportinstead of callingSolr._get()/Solr._post()directly.Eliminates coupling to internal HTTP methods; reduces migration cost for the httpx switch planned in 2.0.0.
No public API changes.
1.8.0 (2026-03-27)
New features:
Bearer token authentication:
Solr(url, auth_token='...')sendsAuthorization: Bearer <token>header on every request.Custom auth callable:
Solr(url, auth=my_fn)callsmy_fn()on every request to produce auth headers dynamically. Enables OAuth2 token refresh and other dynamic authentication schemes.Auth priority:
authcallable >auth_token>http_user/http_pass.
1.7.0 (2026-03-27)
New features (Solr 3.3+):
Grouping / Field Collapsing:
Response.groupedattribute returns aGroupedResultobject when grouped results are present.GroupedResultsupports subscript access (resp.grouped['field']), iteration,intests, andlen().GroupFieldprovides.matches,.ngroups, and.groupsaccessors.Groupprovides.groupValueand.doclist(aResultslist withnumFoundandstart).Works in both JSON and XML response modes. XML
<result name="doclist">tags are wrapped intoResultswith normalized integer attributes.
1.6.0 (2026-03-27)
New features (Solr 1.4+):
Extract class in
solr/extract.py: indexes rich documents (PDF, Word, HTML, etc.) via Solr Cell (Apache Tika) using the/update/extracthandler.Extract.__call__(file_obj, content_type, commit, **params): POST binary file content to/update/extract. First underscore in each keyword argument is replaced with a dot (literal_id→literal.id); field names that contain underscores are preserved (literal_my_field→literal.my_field).Extract.extract_only(file_obj, content_type, **params): extract text and metadata without indexing. Returns(text, metadata)tuple.Extract.from_path(file_path, **params): open a file by path and index it; MIME type guessed viamimetypes.Extract.extract_from_path(file_path, **params): open a file by path and extract without indexing.Extractexported from top-levelsolrpackage.
1.5.0 (2026-03-27)
New features:
Suggest (Solr 4.7+): New
Suggest(conn)wrapper class insolr/suggest.py. Queries the/suggesthandler and returns a flat list of suggestion dicts ('term','weight','payload'). Supportsdictionaryandcountarguments plus arbitrary extra parameters.SpellcheckResult (Solr 1.4+): New
SpellcheckResultclass exposed as theResponse.spellcheckproperty. Provides.correctly_spelled,.collation, and.suggestionsaccessors over the raw spellcheck response data. Works in both JSON and XML response modes.
1.4.2 (2026-03-27)
Improvements:
New
MoreLikeThis(conn)wrapper class insolr/mlt.py. Users no longer need to know the/mlthandler path.Replaces previous
SearchHandler(conn, '/mlt')pattern.
1.4.1 (2026-03-27)
Breaking changes:
conn.schemaauto-created attribute removed. Create explicitly:schema = SchemaAPI(conn).conn.mltauto-created attribute removed. Create explicitly:mlt = SearchHandler(conn, '/mlt').Solr.__init__no longer initializes optional features. Onlyselectremains as a built-in handler.
1.4.0 (2026-03-27)
New features (Solr 4.2+):
Schema API via
conn.schema: -get_schema()— full schema dump -fields()/add_field()/replace_field()/delete_field()-dynamic_fields()/add_dynamic_field()/delete_dynamic_field()-field_types()/add_field_type()/replace_field_type()/delete_field_type()-copy_fields()/add_copy_field()/delete_copy_field()- Version-gated to Solr 4.2+New
solr/schema.pymodule (separated per CLAUDE.md guidelines)
1.3.0 (2026-03-27)
New features (Solr 5.0+):
JSON Facet API:
json_facetparameter onSearchHandler.__call__. Accepts a dict, automatically serialized tojson.facetquery parameter. Response includesfacetsattribute with results. Version-gated to Solr 5.0+. Works in both JSON and XML response modes.
1.2.0 (2026-03-27)
New features (Solr 4.7+):
Cursor pagination:
Response.cursor_next()for cursor-based deep pagination. ReturnsNonewhen all results are consumed.Cursor iterator:
Solr.iter_cursor(q, sort, rows)generator that yields Response batches, automatically following cursor marks.
1.1.0 (2026-03-27)
New features (Solr 4.0+):
Soft Commit:
conn.commit(soft_commit=True)makes changes visible without flushing to disk. Version-gated to Solr 4.0+.Atomic Update:
conn.atomic_update(doc)andatomic_update_many(docs)for partial document updates. Supportsset,add,remove,removeregex(Solr 5.0+), andincmodifiers.{'set': None}removes a field.Real-time Get:
conn.get(id=...)retrieves documents directly from the transaction log via/gethandler without waiting for a commit.MoreLikeThis:
conn.mltSearchHandler bound to/mltendpoint for finding similar documents.
1.0.9 (2026-03-27)
New features:
Per-request timeout override via
timeoutkeyword argument. Applies toselect(),select.raw(),add(),add_many(),delete(),delete_many(),delete_query(), andcommit(). The connection-level timeout is restored after each request.
1.0.8 (2026-03-27)
New features:
Exponential backoff on connection retries. Base delay configurable via
retry_delayconstructor parameter (default0.1seconds). First retry waitsretry_delay, second waitsretry_delay * 2, etc.Each retry attempt is logged at WARNING level to the
solrlogger.
1.0.7 (2026-03-27)
Breaking changes:
EmptyPageno longer inherits fromSolrException; now subclassesValueError.New
PageNotAnIntegerexception (subclass ofTypeError) replaces the previousSolrException('PageNotAnInteger')pattern.Paginator module no longer depends on
SolrExceptionfor flow control.
1.0.6 (2026-03-27)
New features:
Solrconstructor now validates the URL path. AUserWarningis issued if the path does not contain/solr, preparing for Solr 10.0+ which requires the URL to end with/solr.
1.0.5 (2026-03-27)
Breaking changes:
Removed
SolrConnectionclass. UseSolrinstead.Migration:
SolrConnection.add(**fields)→Solr.add(fields),SolrConnection.query()→Solr.select(),SolrConnection.raw_query()→Solr.select.raw().
1.0.4 (2026-03-27)
Breaking changes:
Default
response_formatchanged from'xml'to'json'. Existing code that relies on XML-specific behavior should passresponse_format='xml'explicitly.
1.0.3 (2026-03-27)
New features:
response_formatconstructor option:Solr(url, response_format='json')switches the query pipeline to usewt=jsonand the JSON parser. Default is'xml'for backward compatibility.SearchHandlerautomatically selectswtand parser based on the connection’sresponse_formatsetting.
Refactoring:
Split
solr/core.py(1287 lines) into five focused modules:exceptions.py,utils.py,response.py,parsers.py,core.py.All existing import paths continue to work via re-exports in
__init__.py.
1.0.2 (2026-03-27)
Type safety:
mypy --strictnow passes with zero errors on the entiresolr/package.Added type annotations to all internal classes:
ResponseContentHandler,Node,Results,UTC.Added type annotations to all
@committing-decorated methods (add,add_many,delete,delete_many,delete_query).Fixed
endElementvariable shadowing (name→tag) for type safety.Removed unnecessary
type: ignorecomments.
1.0.1 (2026-03-27)
New features:
Added type annotations to all public methods across
solr/core.pyandsolr/paginator.py.Added
solr/py.typedmarker file for PEP 561 type checker discovery.Added
mypyto dev dependencies;mypy solr/passes with zero errors.
Internal:
Replaced mutable default
post_headers={}withNoneto avoid shared mutable state.Fixed
paginator.pytry/exceptimport with direct relative import.
0.9.11 (2026-03-26)
New features:
parse_json_response()function for parsing JSON responses from Solr. Supports all standard response fields: results, header, highlighting, facet_counts, maxScore, and arbitrary top-level keys.Solr.ping()convenience method. ReturnsTrueif the Solr server is reachable,Falseotherwise.always_commitconstructor option. WhenTrue, all add/delete operations automatically commit. Individual calls can override withcommit=False.Gzip response support.
Accept-Encoding: gzipheader is now sent on all requests. Compressed responses are decompressed transparently via the newread_response()helper.
0.9.10 (2026-03-26)
Documentation:
Added Sphinx-based documentation: quick start guide, full API reference, version detection guide, and changelog.
Rewrote
README.mdwith current API examples, Docker-based test instructions, and changelog section.Updated
CLAUDE.mddevelopment guidelines.
Packaging:
Added
pyproject.tomlmetadata: authors, maintainers, classifiers, keywords, homepage, repository URL.Added Sphinx and sphinx-rtd-theme as docs dependencies.
Added pytest and mypy configuration sections.
Excluded
tests/anddocs/from distribution packages.
0.9.9 (2026-03-26)
Breaking changes:
Python 3.10+ is now required. All Python 2 compatibility code has been removed.
The deprecated
encoderanddecoderattributes onSolrinstances have been removed.Migrated from setuptools (
setup.py) to Poetry (pyproject.toml).
New features:
Automatic Solr version detection via
server_versionattribute.SolrVersionErrorexception raised when a feature requires a higher Solr version than connected.requires_versiondecorator for runtime version gating.
Bug fixes:
commit(_optimize=True)now correctly issues an<optimize/>command. Previously it always issued<commit/>regardless of the flag.
Tests:
Added dedicated tests for
<double>XML type parsing.Added tests for named
<result>tag handling in XML responses.Added tests for version detection,
SolrVersionError, andrequires_versiondecorator.Fixed all tests for Python 3.12 compatibility:
assertEqualsreplaced withassertEqual,assert_replaced withassertTrue.Fixed legacy pickle tests to use bytes literals.
Internal:
Removed
codecsandsysimports (no longer needed).Removed
_python_versionand all associated conditional branches.Replaced
unicodewithstr,basestringwithstr,longwithintthroughout the codebase.Simplified
isinstance(data, bytes)checks to direct.decode('utf-8').
0.9.8
Bump version to 0.9.8.
Fix Python 2/3 compatibility issues and multiple bugs.
0.9.7
Fixed basic authentication to work properly in Python 3.
Prior versions
See the GitHub commit history for details on earlier releases.