Client for the Solr search service
Project description
solrpy
solrpy is a Python client for Solr, an enterprise search server built on top of Lucene. solrpy allows you to add documents to a Solr instance, and then to perform queries and gather search results from Solr using Python.
- Supports Solr 1.2 through 10.x
- Automatic Solr version detection with runtime feature gating
- Python 3.10+ required
Installation
pip install solrpy
Or with Poetry:
poetry add solrpy
Overview
import solr
# create a connection to a solr server
s = solr.Solr('http://localhost:8983/solr/mycore')
# the server version is auto-detected
print(s.server_version) # e.g. (9, 4, 1)
# check if the server is reachable
print(s.ping()) # True
# add a document to the index
doc = {
"id": 1,
"title": "Lucene in Action",
"author": ["Erik Hatcher", "Otis Gospodnetić"],
}
s.add(doc, commit=True)
# do a search
response = s.select('title:lucene')
for hit in response.results:
print(hit['title'])
Response format
Since v1.0.4, solrpy uses JSON (wt=json) by default, matching Solr 7.0+ behavior.
For legacy XML mode:
s = solr.Solr('http://localhost:8983/solr/mycore', response_format='xml')
The Response object API is identical regardless of format.
More powerful queries
Optional parameters for query, faceting, highlighting, and more like this
can be passed in as Python parameters to the query method. Convert the
dot notation (e.g. facet.field) to underscore notation (e.g. facet_field)
so that they can be used as parameter names.
response = s.select('title:lucene', facet='true', facet_field='subject')
If the parameter takes multiple values, pass them in as a list:
response = s.select('title:lucene', facet='true', facet_field=['subject', 'publisher'])
Version detection
solrpy automatically detects the connected Solr version and gates features
accordingly. If a feature requires a newer Solr version than what is
connected, a SolrVersionError is raised with a clear message.
import solr
s = solr.Solr('http://localhost:8983/solr/mycore')
print(s.server_version) # (6, 6, 6)
Tests
Tests require a running Solr instance. Using Docker:
docker run -d --name solr-dev -p 8983:8983 solr:6.6 solr-precreate core0
poetry run pytest tests/
Changelog
1.11.0
- Pydantic response models:
conn.select('*:*', model=MyDoc)converts results to Pydantic models Response.as_models(MyDoc)for post-hoc conversionconn.get(id='1', model=MyDoc)returnsMyDoc | Nonepip install solrpy[pydantic]
1.10.1
- Field builder:
Field('price', alias='p'),Field.func('sum', 'price', 'tax'),Field.transformer('explain') - Sort builder:
Sort('price', 'desc'),Sort.func('geodist()', 'asc') - Facet builder:
Facet.field('category'),Facet.range('price', 0, 100, 10),Facet.query(),Facet.pivot() - Fully backward compatible — raw strings still work
1.10.0
- SolrCloud:
SolrCloud(zk, collection)with ZooKeeper orSolrCloud.from_urls(urls, collection)HTTP-only - Leader-aware writes, automatic failover, collection aliases
SolrZooKeeperclass for ZooKeeper node discoverykazoooptional dependency (pip install solrpy[cloud])- Docker Compose for local SolrCloud testing
1.9.2
- Solr 6~10 full compatibility:
wt=xmlon Solr 7+ (wt=standardchanged in 7.0) - Tested against Solr 6.6, 7.7, 8.11, 9.7, 10.0 — all 0 failures
- GitHub Actions CI matrix for 5 Solr versions
- KNN live tests version-gated (skip on < 9.0, efSearchScaleFactor skip on < 10.0)
- Test isolation: Paginator no longer deletes all documents
1.9.1
- KNN API overhaul:
search(),similarity(),hybrid(),rerank()methods - Full
{!knn}parameters:early_termination,seed_query,pre_filter, etc. {!vectorSimilarity}threshold search (Solr 9.6+)- Hybrid (lexical OR vector) and re-ranking patterns
1.9.0
- KNN / Dense Vector Search:
KNN(conn)for{!knn}queries (Solr 9.0+)
1.8.1
- HTTP transport abstraction:
SolrTransportdecouples companion classes from internal_get/_post - SchemaAPI, Suggest, Extract now use
SolrTransport— prepares for httpx in 2.0.0
1.8.0
- Bearer token auth:
Solr(url, auth_token='...') - Custom auth callable:
Solr(url, auth=my_fn)for OAuth2 dynamic refresh - Priority:
authcallable >auth_token>http_user/http_pass
1.7.0
- Grouping / Field Collapsing:
resp.grouped['field'].groupsfor grouped results (Solr 3.3+) GroupedResult,GroupField,Groupclasses withgroupValue,doclist,matches,ngroups- Works in both JSON and XML modes
1.6.0
- Extract:
Extract(conn)wrapper class for Solr Cell (Apache Tika) via/update/extract(Solr 1.4+). Index rich documents (PDF, Word, HTML, …) with optional literal field values.extract_only()extracts text and metadata without indexing.from_path()/extract_from_path()open files by filesystem path, MIME type guessed automatically.
from solr import Solr, Extract
conn = Solr('http://localhost:8983/solr/mycore')
extract = Extract(conn)
# Index a PDF with metadata
with open('report.pdf', 'rb') as f:
extract(f, content_type='application/pdf',
literal_id='report1', literal_title='Annual Report',
commit=True)
# Extract text only (no indexing)
text, metadata = extract.extract_from_path('report.pdf')
print(text[:200])
# Index from path (MIME type auto-detected)
extract.from_path('document.docx', literal_id='doc1', commit=True)
1.5.0
- Suggest:
Suggest(conn)wrapper class for Solr's SuggestComponent (Solr 4.7+). Returns a flat list of suggestion dicts from the/suggesthandler. - Spellcheck:
Response.spellcheckproperty returns aSpellcheckResultobject with.collationand.suggestionsaccessors. Works in both JSON and XML modes (Solr 1.4+).
from solr import Solr, Suggest
conn = Solr('http://localhost:8983/solr/mycore')
# Suggest
suggest = Suggest(conn)
results = suggest('que', dictionary='mySuggester', count=5)
for s in results:
print(s['term'], s['weight'])
# Spellcheck
resp = conn.select('misspeled query', spellcheck='true', spellcheck_collate='true')
if resp.spellcheck and not resp.spellcheck.correctly_spelled:
print('Did you mean:', resp.spellcheck.collation)
1.4.2
- New
MoreLikeThis(conn)wrapper class — no need to know/mltpath
1.4.1
- Breaking:
conn.schemaandconn.mltremoved from auto-initialization - Use
SchemaAPI(conn)andSearchHandler(conn, '/mlt')explicitly - Keeps
Solrclass lightweight; optional features created on demand
1.4.0
- Schema API:
conn.schema.fields(),add_field(),replace_field(),delete_field(), copy fields, dynamic fields, field types (Solr 4.2+)
1.3.0
- JSON Facet API:
json_facetparameter for advanced faceting (Solr 5.0+)
1.2.0
- Cursor pagination:
resp.cursor_next()andconn.iter_cursor()for deep pagination (Solr 4.7+)
1.1.0
- Soft Commit:
conn.commit(soft_commit=True)(Solr 4.0+) - Atomic Update:
conn.atomic_update(doc)withset/add/remove/incmodifiers (Solr 4.0+) - Real-time Get:
conn.get(id='doc1')via/gethandler (Solr 4.0+) - MoreLikeThis:
conn.mlthandler for similar document search (Solr 4.0+)
1.0.9
- Per-request timeout override:
conn.select('*:*', timeout=5)
1.0.8
- Exponential backoff on connection retries with configurable
retry_delay - Each retry logged at WARNING level
1.0.7
- Breaking:
EmptyPagenow inheritsValueError(wasSolrException) - New
PageNotAnIntegerexception (inheritsTypeError) - Paginator module no longer depends on
SolrException
1.0.6
- URL validation: warns if URL path doesn't contain
/solr(Solr 10.0+ preparation)
1.0.5
- Breaking: Removed
SolrConnectionclass. UseSolrinstead - Migration:
add(**fields)→add(dict),query()→select(),raw_query()→select.raw()
1.0.4
- Breaking: Default
response_formatchanged from'xml'to'json' - Pass
response_format='xml'explicitly for legacy XML behavior
1.0.3
- Added
response_formatconstructor option ('xml'or'json') - Split
solr/core.pyintoexceptions.py,utils.py,response.py,parsers.py - All existing imports continue to work (re-exported via
__init__.py)
1.0.2
mypy --strictpasses with zero errors onsolr/package- Added type hints to all internal classes (
ResponseContentHandler,Node,Results,UTC) - Fixed
endElementvariable shadowing for type safety
1.0.1
- Added type hints to all public methods in
solr/core.pyandsolr/paginator.py - Added
solr/py.typedmarker file for PEP 561 compatibility - Added
mypyto dev dependencies - mypy passes with zero errors on
solr/package
0.9.11
- Added JSON response parser (
parse_json_response) - Added
Solr.ping()convenience method - Added
always_commitconstructor option for auto-commit behavior - Added gzip response support (
Accept-Encoding: gzip)
0.9.10
- Added pyproject.toml metadata (authors, maintainers, classifiers, keywords)
- Added Sphinx documentation (quickstart, API reference, version detection, changelog)
- Rewrote README.md with current API examples and Docker test instructions
- Updated CLAUDE.md development guidelines
0.9.9
- Removed deprecated
encoder/decoderattributes andcodecsimport - Fixed
commit(_optimize=True)to correctly issue<optimize/>command - Added test coverage for
<double>XML type parsing - Added test coverage for named
<result>tag handling - Added Solr version auto-detection (
server_version) - Added
SolrVersionErrorexception andrequires_versiondecorator - Removed all Python 2 compatibility code (Python 3.10+ only)
- Migrated from setuptools to Poetry
- Bumped version to 0.9.9
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file solrpy-1.11.0.tar.gz.
File metadata
- Download URL: solrpy-1.11.0.tar.gz
- Upload date:
- Size: 34.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.12.3 Linux/6.17.0-14-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0b38f79237a1f4a4619f0d4f9fb93d3ef76a6775af7a0c5439724f1f0b0f377
|
|
| MD5 |
c755050f7cbb5a16b4a6482c1ea0a736
|
|
| BLAKE2b-256 |
aa0d5d5fb14c6aaf6906adaca4178f3ab0f750ffef957bfc4a3692455840f846
|
File details
Details for the file solrpy-1.11.0-py3-none-any.whl.
File metadata
- Download URL: solrpy-1.11.0-py3-none-any.whl
- Upload date:
- Size: 39.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.12.3 Linux/6.17.0-14-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
457e68857044677929df24e88195141ad2b64c46a918accbdeaac7b34a8dc4ef
|
|
| MD5 |
955d0ec13e4d54bd2c0c6f744747bd93
|
|
| BLAKE2b-256 |
56ec949a62acce9641bd3e4770d1028e634da2e8e18cb4ac62af427b525b90fd
|