-
Notifications
You must be signed in to change notification settings - Fork 2
feat: Add DynamoDB document schemas #137
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
base: ci/uv-renovate
Are you sure you want to change the base?
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## ci/uv-renovate #137 +/- ##
==================================================
+ Coverage 94.72% 95.17% +0.44%
==================================================
Files 76 79 +3
Lines 2444 2671 +227
==================================================
+ Hits 2315 2542 +227
Misses 129 129 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
These are placeholder types now. They might be annotated with optional validation code in the future.
| """Represents a multivariate feature state value assigned to an identity or environment.""" | ||
|
|
||
| id: NotRequired[int | None] | ||
| """Unique identifier for the multivariate feature state value in Core. TODO: document why and when this can be `None`.""" |
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 seems Core API currently stores both id and mv_fs_value_uuid. I'd like the field docstrings to explain why, but I need input from the team to do it properly.
| django_id: NotRequired[int | None] | ||
| """Unique identifier for the feature state in Core. TODO: document why and when this can be `None`.""" |
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.
Similarly to https://github.com/Flagsmith/flagsmith-common/pull/137/changes#r2620470807, we currently store both django_id and featurestate_uuid, and I'd like to document the order precedence and historical decisions here, if possible.
| django_id: NotRequired[int | None] | ||
| """Unique identifier for the identity in Core. TODO: document why and when this can be `None`.""" |
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.
Apparently, this is None when identities are created by Edge. There's really no workaround for this so far; this is related to Flagsmith/flagsmith#2186.
Let me know if I'm missing anything, @matthewelwell @gagantrivedi.
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 believe this answers your other two comments as well. If you're creating an identity override (for edge identity), the feature state ID will be None, and if that feature state is multivariate, the ID of the multivariate feature state value will also be None.
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.
Isn't this a bug then? I.e. I don't see why Core shouldn't have access to numeric IDs for feature states and multivariate feature states when an identity override gets created?
Is there an identity override creation path via Edge API I'm not familiar with?
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.
Not a bug - this is by design. When identity overrides are created via the Edge API, they never go through Django models/Postgres - they're only stored in DynamoDB. So they don't get a Django ORM primary key.
src/flagsmith_schemas/dynamodb.py
Outdated
| @@ -0,0 +1,363 @@ | |||
| """ | |||
| Types describing Flagsmith Edge API's data model. | |||
| The schemas are written to DynamoDB documents by Core, and read by Edge. | |||
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 comment is very confusing: The comment says "schemas are written to DynamoDB" - but schemas describe the shape of data, they aren't the data itself
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.
Addressed in 0179e00.
| django_id: NotRequired[int | None] | ||
| """Unique identifier for the identity in Core. TODO: document why and when this can be `None`.""" |
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 believe this answers your other two comments as well. If you're creating an identity override (for edge identity), the feature state ID will be None, and if that feature state is multivariate, the ID of the multivariate feature state value will also be None.
| @@ -0,0 +1,363 @@ | |||
| """ | |||
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 comment density here is quite high. Many of these docstrings just restate what the field name already tells us (name: str with "Name of the feature", enabled: bool with "Whether the feature is enabled"). Could we trim these down to only the non-obvious stuff - constraints, edge cases, gotchas?
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 disagree. I'd like to keep the docstrings because even obvious field descriptions help to remove ambiguity, and having all fields documented help to support the discipline to document new fields going forward.
If anything, I'd add a linter that makes sure every field has a docstring in this module.
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'm gonna have to disagree here. If a field name needs a docstring to explain what it is, that's a sign the field name itself isn't good enough. The name and type should tell the story. Comments should explain why, not what.
The maintenance burden is real too - every field change now requires updating two places. Comments that just mirror the code tend to drift out of sync and become misleading over time.
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.
Comments should explain why, not what.
Sometimes the why and the what are the same, and sometimes they're different. The users of the code shouldn't have to guess. This is what I meant by removing ambiguity.
Comments that just mirror the code tend to drift out of sync and become misleading over time.
It's hard to imagine this scenario for me, given that document schemas are supposed to be forward compatible. Once the field is added, it stays. If its purpose changes or it gets deprecated, we only have to edit the docstring. Ideally, I don't see us changing the field names at all.
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.
Let’s open the floor for a wider discussion.: @matthewelwell @Zaimwa9
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.
Fair points. I still think there's a distinction worth making though - if the what isn't clear from the field name, that's a naming problem. But I take your point about forward compatibility reducing the drift risk.
Maybe a middle ground: keep docstrings for fields where there's genuine context to add (constraints, defaults, deprecation notes, edge cases), but skip the ones that are purely restating the name? That way
we're not just adding noise for the sake of consistency.
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 do tend to agree with Gagan here.
As an example, this comment seems unnecessary to me, as I think Gagan already mentioned.
I'm happy for us to lean on the overly verbose side here, but I think this example is probably a little much.
| @@ -0,0 +1,363 @@ | |||
| """ | |||
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 name of this module is pretty generic - doesn't tell us what these models are for. Something like edge_document.. or dynamodb_schemas.. would make the purpose clearer
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.
Great suggestion! Renamed to flagsmith_schemas.dynamodb in ac9e8df.
Contributes to #128.
In this PR, we add Python stdlib-based DynamoDB document schemas for Flagsmith's Edge API data model.
The goals are to:
Initially, I was hesitant to add validation code to this package. I'm considering to add it now, however, in a subsequent PR, so it can be consumed in environments where Pydantic is still possible to use.
I've added a bunch of TODOs that I expect to resolve prior to merging the current PR, and highlighted them by starting relevant review threads.