ethyca-fides 2.71.1b0__py2.py3-none-any.whl → 2.71.1rc0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ethyca-fides might be problematic. Click here for more details.
- {ethyca_fides-2.71.1b0.dist-info → ethyca_fides-2.71.1rc0.dist-info}/METADATA +2 -2
- {ethyca_fides-2.71.1b0.dist-info → ethyca_fides-2.71.1rc0.dist-info}/RECORD +165 -151
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/3efe14d4469a_adds_new_experience_configs_for_vendor_.py +79 -0
- fides/api/alembic/migrations/versions/4bfbeff34611_add_polling_status.py +35 -0
- fides/api/alembic/migrations/versions/7db29f9cd77b_create_new_sub_request_table.py +95 -0
- fides/api/alembic/migrations/versions/9caf76161e55_make_user_assigned_data_uses_nullable_.py +64 -0
- fides/api/alembic/migrations/versions/b97e92b038d2_add_digest_execution_model.py +117 -0
- fides/api/alembic/migrations/versions/f108fa05c579_adds_optional_duration_field_to_assets.py +28 -0
- fides/api/api/v1/endpoints/generic_overrides.py +3 -9
- fides/api/common_exceptions.py +4 -0
- fides/api/main.py +2 -2
- fides/api/models/asset.py +14 -1
- fides/api/models/attachment.py +1 -0
- fides/api/models/detection_discovery/core.py +57 -3
- fides/api/models/digest/__init__.py +2 -0
- fides/api/models/digest/digest_config.py +10 -1
- fides/api/models/digest/digest_execution.py +132 -0
- fides/api/models/event_audit.py +8 -0
- fides/api/models/privacy_experience.py +10 -0
- fides/api/models/privacy_notice.py +131 -20
- fides/api/models/privacy_request/request_task.py +98 -1
- fides/api/models/worker_task.py +8 -0
- fides/api/schemas/saas/async_polling_configuration.py +81 -0
- fides/api/schemas/saas/saas_config.py +10 -3
- fides/api/schemas/saas/strategy_configuration.py +0 -12
- fides/api/service/async_dsr/handlers/__init__.py +0 -0
- fides/api/service/async_dsr/handlers/polling_attachment_handler.py +155 -0
- fides/api/service/async_dsr/handlers/polling_request_handler.py +88 -0
- fides/api/service/async_dsr/handlers/polling_response_handler.py +261 -0
- fides/api/service/async_dsr/handlers/polling_sub_request_handler.py +123 -0
- fides/api/service/async_dsr/strategies/__init__.py +0 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy.py +52 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_callback.py +199 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_factory.py +72 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +678 -0
- fides/api/service/async_dsr/utils.py +130 -0
- fides/api/service/connectors/fides/fides_client.py +63 -1
- fides/api/service/connectors/query_configs/saas_query_config.py +4 -5
- fides/api/service/connectors/saas_connector.py +77 -69
- fides/api/service/privacy_request/attachment_handling.py +9 -2
- fides/api/service/privacy_request/request_runner_service.py +9 -83
- fides/api/service/privacy_request/request_service.py +47 -74
- fides/api/service/saas_request/saas_request_override_factory.py +66 -1
- fides/api/task/execute_request_tasks.py +5 -2
- fides/api/task/filter_results.py +35 -2
- fides/api/task/graph_task.py +34 -2
- fides/config/execution_settings.py +7 -3
- fides/service/dataset/dataset_service.py +0 -39
- fides/service/privacy_request/privacy_request_service.py +48 -103
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/155-c1ae010c664e2245.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1817-1ad037b7d6d2f6d2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3585-f728d32fda6f1ac1.js → 3585-efd5d41f08e180c4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/5279-12c9cbdc67ad7b14.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6277-182efc294d413f64.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7079-bbc7b856802a4834.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-75e99306393938e8.js → manual-4ec03eed67572861.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-fd41ffaff543e05a.js → [id]-e1e2fd704ac2d71d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-e74cb5ea87f15b40.js → new-a5e738a234dadc7e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-9c23fbe813c997d0.js → [id]-5fc78b78a51c239c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-0e5e38bbcfe59fd2.js → new-b79bcb93b5f4c734.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-29c1fb777bd464e0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-153eb88ab4e7dc6d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-f682b1def859931e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-febf156d2977f3ac.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-4d658222ec800511.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-547c6ef0ad52b85d.js → [id]-4d470bbf199a2f9c.js} +1 -1
- fides/ui-build/static/admin/_next/static/css/f38242c11f7fea64.css +1 -0
- fides/ui-build/static/admin/_next/static/vSOB67a-1uIVzRUKBYMSo/_buildManifest.js +1 -0
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/lib/fides-headless.js +1 -1
- fides/ui-build/static/admin/lib/fides-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
- fides/ui-build/static/admin/lib/fides.js +3 -3
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/messaging/[id].html +1 -1
- fides/ui-build/static/admin/messaging/add-template.html +1 -1
- fides/ui-build/static/admin/messaging.html +1 -1
- fides/ui-build/static/admin/poc/ant-components.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
- fides/ui-build/static/admin/poc/forms.html +1 -1
- fides/ui-build/static/admin/poc/table-migration.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/settings/about/alpha.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/new.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/messaging-providers/[key].html +1 -1
- fides/ui-build/static/admin/settings/messaging-providers/new.html +1 -1
- fides/ui-build/static/admin/settings/messaging-providers.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/api/service/async_dsr/async_dsr_service.py +0 -195
- fides/api/service/async_dsr/async_dsr_strategy.py +0 -5
- fides/api/service/async_dsr/async_dsr_strategy_callback.py +0 -16
- fides/api/service/async_dsr/async_dsr_strategy_factory.py +0 -63
- fides/api/service/async_dsr/async_dsr_strategy_polling.py +0 -94
- fides/ui-build/static/admin/_next/static/IPOgh7BMBX7b_r8-scpgv/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/155-047c3806cc41295e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-ca6473f31a67a804.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3700-08e0703b1ef770da.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6084-d0943ee628bf4388.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6416-0ccadfefcdad00cc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2e1e2b7808d3b21f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-01e025f878ba806c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-14120a529d7dac27.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-7dac2302f573f5ee.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-e5d781b28f8e29c8.js +0 -1
- fides/ui-build/static/admin/_next/static/css/073713cd1eddda79.css +0 -1
- {ethyca_fides-2.71.1b0.dist-info → ethyca_fides-2.71.1rc0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.71.1b0.dist-info → ethyca_fides-2.71.1rc0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.71.1b0.dist-info → ethyca_fides-2.71.1rc0.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.71.1b0.dist-info → ethyca_fides-2.71.1rc0.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{_app-a77584f9ad3334af.js → _app-a7c02dd2ff07f9e1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{IPOgh7BMBX7b_r8-scpgv → vSOB67a-1uIVzRUKBYMSo}/_ssgManifest.js +0 -0
fides/_version.py
CHANGED
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-10-03T10:03:48-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.71.
|
|
14
|
+
"full-revisionid": "43bcd93b9c3859ad4a79f3825f1ebc789a58caf3",
|
|
15
|
+
"version": "2.71.1rc0"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""adds new experience configs for vendor asset disclosure
|
|
2
|
+
|
|
3
|
+
Revision ID: 3efe14d4469a
|
|
4
|
+
Revises: f108fa05c579
|
|
5
|
+
Create Date: 2025-09-09 11:19:24.060587
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "3efe14d4469a"
|
|
15
|
+
down_revision = "f108fa05c579"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.add_column(
|
|
23
|
+
"experienceconfigtemplate",
|
|
24
|
+
sa.Column(
|
|
25
|
+
"asset_disclosure_include_types",
|
|
26
|
+
postgresql.ARRAY(sa.String()),
|
|
27
|
+
nullable=True,
|
|
28
|
+
),
|
|
29
|
+
)
|
|
30
|
+
op.add_column(
|
|
31
|
+
"experienceconfigtemplate",
|
|
32
|
+
sa.Column(
|
|
33
|
+
"allow_vendor_asset_disclosure",
|
|
34
|
+
sa.Boolean(),
|
|
35
|
+
server_default="f",
|
|
36
|
+
nullable=False,
|
|
37
|
+
),
|
|
38
|
+
)
|
|
39
|
+
op.add_column(
|
|
40
|
+
"privacyexperienceconfig",
|
|
41
|
+
sa.Column(
|
|
42
|
+
"asset_disclosure_include_types",
|
|
43
|
+
postgresql.ARRAY(sa.String()),
|
|
44
|
+
nullable=True,
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
op.add_column(
|
|
48
|
+
"privacyexperienceconfig",
|
|
49
|
+
sa.Column(
|
|
50
|
+
"allow_vendor_asset_disclosure",
|
|
51
|
+
sa.Boolean(),
|
|
52
|
+
server_default="f",
|
|
53
|
+
nullable=False,
|
|
54
|
+
),
|
|
55
|
+
)
|
|
56
|
+
op.add_column(
|
|
57
|
+
"privacyexperienceconfighistory",
|
|
58
|
+
sa.Column("allow_vendor_asset_disclosure", sa.Boolean(), nullable=True),
|
|
59
|
+
)
|
|
60
|
+
op.add_column(
|
|
61
|
+
"privacyexperienceconfighistory",
|
|
62
|
+
sa.Column(
|
|
63
|
+
"asset_disclosure_include_types",
|
|
64
|
+
postgresql.ARRAY(sa.String()),
|
|
65
|
+
nullable=True,
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
# ### end Alembic commands ###
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def downgrade():
|
|
72
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
73
|
+
op.drop_column("privacyexperienceconfighistory", "asset_disclosure_include_types")
|
|
74
|
+
op.drop_column("privacyexperienceconfighistory", "allow_vendor_asset_disclosure")
|
|
75
|
+
op.drop_column("privacyexperienceconfig", "allow_vendor_asset_disclosure")
|
|
76
|
+
op.drop_column("privacyexperienceconfig", "asset_disclosure_include_types")
|
|
77
|
+
op.drop_column("experienceconfigtemplate", "allow_vendor_asset_disclosure")
|
|
78
|
+
op.drop_column("experienceconfigtemplate", "asset_disclosure_include_types")
|
|
79
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""add polling status
|
|
2
|
+
|
|
3
|
+
Revision ID: 4bfbeff34611
|
|
4
|
+
Revises: 7db29f9cd77b
|
|
5
|
+
Create Date: 2025-09-20 23:02:45.550170
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
|
|
12
|
+
# revision identifiers, used by Alembic.
|
|
13
|
+
revision = "4bfbeff34611"
|
|
14
|
+
down_revision = "7db29f9cd77b"
|
|
15
|
+
branch_labels = None
|
|
16
|
+
depends_on = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def upgrade():
|
|
20
|
+
# Check if value already exists
|
|
21
|
+
connection = op.get_bind()
|
|
22
|
+
result = connection.execute(
|
|
23
|
+
sa.text(
|
|
24
|
+
"SELECT 1 FROM pg_enum WHERE enumlabel = 'polling' "
|
|
25
|
+
"AND enumtypid = (SELECT oid FROM pg_type WHERE typname = 'executionlogstatus')"
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if not result.fetchone():
|
|
30
|
+
op.execute("ALTER TYPE executionlogstatus ADD VALUE 'polling'")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def downgrade():
|
|
34
|
+
# The 'polling' value will remain in the enum but won't be used by older app versions
|
|
35
|
+
pass
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Create new Sub Request Table
|
|
2
|
+
|
|
3
|
+
Revision ID: 7db29f9cd77b
|
|
4
|
+
Revises: b97e92b038d2
|
|
5
|
+
Create Date: 2025-09-16 14:00:16.282996
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy_utils.types.encrypted.encrypted_type import (
|
|
12
|
+
AesGcmEngine,
|
|
13
|
+
StringEncryptedType,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from fides.api.db.base_class import JSONTypeOverride
|
|
17
|
+
from fides.config import CONFIG
|
|
18
|
+
|
|
19
|
+
# revision identifiers, used by Alembic.
|
|
20
|
+
revision = "7db29f9cd77b"
|
|
21
|
+
down_revision = "b97e92b038d2"
|
|
22
|
+
branch_labels = None
|
|
23
|
+
depends_on = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def upgrade():
|
|
27
|
+
op.create_table(
|
|
28
|
+
"request_task_sub_request",
|
|
29
|
+
sa.Column("id", sa.String(length=255), nullable=False),
|
|
30
|
+
sa.Column(
|
|
31
|
+
"created_at",
|
|
32
|
+
sa.DateTime(timezone=True),
|
|
33
|
+
server_default=sa.text("now()"),
|
|
34
|
+
nullable=True,
|
|
35
|
+
),
|
|
36
|
+
sa.Column(
|
|
37
|
+
"updated_at",
|
|
38
|
+
sa.DateTime(timezone=True),
|
|
39
|
+
server_default=sa.text("now()"),
|
|
40
|
+
nullable=True,
|
|
41
|
+
),
|
|
42
|
+
sa.Column("request_task_id", sa.String(length=255), nullable=False),
|
|
43
|
+
sa.Column(
|
|
44
|
+
"param_values",
|
|
45
|
+
StringEncryptedType(
|
|
46
|
+
type_in=JSONTypeOverride,
|
|
47
|
+
key=CONFIG.security.app_encryption_key,
|
|
48
|
+
engine=AesGcmEngine,
|
|
49
|
+
padding="pkcs5",
|
|
50
|
+
),
|
|
51
|
+
nullable=False,
|
|
52
|
+
),
|
|
53
|
+
sa.Column("status", sa.String(), nullable=False),
|
|
54
|
+
sa.Column(
|
|
55
|
+
"access_data",
|
|
56
|
+
StringEncryptedType(
|
|
57
|
+
type_in=JSONTypeOverride,
|
|
58
|
+
key=CONFIG.security.app_encryption_key,
|
|
59
|
+
engine=AesGcmEngine,
|
|
60
|
+
padding="pkcs5",
|
|
61
|
+
),
|
|
62
|
+
nullable=True,
|
|
63
|
+
),
|
|
64
|
+
sa.Column("rows_masked", sa.Integer(), nullable=True),
|
|
65
|
+
sa.ForeignKeyConstraint(
|
|
66
|
+
["request_task_id"],
|
|
67
|
+
["requesttask.id"],
|
|
68
|
+
name="request_task_sub_request_request_task_id_fkey",
|
|
69
|
+
ondelete="CASCADE",
|
|
70
|
+
),
|
|
71
|
+
sa.PrimaryKeyConstraint("id"),
|
|
72
|
+
)
|
|
73
|
+
op.create_index(
|
|
74
|
+
op.f("ix_request_task_sub_request_id"),
|
|
75
|
+
"request_task_sub_request",
|
|
76
|
+
["id"],
|
|
77
|
+
unique=False,
|
|
78
|
+
)
|
|
79
|
+
op.create_index(
|
|
80
|
+
op.f("ix_request_task_sub_request_request_task_id"),
|
|
81
|
+
"request_task_sub_request",
|
|
82
|
+
["request_task_id"],
|
|
83
|
+
unique=False,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def downgrade():
|
|
88
|
+
op.drop_index(
|
|
89
|
+
op.f("ix_request_task_sub_request_request_task_id"),
|
|
90
|
+
table_name="request_task_sub_request",
|
|
91
|
+
)
|
|
92
|
+
op.drop_index(
|
|
93
|
+
op.f("ix_request_task_sub_request_id"), table_name="request_task_sub_request"
|
|
94
|
+
)
|
|
95
|
+
op.drop_table("request_task_sub_request")
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Update user_assigned_data_uses so it's nullable and defaults to none
|
|
2
|
+
|
|
3
|
+
Revision ID: 9caf76161e55
|
|
4
|
+
Revises: 918aefc950c9
|
|
5
|
+
Create Date: 2025-09-29 14:14:37.837616
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "9caf76161e55"
|
|
15
|
+
down_revision = "918aefc950c9"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.alter_column(
|
|
23
|
+
"stagedresource",
|
|
24
|
+
"user_assigned_data_uses",
|
|
25
|
+
existing_type=postgresql.ARRAY(sa.VARCHAR()),
|
|
26
|
+
nullable=True,
|
|
27
|
+
server_default=None,
|
|
28
|
+
default=None,
|
|
29
|
+
existing_server_default=sa.text("'{}'::character varying[]"),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Update web monitor resources with empty array to null
|
|
33
|
+
op.execute(
|
|
34
|
+
"""
|
|
35
|
+
UPDATE stagedresource
|
|
36
|
+
SET user_assigned_data_uses = NULL
|
|
37
|
+
WHERE
|
|
38
|
+
resource_type IN ('Cookie', 'Browser request', 'Image', 'iFrame', 'Javascript tag')
|
|
39
|
+
AND user_assigned_data_uses = '{}'
|
|
40
|
+
"""
|
|
41
|
+
)
|
|
42
|
+
# ### end Alembic commands ###
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def downgrade():
|
|
46
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
47
|
+
op.execute(
|
|
48
|
+
"""
|
|
49
|
+
UPDATE stagedresource
|
|
50
|
+
SET user_assigned_data_uses = '{}'
|
|
51
|
+
WHERE user_assigned_data_uses IS NULL
|
|
52
|
+
"""
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
op.alter_column(
|
|
56
|
+
"stagedresource",
|
|
57
|
+
"user_assigned_data_uses",
|
|
58
|
+
existing_type=postgresql.ARRAY(sa.VARCHAR()),
|
|
59
|
+
nullable=False,
|
|
60
|
+
server_default=sa.text("'{}'::character varying[]"),
|
|
61
|
+
existing_server_default=None,
|
|
62
|
+
default=dict,
|
|
63
|
+
)
|
|
64
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""add digest execution model
|
|
2
|
+
|
|
3
|
+
Revision ID: b97e92b038d2
|
|
4
|
+
Revises: 3efe14d4469a
|
|
5
|
+
Create Date: 2025-10-01 16:42:41.900651
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "b97e92b038d2"
|
|
15
|
+
down_revision = "3efe14d4469a"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.create_table(
|
|
23
|
+
"digest_task_execution",
|
|
24
|
+
sa.Column("id", sa.String(length=255), nullable=False),
|
|
25
|
+
sa.Column(
|
|
26
|
+
"created_at",
|
|
27
|
+
sa.DateTime(timezone=True),
|
|
28
|
+
server_default=sa.text("now()"),
|
|
29
|
+
nullable=True,
|
|
30
|
+
),
|
|
31
|
+
sa.Column(
|
|
32
|
+
"updated_at",
|
|
33
|
+
sa.DateTime(timezone=True),
|
|
34
|
+
server_default=sa.text("now()"),
|
|
35
|
+
nullable=True,
|
|
36
|
+
),
|
|
37
|
+
sa.Column("action_type", sa.String(), nullable=False),
|
|
38
|
+
sa.Column("digest_config_id", sa.String(), nullable=False),
|
|
39
|
+
sa.Column("celery_task_id", sa.String(), nullable=True),
|
|
40
|
+
sa.Column(
|
|
41
|
+
"status",
|
|
42
|
+
postgresql.ENUM(name="executionlogstatus", create_type=False),
|
|
43
|
+
nullable=False,
|
|
44
|
+
),
|
|
45
|
+
sa.Column("total_recipients", sa.Integer(), nullable=True),
|
|
46
|
+
sa.Column("processed_recipients", sa.Integer(), nullable=False),
|
|
47
|
+
sa.Column("successful_communications", sa.Integer(), nullable=False),
|
|
48
|
+
sa.Column("failed_communications", sa.Integer(), nullable=False),
|
|
49
|
+
sa.Column(
|
|
50
|
+
"execution_state", postgresql.JSONB(astext_type=sa.Text()), nullable=True
|
|
51
|
+
),
|
|
52
|
+
sa.Column(
|
|
53
|
+
"processed_user_ids", postgresql.JSONB(astext_type=sa.Text()), nullable=True
|
|
54
|
+
),
|
|
55
|
+
sa.Column("started_at", sa.DateTime(timezone=True), nullable=True),
|
|
56
|
+
sa.Column("completed_at", sa.DateTime(timezone=True), nullable=True),
|
|
57
|
+
sa.Column("last_checkpoint_at", sa.DateTime(timezone=True), nullable=True),
|
|
58
|
+
sa.Column("error_message", sa.Text(), nullable=True),
|
|
59
|
+
sa.ForeignKeyConstraint(
|
|
60
|
+
["digest_config_id"], ["digest_config.id"], ondelete="CASCADE"
|
|
61
|
+
),
|
|
62
|
+
sa.PrimaryKeyConstraint("id"),
|
|
63
|
+
)
|
|
64
|
+
op.create_index(
|
|
65
|
+
op.f("ix_digest_task_execution_action_type"),
|
|
66
|
+
"digest_task_execution",
|
|
67
|
+
["action_type"],
|
|
68
|
+
unique=False,
|
|
69
|
+
)
|
|
70
|
+
op.create_index(
|
|
71
|
+
op.f("ix_digest_task_execution_celery_task_id"),
|
|
72
|
+
"digest_task_execution",
|
|
73
|
+
["celery_task_id"],
|
|
74
|
+
unique=False,
|
|
75
|
+
)
|
|
76
|
+
op.create_index(
|
|
77
|
+
op.f("ix_digest_task_execution_digest_config_id"),
|
|
78
|
+
"digest_task_execution",
|
|
79
|
+
["digest_config_id"],
|
|
80
|
+
unique=False,
|
|
81
|
+
)
|
|
82
|
+
op.create_index(
|
|
83
|
+
op.f("ix_digest_task_execution_id"),
|
|
84
|
+
"digest_task_execution",
|
|
85
|
+
["id"],
|
|
86
|
+
unique=False,
|
|
87
|
+
)
|
|
88
|
+
op.create_index(
|
|
89
|
+
op.f("ix_digest_task_execution_status"),
|
|
90
|
+
"digest_task_execution",
|
|
91
|
+
["status"],
|
|
92
|
+
unique=False,
|
|
93
|
+
)
|
|
94
|
+
# ### end Alembic commands ###
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def downgrade():
|
|
98
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
99
|
+
op.drop_index(
|
|
100
|
+
op.f("ix_digest_task_execution_status"), table_name="digest_task_execution"
|
|
101
|
+
)
|
|
102
|
+
op.drop_index(
|
|
103
|
+
op.f("ix_digest_task_execution_id"), table_name="digest_task_execution"
|
|
104
|
+
)
|
|
105
|
+
op.drop_index(
|
|
106
|
+
op.f("ix_digest_task_execution_digest_config_id"),
|
|
107
|
+
table_name="digest_task_execution",
|
|
108
|
+
)
|
|
109
|
+
op.drop_index(
|
|
110
|
+
op.f("ix_digest_task_execution_celery_task_id"),
|
|
111
|
+
table_name="digest_task_execution",
|
|
112
|
+
)
|
|
113
|
+
op.drop_index(
|
|
114
|
+
op.f("ix_digest_task_execution_action_type"), table_name="digest_task_execution"
|
|
115
|
+
)
|
|
116
|
+
op.drop_table("digest_task_execution")
|
|
117
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""adds optional duration field to assets
|
|
2
|
+
|
|
3
|
+
Revision ID: f108fa05c579
|
|
4
|
+
Revises: 9caf76161e55
|
|
5
|
+
Create Date: 2025-08-22 12:47:31.374493
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
|
|
12
|
+
# revision identifiers, used by Alembic.
|
|
13
|
+
revision = "f108fa05c579"
|
|
14
|
+
down_revision = "9caf76161e55"
|
|
15
|
+
branch_labels = None
|
|
16
|
+
depends_on = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def upgrade():
|
|
20
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
21
|
+
op.add_column("asset", sa.Column("duration", sa.String(), nullable=True))
|
|
22
|
+
# ### end Alembic commands ###
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def downgrade():
|
|
26
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
27
|
+
op.drop_column("asset", "duration")
|
|
28
|
+
# ### end Alembic commands ###
|
|
@@ -54,7 +54,6 @@ from fides.common.api.v1.urn_registry import DATASETS_CLEAN, V1_URL_PREFIX
|
|
|
54
54
|
from fides.service.dataset.dataset_service import (
|
|
55
55
|
DatasetNotFoundException,
|
|
56
56
|
DatasetService,
|
|
57
|
-
LinkedDatasetException,
|
|
58
57
|
)
|
|
59
58
|
from fides.service.taxonomy.taxonomy_service import TaxonomyService
|
|
60
59
|
|
|
@@ -127,7 +126,7 @@ async def update_dataset(
|
|
|
127
126
|
except DatasetNotFoundException as e:
|
|
128
127
|
raise HTTPException(
|
|
129
128
|
status_code=HTTP_404_NOT_FOUND,
|
|
130
|
-
detail=str(e),
|
|
129
|
+
detail={"message": str(e)},
|
|
131
130
|
)
|
|
132
131
|
|
|
133
132
|
|
|
@@ -249,7 +248,7 @@ async def get_dataset(
|
|
|
249
248
|
except DatasetNotFoundException as e:
|
|
250
249
|
raise HTTPException(
|
|
251
250
|
status_code=HTTP_404_NOT_FOUND,
|
|
252
|
-
detail=str(e),
|
|
251
|
+
detail={"message": str(e)},
|
|
253
252
|
)
|
|
254
253
|
|
|
255
254
|
|
|
@@ -276,12 +275,7 @@ async def delete_dataset(
|
|
|
276
275
|
except DatasetNotFoundException as e:
|
|
277
276
|
raise HTTPException(
|
|
278
277
|
status_code=HTTP_404_NOT_FOUND,
|
|
279
|
-
detail=str(e),
|
|
280
|
-
)
|
|
281
|
-
except LinkedDatasetException as e:
|
|
282
|
-
raise HTTPException(
|
|
283
|
-
status_code=HTTP_400_BAD_REQUEST,
|
|
284
|
-
detail=str(e),
|
|
278
|
+
detail={"message": str(e)},
|
|
285
279
|
)
|
|
286
280
|
|
|
287
281
|
|
fides/api/common_exceptions.py
CHANGED
|
@@ -179,6 +179,10 @@ class AwaitingAsyncTask(BaseException):
|
|
|
179
179
|
"""Request Task is Awaiting Processing - Awaiting Async Task"""
|
|
180
180
|
|
|
181
181
|
|
|
182
|
+
class AwaitingAsyncProcessing(BaseException):
|
|
183
|
+
"""Request Task is actively being processed by external system - Fides is polling"""
|
|
184
|
+
|
|
185
|
+
|
|
182
186
|
class UpstreamTasksNotReady(BaseException):
|
|
183
187
|
"""Privacy Request Task awaiting upstream tasks"""
|
|
184
188
|
|
fides/api/main.py
CHANGED
|
@@ -45,9 +45,9 @@ from fides.api.service.privacy_request.email_batch_service import (
|
|
|
45
45
|
initiate_scheduled_batch_email_send,
|
|
46
46
|
)
|
|
47
47
|
from fides.api.service.privacy_request.request_service import (
|
|
48
|
-
initiate_async_tasks_status_polling,
|
|
49
48
|
initiate_interrupted_task_requeue_poll,
|
|
50
49
|
initiate_poll_for_exited_privacy_request_tasks,
|
|
50
|
+
initiate_polling_task_requeue,
|
|
51
51
|
initiate_scheduled_dsr_data_removal,
|
|
52
52
|
)
|
|
53
53
|
|
|
@@ -103,7 +103,7 @@ async def lifespan(wrapped_app: FastAPI) -> AsyncGenerator[None, None]:
|
|
|
103
103
|
initiate_poll_for_exited_privacy_request_tasks()
|
|
104
104
|
initiate_scheduled_dsr_data_removal()
|
|
105
105
|
initiate_interrupted_task_requeue_poll()
|
|
106
|
-
|
|
106
|
+
initiate_polling_task_requeue()
|
|
107
107
|
initiate_bcrypt_migration_task()
|
|
108
108
|
initiate_post_upgrade_index_creation()
|
|
109
109
|
|
fides/api/models/asset.py
CHANGED
|
@@ -17,7 +17,7 @@ from sqlalchemy import (
|
|
|
17
17
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
18
18
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
19
19
|
from sqlalchemy.ext.mutable import MutableDict
|
|
20
|
-
from sqlalchemy.orm import relationship
|
|
20
|
+
from sqlalchemy.orm import relationship, selectinload
|
|
21
21
|
|
|
22
22
|
from fides.api.db.base_class import Base
|
|
23
23
|
from fides.api.db.util import EnumColumn
|
|
@@ -47,6 +47,7 @@ class Asset(Base):
|
|
|
47
47
|
name = Column(String, index=True, nullable=False)
|
|
48
48
|
asset_type = Column(String, index=True, nullable=False)
|
|
49
49
|
domain = Column(String, index=True)
|
|
50
|
+
duration = Column(String, nullable=True)
|
|
50
51
|
parent = Column(ARRAY(String), server_default="{}", nullable=False)
|
|
51
52
|
parent_domain = Column(String)
|
|
52
53
|
locations = Column(ARRAY(String), server_default="{}", nullable=False)
|
|
@@ -190,5 +191,17 @@ class Asset(Base):
|
|
|
190
191
|
.where(System.fides_key == system_fides_key)
|
|
191
192
|
)
|
|
192
193
|
|
|
194
|
+
# Explicitly eager load the `system` relationship to make this query's
|
|
195
|
+
# performance predictable and prevent N+1 issues.
|
|
196
|
+
query = query.options(selectinload(cls.system)) # type: ignore[attr-defined]
|
|
193
197
|
result = await async_session.execute(query)
|
|
194
198
|
return result.scalars().all()
|
|
199
|
+
|
|
200
|
+
# Expose related System attributes for API serialization convenience
|
|
201
|
+
@property
|
|
202
|
+
def system_name(self) -> Optional[str]:
|
|
203
|
+
return self.system.name if self.system else None
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def system_fides_key(self) -> Optional[str]:
|
|
207
|
+
return self.system.fides_key if self.system else None
|
fides/api/models/attachment.py
CHANGED
|
@@ -60,6 +60,56 @@ class MonitorFrequency(Enum):
|
|
|
60
60
|
QUARTERLY_MONTH_PATTERN = r"^\d+,\d+,\d+,\d+$"
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
class StagedResourceType(str, Enum):
|
|
64
|
+
"""
|
|
65
|
+
Enum representing the type of staged resource.
|
|
66
|
+
The resource_type column is a string in the DB, this is just for
|
|
67
|
+
application-level use.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
# Note: If you add a new resource type, make sure to update either
|
|
71
|
+
# get_datastore_resource_types or get_website_monitor_resource_types
|
|
72
|
+
|
|
73
|
+
# Datastore staged resources
|
|
74
|
+
DATABASE = "Database"
|
|
75
|
+
SCHEMA = "Schema"
|
|
76
|
+
TABLE = "Table"
|
|
77
|
+
FIELD = "Field"
|
|
78
|
+
ENDPOINT = "Endpoint"
|
|
79
|
+
# Website monitor staged resources
|
|
80
|
+
COOKIE = "Cookie"
|
|
81
|
+
BROWSER_REQUEST = "Browser request"
|
|
82
|
+
IMAGE_BROWSER_REQUEST = "Image"
|
|
83
|
+
IFRAME_BROWSER_REQUEST = "iFrame"
|
|
84
|
+
JAVASCRIPT_BROWSER_REQUEST = "Javascript tag"
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def get_datastore_resource_types() -> List["StagedResourceType"]:
|
|
88
|
+
return [
|
|
89
|
+
StagedResourceType.DATABASE,
|
|
90
|
+
StagedResourceType.SCHEMA,
|
|
91
|
+
StagedResourceType.TABLE,
|
|
92
|
+
StagedResourceType.FIELD,
|
|
93
|
+
StagedResourceType.ENDPOINT,
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def get_website_monitor_resource_types() -> List["StagedResourceType"]:
|
|
98
|
+
return [
|
|
99
|
+
StagedResourceType.COOKIE,
|
|
100
|
+
StagedResourceType.BROWSER_REQUEST,
|
|
101
|
+
StagedResourceType.IMAGE_BROWSER_REQUEST,
|
|
102
|
+
StagedResourceType.IFRAME_BROWSER_REQUEST,
|
|
103
|
+
StagedResourceType.JAVASCRIPT_BROWSER_REQUEST,
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
def is_datastore_resource(self) -> bool:
|
|
107
|
+
return self in self.get_datastore_resource_types()
|
|
108
|
+
|
|
109
|
+
def is_website_monitor_resource(self) -> bool:
|
|
110
|
+
return self in self.get_website_monitor_resource_types()
|
|
111
|
+
|
|
112
|
+
|
|
63
113
|
class SharedMonitorConfig(Base, FidesBase):
|
|
64
114
|
"""SQL model for shareable monitor configurations"""
|
|
65
115
|
|
|
@@ -499,11 +549,15 @@ class StagedResource(Base):
|
|
|
499
549
|
server_default="{}",
|
|
500
550
|
default=dict,
|
|
501
551
|
)
|
|
552
|
+
# This field is intentionally nullable to distinguish the case when no user assigned data uses
|
|
553
|
+
# have been set (default, value is None) from the case in which they have been explicitly set
|
|
554
|
+
# as empty (value is empty array). This allows users to remove all data uses from a StagedResource,
|
|
555
|
+
# which was not possible when this field was not nullable.
|
|
502
556
|
user_assigned_data_uses = Column(
|
|
503
557
|
ARRAY(String),
|
|
504
|
-
nullable=
|
|
505
|
-
server_default=
|
|
506
|
-
default=
|
|
558
|
+
nullable=True,
|
|
559
|
+
server_default=None,
|
|
560
|
+
default=None,
|
|
507
561
|
)
|
|
508
562
|
user_assigned_system_id = Column(String, nullable=True, index=True)
|
|
509
563
|
|
|
@@ -5,10 +5,12 @@ from fides.api.models.digest.conditional_dependencies import (
|
|
|
5
5
|
DigestConditionType,
|
|
6
6
|
)
|
|
7
7
|
from fides.api.models.digest.digest_config import DigestConfig, DigestType
|
|
8
|
+
from fides.api.models.digest.digest_execution import DigestTaskExecution
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
10
11
|
"DigestConfig",
|
|
11
12
|
"DigestType",
|
|
12
13
|
"DigestCondition",
|
|
13
14
|
"DigestConditionType",
|
|
15
|
+
"DigestTaskExecution",
|
|
14
16
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from typing import Optional, Union
|
|
2
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
3
3
|
|
|
4
4
|
from sqlalchemy import Boolean, Column, DateTime, String, Text
|
|
5
5
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
@@ -19,6 +19,9 @@ from fides.api.task.conditional_dependencies.schemas import (
|
|
|
19
19
|
ConditionLeaf,
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from fides.api.models.digest.digest_execution import DigestTaskExecution
|
|
24
|
+
|
|
22
25
|
|
|
23
26
|
class DigestType(str, Enum):
|
|
24
27
|
"""Types of digests that can be configured."""
|
|
@@ -60,6 +63,12 @@ class DigestConfig(Base):
|
|
|
60
63
|
back_populates="digest_config",
|
|
61
64
|
cascade="all, delete-orphan",
|
|
62
65
|
)
|
|
66
|
+
executions = relationship(
|
|
67
|
+
"DigestTaskExecution",
|
|
68
|
+
back_populates="digest_config",
|
|
69
|
+
cascade="all, delete-orphan",
|
|
70
|
+
order_by="DigestTaskExecution.created_at.desc()",
|
|
71
|
+
)
|
|
63
72
|
|
|
64
73
|
def get_receiver_condition(
|
|
65
74
|
self, db: Session
|