Skip to content

Commit 6c00d1d

Browse files
authored
fix algolia upload (#820)
1 parent b783a02 commit 6c00d1d

File tree

4 files changed

+69
-24
lines changed

4 files changed

+69
-24
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ jobs:
7171
if: github.event.pull_request.head.repo.full_name == github.repository || github.ref == 'refs/heads/main'
7272
env:
7373
PPPR_TOKEN: ${{ secrets.PPPR_TOKEN }}
74-
ALGOLIA_WRITE_API_KEY: ${{ secrets.ALGOLIA_WRITE_API_KEY }}
7574

76-
- run: tree site
75+
- run: tree -sh site
7776
- uses: actions/setup-node@v4
7877
- run: npm install
7978
working-directory: docs-site
@@ -243,6 +242,10 @@ jobs:
243242
- run: npm install
244243
working-directory: docs-site
245244

245+
- uses: astral-sh/setup-uv@v5
246+
with:
247+
enable-cache: true
248+
246249
- uses: actions/download-artifact@v4
247250
with:
248251
name: site
@@ -257,6 +260,11 @@ jobs:
257260
--var GIT_COMMIT_SHA:${{ github.sha }}
258261
--var GIT_BRANCH:main
259262
263+
- run: uv sync --group docs-upload
264+
- run: uv run python docs/.hooks/algolia.py upload
265+
env:
266+
ALGOLIA_WRITE_API_KEY: ${{ secrets.ALGOLIA_WRITE_API_KEY }}
267+
260268
release:
261269
needs: [check]
262270
if: "success() && startsWith(github.ref, 'refs/tags/')"

docs/.hooks/algolia.py

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
from __future__ import annotations as _annotations
33

44
import os
5-
from typing import TypedDict, cast
5+
import sys
6+
from pathlib import Path
7+
from typing import TYPE_CHECKING, TypedDict, cast
68

7-
from algoliasearch.search.client import SearchClientSync
8-
from bs4 import BeautifulSoup
9-
from mkdocs.config import Config
10-
from mkdocs.structure.files import Files
11-
from mkdocs.structure.pages import Page
9+
from pydantic import TypeAdapter
10+
11+
if TYPE_CHECKING:
12+
from mkdocs.config import Config
13+
from mkdocs.structure.files import Files
14+
from mkdocs.structure.pages import Page
1215

1316

1417
class AlgoliaRecord(TypedDict):
@@ -20,19 +23,18 @@ class AlgoliaRecord(TypedDict):
2023

2124

2225
records: list[AlgoliaRecord] = []
26+
records_ta = TypeAdapter(list[AlgoliaRecord])
2327
# these values should match docs/javascripts/search-worker.js.
2428
ALGOLIA_APP_ID = 'KPPUDTIAVX'
2529
ALGOLIA_INDEX_NAME = 'pydantic-ai-docs'
26-
ALGOLIA_WRITE_API_KEY = os.environ.get('ALGOLIA_WRITE_API_KEY')
2730

2831
# Algolia has a limit of 100kb per record in the paid plan,
2932
# leave some space for the other fields as well.
3033
MAX_CONTENT_LENGTH = 90_000
3134

3235

3336
def on_page_content(html: str, page: Page, config: Config, files: Files) -> str:
34-
if not ALGOLIA_WRITE_API_KEY:
35-
return html
37+
from bs4 import BeautifulSoup
3638

3739
assert page.title is not None, 'Page title must not be None'
3840
title = cast(str, page.title)
@@ -93,26 +95,52 @@ def on_page_content(html: str, page: Page, config: Config, files: Files) -> str:
9395
return html
9496

9597

98+
ALGOLIA_RECORDS_FILE = 'algolia_records.json'
99+
100+
96101
def on_post_build(config: Config) -> None:
97-
if not ALGOLIA_WRITE_API_KEY:
98-
return
102+
if records:
103+
algolia_records_path = Path(config['site_dir']) / ALGOLIA_RECORDS_FILE
104+
with algolia_records_path.open('wb') as f:
105+
f.write(records_ta.dump_json(records))
106+
107+
108+
def algolia_upload() -> None:
109+
from algoliasearch.search.client import SearchClientSync
99110

100-
client = SearchClientSync(ALGOLIA_APP_ID, ALGOLIA_WRITE_API_KEY)
111+
algolia_write_api_key = os.environ['ALGOLIA_WRITE_API_KEY']
101112

102-
for record in records:
103-
if len(record['content']) > MAX_CONTENT_LENGTH:
113+
client = SearchClientSync(ALGOLIA_APP_ID, algolia_write_api_key)
114+
filtered_records: list[AlgoliaRecord] = []
115+
116+
algolia_records_path = Path.cwd() / 'site' / ALGOLIA_RECORDS_FILE
117+
118+
with algolia_records_path.open('rb') as f:
119+
all_records = records_ta.validate_json(f.read())
120+
121+
for record in all_records:
122+
content = record['content']
123+
if len(content) > MAX_CONTENT_LENGTH:
104124
print(
105-
f"Record with title '{record['title']}' has more than {MAX_CONTENT_LENGTH} characters, {len(record['content'])}."
125+
f"Record with title '{record['title']}' has more than {MAX_CONTENT_LENGTH} characters, {len(content)}."
106126
)
107-
print(record['content'])
127+
print(content)
128+
else:
129+
filtered_records.append(record)
108130

109-
# Filter the records from the index if the content is bigger than 100kb, Algolia limit
110-
filtered_records = list(filter(lambda record: len(record['content']) < MAX_CONTENT_LENGTH, records))
111-
print(f'Uploading {len(filtered_records)} out of {len(records)} records to Algolia...')
131+
print(f'Uploading {len(filtered_records)} out of {len(all_records)} records to Algolia...')
112132

113133
client.clear_objects(index_name=ALGOLIA_INDEX_NAME)
114134

115135
client.batch(
116136
index_name=ALGOLIA_INDEX_NAME,
117137
batch_write_params={'requests': [{'action': 'addObject', 'body': record} for record in filtered_records]},
118138
)
139+
140+
141+
if __name__ == '__main__':
142+
if sys.argv[-1] == 'upload':
143+
algolia_upload()
144+
else:
145+
print('Run with "upload" argument to upload records to Algolia.')
146+
exit(1)

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ lint = [
6565
"ruff>=0.6.9",
6666
]
6767
docs = [
68-
"algoliasearch>=4.12.0",
6968
"black>=24.10.0",
7069
"bs4>=0.0.2",
7170
"markdownify>=0.14.1",
@@ -74,6 +73,10 @@ docs = [
7473
"mkdocs-material[imaging]>=9.5.45",
7574
"mkdocstrings-python>=1.12.2",
7675
]
76+
docs-upload = [
77+
"algoliasearch>=4.12.0",
78+
"pydantic>=2.10.1",
79+
]
7780

7881
[tool.hatch.build.targets.wheel]
7982
only-include = ["/README.md"]

uv.lock

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)