Skip to content

Conversation

JadeCara
Copy link
Contributor

@JadeCara JadeCara commented Jul 25, 2025

Issue ENG-871

Description Of Changes

Due to some speed required to get Manual Tasks up and running some comments on PRs did not have time to be addressed. This PR addresses this one: #6261 (comment) regarding circular imports.

Code Changes

  • Created a new module for ManualTaskAddress to remove circular dependency issues.
  • Cleaned up some tests.
  • Reduced some nesting by leaning on unique connection_config/manual_task inherent structure.

Steps to Confirm

There are no intended changes to functionality. The tests should all pass. For additional functional testing:

  1. Run with FidesPlus
  2. Create 1 or more ManualTask integrations with access and or erasure tasks
  3. Create 1 or more Privacy requests - verify you can complete/skip etc and that they all complete as expected.

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

Copy link

vercel bot commented Jul 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
fides-plus-nightly ⬜️ Ignored (Inspect) Visit Preview Jul 28, 2025 4:36pm
fides-privacy-center ⬜️ Ignored (Inspect) Jul 28, 2025 4:36pm

@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Optional
from typing import Any, Optional
Copy link
Contributor Author

Choose a reason for hiding this comment

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

My crusade to replace List, Dict with the built ins to reduce imports continues 😂

@@ -111,67 +110,65 @@ def access_request(self, *inputs: List[Row]) -> List[Row]:
def _ensure_manual_task_instances(
self,
db: Session,
manual_tasks: List[ManualTask],
manual_task: ManualTask,
privacy_request: PrivacyRequest,
allowed_config_type: "ManualTaskConfigurationType",
) -> None:
"""Create ManualTaskInstances for configs matching `allowed_config_type` if they don't exist."""

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Able to un-nest this function because we are only looking at one ManualTask at a time.

@@ -182,79 +179,74 @@ def _format_size(size_bytes: int) -> str:
size /= 1024.0
return f"{size:.1f} PB"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Able to un-nest this function because we are only looking at one ManualTask at a time.


# TYPE_CHECKING import placed after all runtime imports to avoid lint issues
if TYPE_CHECKING: # pragma: no cover
from fides.api.graph.traversal import TraversalNode # noqa: F401
from fides.api.models.policy import Policy # noqa: F401


class ManualTaskAddress:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to it separate module to remove circular imports

@@ -98,26 +56,20 @@ def get_manual_task_addresses(db: Session) -> List[CollectionAddress]:
return manual_task_addresses


def get_manual_tasks_for_connection_config(
def get_manual_task_for_connection_config(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

connection_config and manual_task have a 1:1 unique relationship so we will always be getting just one ManualTask from this query. Updated naming and usage across files.

Copy link
Contributor

Choose a reason for hiding this comment

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

just a question, do we enforce uniqueness at the DB level, or just at the application level ? If we do it at the app level can we maybe add a warning if we find more than one?

also I think we might want to use something like one_or_none in the query rather than first -- this makes it super clear that we only ever expect a single result there and it will actually error if it finds more

Copy link
Contributor Author

@JadeCara JadeCara Jul 28, 2025

Choose a reason for hiding this comment

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

It is explicitly defined on both the model and the migration :)

updated to use one_or_none!

@@ -130,24 +82,23 @@ def create_manual_data_traversal_node(
connection_key = address.dataset

# Get manual tasks for this connection to determine fields
manual_tasks = get_manual_tasks_for_connection_config(db, connection_key)
manual_task = get_manual_task_for_connection_config(db, connection_key)

# Create fields based on ManualTaskConfigFields
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Able to un-nest here as well.

Comment on lines -168 to -170
# Create Node and TraversalNode (import locally to avoid cyclic import)
from fides.api.graph.traversal import TraversalNode # local import

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🎉


# Manual task collections act as root nodes - they don't need identity dependencies
# since they provide manually-entered data rather than consuming identity data.
for manual_task in manual_tasks:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Able to un-nest this as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the various task tests for Manual Tasks into the same dir and consolidated the fixtures to this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file was also moved, but due to some removal of outdated tests and other changes it is a big enough change to look like a whole new file.

Copy link

codecov bot commented Jul 25, 2025

Codecov Report

❌ Patch coverage is 76.28866% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.98%. Comparing base (018ab1d) to head (1501c2f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...rc/fides/api/task/manual/manual_task_graph_task.py 57.77% 12 Missing and 7 partials ⚠️
src/fides/api/task/manual/manual_task_address.py 91.66% 1 Missing and 1 partial ⚠️
src/fides/api/task/manual/manual_task_utils.py 91.66% 1 Missing and 1 partial ⚠️

❌ Your patch status has failed because the patch coverage (76.28%) is below the target coverage (100.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6383      +/-   ##
==========================================
+ Coverage   86.80%   86.98%   +0.18%     
==========================================
  Files         453      454       +1     
  Lines       28907    28909       +2     
  Branches     3215     3211       -4     
==========================================
+ Hits        25092    25146      +54     
+ Misses       3095     3046      -49     
+ Partials      720      717       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JadeCara JadeCara changed the title addresses circular import and cleans up some tests [ENG-871] Addresses circular import and cleans up some tests Jul 25, 2025
Copy link
Contributor

@erosselli erosselli left a comment

Choose a reason for hiding this comment

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

Thanks for all the cleanup, this was such a nice PR to review 😌 Remember to add the changelog entry; also I left a suggestion in a comment.

Haven't tested manually but since this is just a refactor and tests are still passing I think that's probably ok?

@@ -98,26 +56,20 @@ def get_manual_task_addresses(db: Session) -> List[CollectionAddress]:
return manual_task_addresses


def get_manual_tasks_for_connection_config(
def get_manual_task_for_connection_config(
Copy link
Contributor

Choose a reason for hiding this comment

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

just a question, do we enforce uniqueness at the DB level, or just at the application level ? If we do it at the app level can we maybe add a warning if we find more than one?

also I think we might want to use something like one_or_none in the query rather than first -- this makes it super clear that we only ever expect a single result there and it will actually error if it finds more

),
],
)
def test_artificial_graphs_filter_by_policy_type(
@pytest.mark.usefixtures("manual_setup")
def test_artificial_graphs_include_all_fields(
Copy link
Contributor

Choose a reason for hiding this comment

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

did we change what we're testing here? or is the git diff just showing up annoyigly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is actually a change. I am not sure why this test was even passing before. The Graph should create initially with all potential nodes. When the traversal runs and the graph executes is where the filtering actually occurs. I updated this test to follow the correct behavior.

@JadeCara
Copy link
Contributor Author

Haven't tested manually but since this is just a refactor and tests are still passing I think that's probably ok?

I have been heavily manually testing. I will run through it one more time before merging :)

@JadeCara JadeCara merged commit fcb49b2 into main Jul 28, 2025
40 of 41 checks passed
@JadeCara JadeCara deleted the ENG-871-manual-task-dsr-follow-up-circular-imports branch July 28, 2025 17:50
Copy link

cypress bot commented Jul 28, 2025

fides    Run #13167

Run Properties:  status check passed Passed #13167  •  git commit fcb49b2eaa: [ENG-871] Addresses circular import and cleans up some tests (#6383)
Project fides
Branch Review main
Run status status check passed Passed #13167
Run duration 00m 53s
Commit git commit fcb49b2eaa: [ENG-871] Addresses circular import and cleans up some tests (#6383)
Committer JadeWibbels
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 5
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.
View all changes introduced in this branch ↗︎

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