-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
✨ Source Facebook Marketing: Add support for multiple Account IDs #33538
✨ Source Facebook Marketing: Add support for multiple Account IDs #33538
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Ignored Deployment
|
Before Merging a Connector Pull RequestWow! What a great pull request you have here! 🎉 To merge this PR, ensure the following has been done/considered for each connector added or updated:
If the checklist is complete, but the CI check is failing,
|
airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json
Outdated
Show resolved
Hide resolved
646f002
to
6a57d60
Compare
airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json
Outdated
Show resolved
Hide resolved
@@ -76,6 +76,7 @@ def _validate_and_transform(self, config: Mapping[str, Any]): | |||
|
|||
if config.end_date: | |||
config.end_date = pendulum.instance(config.end_date) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a validation for account_ids
?
Check for uniqueness
, length
, etc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, regarding the length, Facebook doesn't provide any constraint.
ce51f54
to
6e8e89b
Compare
Warning 🚨 Connector code freeze is in effect until 2024-01-02. This PR is changing connector code. Please contact the current OC engineers if you want to merge this change to master. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know all the intricacies and haven't dug too hard, but this looks straightforward and makes sense to me. Left some smaller comments, nothing big.
With the state transformation, I want to note that while this is not a breaking change in the sense that the customer will have to do something, it is breaking in the sense that in case something goes wrong, we cannot rollback. I think that's okay and worth avoiding a breaking change, but something to keep in mind should any OC issues with this connector occur. Ideally we have a better way of distinguishing these cases from one another in a more accessible way.
With the config transformation, the config control message is very similar - it allows us to migrate them forward but not roll back. I'm not sure how this applies to API users and terraform users - they will have their config updated in the DB, but it won't get back to their resources - so they will probably remain using the old format and also unaware that they can supply multiple, and the migration would run before every sync. I think we also manually update the config formats in the terraform provider - the point at which we did that would be a breaking change on the terraform provider side, I think? A bit out of my wheelhouse - @terencecho I'd love to know if y'all are thinking about stuff like this
airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json
Show resolved
Hide resolved
airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py
Outdated
Show resolved
Hide resolved
airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py
Show resolved
Hide resolved
airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/api.py
Outdated
Show resolved
Hide resolved
...tions/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_streams.py
Show resolved
Hide resolved
airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json
Outdated
Show resolved
Hide resolved
class MigrateAccountIdToArray: | ||
""" | ||
This class stands for migrating the config at runtime, | ||
while providing the backward compatibility when falling back to the previous source version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence is confusing to me - I think it provides compatibility to read data from the previous source version, but doesn't provide compatibility if the connector were to go back to the previous source version (after emitting state from the new version)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It meant that migration is backwards compatible as a new property is created instead of changing the existing one. If the user reverts to the previous version, the config will use the old account_id
. I updated the docs to make sure everything is clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. This is related to my comment here - I didn't realize we didn't remove the old account_id field upon adding the new field
@@ -105,17 +105,15 @@ class ConnectorConfig(BaseConfig): | |||
class Config: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is generated, but my other comments to the spec.json apply here. Not sure which is generated from which
config = json.load(config_file) | ||
migrated_config = MigrateAccountIdToArray.transform(config) | ||
return migrated_config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? I thought the source would perform the migration wherever we pass the config fixture into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Migration is in the main.py, not the source:
https://github.com/airbytehq/airbyte/pull/33538/files#diff-1f20186eea3ef91ef3ce1053eb1dc02fd8ead91b098524ab68af68ae1e15f445R13-R15
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this was a conftest for unit tests this would make sense to me, but this is for cat tests which spin up a source container and run it - wouldn't that run main.py?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixture is passed directly to the source object without the main.py
. https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/test_streams.py#L29
"action_breakdowns": [] | ||
} | ||
], | ||
"account_id": "01234567890", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the new config should not have this still, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, nit: I would name this file test_config and the other one test_old_config - it is clearer migration wise and in future versions it is clear what is the current state of the config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, account_id
would be in the config if it is migrated; otherwise, only account_ids
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it. in this case i think 3 test files could be here - one with account_id (previous version), one with account_id and account ids (upgraded from previous version), one with account_ids only (created or reset on new version)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added one more testing config.
@erohmensing unfortunately right now the terraform provider does not correctly detect configuration drift. So we would probably want to rely on outreach by our support team. In the future when we do get the drift detection working, users will notice the change in their resource the next time they run terraform plan or apply and it will be their responsibility to double check, resolve the changes by updating their tf code. |
e9354f1
to
99fc2d1
Compare
1108736
to
5149197
Compare
for account_id in config.account_ids: | ||
# Get Ad Account to check creds | ||
ad_account = api.get_account(account_id=account_id) | ||
logger.info(f"Select account {ad_account}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move logger before get_account, becuase it run actual reguest using specified accunt , so from logs we'll know which account is failing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
# Get Ad Account to check creds | ||
ad_account = api.account | ||
logger.info(f"Select account {ad_account}") | ||
except facebook_business.exceptions.FacebookRequestError as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall about error handling and logging - we have to be sure that log messages contain info about failing account id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall - we need to decide whether we should stop the whole sync if an error happens for some specific account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error should be raised during the check to indicate missing access to one of the accounts. Additionally, during the sync, the error will be raised to avoid silently missing part of the data. Such errors will require the user to fix the connection configuration before proceeding, thus ensuring no data is missed.
What
This PR introduces the capability to specify multiple Account IDs. Resolves: https://github.com/airbytehq/oncall/issues/3723
How
Modified the
stream_slices
method to iterate over a list ofaccount_ids
. Eachaccount_id
is explicitly passed to all relevant service classes, ensuring the correct account is used in all underlying processes.Recommended reading order
source_facebook_marketing/source.py
source_facebook_marketing/api.py
source_facebook_marketing/streams/base_streams.py
source_facebook_marketing/streams/streams.py
source_facebook_marketing/streams/base_insight_streams.py
🚨 User Impact 🚨
This PR introduces a backwards-incompatible change due to an alteration in the format of stream state. The format has been changed from:
To:
Now, all states are nested under the
account_id
.