graphql-python / gql

A GraphQL client in Python
https://gql.readthedocs.io
MIT License
1.56k stars 180 forks source link

Handling decimals with longer than 6 scale? #464

Closed mnguyenssnc closed 9 months ago

mnguyenssnc commented 9 months ago

Hi,

We came across an issue where the API is returning decimals that can fit into a Decimal with 28 precision, and 10 scale. Because GQL is returning the JSON converted response, the number gets converted to a Python Float and precision is lost. Is there any way to get the raw result using GQL so that we can parse the json ourselves? Or is there any other method to override the json converter to use json.loads() with the parse_float parameter to load it as a Decimal without precision loss?

leszekhanusz commented 9 months ago

This is currently not possible.

On the AIOHTTPTransport, we have the json_serialize parameter which allows us to change the default json.dumps method.

There is no corresponding parameter to change the json.loads method but we could add a new json_deserialize parameter which could be used for that.

Please check if the PR #465 works for you.

mnguyenssnc commented 9 months ago

This should work. We do plan to use AIOHTTPTransport, but haven't migrated to it yet. Any chance you could also add this to RequestsHTTPTransport as well? Thanks for the prompt response!

leszekhanusz commented 9 months ago

Of course! It's done in PR #466

mnguyenssnc commented 9 months ago

This works great for me. I really appreciate it. Looks good!

mnguyenssnc commented 9 months ago

Is there a timeline on when the next release will be that will include these changes?

leszekhanusz commented 9 months ago

It's included in the pre-release v3.6.0b1

mnguyenssnc commented 9 months ago

Thank you. I tried our the pre-release build and it works great for deserializing a decimal from the response by passing def json_loads(obj): return json.loads(obj, parse_float=Decimal) as the json_deserialize input.

However, I was not able to serialize any Decimal type since it is not supported it seems. Got the error: Cannot convert value to AST: <Decimal instance>. I'm not sure if trying to set up custom scalars would solve this problem. I tried it briefly, but did not have any luck.

I was able to get past this by converting the Decimal to a string since my target API accepts Decimals are strings though. All in all, was able to solve the problem, but just wanted to share my results above.

Thanks again.