fava

Fava - A web interface for Beancount.

fava._babel

Custom Babel extractor for Svelte files.

fava._babel.extract_svelte(fileobj, keywords, comment_tags, options)

Extract messages from Svelte files.

Return type:

Generator[tuple[int, str | tuple[str, ...], list[str], str | None], None, None]

fava._ctx_globals_class

Specify types for the flask application context.

class fava._ctx_globals_class.Context

The context values - this is used for flask.g.

beancount_file_slug: str | None

Slug for the active Beancount file.

property conv: Conversion

Conversion to apply (parsed).

property conversion: str

Conversion to apply (raw string).

extension: FavaExtensionBase | None

The current extension, if this is an extension endpoint

property filtered: FilteredLedger

The filtered ledger.

property interval: Interval

Interval to group by.

ledger: FavaLedger

The ledger

fava._structs

msgspec Structs used in serialisation.

class fava._structs.Balance(account: str, amount: _Amount, diff_amount: _Amount | None = None, tolerance: Decimal | None = None, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
account: str
amount: _Amount
diff_amount: _Amount | None
tolerance: Decimal | None
class fava._structs.Close(account: str, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
account: str
class fava._structs.Commodity(currency: str, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
currency: str
class fava._structs.Custom(type: str, values: list[str | bool | date | Decimal | _Amount], *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
type: str
values: list[str | bool | date | Decimal | _Amount]
class fava._structs.Document(account: str, filename: str, tags: frozenset[str] | None = None, links: frozenset[str] | None = None, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
account: str
filename: str
tags: frozenset[str] | None
class fava._structs.EntryStruct(*, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')

msgspec Struct representations of entries.

date: date
entry_hash: str
meta: dict[str, str | bool | int | _Amount]
class fava._structs.Event(type: str, description: str, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
description: str
type: str
class fava._structs.Note(account: str, comment: str, tags: frozenset[str] | None = None, links: frozenset[str] | None = None, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
account: str
comment: str
tags: frozenset[str] | None
class fava._structs.Open(account: str, currencies: list[str] | None, booking: Booking | None = None, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
account: str
booking: Booking | None
currencies: list[str] | None
class fava._structs.Pad(account: str, source_account: str, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
account: str
source_account: str
class fava._structs.Posting(*, account: str, amount: str = '', flag: str = '', meta: dict[str, str | bool | int | _Amount] | None = None)
account: str
amount: str
flag: str
meta: dict[str, str | bool | int | _Amount] | None
class fava._structs.Price(currency: str, amount: _Amount, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
amount: _Amount
currency: str
class fava._structs.Query(name: str, query_string: str, *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
name: str
query_string: str
class fava._structs.Transaction(flag: str, narration: str, postings: list[Posting], payee: str = '', tags: frozenset[str] = frozenset({}), links: frozenset[str] = frozenset({}), *, date: date, meta: dict[str, str | bool | int | _Amount], entry_hash: str = '')
flag: str
narration: str
payee: str
postings: list[Posting]
tags: frozenset[str]

fava.application

Fava’s main WSGI application.

you can use create_app to create a Fava WSGI app for a given list of files. To start a simple server:

from fava.application import create_app

app = create_app(['/path/to/file.beancount'])
app.run('localhost', 5000)
fava.application.create_app(files, *, load=False, incognito=False, read_only=False, poll_watcher=False)

Create a Fava Flask application.

Parameters:
  • files (Iterable[Path | str]) – The list of Beancount files (paths).

  • load (bool) – Whether to load the Beancount files directly.

  • incognito (bool) – Whether to run in incognito mode.

  • read_only (bool) – Whether to run in read-only mode.

  • poll_watcher (bool) – Whether to use old poll watcher

Return type:

Flask

fava.application.static_url(filename)

Return a static url with an mtime query string for cache busting.

Return type:

str

fava.application.translations()

Get translations catalog.

Return type:

dict[str, str]

fava.application.url_for(endpoint, **values)

Wrap flask.url_for using a cache.

Return type:

str

fava.cli

The command-line interface for Fava.

exception fava.cli.AddressInUse(port)
exception fava.cli.NoFileSpecifiedError
exception fava.cli.NonAbsolutePathError(path)

fava.context

Specify types for the flask application context.

fava.helpers

Exceptions and module base class.

class fava.helpers.BeancountError(source: Meta | None, message: str, entry: Directive | None = None)

NamedTuple base for a Beancount-style error.

exception fava.helpers.FavaAPIError(message=None)

Fava’s base exception class.

fava.internal_api

Internal API.

This is used to pre-process some data that is used in the templates, allowing this part of the functionality to be tested and allowing some end-to-end tests for the frontend data validation.

class fava.internal_api.BalancesChart(label: str, data: Sequence[DateAndBalance], type: Literal['balances'] = 'balances')

Data for a balances chart.

data: Sequence[DateAndBalance]
label: str
type: Literal['balances']
class fava.internal_api.BarChart(label: str, data: Sequence[DateAndBalanceWithBudget], type: Literal['bar'] = 'bar')

Data for a bar chart.

data: Sequence[DateAndBalanceWithBudget]
label: str
type: Literal['bar']
class fava.internal_api.ChartApi

Functions to generate chart data.

static account_balance(account_name)

Generate data for an account balances chart.

Return type:

BalancesChart | BarChart | HierarchyChart

static hierarchy(account_name, *, label=None)

Generate data for an account hierarchy chart.

Return type:

BalancesChart | BarChart | HierarchyChart

static interval_totals(interval, account_name, label=None, *, invert=False)

Generate data for an account per interval chart.

Return type:

BalancesChart | BarChart | HierarchyChart

static net_worth()

Generate data for net worth chart.

Return type:

BalancesChart | BarChart | HierarchyChart

class fava.internal_api.HierarchyChart(label: str, data: SerialisedTreeNode, type: Literal['hierarchy'] = 'hierarchy')

Data for a hierarchy chart.

data: SerialisedTreeNode
label: str
type: Literal['hierarchy']
class fava.internal_api.LedgerData(accounts: Sequence[str], account_details: AccountDict, base_url: str, currencies: Sequence[str], currency_names: dict[str, str], errors: Sequence[SerialisedError], fava_options: FavaOptions, incognito: bool, have_excel: bool, links: Sequence[str], options: dict[str, str | Sequence[str]], payees: Sequence[str], precisions: dict[str, int], tags: Sequence[str], years: Sequence[str], user_queries: Sequence[object], upcoming_events_count: int, extensions: Sequence[ExtensionDetails], sidebar_links: Sequence[tuple[str, str]], other_ledgers: Sequence[tuple[str, str]])

This is used as report-independent data in the frontend.

account_details: AccountDict
accounts: Sequence[str]
base_url: str
currencies: Sequence[str]
currency_names: dict[str, str]
errors: Sequence[SerialisedError]
extensions: Sequence[ExtensionDetails]
fava_options: FavaOptions
have_excel: bool
incognito: bool
options: dict[str, str | Sequence[str]]
other_ledgers: Sequence[tuple[str, str]]
payees: Sequence[str]
precisions: dict[str, int]
tags: Sequence[str]
upcoming_events_count: int
user_queries: Sequence[object]
years: Sequence[str]
class fava.internal_api.SerialisedError(type: str, source: Mapping[str, str | int | bool | Decimal | date | Amount] | None, message: str)

A Beancount error, as passed to the frontend.

static from_beancount_error(err)

Get a serialisable error from a Beancount error.

Return type:

SerialisedError

message: str
source: Mapping[str, str | int | bool | Decimal | date | Amount] | None
type: str
fava.internal_api.get_errors()

Serialise errors (do not pass entry as that might fail serialisation.

Return type:

list[SerialisedError]

fava.internal_api.get_ledger_data()

Get the report-independent ledger data.

Return type:

LedgerData

fava.json_api

JSON API.

This module contains the url endpoints of the JSON API that is used by the web interface for asynchronous functionality.

class fava.json_api.AddDocumentForm(folder: str, account: str, hash: str = '')

Required form fields when adding a document.

account: str
folder: str
hash: str
exception fava.json_api.DocumentDirectoryMissingError(message=None)

You need to set a documents folder.

status = 422
class fava.json_api.ErrorResponse(error: str)

Error response object structure.

error: str
exception fava.json_api.FavaJSONAPIError(message=None)

An error with a HTTPStatus.

abstract property status: HTTPStatus

HTTP status that should be used for the response.

exception fava.json_api.FileDoesNotExistError(filename)

The given file does not exist.

status = 404
class fava.json_api.HelpPage(html: str, pages: Sequence[tuple[str, str]])

A rendered help page and the list of all help pages.

html: str
pages: Sequence[tuple[str, str]]
exception fava.json_api.InvalidJsonRequestError

Invalid JSON body.

class fava.json_api.JournalPage(page: int, total_pages: int, journal: str)

A rendered journal page.

journal: str
page: int
total_pages: int
exception fava.json_api.NoFileUploadedError(message=None)

No file uploaded.

status = 400
exception fava.json_api.NotAFileError(filename)

Not a file.

status = 422
exception fava.json_api.NotAValidDocumentOrImportFileError(filename)

Not valid document or import file.

status = 400
exception fava.json_api.NotFoundError(message=None)

Not found.

status = 404
class fava.json_api.Options(fava_options: Mapping[str, str], beancount_options: Mapping[str, str])

Fava and Beancount options as strings.

beancount_options: Mapping[str, str]
fava_options: Mapping[str, str]
class fava.json_api.SourceFile(file_path: str, sha256sum: str, source: str)

Source slice for an entry.

file_path: str
sha256sum: str
source: str
class fava.json_api.SourceSlice(sha256sum: str, slice: str)

Source slice for an entry.

sha256sum: str
slice: str
class fava.json_api.Statistics(all_balance_directives: str, balances: Mapping[str, SimpleCounterInventory], entries_by_type: Mapping[str, int])

Data for the statistics report.

all_balance_directives: str
balances: Mapping[str, SimpleCounterInventory]
entries_by_type: Mapping[str, int]
class fava.json_api.SuccessResponse(data: object, mtime: str)

Response structure.

data: object
mtime: str
exception fava.json_api.TargetPathAlreadyExistsError(path)

The given path already exists.

status = 409
class fava.json_api.TreeReport(date_range: DateRange | None, charts: Sequence[BalancesChart | BarChart | HierarchyChart], trees: Sequence[SerialisedTreeNode])

Data for the tree reports.

charts: Sequence[BalancesChart | BarChart | HierarchyChart]
date_range: DateRange | None
trees: Sequence[SerialisedTreeNode]
exception fava.json_api.UploadedFileIsMissingFilenameError(message=None)

Uploaded file is missing filename.

status = 400
exception fava.json_api.ValidationError(reason)

Validation of data failed.

status = 400
fava.json_api.api_endpoint(func)

Register an API endpoint.

The part of the function name up to the first underscore determines the accepted HTTP method. For GET and DELETE endpoints, the function parameters are converted from the URL query string; for PUT endpoints, they are decoded from the JSON request body. Both use a msgspec Struct generated from the function’s parameters for the typed validation.

Return type:

Callable[[], Response]

fava.json_api.build_json_body_decoder(func)

Build a msgspec-typed decoder for the JSON body of an endpoint.

Return type:

Callable[[bytes], Sequence[object]] | None

fava.json_api.build_query_string_decoder(func)

Build a msgspec-typed decoder for an endpoint’s query string.

Return type:

Callable[[Mapping[str, str]], Sequence[object]] | None

fava.json_api.delete_document(filename)

Delete a document.

Return type:

str

fava.json_api.delete_source_slice(entry_hash, sha256sum)

Delete an entry source slice.

Return type:

str

fava.json_api.get_account_report(a='', r='')

Get the data for the account report.

Return type:

AccountReportJournal | AccountReportTree

fava.json_api.get_balance_sheet()

Get the data for the balance sheet.

Return type:

TreeReport

fava.json_api.get_changed()

Check for file changes.

Return type:

bool

fava.json_api.get_commodities()

Get the prices for all commodity pairs.

Return type:

Sequence[CommodityPairWithPrices]

fava.json_api.get_context(entry_hash)

Entry context.

Return type:

Context

fava.json_api.get_documents()

Get all (filtered) documents.

Return type:

Sequence[object]

fava.json_api.get_events()

Get all (filtered) events.

Return type:

Sequence[object]

fava.json_api.get_extract(filename, importer)

Extract entries using the ingest framework.

Return type:

Sequence[object]

fava.json_api.get_help(page_slug)

Get one of Fava’s help pages, rendered to HTML.

Return type:

HelpPage

fava.json_api.get_imports()

Get a list of the importable files.

Return type:

Sequence[FileImporters]

fava.json_api.get_income_statement()

Get the data for the income statement.

Return type:

TreeReport

fava.json_api.get_journal()

Get all (filtered) entries.

Return type:

Sequence[object]

fava.json_api.get_journal_page(page, order)

Get the HTML contents for a Journal page.

Return type:

JournalPage

fava.json_api.get_narration_transaction(narration)

Last transaction for the given narration.

Return type:

object

fava.json_api.get_narrations()

List of all narrations in the ledger.

Return type:

Sequence[str]

fava.json_api.get_options()

Get all options, rendered to strings for displaying in the frontend.

Return type:

Options

fava.json_api.get_payee_accounts(payee)

Rank accounts for the given payee.

Return type:

Sequence[str]

fava.json_api.get_payee_transaction(payee)

Last transaction for the given payee.

Return type:

object

fava.json_api.get_query(query_string)

Run a Beancount query.

Return type:

QueryResultTable | QueryResultText

fava.json_api.get_source(filename='')

Load one of the source files.

Return type:

SourceFile

fava.json_api.get_source_slice(entry_hash)

Entry slice.

Return type:

SourceSlice

fava.json_api.get_statistics()

Get the data for the statistics report.

Return type:

Statistics

fava.json_api.get_trial_balance()

Get the data for the trial balance.

Return type:

TreeReport

fava.json_api.json_err(msg, status)

Jsonify the error message.

Return type:

Response

fava.json_api.put_add_document()

Upload a document.

Return type:

str

fava.json_api.put_add_entries(entries)

Add multiple entries.

Return type:

str

fava.json_api.put_attach_document(filename, entry_hash)

Attach a document to an entry.

Return type:

str

fava.json_api.put_format_source(source)

Format beancount file.

Return type:

str

fava.json_api.put_move(account, new_name, filename)

Move a document.

Return type:

str

fava.json_api.put_source(file_path, source, sha256sum)

Write one of the source files and return the updated sha256sum.

Return type:

str

fava.json_api.put_source_slice(entry_hash, source, sha256sum)

Write an entry source slice and return the updated sha256sum.

Return type:

str

fava.json_api.put_upload_import_file()

Upload a file for importing.

Return type:

str

fava.json_api.validate_file()

Validate the form request contains a file with filename.

Return type:

tuple[FileStorage, str]

fava.json_api.validate_form(t)

Validate the provided form fields to match the passed type.

Return type:

TypeVar(T)

fava.serialisation

(De)serialisation of entries.

When adding entries, these are saved via the JSON API - using the functionality of this module to obtain the appropriate data structures from beancount.core.data. Similarly, for the full entry completion, a JSON representation of the entry is provided.

This is not intended to work well enough for full roundtrips yet.

exception fava.serialisation.InvalidAmountError(amount)

Invalid amount.

fava.serialisation.deserialise(entry)

Convert an entry received from the frontend to a Beancount entry.

Return type:

Directive

fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)
fava.serialisation.serialise(o)

Map a value so that it can be serialised to JSON.

Return type:

object

fava.template_filters

Template filters for Fava.

All functions in this module will be automatically added as template filters.

fava.template_filters.basename(file_path)

Return the basename of a filepath.

Return type:

str

fava.template_filters.flag_to_type(flag)

Names for entry flags.

Return type:

str

fava.template_filters.format_currency(value, currency=None)

Format a value using the derived precision for a specified currency.

Return type:

str

fava.template_filters.meta_items(meta)

Remove keys from a dictionary.

Return type:

list[tuple[str, str | int | bool | Decimal | date | Amount]]

fava.template_filters.passthrough_numbers(value)

Pass through value unchanged.

Return type:

TypeVar(T)

fava.template_filters.replace_numbers(value)

Replace numbers, to be used in incognito mode.

Return type:

str | None