Is it possible to use the National Bank of Georgia as a currency rate provider?

Hi,
I’m using Tryton 7.6 (server in Docker, PostgreSQL on Windows) and I would like to integrate exchange rates from the National Bank of Georgia (NBG) into Tryton.

What I want
My goal is to have official daily rates from NBG available in Tryton, ideally in a way similar to:

the existing source European Central Bank in Currencies → Scheduled Rate Updates, and/or

the official modules for other national banks (currency_ro, currency_rs).

Concretely, I would like:

either a new Source option in Scheduled Rate Updates like
NBG – National Bank of Georgia,

or a custom provider that Tryton can use to fetch daily rates automatically.

My company’s base currency is GEL, and I mainly need rates for USD/EUR against GEL.

What I have already tried
I’ve experimented in two directions:

Extending currency.rate.provider

I tried to add a custom provider for NBG and implement a method to fetch rates from the NBG JSON API.

This led to some confusion between get_providers / _get_providers depending on Tryton versions and internal implementation, and I got attribute errors around those methods.

I started to suspect that this is not the recommended or simplest way to do it in recent Tryton versions.

Following the pattern of currency_ro / currency_rs

I created a small custom module (let’s call it currency_ge) that extends currency.cron in the same conceptual way that currency_ro and currency_rs do:

add an extra source option for the national bank,

restrict the base currency to GEL when that source is selected,

implement a method that fetches data from NBG’s API and returns the rates in the format Tryton expects.

The module is installed and marked as Activated for my database (Tryton_new), and there are no obvious errors in the logs.

However, despite this, the new source does not appear in Currencies → Scheduled Rate Updates → Source – I only see the default European Central Bank entry.

In addition to this, I already have an external Python script (outside Tryton) that successfully:

calls the NBG JSON API,

converts the data,

and writes exchange rates into the database table currency.currency.rate.

So the technical part of reading NBG rates works, but right now I’m doing it externally, not through Tryton’s UI / built-in scheduling.

My question
Before I go deeper into debugging my custom module, I would like to understand the intended / recommended way in Tryton 7.6 for this use case:

Is it officially supported / recommended to add new national bank sources (like NBG) by extending currency.cron, similar to currency_ro and currency_rs?

Or is it better / expected to integrate new providers via currency.rate.provider instead?

Is there any existing example, guideline, or best practice for adding a custom national bank (for a new country) that I should follow?

From your point of view, is there any restriction or limitation that would prevent adding the National Bank of Georgia as a provider/source in a third-party module?

My ultimate goal is simply:

to have NBG as a selectable source/provider in Tryton,

so that scheduled updates can fetch rates from NBG automatically,

instead of maintaining a separate external script.

Any guidance on the correct approach and what is considered “Trytonic” for this kind of integration would be very helpful.

Yes.

I do not know what this is.

Just follow the design of the other similar modules.

No as long as there is a public API.

I suspect that your extension class of currency.cron is not registered in the pool. Or the __setup__ extension is not done right.

Cedric,

Thanks a lot for your reply.

As you suspected, it really looks like my extension of currency.cron is not registered in the pool.

To keep things minimal, here is exactly what I have now for my custom module currency_ge:

tryton.cfg

[tryton]
version=7.6.0
depends:
currency
company
xml:

_init_.py

from trytond.pool import Pool
from . import currency

all = [‘register’]

def register():
Pool.register(
currency.Cron,
module=‘currency_ge’, type_=‘model’)

currency.py (only the important part)

from decimal import Decimal
import datetime as dt
import json
import ssl
from urllib.request import urlopen, Request
from urllib.error import URLError, HTTPError

from trytond.modules.currency.currency import CronFetchError
from trytond.pool import PoolMeta
from trytond.pyson import Eval, If

all = [‘Cron’]

class Cron(metaclass=PoolMeta):
name = “currency.cron”

@classmethod
def __setup__(cls):
    super().__setup__()
    entry = ("nbg", "National Bank of Georgia")
    if entry not in cls.source.selection:
        cls.source.selection.append(entry)

    cls.currency.domain = [
        cls.currency.domain or [],
        If(Eval('source') == 'nbg',
           ('code', '=', 'GEL'),
           ()),
    ]

def fetch_nbg(self, date):
    # here I call the public JSON API of the National Bank of Georgia
    # and return a mapping { 'USD': Decimal(...), 'EUR': Decimal(...), ... }
    ...

The module directory is named currency_ge and is mounted inside the container under /modules/currency_ge.
In Administration → Modules → Modules the module currency_ge appears and is marked as Activated for my database Tryton_new.

To install/update it I run:

trytond-admin -c /etc/trytond.conf -d Tryton_new -m
trytond-admin -c /etc/trytond.conf -d Tryton_new -u currency_ge --activate-dependencies --verbose

trytond-admin -c /etc/trytond.conf -d Tryton_new -m
trytond-admin -c /etc/trytond.conf -d Tryton_new -u currency_ge --activate-dependencies --verbose

Then I restart the server.

After that, from inside the container I inspect currency.cron with:


from trytond.config import config
from trytond.pool import Pool
from trytond.transaction import Transaction

config.update_etc('/etc/trytond.conf')
db = 'Tryton_new'

with Transaction().start(db, 0, readonly=True):
    pool = Pool()
    pool.init()
    Cron = pool.get('currency.cron')
    print("Has fetch_nbg:", hasattr(Cron, 'fetch_nbg'))
    print("Sources selection:", Cron.source.selection)

The result is:

Has fetch_nbg: False
Sources selection: [(‘ecb’, ‘European Central Bank’)]

So my Cron subclass does not seem to be merged into currency.cron at all:

  • fetch_nbg is not present,

  • and the source.selection only contains the ECB entry.

Given the code above, do you see what I am doing wrong?
Is there something missing in the way I register the model or in the module configuration, so that currency_ge.Cron is not taken into account when building the final currency.cron class?

Thanks again for any hint – I am clearly close, but I’m missing the last piece.

This is strange because in standard docker image, the modules are not at this path. So I suspect that the module activated is not the module with the code you described.

It will be better instead of injecting code like that, to extend the existing image and install your module using pip3 install.