Scout-style full-text search for Arvel — Meilisearch, Elasticsearch, database, collection, and null drivers.
Project description
arvel-search
Scout-style full-text search for Arvel.
Add the Searchable mixin to a model, declare __searchable__, and records sync to your search
backend automatically on create / update / delete. Query with a fluent Model.search("term")
builder. Swap backends — Meilisearch, Elasticsearch, database (ILIKE), in-memory collection, or
null — entirely through config.
Status: Pre-alpha.
Documentation: https://arvel.dev/packages/search
Install
uv add "arvel[search]"
# or: pip install arvel-search
Register the provider in bootstrap/providers.py:
from arvel_search import SearchServiceProvider
providers = [
# ...other providers...
SearchServiceProvider,
]
The provider registers SearchConfig and SearchManager, binds the Search facade, and registers
the SearchIndexJob / SearchRemoveJob queue jobs. There are no migrations.
Quick start
from arvel.database import Model, id_, string
from arvel_search import Searchable
class Article(Model, Searchable):
__tablename__ = "articles"
__searchable__ = ("title", "body")
id: int = id_()
title: str = string(200)
body: str = string(2000)
# Saving auto-indexes; deleting auto-removes (when an engine is bound).
article = await Article.create(title="Python tips", body="...")
# Fluent search, hydrated back into models.
results = await Article.search("python").limit(10).get() # list[Article]
ids = await Article.search("python").keys()
total = await Article.search("python").count()
page = await Article.search("python").paginate(per_page=15, page=1)
The builder supports where(column, value), limit, offset, plus the terminal methods
get, first, keys, count, and paginate.
Optional class attributes: __search_index__ (index name; defaults from the table) and
__search_key__ (document key; defaults to id). Override to_searchable_array() to control the
indexed document.
Drivers
SEARCH_DRIVER picks the backend (default database):
| Driver | Behavior |
|---|---|
database |
ILIKE against the model's own table. Writes are no-ops — no separate index. |
collection |
In-memory substring match. Dev/test only. |
null |
Swallows writes; search returns nothing. |
meilisearch |
Talks to a Meilisearch server over HTTP. Set SEARCH_MEILISEARCH_URL / _KEY. |
elasticsearch |
Talks to Elasticsearch over HTTP. Set SEARCH_ELASTICSEARCH_URL / _KEY. |
The Meilisearch and Elasticsearch drivers send documents and queries only — they don't create indices or mappings. Make sure the index exists on the server first.
Testing
from arvel_search import Search
fake = Search.fake()
article = await Article.create(title="Hello", body="...")
fake.assert_indexed(article)
Search.restore()
See the full guide for custom engines and queued sync.
License
MIT — see 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 arvel_search-0.6.0.tar.gz.
File metadata
- Download URL: arvel_search-0.6.0.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
505e52ff1c686cd86c1b62fa3bdfc2d3334086c65fe361c058f97c9e24433a02
|
|
| MD5 |
3a47f959debb264e52d49117f9e2d8e3
|
|
| BLAKE2b-256 |
fea9af11078d58f7b5cf38edae9e011e080688bb33c0a7543d3193bd2b76a89e
|
Provenance
The following attestation bundles were made for arvel_search-0.6.0.tar.gz:
Publisher:
publish.yml on mohamed-rekiba/arvel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arvel_search-0.6.0.tar.gz -
Subject digest:
505e52ff1c686cd86c1b62fa3bdfc2d3334086c65fe361c058f97c9e24433a02 - Sigstore transparency entry: 1695790683
- Sigstore integration time:
-
Permalink:
mohamed-rekiba/arvel@98e7960df7d80bdd7229a77b0f58c2b6031d50e1 -
Branch / Tag:
refs/tags/arvel-search-v0.6.0 - Owner: https://github.com/mohamed-rekiba
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@98e7960df7d80bdd7229a77b0f58c2b6031d50e1 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file arvel_search-0.6.0-py3-none-any.whl.
File metadata
- Download URL: arvel_search-0.6.0-py3-none-any.whl
- Upload date:
- Size: 21.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15baa4ba9df3734d12e14073d0cc2e92563d86d53b2b1f68e0264442920881fa
|
|
| MD5 |
1f70587814b21c26650fc0907db147b8
|
|
| BLAKE2b-256 |
49dcb38e46572c79fe303ff4648aae913e4e37dc87127f776ac90b2937560406
|
Provenance
The following attestation bundles were made for arvel_search-0.6.0-py3-none-any.whl:
Publisher:
publish.yml on mohamed-rekiba/arvel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arvel_search-0.6.0-py3-none-any.whl -
Subject digest:
15baa4ba9df3734d12e14073d0cc2e92563d86d53b2b1f68e0264442920881fa - Sigstore transparency entry: 1695790965
- Sigstore integration time:
-
Permalink:
mohamed-rekiba/arvel@98e7960df7d80bdd7229a77b0f58c2b6031d50e1 -
Branch / Tag:
refs/tags/arvel-search-v0.6.0 - Owner: https://github.com/mohamed-rekiba
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@98e7960df7d80bdd7229a77b0f58c2b6031d50e1 -
Trigger Event:
workflow_dispatch
-
Statement type: