datetime formatting causes JSON parse failure
matthew-mcallister opened this issue · 7 comments
Using version 9.3.0, when I pass a datetime to LinkTokenCreateRequestUser.phone_number_verified_time
, I get this error:
{
"display_message": null,
"documentation_url": "https://plaid.com/docs/?ref=error#invalid-request-errors",
"error_code": "INVALID_BODY",
"error_message": "body could not be parsed as JSON",
"error_type": "INVALID_REQUEST",
"request_id": "yhfHXxGXoh8NoIQ",
"suggested_action": null
}
Inspecting the request body, I see the issue is that the formatted datetime is missing the "Z" at the end, i.e. "1969-12-31T16:00:00"
instead of "1969-12-31T16:00:00Z"
. Though the error message is misleading, since this is actually valid JSON.
@matthew-mcallister Thank you for the report -- can you show how you are generating and providing the datetime?
request = plaid_api.LinkTokenCreateRequest(
client_name='name',
language='en',
country_codes=[models.CountryCode('US')],
products=[models.Products('auth'), models.Products('transactions')],
user=models.LinkTokenCreateRequestUser(
client_user_id=str(user.external_id),
email_address=user.email,
phone_number=user.phone_number,
# FIXME: https://github.com/plaid/plaid-python/issues/414
# phone_number_verified_time=datetime.fromtimestamp(0),
),
)
Same thing happens with any datetime I input.
Does this suggested approach from StackOverflow work?
https://stackoverflow.com/questions/8556398/generate-rfc-3339-timestamp-in-python
import datetime
n = datetime.datetime.now(datetime.timezone.utc)
n.isoformat()
'2021-07-13T15:28:51.818095+00:00'
I'll also file an issue with the team to see if we can be a little less picky with the date-time formatting, similarly to how we treat phone numbers.
Does this suggested approach from StackOverflow work?
I can't pass a str
to the SDK because it's type-checked:
plaid.exceptions.ApiTypeError: Invalid type for variable 'phone_number_verified_time'. Required value type is datetime and passed type was str at ['phone_number_verified_time']
What about something like this?
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Hi @matthew-mcallister! Looking at the /link/token/create docs, it looks like you'll need to pass in a date-time object that includes timezone information (datetime.fromtimestamp(0)
doesn't appear to include timezone information). @phoenixy1 's suggestion above should work. You could also try something like:
import datetime
# change to your date
n = datetime.datetime(2021, 11, 1, 0, 0, tzinfo=datetime.timezone.utc)
If you really want to use fromtimestamp()
, consider something like:
import datetime
import pytz
n = datetime.fromtimestamp(0, pytz.timezone("UTC"))
If you call .isoformat()
on any of the n variables above (just to inspect the value), you should see +00:00
appended to the end of the string, which is the necessary timezone information (I found this section in Wikipedia helpful: https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators, namely "An offset of zero, in addition to having the special representation "Z", can also be stated numerically as "+00:00", "+0000", or "+00".").
The world of date-times is unfortunately full of rabbit holes, but I hope this is helpful! If you're still encountering issues, please reach out again. Thanks. 🙏
Ah, I didn't understand the first response. Adding a timezone fixes the issue, obviously. Thank you. A better error message would help as it's a tricky problem to diagnose, but that's not really the SDK's problem.