Metadata-Version: 2.5
Name: anygrep
Version: 0.1.0
Summary: Search your notes, PDFs and screenshots by meaning on the CPU, with one local multimodal model (EmbeddingGemma 2). No API key, no GPU.
Project-URL: Homepage, https://github.com/kuroko1t/anygrep
Project-URL: Source, https://github.com/kuroko1t/anygrep
Project-URL: Issues, https://github.com/kuroko1t/anygrep/issues
Project-URL: Changelog, https://github.com/kuroko1t/anygrep/blob/main/CHANGELOG.md
Project-URL: Documentation, https://github.com/kuroko1t/anygrep#readme
Author: kuroko1t
License-Expression: MIT
License-File: LICENSE
Keywords: cli,embeddinggemma,embeddings,grep,images,local-first,multimodal,notes,offline,onnx,pdf,search,semantic-search
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Indexing
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Requires-Dist: certifi>=2023.7.22
Requires-Dist: numpy>=1.24
Requires-Dist: onnxruntime>=1.23
Requires-Dist: pathspec>=0.12
Requires-Dist: pillow>=10.1
Requires-Dist: platformdirs>=3.0
Requires-Dist: pypdfium2>=4.20
Requires-Dist: tokenizers>=0.20
Requires-Dist: tqdm>=4.60
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# anygrep

[![PyPI](https://img.shields.io/pypi/v/anygrep)](https://pypi.org/project/anygrep/)
[![Python](https://img.shields.io/pypi/pyversions/anygrep)](https://pypi.org/project/anygrep/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/kuroko1t/anygrep/blob/main/LICENSE)

anygrep searches your notes, PDFs and screenshots by meaning, from the terminal. It runs one model
([EmbeddingGemma 2](https://huggingface.co/google/embeddinggemma-2), int8 ONNX) on the CPU and keeps one
local index.

![anygrep demo](https://raw.githubusercontent.com/kuroko1t/anygrep/main/demo/anygrep.gif)

The demo searches a folder that was already indexed, and the wait for the model to load is sped up.

## Install

```sh
pipx install anygrep        # or: uv tool install anygrep
uvx anygrep "when is the tax return due" ~/notes   # or try it without installing
```

Requires Python 3.10+. Tested on Linux; CI also runs the tests on Windows and macOS (Apple silicon).
The model is downloaded on first use: about 350 MB, and 200 MB more once you index images. See
[docs/usage.md](https://github.com/kuroko1t/anygrep/blob/main/docs/usage.md#installing) for Intel Macs, Windows on ARM and uninstalling.

## Usage

```sh
anygrep "wifi password reset"                 # search here (new files are indexed first)
anygrep "when is the tax return due" ~/notes  # search one folder
anygrep --image whiteboard.jpg ~/Screenshots  # find similar pictures
anygrep -l "invoice from acme"                # file names only; piped output is path:line:text
anygrep -Q ~/notes                            # interactive: the model stays loaded
anygrep index --background ~/Pictures         # big folder: index in a low-priority process
```

Results are up to 10 files, closest in meaning first (`-m N` for more), not every match; queries are not
regular expressions. A file whose text or name contains a query of 3 or more characters as typed (an
invoice number, an error code) comes first, marked `(exact)`; words found in many files are not boosted
this way ([details](https://github.com/kuroko1t/anygrep/blob/main/docs/usage.md#exact-matches)). Queries and documents can be in different languages.
Weak matches are hidden (`--weak` shows them) and near-duplicate files are shown once. See `anygrep -h`
and [docs/usage.md](https://github.com/kuroko1t/anygrep/blob/main/docs/usage.md).

On a terminal, the first search in a big folder indexes the new files first, with a progress bar; Ctrl-C
keeps what is done and the next run continues. `index --background` does it while you work (your home
folder is never indexed automatically, so name a folder inside it). In a script or cron job, a search
indexes new files only if that takes under about 30 seconds; run `anygrep index` beforehand for a big
folder ([details](https://github.com/kuroko1t/anygrep/blob/main/docs/usage.md#indexing-before-a-search)).

It reads text files (`.md .txt .html` and more), the text layer of PDFs, and `.jpg .png .webp .bmp
.gif` images. Hidden, ignored and binary files are skipped.

## Use from Python

```python
import anygrep

with anygrep.Index() as idx:  # the index the command uses
    idx.update("~/notes")  # index new and changed files
    for hit in idx.search("when is the tax return due", k=5):
        print(hit.score, hit.path, hit.snippet)
```

Install it with pip in your project's environment. It uses the same index, scores and filtering as the
command and prints nothing. The API may change before 1.0; see [docs/python-api.md](https://github.com/kuroko1t/anygrep/blob/main/docs/python-api.md).

## Performance

On a Ryzen 7 7700 with the default 8 threads, text indexes at about 1,100 tokens/s and an image takes
about 1.2 s. A search command takes about 1.5 s, mostly loading the model. More in
[docs/benchmarks.md](https://github.com/kuroko1t/anygrep/blob/main/docs/benchmarks.md).

See also [how it works](https://github.com/kuroko1t/anygrep/blob/main/docs/how-it-works.md), [relevance](https://github.com/kuroko1t/anygrep/blob/main/docs/relevance.md) and
[comparison with other tools](https://github.com/kuroko1t/anygrep/blob/main/docs/comparison.md).

## Limitations

- No OCR: small text inside images is often missed, and scanned PDFs are skipped.
- No audio, video or Office documents yet (anygrep says how many Office files it skipped), and no
  file watching (run `anygrep index` from cron).

## License

MIT. The model is downloaded separately:
[an int8 ONNX conversion](https://huggingface.co/onnx-community/embeddinggemma-2-ONNX) of Google's
EmbeddingGemma 2, released under the Apache License 2.0 (its model card also points to the Gemma
Prohibited Use Policy). anygrep is not affiliated with Google.
