valuta

Currencies done right

In most payment systems that went international, amounts are represented in integers, instead of decimals, as they are represented in minor currency units (smallest units possible).

For EUR it is cent, which is 1/100 of a single Euro. For MRU it is khoums, which is 1/5 of a single Ouguiya.

List of currencies is generated from a single CSV dump obtained from the list of circulating currencies Wikipedia page using the awesome wikitable2csv.

PyPI Version Supported Python versions Build Status Documentation Status GPL-2.0-only OR LGPL-2.1-or-later Coverage

Prerequisites

  • Core package requires Python 3.6, 3.7, 3.8 or 3.9.

  • Django integration package (valuta.contrib.django_integration) requires Django 2.2, 3.0, 3.1 or 3.2.

  • SQLAlchemy integration package (valuta.contrib.sqlalchemy_integration) has been tested with SQLAlchemy 1.4.x.

Documentation

Documentation is available on Read the Docs.

Installation

Latest stable version on PyPI:

pip install valuta

Or development version from GitHub:

pip install https://github.com/barseghyanartur/valuta/archive/master.tar.gz

Usage examples

Pure Python

Using currency classes directly

If you need numbers back for further calculations
import valuta

valuta.EUR.convert_to_currency_units(1_000)
# 10.0

valuta.UGX.convert_to_currency_units(1_000)
# 1000.0

valuta.MRU.convert_to_currency_units(1_000)
# 200.0

valuta.VND.convert_to_currency_units(1_000)
# 100.0

valuta.TND.convert_to_currency_units(1_000)
# 1.0

valuta.JPY.convert_to_currency_units(1_000)
# 10.0
If you need to display the values and want a nice string back
import valuta

valuta.EUR.display_in_currency_units(1_000)
# '€10.00'

valuta.UGX.display_in_currency_units(1_000)
# 'UGX1,000'

valuta.MRU.display_in_currency_units(1_000)
# 'MRU200.00'

valuta.VND.display_in_currency_units(1_000)
# '₫100'

valuta.TND.display_in_currency_units(1_000)
# 'TND1.000'

valuta.JPY.display_in_currency_units(1_000)
# '¥10'
Custom string formatting

Based on the specifics of the given currency, displayed numbers may have or not may have decimal points.

The display_in_currency_units method accepts optional format, locale and decimal_quantization arguments. Most common values for format are listed in the valuta.constants.

format

DISPLAY_FORMAT_NUMBER

Example values: '10000' or '10000.00'.

DISPLAY_FORMAT_HUMAN_READABLE

Displays a human readable number.

Example values: '10,000' or '10,000.00'.

DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_CODE

Displays a human readable number with currency code.

Example values: 'JPY 10,000' or 'EUR 10,000.00'.

DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_SYMBOL

Displays a human readable number with currency symbol.

Example values: 10,000' or '€ 10,000.00'.

A couple of examples:

from valuta.constants import *

valuta.JPY.display_in_currency_units(
    1_000_000,
    format=DISPLAY_FORMAT_HUMAN_READABLE
)
# '10,000'

valuta.JPY.display_in_currency_units(
    1_000_000,
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_CODE
)
# 'JPY 10,000'

valuta.JPY.display_in_currency_units(
    1_000_000,
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_SYMBOL
)
# '¥ 10,000'

valuta.EUR.display_in_currency_units(
    1_000_000,
    format=DISPLAY_FORMAT_HUMAN_READABLE
)
# '10,000.00'

valuta.EUR.display_in_currency_units(
    1_000_000,
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_CODE
)
# 'EUR 10,000.00'

valuta.EUR.display_in_currency_units(
    1_000_000,
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_SYMBOL
)
# '€ 10,000.00'
locale
 valuta.JPY.display_in_currency_units(1_000_000_000, locale="nl_NL")
 # 'JP¥\xa010.000.000'

 valuta.JPY.display_in_currency_units(1_000_000_000, locale="en_US")
 # '¥10,000,000'

 valuta.EUR.display_in_currency_units(1_000_000_000, locale="nl_NL")
 # '€\xa010.000.000,00'

valuta.EUR.display_in_currency_units(1_000_000_000, locale="en_US")
#  '€10,000,000.00'

valuta.AMD.display_in_currency_units(1_000_000_000, locale="en_US")
# 'AMD10,000,000.00'

valuta.AMD.display_in_currency_units(1_000_000_000, locale="hy_AM")
# '10 000 000,00 ֏'

Working with string representations of the (ISO-4217) currency codes

If you need numbers back for further calculations
from valuta.shortcuts import convert_to_currency_units

convert_to_currency_units("EUR", 1_000)
# 10.0

convert_to_currency_units("UGX", 1_000)
# 1000.0

convert_to_currency_units("MRU", 1_000)
# 200.0

convert_to_currency_units("VND", 1_000)
# 100.0

convert_to_currency_units("TND", 1_000)
# 1.0

convert_to_currency_units("JPY", 1_000)
# 10.0
If you need to display the values and want a nice string back
from valuta.shortcuts import display_in_currency_units

display_in_currency_units("EUR", 1_000)
# '€10.00'

display_in_currency_units("UGX", 1_000)
# 'UGX1,000'

display_in_currency_units("MRU", 1_000)
# 'MRU200.00'

display_in_currency_units("VND", 1_000)
# '₫100'

display_in_currency_units("TND", 1_000)
# 'TND1.000'

display_in_currency_units("JPY", 1_000)
# '¥10'

By default, exceptions arising from invalid currency codes are suppressed (None will be returned on invalid currency codes).

If you want to throw exception on invalid currency codes, set fail_silently to False. The following example will throw a valuta.exceptions.InvalidCurrency exception.

convert_to_currency_units("i-dont-exist", 1_000, fail_silently=False)

The display_in_currency_units shortcut function also accepts optional format argument.

Django integration

In its basis, Django integration package is a CurrencyField representing the ISO-4217 codes of the currencies. If bound to certain number fields (SmallIntegerField, IntegerField, BigIntegerField) holding the amount in minor currency units, it adds up (magic) methods to the model class for converting field amounts to major currency units (often simply called currency units).

There are also template tags and filters for when you need to render non-model data (for instance, JSON) in templates without prior pre-processing.

Installation

pip install valuta[django]

Model field

Model definition

Sample model

product/models.py

from django.db import models
from valuta.contrib.django_integration.models import CurrencyField

class Product(models.Model):

    name = models.CharField(max_length=255)
    price = models.IntegerField()  # Amount in minor currency units
    price_with_tax = models.IntegerField()  # Amount in minor currency units
    currency = CurrencyField(amount_fields=["price", "price_with_tax"])

Sample data

import valuta
from product.models import Product
product = Product.objects.create(
    name="My test product",
    price=100,
    price_with_tax=120,
    currency=valuta.AMD.uid,
)
Converting amounts using magic methods

You could then refer to the price and price_with_tax as follows:

product.price_in_currency_units()
# 1.0
product.price_with_tax_in_currency_units()
# 1.2

Note, that every field listed in the amount_fields gets a correspondent model method with suffix _in_currency_units for converting the field amounts to (major) currency units.

Converting amounts for display using magic methods

You could then refer to the price and price_with_tax as follows:

product.price_display_in_currency_units()
# 'AMD1.00'
product.price_with_tax_display_in_currency_units()
# 'AMD1.20'

Note, that every field listed in the amount_fields gets a correspondent model method with suffix _display_in_currency_units for converting the field amounts to (major) currency units.

Magic methods also accept optional format argument.

product = Product.objects.create(
    name="My test product",
    price=100_000,
    price_with_tax=120_000,
    currency=valuta.EUR.uid,
)

product.price_display_in_currency_units(
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_SYMBOL
)
# '€ 1,000.00'
product.price_with_tax_display_in_currency_units(
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_CODE
)
# 'EUR 1,200.00'

Combining format and locale arguments.

product.price_display_in_currency_units(
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_SYMBOL,
    locale="nl_NL"
)
# '€ 1.000,00'
product.price_with_tax_display_in_currency_units(
    format=DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_CODE,
    locale="nl_NL"
)
# 'EUR 1.200,00'
Limiting the currency choices
On the field level

You could limit the currency choices as follows:

currency = CurrencyField(
    amount_fields=["price", "price_with_tax"],
    limit_choices_to=[valuta.AMD.uid, valuta.EUR.uid],
)
Globally

You could also override the CurrencyField choices in the Django settings:

settings.py

VALUTA_FIELD_LIMIT_CHOICES_TO=(
    valuta.AMD.uid,
    valuta.EUR.uid,
)
Casting the converted values

If you want to explicitly cast the result value to a certain type, provide a callable cast_to for the CurrencyField.

For int it would be
currency = CurrencyField(
    amount_fields=("price", "price_with_tax",),
    cast_to=int,
)
For float it would be
currency = CurrencyField(
    amount_fields=("price", "price_with_tax",),
    cast_to=float,
)
For decimal.Decimal it would be
currency = CurrencyField(
    amount_fields=("price", "price_with_tax",),
    cast_to=lambda __v: Decimal(str(__v)),
)
Customize the choices display format

By default, the following format is used (valuta.utils.get_currency_choices_with_code):

[
    ("AMD", "Armenian Dram (AMD)"),
    ("EUR", "Euro (EUR)"),
]

If you want to customize that, provide a callable get_choices_func along:

from valuta.utils import get_currency_choices

currency = CurrencyField(
    amount_fields=("price", "price_with_tax",),
    get_choices_func=get_currency_choices,
)

It would then have the following format:

[
    ("AMD", "Armenian Dram"),
    ("EUR", "Euro"),
]

Take both valuta.utils.get_currency_choices and valuta.utils.get_currency_choices_with_code as a good example of how to customize. You could for instance do something like this:

import operator
from typing import List, Tuple, Set, Union

from babel.numbers import get_currency_symbol
from valuta.base import Registry

def get_currency_choices_with_sign(
        limit_choices_to: Union[Tuple[str, ...], List[str], Set[str]] = None,
        sort_by_key: bool = False,
) -> List[Tuple[str, str]]:
    """Get currency choices with code.

    List of choices in the following format::

        [
            ("AMD", "AMD - Armenian Dram"),
            ("EUR", "€ - Euro"),
            ("USD", "$ - US Dollar"),
        ]
    """
    if limit_choices_to is None:
        values = [
            (__key, f"{get_currency_symbol(__key)} - {__value.name}")
            for __key, __value in Registry.REGISTRY.items()
        ]
    else:
        values = [
            (__key, f"{get_currency_symbol(__key)} - {__value.name}")
            for __key, __value in Registry.REGISTRY.items()
            if __key in limit_choices_to
        ]
    if sort_by_key:
        values.sort(key=operator.itemgetter(0))
    else:
        values.sort(key=operator.itemgetter(1))
    return values

And then use it as follows:

currency = CurrencyField(
    amount_fields=("price", "price_with_tax",),
    get_choices_func=get_currency_choices_with_sign,
)

Template tags and filters

Most of the cases would be covered by the Model field, but it could be that you will have non-model data (for instance, JSON) that you need to properly render in the templates (without prior pre-processing). In that case valuta_tags template tags/filters library might help.

Template tags prerequisites

If you want to use templatetags library, you need to add valuta.contrib.django_integration to your INSTALLED_APPS:

INSTALLED_APPS = (
    # ...
    "valuta.contrib.django_integration",
    # ...
)

If you want to make use of pre-defined rendering formats, it might be useful to add valuta.contrib.django_integration.context_processors.constants to the context_processors.

TEMPLATES = [{
    # ...
    "OPTIONS": {
        # ...
        "context_processors": [
            "django.template.context_processors.debug",
            "django.template.context_processors.request",
            "django.contrib.auth.context_processors.auth",
            "django.contrib.messages.context_processors.messages",
            "valuta.contrib.django_integration.context_processors.constants",
        ],
        # ...
    },
    # ...
}]
Sample data
instance = {
    "price": 1_000,
    "price_with_tax": 1_200,
    "currency_code": "EUR",
}
Without formatting
Sample template filters template

template_filter_price_in_currency_units.html

{% load valuta_tags %}

{{ instance.price|convert_to_currency_units:instance.currency_code }}
Sample template filters renderer
from django.template.loader import render_to_string

render_to_string(
    "template_filter_price_in_currency_units.html", {"instance": instance}
)
Sample template tags template

template_tag_price_in_currency_units.html

{% load valuta_tags %}

{% convert_to_currency_units instance.price instance.currency_code %}
Sample template tags renderer
from django.template.loader import render_to_string

render_to_string(
    "template_tag_price_in_currency_units.html", {"instance": instance}
)
With formatting
Sample template filters template

template_filter_price_display_in_currency_units.html

{% load valuta_tags %}

{{ instance.price|display_in_currency_units:instance.currency_code }}
Sample template filters renderer
from django.template.loader import render_to_string

render_to_string(
    "template_filter_price_display_in_currency_units.html", {"instance": instance}
)
Sample template tags template

template_tag_price_display_in_currency_units.html

{% load valuta_tags %}

{% display_in_currency_units instance.price instance.currency_code %}

You can also display units in specific format (including the currency symbol). Most common use-cases are pre-defined in valuta.constants and if you have included the correspondent context processor as instructed above, you could use it as follows:

{% load valuta_tags %}

{% display_in_currency_units instance.price instance.currency_code DISPLAY_FORMAT_HUMAN_READABLE_WITH_CURRENCY_CODE %}

For the full list of options, see Custom string formatting.

Sample template tags renderer
from django.template.loader import render_to_string

render_to_string(
    "template_tag_price_display_in_currency_units.html", {"instance": instance}
)

SQLAlchemy integration

Similarly to Django integration package, the SQLAlchemy integration package is a simple CurrencyType representing the ISO-4217 codes of the currencies.

No magic methods are implemented yet (although planned to). What you get is a simple SQLAlchemy type for storing the data. For the rest you will have to make use of the valuta.shortcuts.

See examples/sqlalchemy_example/valuta_admin/models.py as a good example.

Installation

pip install valuta[sqlalchemy]

Model definition

Sample model

product/models.py

from valuta.contrib.sqlalchemy_integration.types import CurrencyType
from . import db  # Standard SQLAlchemy way

class Product(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(64), unique=True)
    price = db.Column(db.Integer())
    price_with_tax = db.Column(db.Integer())
    currency = db.Column(CurrencyType())

Sample data

import valuta
from product.models import Product
product = Product(
    name="My test product",
    price=100,
    price_with_tax=120,
    currency=valuta.AMD.uid,
)

Supported currencies

Currencies marked with (*) are custom (added manually). The rest is obtained from the already mentioned list of circulating currencies.

┌───────────┬──────────────────────────────────────────┐
│ ISO code  │ Currency                                 │
├───────────┼──────────────────────────────────────────┤
│ AED       │ United Arab Emirates Dirham              │
├───────────┼──────────────────────────────────────────┤
│ AFN       │ Afghan Afghani                           │
├───────────┼──────────────────────────────────────────┤
│ ALL       │ Albanian Lek                             │
├───────────┼──────────────────────────────────────────┤
│ AMD       │ Armenian Dram                            │
├───────────┼──────────────────────────────────────────┤
│ ANG       │ Netherlands Antillean Guilder            │
├───────────┼──────────────────────────────────────────┤
│ AOA       │ Angolan Kwanza                           │
├───────────┼──────────────────────────────────────────┤
│ ARS       │ Argentine Peso                           │
├───────────┼──────────────────────────────────────────┤
│ AUD       │ Australian Dollar                        │
├───────────┼──────────────────────────────────────────┤
│ AWG       │ Aruban Florin                            │
├───────────┼──────────────────────────────────────────┤
│ AZN       │ Azerbaijani Manat                        │
├───────────┼──────────────────────────────────────────┤
│ BAM       │ Bosnia-Herzegovina Convertible Mark      │
├───────────┼──────────────────────────────────────────┤
│ BBD       │ Barbadian Dollar                         │
├───────────┼──────────────────────────────────────────┤
│ BDT       │ Bangladeshi Taka                         │
├───────────┼──────────────────────────────────────────┤
│ BGN       │ Bulgarian Lev                            │
├───────────┼──────────────────────────────────────────┤
│ BHD       │ Bahraini Dinar                           │
├───────────┼──────────────────────────────────────────┤
│ BIF       │ Burundian Franc                          │
├───────────┼──────────────────────────────────────────┤
│ BMD       │ Bermudan Dollar                          │
├───────────┼──────────────────────────────────────────┤
│ BND       │ Brunei Dollar                            │
├───────────┼──────────────────────────────────────────┤
│ BOB       │ Bolivian Boliviano                       │
├───────────┼──────────────────────────────────────────┤
│ BRL       │ Brazilian Real                           │
├───────────┼──────────────────────────────────────────┤
│ BSD       │ Bahamian Dollar                          │
├───────────┼──────────────────────────────────────────┤
│ BTC       │ Bitcoin (*)                              │
├───────────┼──────────────────────────────────────────┤
│ BTN       │ Bhutanese Ngultrum                       │
├───────────┼──────────────────────────────────────────┤
│ BWP       │ Botswanan Pula                           │
├───────────┼──────────────────────────────────────────┤
│ BYN       │ Belarusian Ruble                         │
├───────────┼──────────────────────────────────────────┤
│ BZD       │ Belize Dollar                            │
├───────────┼──────────────────────────────────────────┤
│ CAD       │ Canadian Dollar                          │
├───────────┼──────────────────────────────────────────┤
│ CDF       │ Congolese Franc                          │
├───────────┼──────────────────────────────────────────┤
│ CHF       │ Swiss Franc                              │
├───────────┼──────────────────────────────────────────┤
│ CKD       │ CKD                                      │
├───────────┼──────────────────────────────────────────┤
│ CLP       │ Chilean Peso                             │
├───────────┼──────────────────────────────────────────┤
│ CNY       │ Chinese Yuan                             │
├───────────┼──────────────────────────────────────────┤
│ COP       │ Colombian Peso                           │
├───────────┼──────────────────────────────────────────┤
│ CRC       │ Costa Rican Colón                        │
├───────────┼──────────────────────────────────────────┤
│ CUP       │ Cuban Peso                               │
├───────────┼──────────────────────────────────────────┤
│ CVE       │ Cape Verdean Escudo                      │
├───────────┼──────────────────────────────────────────┤
│ CZK       │ Czech Koruna                             │
├───────────┼──────────────────────────────────────────┤
│ DJF       │ Djiboutian Franc                         │
├───────────┼──────────────────────────────────────────┤
│ DKK       │ Danish Krone                             │
├───────────┼──────────────────────────────────────────┤
│ DOP       │ Dominican Peso                           │
├───────────┼──────────────────────────────────────────┤
│ DZD       │ Algerian Dinar                           │
├───────────┼──────────────────────────────────────────┤
│ EGP       │ Egyptian Pound                           │
├───────────┼──────────────────────────────────────────┤
│ ERN       │ Eritrean Nakfa                           │
├───────────┼──────────────────────────────────────────┤
│ ETB       │ Ethiopian Birr                           │
├───────────┼──────────────────────────────────────────┤
│ EUR       │ Euro                                     │
├───────────┼──────────────────────────────────────────┤
│ FJD       │ Fijian Dollar                            │
├───────────┼──────────────────────────────────────────┤
│ FKP       │ Falkland Islands Pound                   │
├───────────┼──────────────────────────────────────────┤
│ FOK       │ FOK                                      │
├───────────┼──────────────────────────────────────────┤
│ GBP       │ British Pound                            │
├───────────┼──────────────────────────────────────────┤
│ GEL       │ Georgian Lari                            │
├───────────┼──────────────────────────────────────────┤
│ GGP       │ GGP                                      │
├───────────┼──────────────────────────────────────────┤
│ GHS       │ Ghanaian Cedi                            │
├───────────┼──────────────────────────────────────────┤
│ GIP       │ Gibraltar Pound                          │
├───────────┼──────────────────────────────────────────┤
│ GMD       │ Gambian Dalasi                           │
├───────────┼──────────────────────────────────────────┤
│ GNF       │ Guinean Franc                            │
├───────────┼──────────────────────────────────────────┤
│ GTQ       │ Guatemalan Quetzal                       │
├───────────┼──────────────────────────────────────────┤
│ GYD       │ Guyanaese Dollar                         │
├───────────┼──────────────────────────────────────────┤
│ HKD       │ Hong Kong Dollar                         │
├───────────┼──────────────────────────────────────────┤
│ HNL       │ Honduran Lempira                         │
├───────────┼──────────────────────────────────────────┤
│ HRK       │ Croatian Kuna                            │
├───────────┼──────────────────────────────────────────┤
│ HTG       │ Haitian Gourde                           │
├───────────┼──────────────────────────────────────────┤
│ HUF       │ Hungarian Forint                         │
├───────────┼──────────────────────────────────────────┤
│ IDR       │ Indonesian Rupiah                        │
├───────────┼──────────────────────────────────────────┤
│ ILS       │ Israeli New Shekel                       │
├───────────┼──────────────────────────────────────────┤
│ IMP       │ IMP                                      │
├───────────┼──────────────────────────────────────────┤
│ INR       │ Indian Rupee                             │
├───────────┼──────────────────────────────────────────┤
│ IQD       │ Iraqi Dinar                              │
├───────────┼──────────────────────────────────────────┤
│ IRR       │ Iranian Rial                             │
├───────────┼──────────────────────────────────────────┤
│ ISK       │ Icelandic Króna                          │
├───────────┼──────────────────────────────────────────┤
│ JEP       │ JEP                                      │
├───────────┼──────────────────────────────────────────┤
│ JMD       │ Jamaican Dollar                          │
├───────────┼──────────────────────────────────────────┤
│ JOD       │ Jordanian Dinar                          │
├───────────┼──────────────────────────────────────────┤
│ JPY       │ Japanese Yen                             │
├───────────┼──────────────────────────────────────────┤
│ KES       │ Kenyan Shilling                          │
├───────────┼──────────────────────────────────────────┤
│ KGS       │ Kyrgystani Som                           │
├───────────┼──────────────────────────────────────────┤
│ KHR       │ Cambodian Riel                           │
├───────────┼──────────────────────────────────────────┤
│ KID       │ KID                                      │
├───────────┼──────────────────────────────────────────┤
│ KMF       │ Comorian Franc                           │
├───────────┼──────────────────────────────────────────┤
│ KPW       │ North Korean Won                         │
├───────────┼──────────────────────────────────────────┤
│ KRW       │ South Korean Won                         │
├───────────┼──────────────────────────────────────────┤
│ KWD       │ Kuwaiti Dinar                            │
├───────────┼──────────────────────────────────────────┤
│ KYD       │ Cayman Islands Dollar                    │
├───────────┼──────────────────────────────────────────┤
│ KZT       │ Kazakhstani Tenge                        │
├───────────┼──────────────────────────────────────────┤
│ LAK       │ Laotian Kip                              │
├───────────┼──────────────────────────────────────────┤
│ LBP       │ Lebanese Pound                           │
├───────────┼──────────────────────────────────────────┤
│ LKR       │ Sri Lankan Rupee                         │
├───────────┼──────────────────────────────────────────┤
│ LRD       │ Liberian Dollar                          │
├───────────┼──────────────────────────────────────────┤
│ LSL       │ Lesotho Loti                             │
├───────────┼──────────────────────────────────────────┤
│ LYD       │ Libyan Dinar                             │
├───────────┼──────────────────────────────────────────┤
│ MAD       │ Moroccan Dirham                          │
├───────────┼──────────────────────────────────────────┤
│ MDL       │ Moldovan Leu                             │
├───────────┼──────────────────────────────────────────┤
│ MGA       │ Malagasy Ariary                          │
├───────────┼──────────────────────────────────────────┤
│ MKD       │ Macedonian Denar                         │
├───────────┼──────────────────────────────────────────┤
│ MMK       │ Myanmar Kyat                             │
├───────────┼──────────────────────────────────────────┤
│ MNT       │ Mongolian Tugrik                         │
├───────────┼──────────────────────────────────────────┤
│ MOP       │ Macanese Pataca                          │
├───────────┼──────────────────────────────────────────┤
│ MRU       │ Mauritanian Ouguiya                      │
├───────────┼──────────────────────────────────────────┤
│ MUR       │ Mauritian Rupee                          │
├───────────┼──────────────────────────────────────────┤
│ MVR       │ Maldivian Rufiyaa                        │
├───────────┼──────────────────────────────────────────┤
│ MWK       │ Malawian Kwacha                          │
├───────────┼──────────────────────────────────────────┤
│ MXN       │ Mexican Peso                             │
├───────────┼──────────────────────────────────────────┤
│ MYR       │ Malaysian Ringgit                        │
├───────────┼──────────────────────────────────────────┤
│ MZN       │ Mozambican Metical                       │
├───────────┼──────────────────────────────────────────┤
│ NAD       │ Namibian Dollar                          │
├───────────┼──────────────────────────────────────────┤
│ NGN       │ Nigerian Naira                           │
├───────────┼──────────────────────────────────────────┤
│ NIO       │ Nicaraguan Córdoba                       │
├───────────┼──────────────────────────────────────────┤
│ NOK       │ Norwegian Krone                          │
├───────────┼──────────────────────────────────────────┤
│ NPR       │ Nepalese Rupee                           │
├───────────┼──────────────────────────────────────────┤
│ NZD       │ New Zealand Dollar                       │
├───────────┼──────────────────────────────────────────┤
│ OMR       │ Omani Rial                               │
├───────────┼──────────────────────────────────────────┤
│ PAB       │ Panamanian Balboa                        │
├───────────┼──────────────────────────────────────────┤
│ PEN       │ Peruvian Sol                             │
├───────────┼──────────────────────────────────────────┤
│ PGK       │ Papua New Guinean Kina                   │
├───────────┼──────────────────────────────────────────┤
│ PHP       │ Philippine Piso                          │
├───────────┼──────────────────────────────────────────┤
│ PKR       │ Pakistani Rupee                          │
├───────────┼──────────────────────────────────────────┤
│ PLN       │ Polish Zloty                             │
├───────────┼──────────────────────────────────────────┤
│ PND       │ PND                                      │
├───────────┼──────────────────────────────────────────┤
│ PRB       │ PRB                                      │
├───────────┼──────────────────────────────────────────┤
│ PYG       │ Paraguayan Guarani                       │
├───────────┼──────────────────────────────────────────┤
│ QAR       │ Qatari Rial                              │
├───────────┼──────────────────────────────────────────┤
│ RON       │ Romanian Leu                             │
├───────────┼──────────────────────────────────────────┤
│ RSD       │ Serbian Dinar                            │
├───────────┼──────────────────────────────────────────┤
│ RUB       │ Russian Ruble                            │
├───────────┼──────────────────────────────────────────┤
│ RWF       │ Rwandan Franc                            │
├───────────┼──────────────────────────────────────────┤
│ SAR       │ Saudi Riyal                              │
├───────────┼──────────────────────────────────────────┤
│ SBD       │ Solomon Islands Dollar                   │
├───────────┼──────────────────────────────────────────┤
│ SCR       │ Seychellois Rupee                        │
├───────────┼──────────────────────────────────────────┤
│ SDG       │ Sudanese Pound                           │
├───────────┼──────────────────────────────────────────┤
│ SEK       │ Swedish Krona                            │
├───────────┼──────────────────────────────────────────┤
│ SGD       │ Singapore Dollar                         │
├───────────┼──────────────────────────────────────────┤
│ SHP       │ St. Helena Pound                         │
├───────────┼──────────────────────────────────────────┤
│ SLL       │ Sierra Leonean Leone                     │
├───────────┼──────────────────────────────────────────┤
│ SLS       │ SLS                                      │
├───────────┼──────────────────────────────────────────┤
│ SOS       │ Somali Shilling                          │
├───────────┼──────────────────────────────────────────┤
│ SRD       │ Surinamese Dollar                        │
├───────────┼──────────────────────────────────────────┤
│ SSP       │ South Sudanese Pound                     │
├───────────┼──────────────────────────────────────────┤
│ STN       │ São Tomé & Príncipe Dobra                │
├───────────┼──────────────────────────────────────────┤
│ SYP       │ Syrian Pound                             │
├───────────┼──────────────────────────────────────────┤
│ SZL       │ Swazi Lilangeni                          │
├───────────┼──────────────────────────────────────────┤
│ THB       │ Thai Baht                                │
├───────────┼──────────────────────────────────────────┤
│ TJS       │ Tajikistani Somoni                       │
├───────────┼──────────────────────────────────────────┤
│ TMT       │ Turkmenistani Manat                      │
├───────────┼──────────────────────────────────────────┤
│ TND       │ Tunisian Dinar                           │
├───────────┼──────────────────────────────────────────┤
│ TOP       │ Tongan Paʻanga                           │
├───────────┼──────────────────────────────────────────┤
│ TRY       │ Turkish Lira                             │
├───────────┼──────────────────────────────────────────┤
│ TTD       │ Trinidad & Tobago Dollar                 │
├───────────┼──────────────────────────────────────────┤
│ TVD       │ TVD                                      │
├───────────┼──────────────────────────────────────────┤
│ TWD       │ New Taiwan Dollar                        │
├───────────┼──────────────────────────────────────────┤
│ TZS       │ Tanzanian Shilling                       │
├───────────┼──────────────────────────────────────────┤
│ UAH       │ Ukrainian Hryvnia                        │
├───────────┼──────────────────────────────────────────┤
│ UGX       │ Ugandan Shilling                         │
├───────────┼──────────────────────────────────────────┤
│ USD       │ US Dollar                                │
├───────────┼──────────────────────────────────────────┤
│ UYU       │ Uruguayan Peso                           │
├───────────┼──────────────────────────────────────────┤
│ UZS       │ Uzbekistani Som                          │
├───────────┼──────────────────────────────────────────┤
│ VES       │ Venezuelan Bolívar                       │
├───────────┼──────────────────────────────────────────┤
│ VND       │ Vietnamese Dong                          │
├───────────┼──────────────────────────────────────────┤
│ VUV       │ Vanuatu Vatu                             │
├───────────┼──────────────────────────────────────────┤
│ WST       │ Samoan Tala                              │
├───────────┼──────────────────────────────────────────┤
│ XAF       │ Central African CFA Franc                │
├───────────┼──────────────────────────────────────────┤
│ XCD       │ East Caribbean Dollar                    │
├───────────┼──────────────────────────────────────────┤
│ XOF       │ West African CFA Franc                   │
├───────────┼──────────────────────────────────────────┤
│ XPF       │ CFP Franc                                │
├───────────┼──────────────────────────────────────────┤
│ YER       │ Yemeni Rial                              │
├───────────┼──────────────────────────────────────────┤
│ ZAR       │ South African Rand                       │
├───────────┼──────────────────────────────────────────┤
│ ZMW       │ Zambian Kwacha                           │
├───────────┼──────────────────────────────────────────┤
│ ZWB       │ ZWB                                      │
└───────────┴──────────────────────────────────────────┘

Run the following command in terminal to list all available currencies:

valuta-list-currencies

Custom currencies

To register a new custom currency, do as follows:

from valuta.base import BaseCurrency

class XYZ(BaseCurrency):
    """XYZ - The XYZ currency."""

    uid: str = "XYZ"
    rate: int = 100_000_000

Generating currencies from a CSV dump

If list of circulating currencies is ever updated, grab it the same way, save as list_of_circulating_currencies.csv in the source and run the following command:

valuta-generate-currencies --skip-first-line

Testing

Simply type:

pytest -vvv

Or use tox:

tox

Or use tox to check specific env:

tox -e py39-django32

Writing documentation

Keep the following hierarchy.

=====
title
=====

header
======

sub-header
----------

sub-sub-header
~~~~~~~~~~~~~~

sub-sub-sub-header
^^^^^^^^^^^^^^^^^^

sub-sub-sub-sub-header
++++++++++++++++++++++

sub-sub-sub-sub-sub-header
**************************

License

GPL-2.0-only OR LGPL-2.1-or-later

Support

For any issues contact me at the e-mail given in the Author section.

Author

Artur Barseghyan <artur.barseghyan@gmail.com>

Project documentation

Contents:

Indices and tables