Skip to main content

Dinero is a library for working with monetary values in Python.

Project description

Dinero: Make exact monetary calculations

PyPI PyPI - Python Version Build status Codecov Codacy grade PyPI - License

This project is inspired by the excellent dinero.js library.

Python Decimal instances are enough for basic monetary calculations, but when you face more complex use-cases they often show limitations and are not so intuitive to work with. Dinero provides a cleaner and easier to use API while still relying on the standard library. So it's still Decimal, but easier.

Read the Documentation

Why Dinero?

A Dinero object is an immutable data structure representing a specific monetary value. It comes with methods for creating, parsing, manipulating, testing and formatting.

Install

pip install dinero

Initialization

To create a Dinero object, you need an amount that can be an int, float, str or Decimal, and a currency:

from dinero import Dinero
from dinero.currencies import USD

amount = Dinero(100.4, USD)

Properties

Every Dinero object has the following properties:

>>> amount.raw_amount
Decimal('100.40')
>>> amount.symbol
'$'
>>> amount.code
'USD'
>>> amount.exponent
2
>>> amount.precision
10

Formatting

String

You can return a formatted string representation of Dinero with the format method:

>>> Dinero(2.32, EUR).format()
'2.32'
>>> Dinero(2.32, EUR).format(symbol=True)
'€2.32'
>>> Dinero(2.32, EUR).format(currency=True)
'2.32 EUR'
>>> Dinero(2.32, EUR).format(symbol=True, currency=True)
'€2.32 EUR'

Dictionary

Return a Dinero instance as a Python Dictionary:

>>> Dinero("3333.259", USD).to_dict()
{
    'amount': '3333.26',
    'currency':
        {
            'code': 'USD',
            'base': 10,
            'exponent': 2,
            'symbol': '$'
        }
}
>>> Dinero('3333.26', USD).to_dict(amount_with_format=True)
{
    'amount': '3,333.26',
    'currency':
        {
            'code': 'USD',
            'base': 10,
            'exponent': 2,
            'symbol': '$'
        }
}

Json

Return a Dinero instance as a JSON string:

>>> Dinero('2,00', USD).to_json()
'{"amount": "3333.20", "currency": {"code": "USD", "base": 10...'
>>> Dinero('2,00', USD).to_json(amount_with_format=True)
'{"amount": "3,333.26", "currency": {"code": "USD", "base": 10...'

Operations

If the addend or subtrahend is an str, int, float or Decimal, it will be transformed, under the hood, to a Dinero instance using the same currency:

# those operations
Dinero(1000, USD).add(Dinero(1000, USD))
Dinero(1000, USD) + Dinero(1000, USD)

# are equivalent to
Dinero(1000, USD).add(1000)
Dinero(1000, USD) + 1000
# those operations
Dinero(1000, USD).subtract(Dinero(100, USD))
Dinero(1000, USD) - Dinero(100, USD)

# are equivalent to
Dinero(1000, USD).subtract(1000)
Dinero(1000, USD) - 100

Additions and subtractions must be between instances with the same currency:

>>> total = Dinero(100, USD) + Dinero(100, EUR)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/.../dinero/_dinero.py", line 120, in __add__
    addend_obj = self._get_instance(addend)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/.../dinero/_dinero.py", line 74, in _get_instance
    raise DifferentCurrencyError("Currencies can not be different")
dinero.exceptions.DifferentCurrencyError: Currencies can not be different

The multiplicand and divisor can be int, float or of Decimal type:

Dinero(1000, USD).multiply(2)
Dinero(1000, USD) * 2
Dinero(1000, USD).divide(2)
Dinero(1000, USD) / 2

Comparisons

Dinero(1000, USD).equals_to(Dinero(1000, USD))
Dinero(1000, USD) == Dinero(1000, USD)
Dinero(1000, USD).less_than(Dinero(1000, USD))
Dinero(1000, USD) < Dinero(1000, USD)
Dinero(1000, USD).less_than_or_equal(Dinero(1000, USD))
Dinero(1000, USD) <= Dinero(1000, USD)
Dinero(1000, USD).greater_than(Dinero(1000, USD))
Dinero(1000, USD) > Dinero(1000, USD)
Dinero(1000, USD).greater_than_or_equal(Dinero(1000, USD))
Dinero(1000, USD) >= Dinero(1000, USD)

You can only compare to other Dinero objects:

>>> Dinero(100, USD) == 100
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/.../dinero/_dinero.py", line 146, in __eq__
    self._comparison_amount(amount)
  File "/home/.../dinero/_dinero.py", line 103, in _comparison_amount
    raise InvalidOperationError(InvalidOperationError.comparison_msg)
dinero.exceptions.InvalidOperationError: You can only compare against other Dinero instances.

Currencies

The currency is one of the two pieces necessary to create a Dinero object.

A Dinero currency is composed of:

  • A unique code.
  • A base, or radix.
  • An exponent.
  • A symbol (optional)
EUR: Currency = {
    "code": "EUR",
    "base": 10,
    "exponent": 2,
    "symbol": "€",
}

Dinero give you access to more than 100 different currencies:

>>> from dinero.currencies import USD, EUR, GBP, INR, CLP
>>> Dinero(2.32, EUR)
Dinero(amount=2.32, currency={'code': 'EUR', 'base': 10, 'exponent': 2, 'symbol': '€'})
>>> Dinero(2.32, EUR).format(symbol=True, currency=True)
'€2.32 EUR'
>>> Dinero(2.32, EUR).raw_amount
Decimal('2.32')

Custom Currencies

You can easily create custom currencies:

from dinero import Dinero

BTC = {
    "code": "BTC",
    "base": 10,
    "exponent": 2,
    "symbol": "₿",
}

Dinero(1000.5, BTC)

Type hints

If you are using type hints in your project you would want to import dinero.types.Currency to prevent warnings:

class Currency(TypedDict):
    code: str
    base: int
    exponent: int
    symbol: NotRequired[str]
from dinero.types import Currency

BTC: Currency = {
    "code": "BTC",
    "base": 10,
    "exponent": 2,
    "symbol": "₿",
}

Dinero(1000.5, BTC)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dinero-0.1.8.tar.gz (18.2 kB view hashes)

Uploaded Source

Built Distribution

dinero-0.1.8-py3-none-any.whl (44.0 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page