Skip to content

Conversation

@jawad-khan
Copy link
Contributor

@jawad-khan jawad-khan commented Dec 3, 2025

Related issue

Fixes #1168

What does this PR do?

Update Index APIs to Support customMetadata

This PR updates the index-related APIs in the Python SDK to align with recent Meilisearch server changes and adds support for the new customMetadata field.

Key Updates

  • Added customMetadata support across index creation and update methods.

  • Synced request/response structures with the latest Meilisearch index API.

  • ...

PR checklist

Please check if your PR fulfills the following requirements:

  • Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
  • Have you read the contributing guidelines?
  • Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!

Summary by CodeRabbit

  • New Features

    • Tasks now accept and carry optional custom metadata. Document operations (add, update, delete, single and batched) can include metadata that is attached to the created task and returned in task info for easier tracking.
  • Tests

    • Test suite updated to pass metadata and verify it is propagated and exposed on returned task information after operations.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 3, 2025 12:57
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds an optional metadata parameter to document add/update/delete index methods, threads it into internal URL construction as customMetadata query param, and exposes it on returned Task objects via a new customMetadata field. Tests updated to assert propagation.

Changes

Cohort / File(s) Summary
Index API methods
meilisearch/index.py
Added metadata: Optional[str] = None to public document methods (add, update, delete, batch and raw/CSV/NDJSON variants). Metadata is forwarded through internals and _build_url so customMetadata=<value> is appended to request URLs when provided.
Task model
meilisearch/models/task.py
Added customMetadata: Optional[str] = None field to the Task model so server-returned metadata is captured.
Tests
tests/index/test_index_document_meilisearch.py
Updated tests to pass metadata="Test metadata" to document operations and assert returned TaskInfo contains the provided customMetadata.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25–35 minutes

  • Inspect all changed public method signatures in meilisearch/index.py for consistent parameter ordering and defaults.
  • Verify _build_url appends customMetadata only when metadata is non-empty and uses proper URL encoding.
  • Confirm batch methods forward metadata for every per-batch request.
  • Check Task parsing/deserialization populates customMetadata from API responses and tests cover presence.

Suggested labels

enhancement

Suggested reviewers

  • Strift

Poem

🐇 I hopped through code with a tiny cheer,
Tucked a message where tasks appear.
A whisper carried in each request,
Custom metadata now travels the rest. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.68% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding customMetadata support to index APIs, which is the primary objective of the PR.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #1168: metadata parameter added to all document operation methods (add, update, delete variants), Task model includes customMetadata field, and comprehensive tests verify metadata propagation.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue #1168: metadata parameter threading through index methods, Task model extension, and test coverage for metadata functionality.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for the customMetadata field to index-related APIs in the Python SDK, aligning with recent Meilisearch server changes. The implementation adds an optional metadata parameter to all document manipulation methods (add, update, delete) that gets passed to the Meilisearch server as a query parameter.

Key changes:

  • Added customMetadata field to the Task model to capture metadata returned by the server
  • Updated all document methods in the Index class to accept an optional metadata parameter
  • Enhanced test coverage by adding metadata assertions to document operation tests

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
meilisearch/models/task.py Added customMetadata field as Optional[str] to Task model
meilisearch/index.py Added metadata parameter to all document methods (add/update/delete variants) and updated URL building logic to include customMetadata as a query parameter
tests/index/test_index_document_meilisearch.py Updated tests to pass metadata parameter and assert that customMetadata is persisted on task objects

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

self,
documents: Sequence[Mapping[str, Any]],
batch_size: int = 1000,
primary_key: Optional[str] = None,
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent API design: In add_documents_in_batches, serializer is a keyword-only argument (line 521-522 uses *,), but in this method it's not keyword-only. For consistency, consider adding *, before serializer on line 906 to make it keyword-only, or update add_documents_in_batches to match this signature. The new metadata parameter should also be keyword-only to match the pattern in add_documents_in_batches.

Suggested change
primary_key: Optional[str] = None,
primary_key: Optional[str] = None,
*,

Copilot uses AI. Check for mistakes.
index.wait_for_task(response.task_uid)
response = index.delete_documents(filter="genre=action", metadata="Test metadata")
task = index.wait_for_task(response.task_uid)
task.customMetadata = "Test metadata"
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be an assertion (assert task.customMetadata == "Test metadata") instead of an assignment. Unlike all other test cases in this file, this line assigns a value instead of verifying it, which means the test isn't actually validating that the metadata was properly persisted.

Suggested change
task.customMetadata = "Test metadata"
assert task.customMetadata == "Test metadata"

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
meilisearch/index.py (4)

601-634: Inconsistent parameter style: metadata is positional here but keyword-only in similar methods.

In add_documents, add_documents_in_batches, and add_documents_json, the metadata parameter is keyword-only (after *). However, in add_documents_csv, it's a regular positional parameter.

For API consistency, consider making metadata keyword-only:

 def add_documents_csv(
     self,
     str_documents: bytes,
     primary_key: Optional[str] = None,
     csv_delimiter: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:

636-666: Same inconsistency: metadata should be keyword-only for consistency.

 def add_documents_ndjson(
     self,
     str_documents: bytes,
     primary_key: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:

751-781: Same inconsistency: metadata should be keyword-only.

 def update_documents_ndjson(
     self,
     str_documents: str,
     primary_key: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:

820-853: Same inconsistency: metadata should be keyword-only.

 def update_documents_csv(
     self,
     str_documents: str,
     primary_key: Optional[str] = None,
     csv_delimiter: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fdcb7b and a03eff0.

📒 Files selected for processing (3)
  • meilisearch/index.py (37 hunks)
  • meilisearch/models/task.py (1 hunks)
  • tests/index/test_index_document_meilisearch.py (15 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/index/test_index_document_meilisearch.py (1)
meilisearch/index.py (14)
  • add_documents (479-514)
  • update (108-152)
  • add_documents_in_batches (516-562)
  • add_documents_json (564-599)
  • update_documents (714-749)
  • update_documents_json (783-818)
  • update_documents_in_batches (901-946)
  • delete_document (948-975)
  • delete_documents (978-1030)
  • delete_all_documents (1032-1055)
  • add_documents_csv (601-634)
  • update_documents_csv (820-853)
  • add_documents_ndjson (636-666)
  • update_documents_ndjson (751-781)
meilisearch/index.py (2)
meilisearch/_httprequests.py (2)
  • put (120-140)
  • post (98-108)
meilisearch/models/task.py (1)
  • TaskInfo (79-108)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Agent
🔇 Additional comments (31)
meilisearch/models/task.py (1)

25-25: LGTM - customMetadata field added to Task model.

The field correctly uses Optional[str] and follows the existing CamelBase naming convention for API compatibility.

tests/index/test_index_document_meilisearch.py (18)

31-40: LGTM - Test correctly verifies metadata propagation.


65-74: LGTM - Batch test correctly verifies metadata on each task.


112-120: LGTM - JSON serializer test with metadata verification.


129-140: LGTM - Raw documents test with metadata verification.


149-155: LGTM - Update documents test with metadata.


177-185: LGTM - Update documents JSON test with metadata.


194-205: LGTM - Update documents raw test with metadata.


393-398: LGTM - Update documents test with metadata.


423-432: LGTM - Update documents in batches test with metadata.


440-444: LGTM - Delete document test with metadata.


455-459: LGTM - Delete documents by ID test with metadata.


486-490: LGTM - Delete all documents test with metadata.


499-503: LGTM - Add documents CSV test with metadata.


525-530: LGTM - Update documents CSV test with metadata.


551-556: LGTM - Add documents JSON test with metadata.


563-567: LGTM - Update documents JSON test with metadata.


575-579: LGTM - Add documents NDJSON test with metadata.


587-592: LGTM - Update documents NDJSON test with metadata.

meilisearch/index.py (12)

479-514: LGTM - add_documents method correctly supports metadata parameter.

The metadata is properly threaded through to _build_url and documented in the docstring.


516-562: LGTM - add_documents_in_batches correctly propagates metadata to each batch.


564-599: LGTM - add_documents_json correctly propagates metadata.


668-712: LGTM - add_documents_raw correctly implements metadata as keyword-only.


714-749: LGTM - update_documents correctly implements metadata.


783-818: LGTM - update_documents_json correctly implements metadata as keyword-only.


855-899: LGTM - update_documents_raw correctly implements metadata as keyword-only.


901-946: LGTM - update_documents_in_batches correctly propagates metadata.

Note: The parameter style follows the existing pattern for this method (positional optional parameters), though it differs from add_documents_in_batches which uses keyword-only parameters. This is a pre-existing inconsistency.


948-975: LGTM - delete_document correctly implements metadata with URL encoding.


977-1030: LGTM - delete_documents correctly handles metadata in both the ids and filter branches.


1032-1055: LGTM - delete_all_documents correctly implements metadata.


2430-2445: LGTM - _build_url correctly centralizes the metadata query parameter construction.

Good approach to centralize the metadatacustomMetadata mapping in the URL builder.

@jawad-khan
Copy link
Contributor Author

@Strift Tests are failing because sharding require Enterprose addition now. Should we adjust test cases or somehow we can skip this check.

@jawad-khan
Copy link
Contributor Author

@Strift Please re trigger test cases.

@jawad-khan jawad-khan force-pushed the jawad/update-index-apis branch from 690ec39 to f27c052 Compare December 16, 2025 20:04
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
meilisearch/index.py (1)

901-908: Inconsistent API design: serializer and metadata should be keyword-only.

Unlike add_documents_in_batches (line 521-523), this method does not use *, to make serializer and metadata keyword-only. This was flagged in a prior review.

Apply this diff for consistency:

 def update_documents_in_batches(
     self,
     documents: Sequence[Mapping[str, Any]],
     batch_size: int = 1000,
     primary_key: Optional[str] = None,
+    *,
     serializer: Optional[Type[JSONEncoder]] = None,
     metadata: Optional[str] = None,
 ) -> List[TaskInfo]:
🧹 Nitpick comments (4)
meilisearch/index.py (4)

601-634: Inconsistent API design: metadata should be keyword-only.

In add_documents_csv, metadata is a positional parameter, but in similar methods like add_documents and add_documents_json, metadata is keyword-only (placed after *,). This inconsistency can lead to confusing API usage.

Apply this diff for consistency:

 def add_documents_csv(
     self,
     str_documents: bytes,
     primary_key: Optional[str] = None,
     csv_delimiter: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:

636-666: Inconsistent API design: metadata should be keyword-only.

Same issue as add_documents_csv - for consistency with other methods, metadata should be keyword-only.

Apply this diff:

 def add_documents_ndjson(
     self,
     str_documents: bytes,
     primary_key: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:

751-781: Inconsistent API design: metadata should be keyword-only.

For consistency with update_documents and update_documents_json, make metadata keyword-only.

Apply this diff:

 def update_documents_ndjson(
     self,
     str_documents: str,
     primary_key: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:

820-853: Inconsistent API design: metadata should be keyword-only.

For consistency, make metadata keyword-only.

Apply this diff:

 def update_documents_csv(
     self,
     str_documents: str,
     primary_key: Optional[str] = None,
     csv_delimiter: Optional[str] = None,
+    *,
     metadata: Optional[str] = None,
 ) -> TaskInfo:
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 690ec39 and f27c052.

📒 Files selected for processing (3)
  • meilisearch/index.py (37 hunks)
  • meilisearch/models/task.py (1 hunks)
  • tests/index/test_index_document_meilisearch.py (15 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • meilisearch/models/task.py
🧰 Additional context used
🧬 Code graph analysis (1)
meilisearch/index.py (3)
meilisearch/_httprequests.py (3)
  • put (120-140)
  • delete (142-147)
  • post (98-108)
meilisearch/models/task.py (1)
  • TaskInfo (79-108)
meilisearch/client.py (1)
  • index (231-247)
🔇 Additional comments (30)
tests/index/test_index_document_meilisearch.py (19)

31-40: LGTM - metadata propagation test looks correct.

The test properly verifies that the customMetadata parameter is passed through add_documents and returned on the completed task.


57-76: LGTM - batch metadata propagation test is thorough.

The test correctly verifies that customMetadata is propagated for each batch task in add_documents_in_batches.


106-120: LGTM - JSON serializer with metadata test is correct.


123-140: LGTM - raw document addition with metadata test is correct.


143-155: LGTM - update documents with metadata test is correct.


171-185: LGTM - update documents JSON with metadata test is correct.


188-205: LGTM - update documents raw with metadata test is correct.


386-408: LGTM - update single document with metadata test is correct.


415-434: LGTM - update documents in batches with metadata test is correct.


437-447: LGTM - delete single document with metadata test is correct.


450-464: LGTM - delete documents by ID with metadata test is correct.


467-480: LGTM - delete documents with filter and metadata test is correct.

The previously reported assignment bug on line 475 has been addressed.


483-493: LGTM - delete all documents with metadata test is correct.


496-506: LGTM - add documents CSV with metadata test is correct.


522-531: LGTM - update documents CSV with metadata test is correct.


548-557: LGTM - add documents JSON file with metadata test is correct.


560-569: LGTM - update documents JSON file with metadata test is correct.


572-581: LGTM - add documents NDJSON with metadata test is correct.


584-593: LGTM - update documents NDJSON with metadata test is correct.

meilisearch/index.py (11)

948-975: LGTM - delete_document metadata implementation is correct.

The inline URL construction with parse.urlencode properly handles the customMetadata query parameter.


1010-1030: LGTM - delete_documents metadata handling is correct.

Both the deprecated ids path and the filter path correctly append the customMetadata query parameter when provided.


1032-1055: LGTM - delete_all_documents metadata implementation is correct.


2430-2445: LGTM - _build_url metadata handling is correct.

The implementation properly adds customMetadata to the query parameters only when metadata is provided, and uses parse.urlencode for proper URL encoding.


479-514: LGTM - add_documents metadata implementation is correct.

The metadata parameter is properly defined as keyword-only and correctly passed to _build_url.


516-562: LGTM - add_documents_in_batches metadata propagation is correct.

Metadata is properly propagated to each batch call.


564-599: LGTM - add_documents_json metadata propagation is correct.


668-712: LGTM - add_documents_raw metadata implementation is correct.


714-749: LGTM - update_documents metadata implementation is correct.


783-818: LGTM - update_documents_json metadata propagation is correct.


855-899: LGTM - update_documents_raw metadata implementation is correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v1.26] Add tasks custom metadata

1 participant