Skip to content

Commit 3b230da

Browse files
authored
Merge pull request #1068 from 07pepa/add-http2-support
enable http2 support
2 parents 4be331a + 6aa0af6 commit 3b230da

File tree

14 files changed

+375
-110
lines changed

14 files changed

+375
-110
lines changed

.github/workflows/testing.yaml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,50 @@ jobs:
7272
- name: Minimize uv cache
7373
run: uv cache prune --ci
7474

75+
parallel-testing-http2:
76+
strategy:
77+
fail-fast: false
78+
matrix:
79+
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13.0-beta.4" ]
80+
runs-on: ubuntu-latest
81+
steps:
82+
- uses: actions/checkout@v4
83+
- name: install Just
84+
uses: taiki-e/install-action@just
85+
- name: Install uv
86+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
87+
- name: Set up Python ${{ matrix.python-version }}
88+
uses: actions/setup-python@v5
89+
with:
90+
python-version: ${{ matrix.python-version }}
91+
- name: Restore uv cache
92+
uses: actions/cache@v4
93+
with:
94+
path: ${{ env.UV_CACHE_DIR }}
95+
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
96+
restore-keys: |
97+
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
98+
uv-${{ runner.os }}
99+
- name: Install Dependencies
100+
run: just install
101+
- name: Test with pytest
102+
run: |
103+
sudo apt-get update && \
104+
sudo apt-get install -y libnss3-tools build-essential gcc && \
105+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && \
106+
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" && \
107+
brew install mkcert && \
108+
mkcert -install && \
109+
mkcert -key-file meilisearch.key -cert-file meilisearch.crt localhost 127.0.0.1 ::1 && \
110+
just test-parallel-ci-http2
111+
- name: Upload coverage
112+
uses: codecov/codecov-action@v4
113+
with:
114+
token: ${{ secrets.CODECOV_TOKEN }}
115+
fail_ci_if_error: true
116+
- name: Minimize uv cache
117+
run: uv cache prune --ci
118+
75119
no-parallel-testing:
76120
strategy:
77121
fail-fast: false
@@ -108,6 +152,51 @@ jobs:
108152
- name: Minimize uv cache
109153
run: uv cache prune --ci
110154

155+
no-parallel-testing-http2:
156+
strategy:
157+
fail-fast: false
158+
matrix:
159+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13.0-beta.4"]
160+
runs-on: ubuntu-latest
161+
steps:
162+
- uses: actions/checkout@v4
163+
- name: install Just
164+
uses: taiki-e/install-action@just
165+
- name: Install uv
166+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
167+
- name: Set up Python ${{ matrix.python-version }}
168+
uses: actions/setup-python@v5
169+
with:
170+
python-version: ${{ matrix.python-version }}
171+
- name: Restore uv cache
172+
uses: actions/cache@v4
173+
with:
174+
path: ${{ env.UV_CACHE_DIR }}
175+
key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
176+
restore-keys: |
177+
uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
178+
uv-${{ runner.os }}
179+
- name: Install Dependencies
180+
run: just install
181+
- name: Test with pytest
182+
run: |
183+
sudo apt-get update && \
184+
sudo apt-get install -y libnss3-tools build-essential gcc && \
185+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && \
186+
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" && \
187+
brew install mkcert && \
188+
mkcert -install && \
189+
mkcert -key-file meilisearch.key -cert-file meilisearch.crt localhost 127.0.0.1 ::1 && \
190+
just test-no-parallel-ci-http2
191+
- name: Upload coverage
192+
uses: codecov/codecov-action@v4
193+
with:
194+
token: ${{ secrets.CODECOV_TOKEN }}
195+
fail_ci_if_error: true
196+
- name: Minimize uv cache
197+
run: uv cache prune --ci
198+
199+
111200
docs:
112201
runs-on: ubuntu-latest
113202
steps:

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
meilisearch.crt
2+
meilisearch.key
13
# Byte-compiled / optimized / DLL files
24
__pycache__/
35
*.py[cod]

docker-compose.https.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
services:
2+
meilisearch:
3+
image: getmeili/meilisearch:latest
4+
ports:
5+
- "7700:7700"
6+
environment:
7+
- MEILI_MASTER_KEY=masterKey
8+
- MEILI_NO_ANALYTICS=true
9+
volumes:
10+
- ./meilisearch.key:/meilisearch.key
11+
- ./meilisearch.crt:/meilisearch.crt
12+
command: ["meilisearch", "--ssl-cert-path", "/meilisearch.crt", "--ssl-key-path", "/meilisearch.key"]

justfile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,21 @@
1818
@test:
1919
-uv run pytest -x
2020

21+
@test-http2:
22+
-uv run pytest -x --http2
23+
2124
@test-parallel:
2225
-uv run pytest -n auto -x -m "not no_parallel"
2326

2427
@test-no-parallel:
2528
-uv run pytest -x -m "no_parallel"
2629

30+
@test-parallel-http2:
31+
-uv run pytest -n auto -x -m "not no_parallel" --http2
32+
33+
@test-no-parallel-http2:
34+
-uv run pytest -x -m "no_parallel" --http2
35+
2736
@test-ci: start-meilisearch-detached && stop-meilisearch
2837
uv run pytest --cov=meilisearch_python_sdk --cov-report=xml
2938

@@ -33,6 +42,13 @@
3342
@test-no-parallel-ci: start-meilisearch-detached && stop-meilisearch
3443
uv run pytest --cov=meilisearch_python_sdk --cov-report=xml -m "no_parallel"
3544

45+
@test-parallel-ci-http2: start-meilisearch-detached-http2 && stop-meilisearch-http2
46+
uv run pytest --cov=meilisearch_python_sdk --cov-report=xml -n auto -m "not no_parallel" --http2
47+
48+
@test-no-parallel-ci-http2: start-meilisearch-detached-http2 && stop-meilisearch-http2
49+
uv run pytest --cov=meilisearch_python_sdk --cov-report=xml -m "no_parallel" --http2
50+
51+
3652
@start-meilisearch:
3753
docker compose up
3854

@@ -42,6 +58,15 @@
4258
@stop-meilisearch:
4359
docker compose down
4460

61+
@start-meilisearch-http2:
62+
docker compose -f docker-compose.https.yml up
63+
64+
@start-meilisearch-detached-http2:
65+
docker compose -f docker-compose.https.yml up -d
66+
67+
@stop-meilisearch-http2:
68+
docker compose -f docker-compose.https.yml down
69+
4570
@build-docs:
4671
uv run mkdocs build --strict
4772

meilisearch_python_sdk/_client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ def __init__(
150150
verify: str | bool | SSLContext = True,
151151
custom_headers: dict[str, str] | None = None,
152152
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
153+
http2: bool = False,
153154
) -> None:
154155
"""Class initializer.
155156
@@ -168,11 +169,12 @@ def __init__(
168169
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
169170
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
170171
extra needs to be included. Default: BuiltinHandler.
172+
http2: Whether or not to use HTTP/2. Defaults to False.
171173
"""
172174
super().__init__(api_key, custom_headers, json_handler)
173175

174176
self.http_client = HttpxAsyncClient(
175-
base_url=url, timeout=timeout, headers=self._headers, verify=verify
177+
base_url=url, timeout=timeout, headers=self._headers, verify=verify, http2=http2
176178
)
177179
self._http_requests = AsyncHttpRequests(self.http_client, json_handler=self.json_handler)
178180

@@ -1073,6 +1075,7 @@ def __init__(
10731075
verify: str | bool | SSLContext = True,
10741076
custom_headers: dict[str, str] | None = None,
10751077
json_handler: BuiltinHandler | OrjsonHandler | UjsonHandler | None = None,
1078+
http2: bool = False,
10761079
) -> None:
10771080
"""Class initializer.
10781081
@@ -1091,12 +1094,14 @@ def __init__(
10911094
(uses the json module from the standard library), OrjsonHandler (uses orjson), or
10921095
UjsonHandler (uses ujson). Note that in order use orjson or ujson the corresponding
10931096
extra needs to be included. Default: BuiltinHandler.
1097+
http2: If set to True, the client will use HTTP/2. Defaults to False.
10941098
"""
10951099
super().__init__(api_key, custom_headers, json_handler)
10961100

10971101
self.http_client = HttpxClient(
1098-
base_url=url, timeout=timeout, headers=self._headers, verify=verify
1102+
base_url=url, timeout=timeout, headers=self._headers, verify=verify, http2=http2
10991103
)
1104+
11001105
self._http_requests = HttpRequests(self.http_client, json_handler=self.json_handler)
11011106

11021107
def create_dump(self) -> TaskInfo:

meilisearch_python_sdk/decorators.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def async_add_documents(
2626
batch_size: int | None = None,
2727
primary_key: str | None = None,
2828
wait_for_task: bool = False,
29+
verify: bool = True,
2930
) -> Callable:
3031
"""Decorator that takes the returned documents from a function and asyncronously adds them to Meilisearch.
3132
@@ -42,6 +43,7 @@ def async_add_documents(
4243
Defaults to None.
4344
wait_for_task: If set to `True` the decorator will wait for the document addition to finish
4445
indexing before returning, otherwise it will return right away. Default = False.
46+
verify: If set to `False` the decorator will not verify the SSL certificate of the server.
4547
4648
Returns:
4749
@@ -89,7 +91,9 @@ async def wrapper(*args: Any, **kwargs: Any) -> Any:
8991
)
9092
return result
9193

92-
async with AsyncClient(connection_info.url, connection_info.api_key) as client:
94+
async with AsyncClient(
95+
connection_info.url, connection_info.api_key, verify=verify
96+
) as client:
9397
await _async_add_documents(
9498
client, index_name, result, batch_size, primary_key, wait_for_task
9599
)
@@ -108,6 +112,7 @@ def add_documents(
108112
batch_size: int | None = None,
109113
primary_key: str | None = None,
110114
wait_for_task: bool = False,
115+
verify: bool = True,
111116
) -> Callable:
112117
"""Decorator that takes the returned documents from a function and adds them to Meilisearch.
113118
@@ -124,6 +129,7 @@ def add_documents(
124129
Defaults to None.
125130
wait_for_task: If set to `True` the decorator will wait for the document addition to finish
126131
indexing before returning, otherwise it will return right away. Default = False.
132+
verify: If set to `False` the decorator will not verify the SSL certificate of the server.
127133
128134
Returns:
129135
@@ -171,7 +177,9 @@ def wrapper(*args: Any, **kwargs: Any) -> Any:
171177
)
172178
return result
173179

174-
decorator_client = Client(url=connection_info.url, api_key=connection_info.api_key)
180+
decorator_client = Client(
181+
url=connection_info.url, api_key=connection_info.api_key, verify=verify
182+
)
175183
_add_documents(
176184
decorator_client,
177185
index_name,

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dependencies = [
2727
"camel-converter>=1.0.0",
2828
# allows pydantic to use pipe instead of Union
2929
"eval-type-backport>=0.2.0; python_version < '3.10'",
30-
"httpx>=0.17",
30+
"httpx[http2]>=0.17",
3131
"pydantic>=2.0.0",
3232
"PyJWT>=2.3.0",
3333
]
@@ -49,13 +49,16 @@ dev-dependencies = [
4949
"pytest-asyncio==0.24.0",
5050
"pytest-xdist==3.6.1",
5151
"ruff==0.6.2",
52+
"truststore==0.9.2; python_version >= '3.10'",
5253
"types-aiofiles==24.1.0.20240626",
5354
"typing-extensions==4.12.2",
5455
"types-ujson==5.10.0.20240515",
5556
"meilisearch==0.31.5",
5657
"rich==13.7.1",
5758
]
5859

60+
environments = ["python_version < '3.10'", "python_version >= '3.10'"]
61+
5962
[tool.hatch.version]
6063
path = "meilisearch_python_sdk/_version.py"
6164

0 commit comments

Comments
 (0)