Skip to content

Add HuggingFace API search for models and datasets#9

Merged
j4ys0n merged 2 commits into
mainfrom
claude/huggingface-model-dataset-search-011CUnTZx7SpDWLBg1YkphMT
Nov 4, 2025
Merged

Add HuggingFace API search for models and datasets#9
j4ys0n merged 2 commits into
mainfrom
claude/huggingface-model-dataset-search-011CUnTZx7SpDWLBg1YkphMT

Conversation

@j4ys0n

@j4ys0n j4ys0n commented Nov 4, 2025

Copy link
Copy Markdown
Contributor

Implemented comprehensive search feature for HuggingFace models and datasets:

  • Created HuggingFaceService for API integration

    • Search models with sorting and filtering
    • Search datasets with sorting and filtering
    • Fetch detailed model/dataset information
    • Comprehensive error handling and input validation
  • Created HFSearchDialog component

    • Maximized overlay dialog for search results
    • Display search results with key metadata (downloads, likes, tags)
    • View detailed information including descriptions and model cards
    • Direct links to HuggingFace website for each result
    • Support for both models and datasets
  • Integrated search into Configure page

    • Added "Search Models" button next to Model ID input
    • Added "Search Datasets" button next to Calibration Dataset input
    • Users can now browse and select from HuggingFace Hub instead of manual typing
  • All API calls use the huggingface_hub library

  • Type-safe with proper error handling and logging

  • Validated all input parameters to ensure correct API usage

Implemented comprehensive search feature for HuggingFace models and datasets:

- Created HuggingFaceService for API integration
  - Search models with sorting and filtering
  - Search datasets with sorting and filtering
  - Fetch detailed model/dataset information
  - Comprehensive error handling and input validation

- Created HFSearchDialog component
  - Maximized overlay dialog for search results
  - Display search results with key metadata (downloads, likes, tags)
  - View detailed information including descriptions and model cards
  - Direct links to HuggingFace website for each result
  - Support for both models and datasets

- Integrated search into Configure page
  - Added "Search Models" button next to Model ID input
  - Added "Search Datasets" button next to Calibration Dataset input
  - Users can now browse and select from HuggingFace Hub instead of manual typing

- All API calls use the huggingface_hub library
- Type-safe with proper error handling and logging
- Validated all input parameters to ensure correct API usage
Copilot AI review requested due to automatic review settings November 4, 2025 16:26

Copilot AI left a comment

Copy link
Copy Markdown

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 HuggingFace Hub integration to MSQuant, enabling users to search and select models and datasets directly from the UI instead of manually typing repository IDs.

  • Adds a new HuggingFaceService class for searching models/datasets via the HuggingFace Hub API
  • Creates a HFSearchDialog UI component with search functionality, sorting, and detail views
  • Integrates search dialogs into the configure page with "Search Models" and "Search Datasets" buttons

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/msquant/services/huggingface.py New service implementing HuggingFace Hub API wrapper for searching models/datasets and fetching details
src/msquant/services/init.py Exports new HuggingFaceService and HFSearchResult classes
src/msquant/app/components/hf_search_dialog.py New UI component providing interactive search dialog for HuggingFace models and datasets
src/msquant/app/components/init.py Exports new HFSearchDialog component
src/msquant/app/pages/configure.py Integrates search dialogs into model and dataset input fields
src/msquant/app/main.py Initializes HuggingFaceService and passes it to configure page

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

Comment on lines +185 to +186
description = card_data.get('description', '') or card_data.get('model-index', {}).get('results', [{}])[0].get('task', {}).get('name', '')
elif hasattr(card_data, 'to_dict'):

Copilot AI Nov 4, 2025

Copy link

Choose a reason for hiding this comment

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

This line is excessively complex with deeply nested .get() calls, making it difficult to read and maintain. Consider breaking this into multiple lines with intermediate variables to improve clarity. For example, extract the model-index fallback logic into a separate variable or helper method.

Suggested change
description = card_data.get('description', '') or card_data.get('model-index', {}).get('results', [{}])[0].get('task', {}).get('name', '')
elif hasattr(card_data, 'to_dict'):
# Try to get description directly
description = card_data.get('description', '')
# Fallback: try to get task name from model-index
if not description:
model_index = card_data.get('model-index', {})
results = model_index.get('results', [{}])
if isinstance(results, list) and results:
first_result = results[0]
task = first_result.get('task', {})
description = task.get('name', '')

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +62
if not isinstance(query, str):
raise ValueError(f"query must be a string, got {type(query)}")

Copilot AI Nov 4, 2025

Copy link

Choose a reason for hiding this comment

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

The input validation logic for parameters (query, limit, sort, direction) is duplicated between search_models and search_datasets methods (lines 61-68 and 121-128). Consider extracting this validation into a private helper method to reduce code duplication.

Copilot uses AI. Check for mistakes.
Comment on lines +265 to +278
def _model_to_search_result(self, model: ModelInfo) -> HFSearchResult:
"""Convert ModelInfo to HFSearchResult."""
return HFSearchResult(
id=model.id,
author=getattr(model, 'author', None),
description=None, # Description not available in list results
downloads=getattr(model, 'downloads', 0),
likes=getattr(model, 'likes', 0),
tags=getattr(model, 'tags', []) or [],
last_modified=str(getattr(model, 'lastModified', '')),
created_at=str(getattr(model, 'created_at', '')),
library_name=getattr(model, 'library_name', None),
pipeline_tag=getattr(model, 'pipeline_tag', None),
)

Copilot AI Nov 4, 2025

Copy link

Choose a reason for hiding this comment

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

The pattern getattr(model, 'tags', []) or [] on line 273 is redundant - if the default value [] is returned by getattr, the or [] has no effect. Consider simplifying to getattr(model, 'tags', []). The same issue exists in the _dataset_to_search_result method on line 288.

Copilot uses AI. Check for mistakes.
with ui.row().classes('gap-4'):
ui.button(
'Select This',
on_click=lambda: [self._select_item(result), details_dialog.close()]

Copilot AI Nov 4, 2025

Copy link

Choose a reason for hiding this comment

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

Using a list comprehension in a lambda for side effects (line 284) is not idiomatic Python and can be confusing. Consider defining a proper function or using a lambda with a simple function call that performs both actions.

Copilot uses AI. Check for mistakes.

def __init__(self):
"""Initialize the HuggingFace service."""
self._cache: Dict[str, Any] = {}

Copilot AI Nov 4, 2025

Copy link

Choose a reason for hiding this comment

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

The _cache attribute is initialized but never used anywhere in the HuggingFaceService class. Consider removing it or implementing caching functionality if it was intended to be used.

Suggested change
self._cache: Dict[str, Any] = {}

Copilot uses AI. Check for mistakes.
@j4ys0n

j4ys0n commented Nov 4, 2025

Copy link
Copy Markdown
Contributor Author

Automated review 🤖

Summary of Changes

This PR introduces a HuggingFace API integration for searching models and datasets within the MSQuant application. It adds a new HuggingFaceService to handle API calls and a HFSearchDialog component for UI interaction. The feature is integrated into the Configure page, allowing users to search and select models/datasets from HuggingFace Hub instead of manual input.

Key Changes & Positives

  • 🟢 New Service Layer: HuggingFaceService provides clean abstraction for HuggingFace API interactions with proper error handling and input validation.
  • 🟢 UI Component: HFSearchDialog offers a user-friendly overlay interface for browsing models/datasets with sorting, filtering, and detailed views.
  • 🟢 Integration: Search buttons added to the Configure page for both Model ID and Calibration Dataset inputs, improving UX.
  • 🟢 Type Safety: Strong typing with HFSearchResult dataclass and proper type hints throughout.
  • 🟢 Error Handling: Comprehensive logging and user-facing error messages for API failures.

Potential Issues & Recommendations

  1. Issue / Risk: In hf_search_dialog.py, the _perform_search method uses synchronous service calls (self.hf_service.search_models) inside an async method, which can block the UI.

    • Impact: May cause UI unresponsiveness during API calls.
    • Recommendation: Make service calls awaited (e.g., await self.hf_service.search_models(...)).
    • Status: 🔴 Problem
  2. Issue / Risk: The _show_details method in hf_search_dialog.py makes synchronous API calls (self.hf_service.get_model_details) inside an async method.

    • Impact: Can block the UI during detail loading.
    • Recommendation: Use await for async service calls.
    • Status: 🔴 Problem
  3. Issue / Risk: In huggingface.py, the get_model_details and get_dataset_details methods use multiple fallbacks for description extraction, which may be brittle or inconsistent.

    • Impact: Could miss descriptions or extract incorrect data.
    • Recommendation: Simplify description extraction logic or add more robust fallbacks.
    • Status: 🟡 Needs review
  4. Issue / Risk: The search_models and search_datasets methods in huggingface.py catch all exceptions and re-raise as RuntimeError, potentially masking specific issues.

    • Impact: Makes debugging harder by losing original exception context.
    • Recommendation: Re-raise specific exceptions or log more details before re-raising.
    • Status: 🟡 Needs review

Language/Framework Checks

  • Python:
    • ✅ Type hints and dataclasses used correctly.
    • ✅ Logging levels appropriate.
    • async/await usage inconsistent in UI components (needs fixing).
    • � Exception handling could be more granular.

Security & Privacy

  • No sensitive data handling or authentication logic introduced.
  • API calls use standard huggingface_hub library, no custom secrets management needed.

Build/CI & Ops

  • No build or deployment changes included.
  • No observability or monitoring changes.

Tests

  • No test files added.
  • Recommendation: Add unit tests for HuggingFaceService methods and integration tests for HFSearchDialog.

Approval Recommendation

Request changes

  • Fix async/await usage in HFSearchDialog methods
  • Review description extraction logic in HuggingFaceService
  • Improve exception handling granularity in HuggingFaceService
  • Add unit/integration tests for new components and services

Fixed all pyright type checking errors identified in CI:

hf_search_dialog.py:
- Removed Optional types from UI elements (they're always initialized)
- Removed async from _perform_search and _show_details (no await statements)
- Added proper type casting for sort (str) and direction (int) values
- Fixed lambda event handlers to accept event parameter properly
- Added missing type annotations for sort_select and direction_select

huggingface.py:
- Added Literal type import for proper typing
- Fixed direction parameter to match huggingface_hub API expectations
- Convert direction parameter: -1 maps to Literal[-1], 1 maps to None
- This matches the HuggingFace Hub API signature requirements

All 20 type errors are now resolved.
@j4ys0n

j4ys0n commented Nov 4, 2025

Copy link
Copy Markdown
Contributor Author

Automated review 🤖

Summary of Changes

This PR introduces a HuggingFace API integration for searching models and datasets within the MSQuant application. It adds a new HuggingFaceService to handle API calls and a HFSearchDialog component for UI interaction. The feature is integrated into the Configure page, allowing users to search and select models/datasets from HuggingFace Hub instead of manual input.

Key Changes & Positives

  • 🟢 New Service Layer: HuggingFaceService provides clean abstraction for HuggingFace API interactions with proper error handling and input validation.
  • 🟢 UI Component: HFSearchDialog offers a user-friendly overlay for browsing models/datasets with sorting, filtering, and detailed views.
  • 🟢 Integration: Search buttons added to Configure page for both Model ID and Calibration Dataset inputs, improving UX.
  • 🟢 Type Safety: Strong typing with HFSearchResult dataclass and proper type hints throughout.

Potential Issues & Recommendations

  1. Issue / Risk: Inconsistent handling of direction parameter in list_models/list_datasets calls.

    • Impact: Sorting behavior may not match user expectations for ascending order.
    • Recommendation: Review HuggingFace library documentation for correct direction parameter usage; ensure 1 maps to ascending correctly.
    • Status: 🟡 Needs review
  2. Issue / Risk: Error handling in _model_to_search_result and _dataset_to_search_result may silently skip invalid results.

    • Impact: Some search results may be lost if conversion fails.
    • Recommendation: Add more robust logging or raise exceptions for critical data conversion failures.
    • Status: 🟡 Needs review
  3. Issue / Risk: get_model_details and get_dataset_details use multiple fallbacks for description extraction.

    • Impact: Risk of inconsistent or incomplete description display.
    • Recommendation: Simplify description extraction logic to prioritize one reliable source.
    • Status: 🟡 Needs review
  4. Issue / Risk: get_hub_url method assumes repo_type is always 'model' or 'dataset'.

    • Impact: Could break if new repo types are added without updating this method.
    • Recommendation: Add validation or use a more robust URL generation approach.
    • Status: 🔴 Problem

Language/Framework Checks

  • Python:
    • ✅ Proper use of dataclass for HFSearchResult
    • ✅ Type hints and validation in service methods
    • ✅ Logging with appropriate levels
    • huggingface_hub library usage is correct
    • � Exception handling follows standard Python practices

Security & Privacy

  • No sensitive data handling or authentication logic introduced.
  • API calls use standard HuggingFace library without custom auth tokens.
  • No secrets or credentials exposed in code.

Build/CI & Ops

  • No build or deployment changes.
  • All new code is properly typed and integrated into existing service structure.

Tests

  • No test files included in diff.
  • Recommendation: Add unit tests for HuggingFaceService methods and HFSearchDialog component behavior.

Approval Recommendation

Approve with caveats

  • Verify direction parameter behavior with HuggingFace API
  • Review description extraction logic in detail
  • Confirm get_hub_url method handles all repo types correctly
  • Add unit tests for new service and component logic

@j4ys0n
j4ys0n merged commit 5117dbf into main Nov 4, 2025
1 check passed
@j4ys0n
j4ys0n deleted the claude/huggingface-model-dataset-search-011CUnTZx7SpDWLBg1YkphMT branch November 4, 2025 16:44
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.

3 participants