Skip to content

feat(search): add unified search command across Kaggle content#1143

Merged
stevemessick merged 5 commits into
Kaggle:mainfrom
sridipbasu:feat/kaggle-search
Jul 24, 2026
Merged

feat(search): add unified search command across Kaggle content#1143
stevemessick merged 5 commits into
Kaggle:mainfrom
sridipbasu:feat/kaggle-search

Conversation

@sridipbasu

Copy link
Copy Markdown
Contributor

Summary

This PR adds a new top-level command:

kaggle search "<query>"

It provides a unified way to search across multiple Kaggle content types from a single command, including datasets, competitions, notebooks, models, users, and discussions.

Motivation

Currently, searching in the Kaggle CLI is only available through individual commands such as:

kaggle datasets list --search "<query>"
kaggle competitions list --search "<query>"
kaggle kernels list --search "<query>"
kaggle models list --search "<query>"

This means users have to run multiple commands when they are not sure where the content they are looking for exists.

For example, searching for "Gemma" may require checking models, notebooks, datasets, and competitions separately. A unified search command makes content discovery much easier from the terminal.

What this adds

A new command:

kaggle search "<query>"

Supported features

  • Search across datasets, competitions, notebooks, models, users, and discussions
  • Filter results using --type
  • Search only your own content using --mine
  • Pagination support
  • Backend relevance ranking
  • Table, CSV, and JSON output formats

Example usage

kaggle search "gemma"

kaggle search "llm" --type dataset

kaggle search "gemma" --type model

kaggle search "andrew ng" --type user

kaggle search "baseline" --mine

Implementation

This feature uses the existing SearchApiService.list_entities endpoint available through kagglesdk.

The CLI builds a ListEntitiesRequest, sends it through the existing authenticated client, and normalizes the mixed search results so they can reuse the existing output formatting for table, CSV, and JSON outputs.

By default, the search is limited to the CLI-supported content types (datasets, competitions, notebooks, models, users, and discussions). This keeps the results focused on content that the CLI can represent and use directly while still using the backend's canonical ranking.

Testing

Added tests covering:

  • Parser registration
  • Request construction
  • Default and explicit content types
  • Pagination
  • Sort validation
  • Output formatting
  • JSON output
  • CSV output
  • Invalid inputs
  • Backend error handling

The new tests pass, and the existing test suite continues to pass except for the pre-existing Windows path-related failures already present on main.

Backward Compatibility

This change is fully additive and does not modify any existing commands or flags.

Future Improvements

Possible future enhancements include:

  • Additional per-content-type filters
  • Privacy and ownership filters
  • Support for additional searchable content types exposed by the backend

@sridipbasu

Copy link
Copy Markdown
Contributor Author

Here are a few examples of the new kaggle search command. It supports unified search across different Kaggle content types, along with filtering using --type for datasets, models, and users.

image image image image

@sridipbasu

Copy link
Copy Markdown
Contributor Author

Hi Steve and Bovard!
This is the feature I mentioned earlier. I'd appreciate any feedback whenever you have the time. Thanks!

@stevemessick

Copy link
Copy Markdown
Contributor

/gcbrun

@stevemessick

Copy link
Copy Markdown
Contributor

@sridipbasu Thanks! I see what you mean about potentially changing the way the tool is used. :) I'm looking at the PR now, but it's going to take a while. I just wanted to let you know that a change to the command set won't be included in a X.Y.Z point release; it needs a X.Y.0 version. So, while I may release 2.2.4 this week, it won't include this PR. This will be in 2.3 assuming all goes well.

And, one question: you mentioned "pre-existing Windows path-related failures" in tests. Are there any that are not marked as failures? I need to take a look at the known failing test and if there are any others they need to get cleaned up, too.

@stevemessick stevemessick left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks good, thanks. I think you should add benchmarks to the list of searchable entities. Also, I'm puzzled why comments are excluded while discussions are included. Have you checked that discussions attached to entities like notebooks and datasets are searched?

None of the images embedded in your comment above are clickable for me. Fortunately, they are of sufficient quality I can use the browser to zoom in and read them.

Comment thread src/kaggle/api/kaggle_api_extended.py Outdated
"""
if not document_types:
return []
mapping = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You can eliminate most of this by using lookup_enum() instead. (Might still need to drop 's')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I updated this to use lookup_enum() instead of the manual mapping. I kept the small alias handling (notebook/discussion) and the plural stripping so the existing CLI behavior stays the same.

Comment thread src/kaggle/api/kaggle_api_extended.py Outdated
Returns:
ListSearchContentOrderBy: The resolved enum value.
"""
mapping = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Again, use lookup_enum() instead. See how 'relevance' is handled elsewhere in the code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Switched this over to lookup_enum(). I only kept relevance as a special case since it doesn't have a matching enum value.

Comment thread src/kaggle/api/kaggle_api_extended.py Outdated
Returns:
str: A lowercase label such as "notebook" or "discussion".
"""
labels = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Honest question: does Python not have a built-in translation from enum to name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ahh yes correct, updated this to use enum.name. I only kept the two overrides for KERNEL -> notebook and TOPIC -> discussion to preserve the CLI labels.

@sridipbasu

Copy link
Copy Markdown
Contributor Author

Addressed the review comments in the latest commit.

Changes made:

  • Replaced the manual enum mappings with the existing lookup_enum() helper where applicable.
  • Switched enum-to-label conversion to use enum.name, keeping only the small overrides needed for the CLI labels (KERNEL -> notebook and TOPIC -> discussion).
  • Kept relevance as the only special case for --sort-by since there isn't a corresponding ListSearchContentOrderBy enum value.
  • Updated the tests and documentation to match the refactored implementation.

Thanks for the suggestions!

@sridipbasu

Copy link
Copy Markdown
Contributor Author

@sridipbasu Thanks! I see what you mean about potentially changing the way the tool is used. :) I'm looking at the PR now, but it's going to take a while. I just wanted to let you know that a change to the command set won't be included in a X.Y.Z point release; it needs a X.Y.0 version. So, while I may release 2.2.4 this week, it won't include this PR. This will be in 2.3 assuming all goes well.

And, one question: you mentioned "pre-existing Windows path-related failures" in tests. Are there any that are not marked as failures? I need to take a look at the known failing test and if there are any others they need to get cleaned up, too.

@stevemessick

  1. Cool, I am excited to see this command in the version 2.3.
  2. I ran the full tests/unit suite on my machine and it reports exactly 3 FAILED (all in test_kernels_pull.py) and 1 XFAIL (test_http_client.py::test_get_apikey_creds_invalid_json). There aren't any other unexpected failures.
    The three failing tests also reproduce on main, so they're unrelated to this PR. After looking into them, they appear to be Windows-only path assertion issues in the tests rather than a problem with the production code. The XFAIL is already marked as an expected failure.
    I also traced the root cause locally, and it looks like those tests can be fixed without changing any production code. I'd be happy to open a small separate PR to make those path assertions OS-agnostic so they pass on Windows as well.

@stevemessick

Copy link
Copy Markdown
Contributor

/gcbrun

@sridipbasu

Copy link
Copy Markdown
Contributor Author

Earlier it showed, the branch had conflicts. I've updated and fixed it.

@stevemessick

Copy link
Copy Markdown
Contributor

/gcbrun

@stevemessick

Copy link
Copy Markdown
Contributor

/gcbrun

@stevemessick

Copy link
Copy Markdown
Contributor

@sridipbasu After merging your other PR I noticed this one had a merge conflict, so I fixed that.

Just as a reminder, I'm still waiting on the changes I suggested in my main review (benchmarks, comments). This is looking good so far!

Once we get everything caught up, if you have time to fix the tests that fail on Windows, I'd be glad to review the PR. (You probably noticed that we don't test on Windows.)

@sridipbasu

Copy link
Copy Markdown
Contributor Author

@stevemessick

I addressed the remaining feedback in the latest commit.

  • Added benchmark as a searchable entity, including support for --type benchmark, default search, tests, and documentation.
  • Looked into the comments vs. discussions question by testing against the live Search API.

From what I found, TOPIC returns discussion threads, while COMMENT returns individual replies. Notebook discussions currently show up as COMMENT objects instead of TOPIC, whereas competition and dataset discussions are generally returned as TOPIC.

For now, I kept the TOPIC mapping because it gives cleaner, thread-level search results. Including COMMENT by default mostly returns individual reply snippets, which don't fit very well with the current CLI output. I think exposing those through a future --type comment option would make more sense.

Thanks again for the suggestions, they definitely helped improve the implementation!

@stevemessick

Copy link
Copy Markdown
Contributor

/gcbrun

@stevemessick stevemessick left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks! This is going to be really useful, I think.

@stevemessick
stevemessick merged commit 77527f7 into Kaggle:main Jul 24, 2026
12 checks passed
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.

2 participants