Skip to content

Conversation

@jithinAB
Copy link

Summary

  • add a shared helper to normalize hardware dictionaries and populate lowercase keys
  • ensure FastAPI hardware routes format hardware records before serializing responses
  • update the Flask hardware list route to return normalized hardware payloads as well

Testing

  • python -m compileall BudSimulator/apis/routers/hardware.py BudSimulator/src/api/hardware_routes.py BudSimulator/src/utils/hardware_formatting.py

https://chatgpt.com/codex/tasks/task_b_68daf0d798348326822297517c697e2a

@gemini-code-assist
Copy link

Summary of Changes

Hello @jithinAB, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request aims to enhance the robustness and predictability of hardware data across the API by implementing a consistent key normalization strategy. By ensuring all hardware dictionaries returned by both FastAPI and Flask endpoints have standardized lowercase keys, it simplifies data consumption for clients and prevents potential issues arising from varied key casing in source data.

Highlights

  • New Utility Function: A new helper function, normalize_hardware_keys, has been introduced to standardize hardware dictionary keys by ensuring lowercase versions exist for any uppercase counterparts.
  • FastAPI Integration: All FastAPI hardware routes (create, list, filter, get, update) now utilize the normalize_hardware_keys utility to format hardware records consistently before serializing responses.
  • Flask API Integration: The Flask API's hardware list route has been updated to also use the normalize_hardware_keys function, ensuring consistent payload formatting across both API frameworks.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a utility function to normalize keys in hardware data dictionaries, ensuring consistency across API responses from both FastAPI and Flask routes. My review identifies a potential issue in the new normalization logic and an opportunity for refactoring.

Specifically, I've suggested an improvement to normalize_hardware_keys to handle mixed-case keys in addition to uppercase ones, which is crucial for ensuring all data is correctly processed. I've also recommended refactoring duplicated code in the FastAPI routes into a helper function to improve maintainability.

Comment on lines +5 to +22
def normalize_hardware_keys(hardware: Dict[str, Any]) -> Dict[str, Any]:
"""Ensure lowercase hardware keys exist for their uppercase counterparts.
Some hardware records may come from sources that use uppercase keys (e.g.,
``FLOPS`` instead of ``flops``). This helper preserves the original keys
while populating the expected lowercase versions when they are missing so
that API serializers can rely on a consistent shape.
"""
if hardware is None:
return {}

normalized = dict(hardware)
for key, value in hardware.items():
if isinstance(key, str) and key.isupper():
lower_key = key.lower()
if lower_key not in normalized:
normalized[lower_key] = value
return normalized

Choose a reason for hiding this comment

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

high

The current implementation of normalize_hardware_keys only handles fully uppercase keys (e.g., FLOPS) because of key.isupper(). However, other parts of the codebase suggest that keys can also be in PascalCase or mixed case (e.g., Memory_size, Flops). These keys would not be correctly normalized.

To make this utility more robust and handle all non-lowercase keys, I suggest modifying the logic to check if key.lower() != key. This will correctly handle uppercase, PascalCase, and mixed-case keys. I've also updated the docstring to reflect this broader scope.

This change will ensure that all expected keys are normalized, making the API responses more consistent.

Suggested change
def normalize_hardware_keys(hardware: Dict[str, Any]) -> Dict[str, Any]:
"""Ensure lowercase hardware keys exist for their uppercase counterparts.
Some hardware records may come from sources that use uppercase keys (e.g.,
``FLOPS`` instead of ``flops``). This helper preserves the original keys
while populating the expected lowercase versions when they are missing so
that API serializers can rely on a consistent shape.
"""
if hardware is None:
return {}
normalized = dict(hardware)
for key, value in hardware.items():
if isinstance(key, str) and key.isupper():
lower_key = key.lower()
if lower_key not in normalized:
normalized[lower_key] = value
return normalized
def normalize_hardware_keys(hardware: Dict[str, Any]) -> Dict[str, Any]:
"""Ensure lowercase hardware keys exist for their non-lowercase counterparts.
Some hardware records may come from sources that use uppercase or mixed-case
keys (e.g., ``FLOPS`` or ``Memory_size`` instead of ``flops`` or ``memory_size``).
This helper preserves the original keys while populating the expected lowercase
versions when they are missing so that API serializers can rely on a consistent shape.
"""
if hardware is None:
return {}
normalized = dict(hardware)
for key, value in hardware.items():
if isinstance(key, str):
lower_key = key.lower()
if key != lower_key and lower_key not in normalized:
normalized[lower_key] = value
return normalized

Comment on lines 207 to +225
enhanced_results = []
for hw in results:
normalized_hw = normalize_hardware_keys(hw)

# Calculate price indicator if specs are available
flops = hw.get('flops', 0)
memory_size = hw.get('memory_size', 0)
memory_bw = hw.get('memory_bw', 0)
flops = normalized_hw.get('flops', 0)
memory_size = normalized_hw.get('memory_size', 0)
memory_bw = normalized_hw.get('memory_bw', 0)

if flops > 0 and memory_size > 0 and memory_bw > 0:
hw['price_approx'] = BudHardware.calculate_price_indicator(
normalized_hw['price_approx'] = BudHardware.calculate_price_indicator(
flops=flops,
memory_gb=memory_size,
bandwidth_gbs=memory_bw
)
else:
hw['price_approx'] = None
enhanced_results.append(hw)
normalized_hw['price_approx'] = None

enhanced_results.append(normalized_hw)

Choose a reason for hiding this comment

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

medium

There is significant code duplication between this loop in list_hardware and a similar loop in filter_hardware (lines 282-300). To improve maintainability and reduce redundancy, consider extracting this logic into a private helper function.

For example, you could create a function _enhance_hardware_results:

def _enhance_hardware_results(hardware_list: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
    enhanced_results = []
    for hw in hardware_list:
        normalized_hw = normalize_hardware_keys(hw)

        # Calculate price indicator if specs are available
        flops = normalized_hw.get('flops', 0)
        memory_size = normalized_hw.get('memory_size', 0)
        memory_bw = normalized_hw.get('memory_bw', 0)

        if flops > 0 and memory_size > 0 and memory_bw > 0:
            normalized_hw['price_approx'] = BudHardware.calculate_price_indicator(
                flops=flops,
                memory_gb=memory_size,
                bandwidth_gbs=memory_bw
            )
        else:
            normalized_hw['price_approx'] = None

        enhanced_results.append(normalized_hw)
    return enhanced_results

Then, both list_hardware and filter_hardware can be simplified to:

        enhanced_results = _enhance_hardware_results(results)
        return [HardwareResponse(**hw) for hw in enhanced_results]

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants