Skip to content

Commit a614ae3

Browse files
authored
Merge pull request #10 from zzstoatzz/sync
sync first and update docs
2 parents bd4513b + a7fd007 commit a614ae3

File tree

21 files changed

+709
-351
lines changed

21 files changed

+709
-351
lines changed

.github/workflows/publish-docs.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
push:
55
tags:
66
- v*
7+
branches:
8+
- main
9+
paths:
10+
- "docs/**"
711
workflow_dispatch:
812

913
permissions:
@@ -31,4 +35,4 @@ jobs:
3135
cairosvg
3236

3337
- name: Publish docs
34-
run: mkdocs gh-deploy --force
38+
run: mkdocs gh-deploy --force

README.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ pip install raggy
66

77
Read the [docs](https://zzstoatzz.github.io/raggy/)
88

9-
### examples
9+
### What is it?
10+
11+
A Python library for:
1012

1113
- scraping the web to produce rich documents
1214
- putting these documents in vectorstores
1315
- querying the vectorstores to find documents similar to a query
1416

15-
see this [example](https://github.com/zzstoatzz/raggy/blob/main/examples/refresh_vectorstore/refresh_tpuf.py) I use to refresh a chatbot that knows about `prefect`.
17+
See this [example](https://github.com/zzstoatzz/raggy/blob/main/examples/chat_with_X/website.py) to chat with any website, or this [example](https://github.com/zzstoatzz/raggy/blob/main/examples/chat_with_X/repo.py) to chat with any GitHub repo.
18+
19+
### Contributing
20+
21+
We welcome contributions! See our [contributing guide](https://zzstoatzz.github.io/raggy/contributing) for details.

docs/contributing.md

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Contributing to Raggy
2+
3+
We love your input! We want to make contributing to Raggy as easy and transparent as possible.
4+
5+
## Development Setup
6+
7+
We recommend using [uv](https://github.com/astral-sh/uv) for Python environment management and package installation:
8+
9+
```bash
10+
# Install uv
11+
curl -LsSf https://astral.sh/uv/install.sh | sh
12+
13+
# Clone the repo
14+
git clone https://github.com/zzstoatzz/raggy.git
15+
cd raggy
16+
17+
# Create and activate a virtual environment
18+
uv venv
19+
20+
# Install in editable mode with dev dependencies
21+
uv pip install -e ".[dev]"
22+
```
23+
24+
## Running Tests
25+
26+
```bash
27+
# Install test dependencies
28+
uv pip install -e ".[test]"
29+
30+
# Run tests
31+
pytest
32+
```
33+
34+
## Building Documentation
35+
36+
```bash
37+
# Install docs dependencies
38+
uv pip install -e ".[docs]"
39+
40+
# Serve docs locally
41+
mkdocs serve
42+
```
43+
44+
## Code Style
45+
46+
```
47+
pre-commit install
48+
pre-commit run --all-files # happens automatically on commit
49+
```
50+
51+
## Running Examples
52+
53+
All examples can be run using uv:
54+
55+
!!! question "where are the dependencies?"
56+
`uv` will run the example in an isolated environment using [inline script dependencies](https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies).
57+
58+
```bash
59+
# Run example
60+
uv run examples/chat_with_X/website.py
61+
```
62+
63+
See our [example gallery](examples/index.md) for more details.
64+
65+
## Versioning
66+
67+
We use [Semantic Versioning](http://semver.org/). For the versions available, see the [tags on this repository](https://github.com/zzstoatzz/raggy/tags).

docs/examples/index.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Example Gallery
2+
3+
Here are some practical examples of using `raggy` in real-world scenarios.
4+
5+
## Chat with Content
6+
7+
Ye old "chat your data" examples.
8+
9+
#### Chat with a Website
10+
11+
```bash
12+
uv run examples/chat_with_X/website.py "let's chat about docs.astral.sh/uv"
13+
```
14+
15+
#### Chat with a GitHub Repo
16+
17+
```bash
18+
uv run examples/chat_with_X/repo.py "let's chat about astral-sh/uv"
19+
```
20+
21+
## Refresh Vectorstores
22+
23+
A `prefect` flow to gather documents from sources of knowledge, embed them and put them in a vectorstore.
24+
25+
#### Refresh TurboPuffer
26+
27+
```bash
28+
uv run examples/refresh_vectorstore/tpuf_namespace.py
29+
```
30+
31+
#### Refresh Chroma
32+
33+
```bash
34+
uv run examples/refresh_vectorstore/chroma_collection.py
35+
```

docs/hooks.py

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,8 @@
11
import logging
2-
import subprocess
32

43
log = logging.getLogger("mkdocs")
54

65

76
def on_pre_build(config, **kwargs):
8-
"""Add a custom route to the server."""
9-
try:
10-
subprocess.run(
11-
[
12-
"npx",
13-
"tailwindcss",
14-
"-i",
15-
"./docs/overrides/tailwind.css",
16-
"-o",
17-
"./docs/static/css/tailwind.css",
18-
]
19-
)
20-
except Exception:
21-
log.error("You need to install tailwindcss using npx install tailwindcss")
7+
"""Add any pre-build hooks here."""
8+
pass

docs/ingest_strategy.md

+86-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,86 @@
1-
# Coming soon!
1+
# Ingest Strategy
2+
3+
When building RAG applications, you often need to load and refresh content from multiple sources. This can involve:
4+
- Expensive API calls
5+
- Large document processing
6+
- Concurrent embedding operations
7+
8+
We use [Prefect](https://docs.prefect.io) to handle these challenges, giving us:
9+
10+
- Automatic caching of expensive operations
11+
- Concurrent processing with backpressure
12+
- Observability and retries
13+
14+
Let's look at a real example that demonstrates these concepts.
15+
16+
## Building a Knowledge Base
17+
18+
```python
19+
from datetime import timedelta
20+
import httpx
21+
from prefect import flow, task
22+
from prefect.tasks import task_input_hash
23+
24+
from raggy.loaders.github import GitHubRepoLoader
25+
from raggy.loaders.web import SitemapLoader
26+
from raggy.vectorstores.tpuf import TurboPuffer
27+
28+
# Cache based on content changes
29+
def get_last_modified(context, parameters):
30+
"""Only reload if the content has changed."""
31+
try:
32+
return httpx.head(parameters["urls"][0]).headers.get("Last-Modified", "")
33+
except Exception:
34+
return None
35+
36+
@task(
37+
cache_key_fn=get_last_modified,
38+
cache_expiration=timedelta(hours=24),
39+
retries=2,
40+
)
41+
async def gather_documents(urls: list[str]):
42+
return await SitemapLoader(urls=urls).load()
43+
44+
@flow
45+
async def refresh_knowledge():
46+
# Load from multiple sources
47+
documents = []
48+
for loader in [
49+
SitemapLoader(urls=["https://docs.prefect.io/sitemap.xml"]),
50+
GitHubRepoLoader(repo="PrefectHQ/prefect", include_globs=["README.md"]),
51+
]:
52+
documents.extend(await gather_documents(loader))
53+
54+
# Store efficiently with concurrent embedding
55+
with TurboPuffer(namespace="knowledge") as tpuf:
56+
await tpuf.upsert_batched(
57+
documents,
58+
batch_size=100, # tune based on document size
59+
max_concurrent=8 # tune based on rate limits
60+
)
61+
```
62+
63+
This example shows key patterns:
64+
65+
1. Content-aware caching (`Last-Modified` headers, commit SHAs, etc)
66+
2. Automatic retries for resilience
67+
3. Concurrent processing with backpressure
68+
4. Efficient batching of embedding operations
69+
70+
See the [refresh examples](https://github.com/zzstoatzz/raggy/tree/main/examples/refresh_vectorstore) for complete implementations using both Chroma and TurboPuffer.
71+
72+
## Performance Tips
73+
74+
For production workloads:
75+
```python
76+
@task(
77+
retries=2,
78+
retry_delay_seconds=[3, 60], # exponential backoff
79+
cache_expiration=timedelta(days=1),
80+
persist_result=True, # save results to storage
81+
)
82+
async def gather_documents(loader):
83+
return await loader.load()
84+
```
85+
86+
See [Prefect's documentation](https://docs.prefect.io/latest/concepts/tasks/) for more on task configuration and caching strategies.

docs/overrides/main.html

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% extends "base.html" %}
2+
3+
{% block announce %}
4+
<style>
5+
.md-announce {
6+
font-family: 'Roboto Mono', monospace;
7+
background-color: var(--md-primary-fg-color);
8+
}
9+
.md-announce__inner {
10+
margin: 0 auto;
11+
padding: 0.2rem;
12+
text-align: center;
13+
font-weight: 300;
14+
letter-spacing: 0.05em;
15+
}
16+
</style>
17+
<a href="{{ config.extra.announcement.link }}" style="color: currentColor">
18+
{{ config.extra.announcement.text }}
19+
</a>
20+
{% endblock %}

docs/welcome/tutorial.md

+32-9
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,44 @@ print(documents[0])
1616

1717
## Adding documents to a vectorstore
1818

19-
```python
20-
from raggy.vectorstores.tpuf import Turbopuffer
19+
!!! note "New in 0.2.0"
20+
Vectorstore operations are now synchronous by default, with async batching available via `upsert_batched`.
2121

22-
async with Turbopuffer() as vectorstore: # uses default `raggy` namespace
23-
await vectorstore.upsert(documents)
22+
```python
23+
from raggy.vectorstores.tpuf import TurboPuffer
24+
25+
with TurboPuffer(namespace="my_documents") as vectorstore:
26+
# Synchronous operation
27+
vectorstore.upsert(documents)
28+
29+
# Async batched usage for large document sets
30+
await vectorstore.upsert_batched(
31+
documents,
32+
batch_size=100,
33+
max_concurrent=8
34+
)
2435
```
2536

2637
## Querying the vectorstore
2738

2839
```python
29-
from raggy.vectorstores.tpuf import query_namespace
30-
31-
print(await query_namespace("how do I get started with raggy?"))
40+
from raggy.vectorstores.tpuf import query_namespace, multi_query_tpuf
41+
42+
# Single query
43+
result = query_namespace("how do I get started with raggy?")
44+
print(result)
45+
46+
# Multiple related queries for better coverage
47+
result = multi_query_tpuf([
48+
"how to install raggy",
49+
"basic raggy usage",
50+
"raggy getting started"
51+
])
52+
print(result)
3253
```
3354

34-
## Real-world example
55+
## Real-world examples
3556

36-
See [this example](https://github.com/zzstoatzz/raggy/blob/main/examples/refresh_vectorstore/refresh_tpuf.py) I use to refresh a chatbot that knows about `prefect`.
57+
- [Chat with a GitHub repo](https://github.com/zzstoatzz/raggy/blob/main/examples/chat_with_X/repo.py)
58+
- [Chat with a website](https://github.com/zzstoatzz/raggy/blob/main/examples/chat_with_X/website.py)
59+
- [Refresh a vectorstore](https://github.com/zzstoatzz/raggy/blob/main/examples/refresh_vectorstore/tpuf_namespace.py)

0 commit comments

Comments
 (0)