Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge release/v1.2.0 to develop #5302

Merged
merged 23 commits into from
Dec 20, 2024
Merged

Merge release/v1.2.0 to develop #5302

merged 23 commits into from
Dec 20, 2024

Conversation

voxel51-bot
Copy link
Collaborator

@voxel51-bot voxel51-bot commented Dec 19, 2024

Merge release/v1.2.0 to develop

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced error reporting for unsupported evaluation types with detailed serialized information.
    • Introduced permission-based evaluation actions in the UI, improving user feedback on permissions.
    • Added a new Databricks connector for the Data Lens feature, enabling dynamic field configuration.
  • Bug Fixes

    • Resolved potential StopIteration errors during long-running API operations.
  • Documentation

    • Updated documentation for the Data Lens feature, including a comprehensive guide for the new Databricks integration.
  • Chores

    • Updated dependency version for voxel51-eta.

Copy link
Contributor

coderabbitai bot commented Dec 19, 2024

Walkthrough

The pull request introduces modifications across several components related to model evaluation. Key changes include repositioning the serialized_info = info.serialize() line in the load_evaluation method to enhance error reporting. The Evaluate, Evaluation, and Status components have been updated to improve permission handling and user feedback. Specifically, new properties were added to manage permissions, and rendering logic was adjusted to reflect user capabilities more clearly. Overall, these changes refine error handling and enhance the user experience within the model evaluation panel.

Changes

File Change Summary
fiftyone/operators/builtins/panels/model_evaluation/__init__.py Repositioned serialized_info line and updated error handling for unsupported evaluation types. Updated get_confusion_matrices to use results._confusion_matrix() for detailed output.
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluate.tsx Updated EvaluateProps to include permissions, modified rendering logic for evaluation button based on permissions.
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx Defined NONE_CLASS, updated rendering of editing notes with permission checks, and modified confusion matrix handling to include NONE_CLASS.
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Overview.tsx Added readOnly prop to Status component to indicate read-only mode.
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Status.tsx Updated StatusProps to include readOnly and modified rendering logic based on this property.
app/packages/operators/src/CustomPanel.tsx Added usePanelEvent import and integrated onUnLoad prop for enhanced event handling in CustomPanel.
app/packages/operators/src/useCustomPanelHooks.ts Removed cleanup effect for onUnLoad, updated state change handling, and optimized performance with debounced functions.
docs/source/teams/data_lens.rst Enhanced documentation with new Databricks integration section, updated existing content, and added images for clarity.
docs/source/release-notes.rst Added new release note sections for "FiftyOne Teams 2.3.0" and "FiftyOne 1.2.0" detailing enhancements and bug fixes.
fiftyone/core/utils.py Removed __call__ method from ProgressBar class to simplify control flow.
setup.py Updated voxel51-eta dependency version from >=0.13.0,<0.14 to >=0.13.1,<0.14.

Possibly related PRs

  • various model evaluation fixes and enhancements #5123: This PR introduces various fixes and enhancements to the model evaluation panel, including improved handling of confusion matrices and error reporting.
  • model evaluation bug fixes #5166: This PR addresses bugs in the evaluation component, specifically enhancing the handling of evaluation notes and adding error handling for evaluation data.
  • fix load_evaluation bug with serialized_info #5301: This PR fixes a bug in the load_evaluation method related to the serialized_info, ensuring that error handling is more robust.
  • Release notes #5307: This PR updates the release notes to include significant enhancements and fixes related to model evaluation, including the introduction of new features and improvements in the evaluation panel.

Suggested labels

documentation, enhancement, app

Suggested reviewers

  • findtopher

Poem

🐰 In the land of code where bunnies play,
Serialized info now leads the way.
With permissions clear, the buttons gleam,
Evaluations flow like a sweet dream.
Error messages bright, no more dismay,
In FiftyOne's world, we hop and sway! 🌟

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e53d95 and eee6553.

📒 Files selected for processing (2)
  • fiftyone/core/utils.py (0 hunks)
  • setup.py (1 hunks)
💤 Files with no reviewable changes (1)
  • fiftyone/core/utils.py
🔇 Additional comments (1)
setup.py (1)

79-79: Verify compatibility with updated eta package

The minimum required version of voxel51-eta has been bumped from 0.13.0 to 0.13.1. Please ensure that:

  1. The new version is available in PyPI
  2. There are no breaking changes that could affect FiftyOne
✅ Verification successful

Package version 0.13.1 is available and usage is minimal

The verification shows that:

  1. Version 0.13.1 of voxel51-eta is available on PyPI
  2. The package is only imported in fiftyone/zoo/models/__init__.py for core configuration and learning functionality, which are typically stable APIs

Let's verify if there are any breaking changes by checking the changelog or release notes:


Let's check the changelog for version 0.13.1 to verify if there are any breaking changes:


Package version 0.13.1 is compatible and safe to use

The verification shows that:

  1. Version 0.13.1 is available on PyPI
  2. The eta package is used in a limited scope, primarily for core model functionality through well-defined interfaces
  3. The usage is through stable APIs (eta.core.learning, eta.core.models, eta.core.config) that typically maintain backward compatibility
  4. The minor version bump (0.13.0 to 0.13.1) suggests only bug fixes or minor improvements, not breaking changes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify eta package version and changelog

# Check if the required version exists on PyPI
curl -s https://pypi.org/pypi/voxel51-eta/json | jq '.releases | keys[]' | grep "0.13.1"

# Look for imports of eta to understand usage
echo "Checking eta usage patterns..."
rg "from eta\." -A 2

Length of output: 391


Script:

#!/bin/bash
# Check git repository for changelog or release notes
fd -i changelog
fd -i release

# Check for any potential breaking changes in the core modules we use
rg "ConfigError|core\.learning|core\.models" -A 2

Length of output: 63530


Script:

#!/bin/bash
# Check for changelog in eta repository
curl -s https://raw.githubusercontent.com/voxel51/eta/v0.13.1/CHANGELOG.md || curl -s https://raw.githubusercontent.com/voxel51/eta/main/CHANGELOG.md

# Also check for any potential breaking changes in core functionality we use
rg "ConfigError|core\.learning|core\.models" -C 5 fiftyone/utils/eta.py

Length of output: 2115


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🔭 Outside diff range comments (1)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluate.tsx (1)

Line range hint 25-29: Consider using a more specific permissions type

The current Record<string, boolean> type is too generic. Consider creating a specific type for the permissions:

+type EvaluatePermissions = {
+  can_evaluate: boolean;
+  // Add other known permissions here
+};

 type EvaluateProps = {
   variant: "empty" | "overview";
   onEvaluate: () => void;
-  permissions: Record<string, boolean>;
+  permissions: EvaluatePermissions;
 };

This provides better type safety and auto-completion for permission keys.

🧹 Nitpick comments (6)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (1)

614-633: Improved permission handling and user feedback for evaluation notes.

The changes enhance the UX by:

  1. Visually indicating permission status through cursor styles
  2. Providing clear feedback via tooltip when user lacks permission
  3. Properly disabling the edit button when user lacks permission

Consider extracting this permission-aware button pattern into a reusable component since similar permission-based UI patterns might be needed elsewhere:

+interface PermissionAwareIconButtonProps {
+  canEdit: boolean;
+  onClick: () => void;
+  icon: React.ReactNode;
+  disabledTooltip: string;
+}
+
+const PermissionAwareIconButton: React.FC<PermissionAwareIconButtonProps> = ({
+  canEdit,
+  onClick,
+  icon,
+  disabledTooltip
+}) => (
+  <Box
+    title={canEdit ? "" : disabledTooltip}
+    sx={{ cursor: canEdit ? "pointer" : "not-allowed" }}
+  >
+    <IconButton
+      size="small"
+      color="secondary"
+      sx={{ borderRadius: 16 }}
+      onClick={onClick}
+      disabled={!canEdit}
+    >
+      {icon}
+    </IconButton>
+  </Box>
+);

Then use it like:

-<Box
-  title={can_edit_note ? "" : "You do not have permission to edit evaluation notes"}
-  sx={{ cursor: can_edit_note ? "pointer" : "not-allowed" }}
->
-  <IconButton
-    size="small"
-    color="secondary" 
-    sx={{ borderRadius: 16 }}
-    onClick={() => {
-      setEditNoteState((note) => ({ ...note, open: true }));
-    }}
-    disabled={!can_edit_note}
-  >
-    <EditNote />
-  </IconButton>
-</Box>
+<PermissionAwareIconButton
+  canEdit={can_edit_note}
+  onClick={() => setEditNoteState((note) => ({ ...note, open: true }))}
+  icon={<EditNote />}
+  disabledTooltip="You do not have permission to edit evaluation notes"
+/>
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluate.tsx (2)

7-8: Consider memoizing the permission check

For better performance in cases of frequent parent re-renders, consider using useMemo:

-  const { onEvaluate, permissions } = props;
-  const canEvaluate = permissions.can_evaluate;
+  const { onEvaluate, permissions } = props;
+  const canEvaluate = React.useMemo(
+    () => permissions.can_evaluate,
+    [permissions.can_evaluate]
+  );

10-13: Simplify the title conditional

The empty string title when canEvaluate is true is unnecessary. Consider simplifying:

-      title={canEvaluate ? "" : "You do not have permission to evaluate model"}
+      title={!canEvaluate ? "You do not have permission to evaluate model" : undefined}
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Status.tsx (2)

7-7: Props and conditional rendering look good, consider making readOnly required

The separation between readOnly (view mode) and canEdit (permissions) is well-implemented. The conditional rendering and disabled state handling are clear and provide good user feedback.

Consider making the readOnly prop required since it's used for core rendering logic:

type StatusProps = {
  status?: string;
  canEdit?: boolean;
-  readOnly?: boolean;
+  readOnly: boolean;
  setStatusEvent: string;
};

Also applies to: 10-30


Line range hint 1-89: Consider performance and architecture improvements

While the component is well-structured, consider these improvements:

  1. Memoize the component since it's likely used in lists:
  2. Consider moving color constants to a shared theme file for consistency

Example memoization:

-export default function Status(props: StatusProps) {
+const Status = React.memo(function Status(props: StatusProps) {
   // ... component implementation
-}
+});
+
+export default Status;
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Overview.tsx (1)

100-100: Status component integration looks good, consider performance optimization

The readOnly prop is correctly passed to the Status component. Since this is rendered within a list, consider the following optimization:

  1. Memoize the EvaluationCard component to prevent unnecessary re-renders:
-function EvaluationCard(props: EvaluationCardProps) {
+const EvaluationCard = React.memo(function EvaluationCard(props: EvaluationCardProps) {
   // ... component implementation
-}
+});
  1. Use a callback for the onClick handler to prevent recreation on each render:
-onClick={() => {
-  onSelect(eval_key, id);
-}}
+onClick={React.useCallback(() => {
+  onSelect(eval_key, id);
+}, [eval_key, id, onSelect])}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between add8ff1 and 8d5be1f.

📒 Files selected for processing (4)
  • app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluate.tsx (1 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (1 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Overview.tsx (1 hunks)
  • app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Status.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Overview.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluate.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Status.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (2)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluate.tsx (1)

14-21: LGTM! Button implementation follows best practices

The button implementation correctly handles permissions and provides appropriate visual feedback through the disabled state.

app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Status.tsx (1)

72-73: Type changes improve type safety

Making setStatusEvent required is a good change since it's used unconditionally in the component. The types are well-defined and properly reflect the component's requirements.

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

🧹 Nitpick comments (1)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (1)

1666-1682: Consider improving code readability.

While the logic is correct, the code could be more readable with destructuring and intermediate variables.

Consider this refactor:

-  const originalClasses = matrices[`${sortBy}_classes`];
-  const originalMatrix = matrices[`${sortBy}_matrix`];
-  const classes = originalClasses.slice(0, parsedLimit);
-  const matrix = originalMatrix.slice(0, parsedLimit);
+  const {
+    [`${sortBy}_classes`]: originalClasses,
+    [`${sortBy}_matrix`]: originalMatrix,
+    [`${sortBy}_colorscale`]: colorscale
+  } = matrices;
+
+  const classes = originalClasses.slice(0, parsedLimit);
+  const matrix = originalMatrix.slice(0, parsedLimit);
+
+  const shouldAppendNoneClass = parsedLimit < originalClasses.length;
+  if (shouldAppendNoneClass) {
+    const noneIndex = originalClasses.indexOf(NONE_CLASS);
+    const noneLabel = compareMaskTargets?.[NONE_CLASS] ||
+      maskTargets?.[NONE_CLASS] ||
+      NONE_CLASS;
+
+    labels.push(noneLabel);
+    matrix.push(originalMatrix[noneIndex]);
+  }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d5be1f and 84cbf13.

📒 Files selected for processing (2)
  • app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (4 hunks)
  • fiftyone/operators/builtins/panels/model_evaluation/__init__.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • fiftyone/operators/builtins/panels/model_evaluation/init.py
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (3)
app/packages/core/src/plugins/SchemaIO/components/NativeModelEvaluationView/Evaluation.tsx (3)

54-54: LGTM!

The constant follows TypeScript naming conventions and is appropriately placed with other constants.


615-634: LGTM! Well-implemented permission handling.

The changes improve user experience by:

  • Providing clear visual feedback through cursor styling
  • Adding a helpful tooltip when permission is denied
  • Properly disabling the edit button

1708-1708: LGTM! Good defensive programming.

The addition of the fallback for undefined filter prevents potential runtime errors.

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: 2

🔭 Outside diff range comments (1)
app/packages/operators/src/CustomPanel.tsx (1)

Line range hint 36-43: Add missing dependency to useEffect

The cleanup effect uses props.onUnLoad but doesn't include it in the dependency array. This could lead to stale closures if the callback changes during the component's lifecycle.

Apply this change:

  useEffect(() => {
    setPanelCloseEffect(() => {
      clearUseKeyStores(panelId);
      trackEvent("close_panel", { panel: panelName });
      triggerPanelEvent(panelId, { operator: props.onUnLoad });
    });
-  }, []);
+  }, [panelId, panelName, props.onUnLoad, setPanelCloseEffect, trackEvent, triggerPanelEvent]);
🧰 Tools
🪛 GitHub Check: lint / eslint

[warning] 43-43:
React Hook useEffect has missing dependencies: 'panelId', 'panelName', 'props.onUnLoad', 'setPanelCloseEffect', 'trackEvent', and 'triggerPanelEvent'. Either include them or remove the dependency array

🧹 Nitpick comments (3)
app/packages/operators/src/CustomPanel.tsx (1)

41-41: Add type safety check for onUnLoad callback

Consider adding a type guard before triggering the panel event to ensure type safety and prevent potential runtime errors.

Apply this change:

-      triggerPanelEvent(panelId, { operator: props.onUnLoad });
+      if (typeof props.onUnLoad === 'function') {
+        triggerPanelEvent(panelId, { operator: props.onUnLoad });
+      }
docs/source/teams/data_lens.rst (2)

827-827: Consider making the polling interval configurable.

The hardcoded sleep duration of 2.5 seconds in the polling loop could be made configurable to allow for different Databricks environments and workloads.

-                time.sleep(2.5)
+                # Configure polling interval through operator config or environment
+                polling_interval = float(ctx.secret("DATABRICKS_POLLING_INTERVAL", "2.5"))
+                time.sleep(polling_interval)

746-762: Consider enhancing warehouse selection logic.

The current warehouse selection logic is basic and could be improved to:

  1. Consider warehouse size/type for the workload
  2. Handle cases where all warehouses are busy
  3. Implement retry logic for warehouse startup failures
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 84cbf13 and 65f977e.

📒 Files selected for processing (3)
  • app/packages/operators/src/CustomPanel.tsx (2 hunks)
  • app/packages/operators/src/useCustomPanelHooks.ts (0 hunks)
  • docs/source/teams/data_lens.rst (4 hunks)
💤 Files with no reviewable changes (1)
  • app/packages/operators/src/useCustomPanelHooks.ts
🧰 Additional context used
📓 Path-based instructions (1)
app/packages/operators/src/CustomPanel.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🔇 Additional comments (1)
app/packages/operators/src/CustomPanel.tsx (1)

17-17: LGTM: Import follows React hook conventions

The import statement follows React hook naming conventions and is properly organized with other hook imports.

Comment on lines +819 to +828
while (
statement_response.status.state in
(StatementState.PENDING, StatementState.RUNNING)
):
statement_response = self.client.statement_execution.get_statement(
statement_response.statement_id
)

time.sleep(2.5)

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add retry mechanism for transient failures.

The polling loop should implement a retry mechanism with exponential backoff for transient failures, and handle cases where the statement execution takes longer than expected.

+            retry_count = 0
+            max_retries = 3
+            base_delay = 2.5
             while (
                     statement_response.status.state in
                     (StatementState.PENDING, StatementState.RUNNING)
             ):
-                statement_response = self.client.statement_execution.get_statement(
-                    statement_response.statement_id
-                )
-                time.sleep(2.5)
+                try:
+                    statement_response = self.client.statement_execution.get_statement(
+                        statement_response.statement_id
+                    )
+                    retry_count = 0  # Reset on success
+                    time.sleep(base_delay)
+                except Exception as e:
+                    retry_count += 1
+                    if retry_count > max_retries:
+                        raise
+                    time.sleep(base_delay * (2 ** retry_count))  # Exponential backoff
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
while (
statement_response.status.state in
(StatementState.PENDING, StatementState.RUNNING)
):
statement_response = self.client.statement_execution.get_statement(
statement_response.statement_id
)
time.sleep(2.5)
retry_count = 0
max_retries = 3
base_delay = 2.5
while (
statement_response.status.state in
(StatementState.PENDING, StatementState.RUNNING)
):
try:
statement_response = self.client.statement_execution.get_statement(
statement_response.statement_id
)
retry_count = 0 # Reset on success
time.sleep(base_delay)
except Exception as e:
retry_count += 1
if retry_count > max_retries:
raise
time.sleep(base_delay * (2 ** retry_count)) # Exponential backoff

Comment on lines +1191 to +1198
def _remap_sample_fields(self, sample: dict, request: DataLensSearchRequest):
remappable_fields = ("field_a", "field_b")
for field_name in remappable_fields:
remapped_field_name = request.search_params.get(f"{field_name}_remap")
if remapped_field_name not in (None, ""):
sample[remapped_field_name] = sample[field_name]
del sample[field_name]

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add field validation and security considerations.

The field remapping example should include:

  1. Validation of remapped field names to prevent injection attacks
  2. Warning about potential security implications
  3. Best practices for field name validation
     def _remap_sample_fields(self, sample: dict, request: DataLensSearchRequest):
         remappable_fields = ("field_a", "field_b")
         for field_name in remappable_fields:
             remapped_field_name = request.search_params.get(f"{field_name}_remap")
             if remapped_field_name not in (None, ""):
+                # Validate remapped field name to prevent injection attacks
+                if not self._is_valid_field_name(remapped_field_name):
+                    raise ValueError(f"Invalid field name: {remapped_field_name}")
                 sample[remapped_field_name] = sample[field_name]
                 del sample[field_name]

+    def _is_valid_field_name(self, field_name: str) -> bool:
+        """Validate field name against allowed patterns."""
+        import re
+        return bool(re.match(r'^[a-zA-Z][a-zA-Z0-9_]*$', field_name))

Committable suggestion skipped: line range outside the PR's diff.

@benjaminpkane benjaminpkane merged commit 1a3aa6a into develop Dec 20, 2024
14 checks passed
@benjaminpkane benjaminpkane deleted the merge/release/v1.2.0 branch December 20, 2024 15:03
@coderabbitai coderabbitai bot mentioned this pull request Dec 23, 2024
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.

7 participants