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

Extract DateTime logic #35527

Merged
merged 7 commits into from
Dec 20, 2024
Merged

Extract DateTime logic #35527

merged 7 commits into from
Dec 20, 2024

Conversation

mjriley
Copy link
Contributor

@mjriley mjriley commented Dec 16, 2024

Product Description

Purely a backend change.

Technical Summary

The recent CommCare Version Tile made me aware that we're inconsistent in how we're treating deserialization. The full logic is in DateTimeProperty._wrap(), but because it is an instance method, we ended up doing our own manual deserialization with datetime.strptime(date_of_use, ISO_DATETIME_FORMAT). Although this works, it ignores the additional checks that DateTimeProperty does. Since, in both cases, we're handling data from the same source (data that was serialized by DateTimeProperty), I've added a class method to allow us to re-use the same logic.

Safety Assurance

Safety story

I haven't done any testing beyond the unit tests, but I believe those tests are sufficient to prove that the existing behavior has been preserved.

Automated test coverage

Added new tests to verify that the existing behavior has not been disrupted while adding the deserialize method.

QA Plan

No QA

Rollback instructions

  • This PR can be reverted after deploy with no further considerations

Labels & Review

  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@mjriley mjriley added the product/invisible Change has no end-user visible impact label Dec 16, 2024
Copy link

sentry-io bot commented Dec 16, 2024

🔍 Existing Issues For Review

Your pull request is modifying functions with the following pre-existing issues:

📄 File: corehq/apps/reports/util.py

Function Unhandled Issue
get_commcare_version_and_date_from_last_usage UnboundLocalError: local variable 'version' referenced before assignment /a/{domain}/enterprise...
Event Count: 1

Did you find this useful? React with a 👍 or 👎

@jingcheng16
Copy link
Contributor

data that was serialized by DateTimeProperty

Can you show where is last_submission.date_of_use and last_device.date_of_use being serialized?

@mjriley
Copy link
Contributor Author

mjriley commented Dec 17, 2024

Can you show where is last_submission.date_of_use and last_device.date_of_use being serialized?

I haven't traced through this, but my understanding is that somewhere along either the Pillow or Couch process, Document models are converted to JSON using the field definitions from jsonobject. Jsonobject serializes and deserializes via its wrap and unwrap methods

@jingcheng16
Copy link
Contributor

@mjriley Without confirming we did _unwrap the DateTimeProperty, I'm not very confident to approve the PR. I searched _unwrap in commcare-hq and cannot find any reference.
@dannyroberts @millerdev (Tagging people who might more familiar with Couch. )

@jingcheng16
Copy link
Contributor

jingcheng16 commented Dec 18, 2024

One question ( no need to address it in your PR ):
Can we say all occurrences of datetime.strptime(date_of_use, ISO_DATETIME_FORMAT) can be replaced with your new deserialize function now?

@mjriley
Copy link
Contributor Author

mjriley commented Dec 18, 2024

@mjriley Without confirming we did _unwrap the DateTimeProperty, I'm not very confident to approve the PR. I searched _unwrap in commcare-hq and cannot find any reference. @dannyroberts @millerdev (Tagging people who might more familiar with Couch. )

@esoergel was kind enough to point me to the code (mostly) responsible for this.

The code that inserts it into ElasticSearch is here. which you can see from the method's docstring:

Takes a user dict and applies required transfomation to make it suitable for ES.
:param user: an instance dict which is result of CouchUser.to_json()

The parent class has that to_json call here, where, because ElasticUser's model_cls is CouchUser, we'll be calling to_json on a CouchUser object.

At that point, the details of how to_json ends upcalling unwrap is within Couch's Document class and JSONobject.

Edit: copying his notes on how the internals of JSONobject work:

each declared field a jsonobject instance is a subclass of JsonProperty, added there via the metaclass stuff. Then when you set or modify those fields, it calls instance[self.name] = value, which wraps through JsonObject.setitem, which in turn updates self._obj
and to update self._obj, it calls unwrap on the property

@mjriley
Copy link
Contributor Author

mjriley commented Dec 18, 2024

One question ( no need to address it in your PR ): Can we say all occurrences of datetime.strptime(date_of_use, ISO_DATETIME_FORMAT) can be replaced with your new deserialize function now?

Provided these calls represented data that was serialized by DateTimeProperty, yes.

Copy link
Contributor

@jingcheng16 jingcheng16 left a comment

Choose a reason for hiding this comment

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

Nice! Thank you for the explanation I also learned something new from it.

@mjriley mjriley merged commit 349a0d3 into master Dec 20, 2024
13 checks passed
@mjriley mjriley deleted the mjr/extract-datetime-logic branch December 20, 2024 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
product/invisible Change has no end-user visible impact
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants