Package: smart-importer
https://github.com/beancount/smart_importerAugmentsBeancountimporters
with machine learning functionality.StatusWorking protoype, development status: betaInstallationThesmart_importercan be installed from PyPI:pipinstallsmart_importerQuick StartThis package provides import hooks that can modify the imported entries. When
running the importer, the existing entries will be used as training data for a
machine learning model, which will then predict entry attributes.The following example shows how to apply thePredictPostingshook to
an existing CSV importer:frombeancount.ingest.importersimportcsvfrombeancount.ingest.importers.csvimportColfromsmart_importerimportapply_hooks,PredictPostingsclassMyBankImporter(csv.Importer):'''Conventional importer for MyBank'''def__init__(self,*,account):super().__init__({Col.DATE:'Date',Col.PAYEE:'Transaction Details',Col.AMOUNT_DEBIT:'Funds Out',Col.AMOUNT_CREDIT:'Funds In'},account,'EUR',('Date, Transaction Details, Funds Out, Funds In'))CONFIG=[apply_hooks(MyBankImporter(account='Assets:MyBank:MyAccount'),[PredictPostings()])]DocumentationThis section explains in detail the relevant concepts and artifacts
needed for enhancing Beancount importers with machine learning.Beancount ImportersLet’s assume you have created an importer for “MyBank” calledMyBankImporter:classMyBankImporter(importer.ImporterProtocol):"""My existing importer"""# the actual importer logic would be here...Note:
This documentation assumes you already know how to create Beancount importers.
Relevant documentation can be found in thebeancount import documentation.
With the functionality of beancount.ingest, users can
write their own importers and use them to convert downloaded bank statements
into lists of Beancount entries.
An example is provided as part of beancount v2’s source code underexamples/ingest/office.smart_importer only works by appending onto incomplete single-legged postings
(i.e. It will not work by modifying postings with accounts like “Expenses:TODO”).
Theextractmethod in the importer should follow thelatest interfaceand include anexisting_entriesargument.Applyingsmart_importerhooksAny Beancount importer can be converted into a smart importer by applying one
of the following hooks:PredictPostings- predict the list of postings.PredictPayees- predict the payee of the transaction.DuplicateDetector- detect duplicatesFor example, to convert an existingMyBankImporterinto a smart importer:fromyour_custom_importerimportMyBankImporterfromsmart_importerimportapply_hooks,PredictPayees,PredictPostingsmy_bank_importer=MyBankImporter('whatever','config','is','needed')apply_hooks(my_bank_importer,[PredictPostings(),PredictPayees()])CONFIG=[my_bank_importer,]Note that the importer hooks need to be applied to an importer instance, as
shown above.Specifying Training DataThesmart_importerhooks need training data, i.e. an existing list of
transactions in order to be effective. Training data can be specified by
calling bean-extract with an argument that references existing Beancount
transactions, e.g.,bean-extract-fexisting_transactions.beancount. When
using the importer in Fava, the existing entries are used as training data
automatically.Usage with FavaSmart importers play nice withFava.
This means you can use smart importers together with Fava in the exact same way
as you would do with a conventional importer. SeeFava’s help on importersfor more
information.DevelopmentPull requests welcome!Executing the Unit TestsSimply run (requires tox):maketestConfiguring LoggingPython’sloggingmodule is used by the smart_importer module.
The according log level can be changed as follows:importlogginglogging.getLogger('smart_importer').setLevel(logging.DEBUG)Using TokenizerCustom tokenizers can let smart_importer support more languages, eg. Chinese.If you looking for Chinese tokenizer, you can follow this example:First make sure thatjiebais installed in your python environment:pipinstalljiebaIn your importer code, you can then passjiebato be used as tokenizer:fromsmart_importerimportPredictPostingsimportjiebajieba.initialize()tokenizer=lambdas:list(jieba.cut(s))predictor=PredictPostings(string_tokenizer=tokenizer)