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

[py-tx] Deprecate SignalExchange API method #1773

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

b8zhong
Copy link
Contributor

@b8zhong b8zhong commented Feb 26, 2025

Summary

Added deprecation notices to both methods in SignalExchangeAPI class, indicating they will be removed in version 2.x.x

Remove the few references to it there was.

Closes #1218

Test Plan

Yep

@b8zhong b8zhong requested a review from Dcallies as a code owner February 26, 2025 23:04
@b8zhong b8zhong changed the title 1218 deprecate signal exchange api [py-tx] Deprecate SignalExchange API method Feb 26, 2025
Copy link
Contributor

@Dcallies Dcallies 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 taking a look!

Let's use the @deprecated decorator, and leave naive_fetch_merge around as a documentation of the correct way to merge this data.

Comment on lines 418 to 419
if new.deleted:
return None
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, this is a real functionality we need to store somewhere. The task mentions changing the behavior of fetch(). See L434 on the new code for where this is handled in convert

Comment on lines 196 to 197
DEPRECATED: This method will be removed in version 2.x.x.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should keep this version around - it's marked final, and the argument to keep it around is on L198.

Instead, we should should try and tell if it's safe to change this method not to call fetch_value_merge.

Suggested change
DEPRECATED: This method will be removed in version 2.x.x.

@@ -167,6 +167,10 @@ def fetch_value_merge(
"""
Merge a new update produced by fetch.

DEPRECATED: This method will be removed in version 2.x.x.
Copy link
Contributor

Choose a reason for hiding this comment

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

In addition, we should use the @deprecated annotation - you can include the removal message there.

https://typing.readthedocs.io/en/latest/spec/directives.html#deprecated

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Dcallies py-tx goes back to Python 3.8 right? @deprecated I think is only introduced in 3.13

What do you think of using warnings.warn?

Copy link
Contributor

Choose a reason for hiding this comment

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

D'oh! It goes back to 3.9 (3.8 is deprecated).

Warnings is a fine workaround.

@@ -56,7 +56,13 @@ def delta(self, value: fetch_state.FetchDeltaTyped) -> None:
self._delta = value
else:
old = self._delta.updates
self.api_cls.naive_fetch_merge(old, value.updates)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's keep this version around, it's useful to formally describe the update logic somewhere.

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 agree

@github-actions github-actions bot added the python-threatexchange Items related to the threatexchange python tool / library label Mar 11, 2025
@@ -197,11 +210,10 @@ def naive_fetch_merge(
together keyed by ID will eventually get you an entire copy of the database.
"""
for k, v in new.items():
new_v = cls.fetch_value_merge(old.get(k), v)
if new_v is None:
if v is None:
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 think... this might be right? If something is deleted -- it would already be None... ?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we were outright deleting fetch_value_merge, then yes!

However, we might need to keep the old code around until 2.x.x. See toplevel comment about what to do.

@b8zhong b8zhong requested a review from Dcallies March 11, 2025 22:09
Copy link
Contributor

@Dcallies Dcallies left a comment

Choose a reason for hiding this comment

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

Hmm, as written I think this might break the NCMEC fetch code! We might be missing a unittest that tests to make sure NCMEC deletions are handled properly (or else it might be a bug that is compensated for later).

Let's break this up into stages:

  1. Review the current API integrations and see which ones are relying on an override of fetch_value_merge
  2. Fix the implementations relying on fetch_value_merge to not do so, which allows for the deletion of the override on that exchange class
  3. In order to defend against the existence of any third party extensions that rely on overrides, you could try detecting whether the class has an override which is not equal to the default. I think you might be able to determine that via reflection. If you detect an override, emit a warning.

"""
warnings.warn(
"fetch_value_merge() is deprecated and will be removed in version 2.x.x. "
"The deletion logic has been moved directly to fetch_iter().",
Copy link
Contributor

Choose a reason for hiding this comment

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

Not quite - you need to add this logic in fetch_iter!

Comment on lines +377 to +380
{
f"{update.member_id}-{update.id}": update
for update in entry.updates
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of yielding : update, you need to yield None if update is deleted - you could inline it here.

@@ -167,6 +167,10 @@ def fetch_value_merge(
"""
Merge a new update produced by fetch.

DEPRECATED: This method will be removed in version 2.x.x.
Copy link
Contributor

Choose a reason for hiding this comment

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

D'oh! It goes back to 3.9 (3.8 is deprecated).

Warnings is a fine workaround.

warnings.warn(
"fetch_value_merge() is deprecated and will be removed in version 2.x.x. "
"Any implementations that convert records into None to signal a deletion "
"should instead move that logic into the fetch() method.",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we figured out it's fetch_iter

@@ -197,11 +210,10 @@ def naive_fetch_merge(
together keyed by ID will eventually get you an entire copy of the database.
"""
for k, v in new.items():
new_v = cls.fetch_value_merge(old.get(k), v)
if new_v is None:
if v is None:
Copy link
Contributor

Choose a reason for hiding this comment

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

If we were outright deleting fetch_value_merge, then yes!

However, we might need to keep the old code around until 2.x.x. See toplevel comment about what to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed python-threatexchange Items related to the threatexchange python tool / library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[py-tx] Deprecate SignalExchangeAPI.fetch_value_merge
3 participants