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

Fix exporting projects with honeypots #8597

Merged
merged 10 commits into from
Oct 31, 2024

Conversation

Marishka17
Copy link
Contributor

@Marishka17 Marishka17 commented Oct 25, 2024

Motivation and context

PR fixes an issue with exporting project datasets: task honeypots are no longer exported

How has this been tested?

Checklist

  • I submit my changes into the develop branch
  • I have created a changelog fragment
    - [ ] I have updated the documentation accordingly
  • I have added tests to cover my changes
  • I have linked related issues (see GitHub docs)
    - [ ] I have increased versions of npm packages if it is necessary
    (cvat-canvas,
    cvat-core,
    cvat-data and
    cvat-ui)

License

  • I submit my code changes under the same MIT License that covers the project.
    Feel free to contact the maintainers if that's a concern.

Summary by CodeRabbit

  • New Features

    • Enhanced frame management and data initialization for improved efficiency.
    • Streamlined media file handling during export processes.
  • Bug Fixes

    • Refined frame filtering logic to ensure only valid frames are processed.
  • Documentation

    • Updated method signatures for clarity and simplicity.

@Marishka17
Copy link
Contributor Author

/check

Copy link
Contributor

coderabbitai bot commented Oct 25, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes in this pull request involve enhancements to the cvat/apps/dataset_manager/bindings.py and cvat/apps/dataset_manager/formats/cvat.py files. In bindings.py, modifications improve frame management and task data initialization, including the addition of a new attribute in the CommonData class and updates to methods in the ProjectData class. In cvat.py, the dump_media_files function is simplified by removing the project_data parameter, streamlining media file handling during exports.

Changes

File Path Change Summary
cvat/apps/dataset_manager/bindings.py - Added variable _initialized_included_frames: Optional[Set[int]] in CommonData.
- Updated method get_included_frames signature.
- Updated group_by_frame method signature and logic in ProjectData.
- Added method init_task_data in ProjectData.
cvat/apps/dataset_manager/formats/cvat.py - Updated dump_media_files method signature to remove project_data parameter and adjusted logic accordingly. Updated calls to dump_media_files in _export_task_or_job and _export_project.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CommonData
    participant ProjectData
    participant CvatExtractor

    User->>CommonData: Request included frames
    CommonData->>CommonData: Check _initialized_included_frames
    alt Not initialized
        CommonData->>CommonData: Calculate included frames
        CommonData->>CommonData: Set _initialized_included_frames
    end
    CommonData->>User: Return included frames

    User->>CvatExtractor: Export media files
    CvatExtractor->>CommonData: Dump media files
    CommonData->>CvatExtractor: Return media files
Loading

🐇 "In the dataset's dance, frames now glide,
With tasks and media, side by side.
No more clutter, just clear paths,
A hop, a skip, in data's baths.
So let us cheer, for changes bright,
In code we trust, our future's light!" 🐇


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 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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

github-actions bot commented Oct 25, 2024

❌ Some checks failed
📄 See logs here

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 and nitpick comments (2)
cvat/apps/dataset_manager/formats/cvat.py (1)

Line range hint 1373-1389: Consider using a public API for excluded frames.

The function now correctly handles honeypots by excluding them from export, which is good for security. However, it uses the protected member _excluded_frames. Consider:

  1. Making this attribute public if it's part of the stable API
  2. Adding a public method to check if a frame should be excluded

Also, the comment could be more descriptive:

-        # exclude deleted frames and honeypots
+        # Skip deleted frames and honeypot frames (frames used for quality control)
cvat/apps/dataset_manager/bindings.py (1)

1118-1121: Improve readability by avoiding backslashes for line continuation

Consider using parentheses to wrap the expression instead of using a backslash for line continuation. This enhances readability and adheres to PEP 8 guidelines.

Apply this diff to improve the code:

- "path": mangle_image_name(db_image.path, defaulted_subset, original_names) \
-     if not db_image.is_placeholder else db_image.path,
+ "path": (
+     mangle_image_name(db_image.path, defaulted_subset, original_names)
+     if not db_image.is_placeholder else db_image.path
+ ),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8b8140e and c236751.

📒 Files selected for processing (2)
  • cvat/apps/dataset_manager/bindings.py (5 hunks)
  • cvat/apps/dataset_manager/formats/cvat.py (3 hunks)
🔇 Additional comments (4)
cvat/apps/dataset_manager/formats/cvat.py (2)

1416-1416: LGTM!

The call to dump_media_files has been correctly updated to match the new function signature, maintaining proper handling of project data export with subsets.


Line range hint 1373-1416: Verify all call sites are updated.

Let's verify that all calls to dump_media_files have been updated and that the frame filtering logic is consistent.

✅ Verification successful

Based on the search results, I can now generate the final response:

Frame filtering logic is consistent across the codebase

The verification shows that:

  • All calls to dump_media_files are within the same file and use the correct instance_data parameter
  • The _excluded_frames handling is consistently implemented:
    • Initialized and managed in bindings.py
    • Used correctly for frame filtering in cvat.py
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining calls to dump_media_files with project_data
# and verify frame filtering consistency

# Test 1: Search for calls to dump_media_files
echo "Checking dump_media_files calls..."
rg -p "dump_media_files\(" --type py

# Test 2: Search for other uses of _excluded_frames to ensure consistent frame filtering
echo "Checking frame filtering consistency..."
rg "_excluded_frames" --type py

Length of output: 1092

cvat/apps/dataset_manager/bindings.py (2)

288-288: Efficient caching with _initialized_included_frames

The introduction of _initialized_included_frames to cache the included frames improves performance by avoiding redundant computations in get_included_frames.


540-547: Ensure cache validity in get_included_frames

While caching included frames enhances performance, ensure that _initialized_included_frames remains valid if the frame data changes after initialization. If frames can be modified after the cache is set, consider implementing a mechanism to invalidate or update the cache accordingly.

Comment on lines 1280 to 1295
for task_id, frame in sorted(self._frame_info):
if not self._tasks_data.get(task_id):
self.init_task_data(task_id)

task_included_frames = self._tasks_data[task_id].get_included_frames()
if (task_id, frame) not in self._deleted_frames and frame in task_included_frames:
get_frame(task_id, frame)

for t_data in self.task_data:
task: Task = t_data.db_instance

for task in self._db_tasks.values():
anno_manager = AnnotationManager(
self._annotation_irs[task.id], dimension=self._annotation_irs[task.id].dimension
)
task_included_frames = t_data.get_included_frames()

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

Refactor to avoid redundant task data initialization

The loop starting at line 1281 initializes task_data for each task_id if not already done. However, the subsequent loop starting at line 1289 iterates over self.task_data, which also initializes task_data when necessary. Consider refactoring to eliminate the redundancy and improve efficiency.

Comment on lines +1388 to +1407

def init_task_data(self, task_id: int) -> TaskData:
try:
task = self._db_tasks[task_id]
except KeyError as ex:
raise Exception("There is no such task in the project") from ex

task_data = TaskData(
annotation_ir=self._annotation_irs[task_id],
db_task=task,
host=self._host,
create_callback=self._task_annotations[task_id].create \
if self._task_annotations is not None else None,
)
task_data._MAX_ANNO_SIZE //= len(self._db_tasks)
task_data.soft_attribute_import = self.soft_attribute_import
self._tasks_data[task_id] = task_data

return task_data

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Raise a more specific exception in init_task_data

Instead of raising a generic Exception when a task is not found, consider raising a more specific exception like KeyError or creating a custom exception. This improves error handling and clarity.

Handle potential division by zero in _MAX_ANNO_SIZE calculation

In line 1402, ensure that len(self._db_tasks) is not zero before performing integer division to prevent a possible ZeroDivisionError.

Apply this diff to handle the potential error:

+ if len(self._db_tasks) == 0:
+     raise ValueError("No tasks available to initialize task data.")
  task_data._MAX_ANNO_SIZE //= len(self._db_tasks)

Committable suggestion was skipped due to low confidence.

@Marishka17 Marishka17 force-pushed the mk/do_not_export_honeypots_when_exporting_project branch from c236751 to 602e6cd Compare October 25, 2024 20:26
@codecov-commenter
Copy link

codecov-commenter commented Oct 25, 2024

Codecov Report

Attention: Patch coverage is 93.75000% with 2 lines in your changes missing coverage. Please review.

Project coverage is 74.25%. Comparing base (16d4d75) to head (add0cab).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8597      +/-   ##
===========================================
- Coverage    74.29%   74.25%   -0.04%     
===========================================
  Files          401      401              
  Lines        43379    43395      +16     
  Branches      3945     3945              
===========================================
- Hits         32227    32223       -4     
- Misses       11152    11172      +20     
Components Coverage Δ
cvat-ui 78.56% <ø> (-0.09%) ⬇️
cvat-server 70.56% <93.75%> (+0.01%) ⬆️

@Marishka17 Marishka17 changed the title [Do not merge] Fix exporting projects with honeypots Fix exporting projects with honeypots Oct 29, 2024
@property
def task_data(self):
for task_id, task in self._db_tasks.items():
for task_id, _ in self._db_tasks.items():
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
for task_id, _ in self._db_tasks.items():
for task_id in self._db_tasks:

Or maybe with .keys()

Copy link

sonarcloud bot commented Oct 31, 2024

@Marishka17 Marishka17 merged commit 663fab7 into develop Oct 31, 2024
34 checks passed
@Marishka17 Marishka17 deleted the mk/do_not_export_honeypots_when_exporting_project branch October 31, 2024 13:01
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