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

Pydantic (2) support – addition of __get_pydantic_core_schema__ #276

Merged
merged 15 commits into from
Nov 23, 2023

Conversation

kalaspuff
Copy link
Owner

@kalaspuff kalaspuff commented Nov 23, 2023

Use stockholm.Money in Pydantic models

Money objects can be used in Pydantic (Pydantic>=2.2 supported) models and used with Pydantic's JSON serialization and validation – the same goes for Number and Currency objects as well.

Previously validation of these types required the Pydantic config option arbitrary_types_allowed and JSON serialization with model_dump_json() resulted in an exception. With these updates there's no need for arbitrary_types_allowed and pydantic model's using Money fields can use JSON serialization+deserialization natively.

Specify the stockholm.Money type as the field type and you're good to go.

from pydantic import BaseModel
from stockholm import Money

class Transaction(BaseModel):
    reference: str
    amount: Money

transaction = Transaction(reference="abc123", amount=Money("100.00", "SEK"))
# Transaction(reference='abc123', amount=<stockholm.Money: "100.00 SEK">)

json_data = transaction.model_dump_json()
# '{"reference":"abc123","amount":{"value":"100.00 SEK","units":100,"nanos":0,"currency_code":"SEK"}}'

Transaction.model_validate_json(json_data)
# Transaction(reference='abc123', amount=<stockholm.Money: "100.00 SEK">)

It's also possible to use the stockholm.types Pydantic field types, for example stockholm.types.ConvertibleToMoney, which will automatically coerce input into a Money object.

from pydantic import BaseModel
from stockholm import Money
from stockholm.types import ConvertibleToMoney

class ExampleModel(BaseModel):
    amount: ConvertibleToMoney

example = ExampleModel(amount="4711.50 USD")
# ExampleModel(amount=<stockholm.Money: "4711.50 USD">)

example.model_dump_json()
# '{"amount":{"value":"4711.50 USD","units":4711,"nanos":500000000,"currency_code":"USD"}}'

Other similar field types that can be used on Pydantic fields are:

  • stockholm.types.ConvertibleToNumber
  • stockholm.types.ConvertibleToMoneyWithRequiredCurrency
  • stockholm.types.ConvertibleToCurrency

Note that it's generally recommended to opt for the more strict types (stockholm.Money, stockholm.Number and stockholm.Currency) when possible and the coercion field types should be used with caution and is mainly suited for experimentation and early development.


Related to issue:

Copy link

codecov bot commented Nov 23, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (b4d5dc5) 100.00% compared to head (b4d5c4f) 100.00%.

Additional details and impacted files
@@            Coverage Diff             @@
##            master      #276    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            8         9     +1     
  Lines         1801      1960   +159     
==========================================
+ Hits          1801      1960   +159     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kalaspuff kalaspuff merged commit cf00400 into master Nov 23, 2023
14 checks passed
@kalaspuff kalaspuff deleted the feature/pydantic-support branch November 23, 2023 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant