Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 4 additions & 55 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,6 @@ jobs:
- name: Test with pytest
run: uv run pytest --cov-report=xml

pylint:
name: pylint
runs-on: ubuntu-latest
env:
PYTHONUNBUFFERED: 1
PYTHON_VERSION: "3.10"
UV_LOCKED: 1
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
version: "0.11.21"
python-version: ${{ env.PYTHON_VERSION }}

- name: Linter with pylint
run: uv run pylint meilisearch tests

mypy:
name: mypy
runs-on: ubuntu-latest
Expand Down Expand Up @@ -111,37 +84,13 @@ jobs:
with:
persist-credentials: false

- name: ruff format
- name: Run linter
uses: astral-sh/ruff-action@0ce1b0bf8b818ef400413f810f8a11cdbda0034b # v4.0.0
with:
args: "format --check"

isort:
name: isort
runs-on: ubuntu-latest
env:
PYTHONUNBUFFERED: 1
PYTHON_VERSION: "3.10"
UV_LOCKED: 1
steps:
- name: Checkout the repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
version: "0.11.21"
python-version: ${{ env.PYTHON_VERSION }}
args: "check"
Comment thread
sanders41 marked this conversation as resolved.
Outdated

- name: isort
run: uv run isort meilisearch tests --check-only
- name: Run formatter
run: ruff format --check

yaml-lint:
name: Yaml linting check
Expand Down
14 changes: 7 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ You can set up your local environment natively or using `docker`, check out the

Example of running all the checks with docker:
```bash
docker-compose run --rm package bash -c "uv run mypy meilisearch && uv run pylint meilisearch tests && uv run pytest tests"
docker-compose run --rm package bash -c "uv run mypy meilisearch && uv run ruff check && uv run ruff format --check && uv run pytest tests"
```

To install dependencies:
Expand All @@ -55,22 +55,22 @@ uv sync

### Tests and Linter <!-- omit in toc -->

Each PR should pass the tests, mypy type checking, and the linter to be accepted.
Your PR also needs to be formatted using ruff and have its imports sorted using isort.
Each PR should pass the tests, mypy type checking, linting, and formatting before it can be accepted.

```bash
# Tests
curl -L https://install.meilisearch.com | sh # download Meilisearch
./meilisearch --master-key=masterKey --no-analytics # run Meilisearch
uv run pytest tests

# MyPy
uv run mypy meilisearch

# Linter
uv run pylint meilisearch tests
# Format
uv run ruff check --fix .

# Formatter
uv run ruff format .
# Isort
uv run isort meilisearch tests
```

Optionally tox can be used to run test on all supported version of Python, mypy, and linting.
Expand Down
2 changes: 1 addition & 1 deletion meilisearch/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from meilisearch.client import Client as Client # pylint: disable=useless-import-alias
from meilisearch.client import Client as Client
98 changes: 51 additions & 47 deletions meilisearch/_httprequests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import annotations

import json
from collections.abc import Callable, Mapping, Sequence
from functools import lru_cache
from typing import Any, Callable, List, Mapping, Optional, Sequence, Tuple, Type, Union
from typing import Any

import requests

Expand All @@ -17,7 +18,7 @@


class HttpRequests:
def __init__(self, config: Config, custom_headers: Optional[Mapping[str, str]] = None) -> None:
def __init__(self, config: Config, custom_headers: Mapping[str, str] | None = None) -> None:
self.config = config
self.headers = {
"Authorization": f"Bearer {self.config.api_key}",
Expand All @@ -31,21 +32,18 @@ def send_request(
self,
http_method: Callable,
path: str,
body: Optional[
Union[
Mapping[str, Any],
Sequence[Mapping[str, Any]],
List[str],
bool,
bytes,
str,
int,
ProximityPrecision,
]
] = None,
content_type: Optional[str] = None,
body: Mapping[str, Any]
| Sequence[Mapping[str, Any]]
| list[str]
| bool
| bytes
| str
| int
| ProximityPrecision
| None = None,
content_type: str | None = None,
*,
serializer: Optional[Type[json.JSONEncoder]] = None,
serializer: type[json.JSONEncoder] | None = None,
) -> Any:
if content_type:
self.headers["Content-Type"] = content_type
Expand Down Expand Up @@ -102,63 +100,69 @@ def get(self, path: str) -> Any:
def post(
self,
path: str,
body: Optional[
Union[Mapping[str, Any], Sequence[Mapping[str, Any]], List[str], bytes, str]
] = None,
content_type: Optional[str] = "application/json",
body: Mapping[str, Any]
| Sequence[Mapping[str, Any]]
| list[str]
| bytes
| str
| None = None,
content_type: str | None = "application/json",
*,
serializer: Optional[Type[json.JSONEncoder]] = None,
serializer: type[json.JSONEncoder] | None = None,
) -> Any:
return self.send_request(requests.post, path, body, content_type, serializer=serializer)

def patch(
self,
path: str,
body: Optional[
Union[Mapping[str, Any], Sequence[Mapping[str, Any]], List[str], bytes, str]
] = None,
content_type: Optional[str] = "application/json",
body: Mapping[str, Any]
| Sequence[Mapping[str, Any]]
| list[str]
| bytes
| str
| None = None,
content_type: str | None = "application/json",
) -> Any:
return self.send_request(requests.patch, path, body, content_type)

def put(
self,
path: str,
body: Optional[
Union[
Mapping[str, Any],
Sequence[Mapping[str, Any]],
List[str],
bool,
bytes,
str,
int,
PrefixSearch,
ProximityPrecision,
]
] = None,
content_type: Optional[str] = "application/json",
body: Mapping[str, Any]
| Sequence[Mapping[str, Any]]
| list[str]
| bool
| bytes
| str
| int
| PrefixSearch
| ProximityPrecision
| None = None,
content_type: str | None = "application/json",
*,
serializer: Optional[Type[json.JSONEncoder]] = None,
serializer: type[json.JSONEncoder] | None = None,
) -> Any:
return self.send_request(requests.put, path, body, content_type, serializer=serializer)

def delete(
self,
path: str,
body: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]], List[str]]] = None,
body: Mapping[str, Any] | Sequence[Mapping[str, Any]] | list[str] | None = None,
) -> Any:
return self.send_request(requests.delete, path, body)

def post_stream(
self,
path: str,
body: Optional[
Union[Mapping[str, Any], Sequence[Mapping[str, Any]], List[str], bytes, str]
] = None,
content_type: Optional[str] = "application/json",
body: Mapping[str, Any]
| Sequence[Mapping[str, Any]]
| list[str]
| bytes
| str
| None = None,
content_type: str | None = "application/json",
*,
serializer: Optional[Type[json.JSONEncoder]] = None,
serializer: type[json.JSONEncoder] | None = None,
) -> requests.Response:
"""Send a POST request with streaming enabled.

Expand Down Expand Up @@ -236,7 +240,7 @@ def __validate(request: requests.Response) -> Any:


@lru_cache(maxsize=1)
def _build_user_agent(client_agents: Optional[Tuple[str, ...]] = None) -> str:
def _build_user_agent(client_agents: tuple[str, ...] | None = None) -> str:
user_agent = qualified_version()
if not client_agents:
return user_agent
Expand Down
3 changes: 1 addition & 2 deletions meilisearch/_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import datetime
from functools import lru_cache
from typing import Union

import pydantic

Expand All @@ -20,7 +19,7 @@ def is_pydantic_2() -> bool:
return False


def iso_to_date_time(iso_date: Union[datetime, str, None]) -> Union[datetime, None]:
def iso_to_date_time(iso_date: datetime | str | None) -> datetime | None:
"""Handle conversion of iso string to datetime.

The microseconds from Meilisearch are sometimes too long for python to convert so this
Expand Down
Loading
Loading