fava.util

Some small utility functions.

fava.util.filter_api_changed(record)

Filter out LogRecords for requests that poll for changes.

Return type:

bool

fava.util.listify(func)

Make generator function return a list (decorator).

Return type:

Callable[[ParamSpec(P, bound= None)], list[TypeVar(Item)]]

fava.util.next_key(basekey, keys)

Return the next unused key for basekey in the supplied dictionary.

The first try is basekey, followed by basekey-2, basekey-3, etc until a free one is found.

Return type:

str

fava.util.send_file_inline(filename)

Send a file inline, including the original filename.

Ref: http://test.greenbytes.de/tech/tc2231/.

Return type:

Response

fava.util.setup_logging()

Set up logging for Fava.

Return type:

None

fava.util.simple_wsgi(_, start_response)

Return an empty response (a simple WSGI app).

Return type:

list[bytes]

fava.util.slugify(string)

Slugify a string.

Parameters:

string (str) – A string.

Returns:

str – A ‘slug’ of the string suitable for URLs. Retains non-ascii characters.

fava.util.timefunc(func)

Time function for debugging (decorator).

Return type:

Callable[[ParamSpec(P, bound= None)], TypeVar(T)]

fava.util.date

Date-related functionality.

Note

Date ranges are always tuples (start, end) from the (inclusive) start date to the (exclusive) end date.

class fava.util.date.DateRange(begin, end)

A range of dates, usually matching an interval.

begin: date

The inclusive start date of this range of dates.

end: date

The exclusive end date of this range of dates.

property end_inclusive: date

The last day of this interval.

class fava.util.date.FiscalYearEnd(month, day)

Month and day that specify the end of the fiscal year.

day: int
has_quarters()

Whether this fiscal year end supports fiscal quarters.

Return type:

bool

month: int
property month_of_year: int

Actual month of the year.

property year_offset: int

Number of years that this is offset into the future.

exception fava.util.date.FyeHasNoQuartersError

Only fiscal year that start on the first of a month have quarters.

class fava.util.date.Interval(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

The possible intervals.

DAY = 'day'
MONTH = 'month'
QUARTER = 'quarter'
WEEK = 'week'
YEAR = 'year'
format_date(date)

Format a date for this interval for human consumption.

Return type:

str

format_date_filter(date)

Format a date for this interval for the Fava time filter.

Return type:

str

static get(string)

Return the enum member for a string.

Return type:

Interval

property label: str

The label for the interval.

fava.util.date.dateranges(begin, end, interval)

Get date ranges for the given begin and end date.

Parameters:
  • begin (date) – The begin date - the first interval date range will include this date

  • end (date) – The end date - the last interval will end on or after date

  • interval (Interval) – The type of interval to generate ranges for.

Yields:

Date ranges for all intervals of the given in the

Return type:

Iterable[DateRange]

fava.util.date.days_in_daterange(start_date, end_date)

Yield a datetime for every day in the specified interval.

Parameters:
  • start_date (date) – A start date.

  • end_date (date) – An end date (exclusive).

Returns:

Iterator[date] – An iterator yielding all days between start_date to end_date.

fava.util.date.get_fiscal_period(year, fye, quarter=None)

Calculate fiscal periods.

Uses the fava option “fiscal-year-end” which should be in “%m-%d” format. Defaults to calendar year [12-31]

Parameters:
  • year (int) – An integer year

  • fye (FiscalYearEnd | None) – End date for period in “%m-%d” format

  • quarter (int | None) – one of [None, 1, 2, 3 or 4]

Returns:

tuple[date | None, date | None] – A tuple (start, end) of dates.

fava.util.date.get_next_interval(date, interval)

Get the start date of the next interval.

Parameters:
  • date (date) – A date.

  • interval (Interval) – An interval.

Returns:

date – The start date of the next interval after date.

fava.util.date.get_prev_interval(date, interval)

Get the start date of the interval in which the date falls.

Parameters:
  • date (date) – A date.

  • interval (Interval) – An interval.

Returns:

date – The start date of the interval before date.

fava.util.date.interval_ends(first, last, interval)

Get interval ends.

Return type:

Iterator[date]

fava.util.date.local_today()

Today as a date in the local timezone.

Return type:

date

fava.util.date.month_offset(date, months)

Offsets a date by a given number of months.

Maintains the day, unless that day is invalid when it will raise a ValueError

Return type:

date

fava.util.date.number_of_days_in_period(interval, date)

Get number of days in the surrounding interval.

Parameters:
  • interval (Interval) – An interval.

  • date (date) – A date.

Returns:

int – A number, the number of days surrounding the given date in the interval.

fava.util.date.parse_date(string, fye=None)

Parse a date.

Example of supported formats:

  • 2010-03-15, 2010-03, 2010

  • 2010-W01, 2010-Q3

  • FY2012, FY2012-Q2

Ranges of dates can be expressed in the following forms:

  • start - end

  • start to end

where start and end look like one of the above examples

Parameters:
  • string (str) – A date(range) in our custom format.

  • fye (FiscalYearEnd | None) – The fiscal year end to consider.

Returns:

tuple[date | None, date | None] – A tuple (start, end) of dates.

fava.util.date.parse_fye_string(fye)

Parse a string option for the fiscal year end.

Parameters:

fye (str) – The end of the fiscal year to parse.

Return type:

FiscalYearEnd | None

fava.util.date.substitute(string, fye=None)

Replace variables referring to the current day.

Parameters:
  • string (str) – A string, possibly containing variables for today.

  • fye (FiscalYearEnd | None) – Use a specific fiscal-year-end

Returns:

str – A string, where variables referring to the current day, like ‘year’ or ‘week’ have been replaced by the corresponding string understood by parse_date(). Can compute addition and subtraction.

fava.util.excel

Writing query results to CSV and spreadsheet documents.

fava.util.excel.to_csv(types, rows)

Save result to CSV.

Parameters:
Returns:

BytesIO – The (binary) file contents.

fava.util.excel.to_excel(types, rows, result_format, query_string)

Save result to spreadsheet document.

Parameters:
  • types (list[tuple[str, type[Any]]]) – query result_types.

  • rows (list[tuple[Any, ...]]) – query result_rows.

  • result_format (str) – ‘xlsx’ or ‘ods’.

  • query_string (str) – The query string (is written to the document).

Returns:

BytesIO – The (binary) file contents.

fava.util.ranking

Ranking utilities.

class fava.util.ranking.ExponentialDecayRanker(list_=None, rate=0.0018990333713971104)

Rank a list by exponential decay.

Maintains scores for the items in a list. We can think of this as the sum of all ‘likes’, where the value of a ‘like’ starts at 1 and decays exponentially. So the current score would be given by (where t is the current time and l is the time of the ‘like’)

s = Σ exp(-RATE * (t - l))

As only the relative order on the items is relevant, we can multiply all scores by exp(RATE * t) and so we need to compute the following score:

s = Σ exp(RATE * l)

To avoid huge numbers, we actually compute and store the logarithm of that sum.

Parameters:
  • list – If given, this list is ranked is by .sort() otherwise all items with at least one ‘like’ will be ranked.

  • rate (float) – This sets the rate of decay. 1/rate will be the time (in days) that it takes for the value of a ‘like’ to decrease by 1/e. The default rate is set to math.log(2) * 1/365 so that a ‘like’ from a year ago will count half as much as one from today.

get(item)

Get the current score for an item, or zero.

Return type:

float

list
rate
scores: dict[str, float]
sort()

Return items sorted by rank.

Return type:

list[str]

update(item, date)

Add ‘like’ for item.

Parameters:
  • item (str) – An item in the list that is being ranked.

  • date (date) – The date on which the item has been liked.

Return type:

None

fava.util.sets

Utils for Python sets.

fava.util.sets.add_to_set(set_, new)

Add an entry to a set (or create it if doesn’t exist).

Parameters:
  • set – The (optional) set to add an element to.

  • new (str) – The string to add to the set.

Return type:

set[str]