Giter VIP home page Giter VIP logo

financespy's Introduction

FinancesPy

FinancesPy is an API for personal finances inspired by Gnucash, Mint, Ynab, and similar software. It provides:

  • A literate API for personal finances concepts that can be used in any Python application.
  • Support for multiple storage (called backends in the project): comma-separated-values files, XLSX files, relational, and relational databases.
  • Importing and exporting from one storage type to another.
  • Time iterators for querying transactions by months, weeks, or days.
  • Hierarchical categorization of transactions (e.g.: food -> groceries -> [aldi, rewe, penny, ...])

It does not provide:

However, FinancesPy is usable out of the box with Jupyter notebooks. Some examples will be available in this repository.

Categories

Categories are just labels you put on your transactions according to the source or destination of the money. The concept appears at virtually any other software of the genre. FinancesPy has two distinct features in this regard:

  • Multiples categories can be assigned to a transaction. Every transaction should have a main category, additional categories are optional
  • Categories are hierarchical. A category can form a "tree" (in CS sense) of categories, for example:
    • food
      • restaurant
      • junk_food
      • bakery
      • icecream
      • ...
      • groceries
        • aldi
        • edeka
        • penny

In the example above, you have a super-category "food" for every euro/dollar/rupee you spend to the purpose of feeding yourself. If you mark a transaction with the category "penny", it is also belongs to the "groceries" and "food" categories. Having this hierarchical labeling system allows precise queries being made over the records:

  • How much did I spend in penny and aldi: penny and aldi
  • How much did I spend eating outside: food and (not groceries)
  • How much did I spend eating outside with my girlfriend: food and (not groceries) and gilrfriend. In this example you combine having multiple labels with hierarchical labeling.

Looks overkill, I know, but I found this concept useful for my own financial tracking. It's nice being able to visualize my spending in multiple ways. You also don't need to abuse this system if you don't need/want to.

Categories are best represented in the same way identifiers are represented in a programming language: no spaces in between. You can follow snake or camel-case conventions to express multi-word concepts. If follow this convention, then you can use the magic method "is_" in the class transaction.

Gnucash users can realize this is partially an imitation of the hierarchical account settings from their software. Yes, that is true, FinancesPy also benefits from hierarchical classification of transactions. In FinancesPy, however, they are not "accounts", but just "labels", and a transaction can have multiple labels. For the mapping between Gnucash and FinancesPy concepts, refer to the section (TODO)...

march_records = ...
groceries_march = [ trans for trans in march_records if trans.is_groceries ]

If you don't follow this convention, the method "matches_category" should be used instead:

march_records = ...
junk_food_march = [ trans for trans in march_records if trans.matches_category("junk food") ]

The boolean queries mentioned above look prettier if you use this convention.

Backends

"Backend" refers to the storage medium/file/database/etc on which the transactions are stored. The following list describes the supported backends at time of writing:

In memory

A volatile storage of transaction records. It uses Python maps and lists internally, and it provides all time iterators for querying months, weeks and days. This backend is used for two purposes:

  • For the unit/integration tests in the project
  • For exporting data from other backends (the SQL backend uses it internally, for instance)
categories = categories_from_list([
...
])

be = MemoryBackend(categories)

transaction = parse_transaction("97.2, monthly_ticket")
be.insert_record(date=datetime(10, 12, 2020), transaction))

Comma separated files

This is a persistent backend that uses just plain text files to store the transaction data. To create a backend object that uses CSV files, you have to point to the root folder which the files are stored:

csv_backend = FilesystemBackend(categories, "/home/john/Documents/finance/savings")

The subfolders and files should be written according to the following conventions:

  • There should be a folder for each year, if there are recordings for this year. The folder name is the year with all digits ("2019", "2020", "2021", etc.)
  • Inside the folder for each year, there should be a folder for each month, and they are named with the three initial letters of the english name of the month: jan, feb, mar, ...
  • For each day which has recordings, you append transactions in a csv file named: <day number>.csv (starts with 1)
  • Each line in the CSV has the following format (elements inside [] are optional):
    • <value>, <main_category>, [description], [additional categories separated by a comma]

XLSX files

Using Excel is the most common form of tracking spending with a computer. The XLSXBackend class allows to use Excel spreadsheets as a backend for FinancesPy. It is also necessary to follow a certain convention so FinancesPy can know how to read the spreadsheet. The picture below shows an Excel spreadsheet adapted for FinancesPy:

alt text

You can use any font, cell colors, etc. FinancesPy will just enforce the following conventions:

  • A XLSX backend is represented by a folder that contains XLSX files. Each file represents a year, and it is named: .xlsx
  • There should be a sheet for each month, and they can have any name, but it's better to name them: jan, feb, mar, ...
  • Each sheet has the following layout:
    • First column is the day number for the record
    • Second column is the main category
    • Third column is the value
    • Fourth column is a description (optional)
    • Fifth column are additional categories, separated by comma (optional)

An example of such spreadsheet can be found here, and a blank template is available here.

SQL backend

For using FinancesPy in a larger and multi-user application, using relational databases is the best way. SQLAlchemy is used for being independent of database. Check the source file of the SQLBackend class to inspect the table structure and verify which column types should be used for your favorite database.

financespy's People

Contributors

calexandrepcjr avatar danilomo avatar dependabot[bot] avatar mateusrangel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

financespy's Issues

Document classes and functions

Currently the project has zero docstrings. It is important, for an API, that each method and class be well documented.

We should make an effort to document the current classes and functions in the project, and require that new public API types and functions be documented before being committed to master.

Create XLSX backend

Currently we only support plain text files as storage for recording transaction data. Support to SQLite and PostgreSQL databases may be needed to use the API in more robust scenarios. Storing the data in an Excel spreadsheet could also be convenient to some users.

Improving README

We need to make a proper initial README document describing what the project is, which features it provides, and what features are scheduled to be added.

Charting and filtering API

Creating charts with Pandas/matplotlib/seaborn is an utterly important feature of FinancesPy. We need to move the code located at ./notebook.ipynb to a specific class inside the package, and also continue to work on it to have a nice charting API.

Stop using metaclasses for representing record labels

Well, at first it seemed to be a good idea, but if you think a bit more, representing record labels (e.g. food, travel, etc) as metaclasses may incur in a lot of problems later.

The idea of having hierarchical labels ( fixed_expenses -> food -> groceries ) is neat, let's keep this, but without classes and inheritance.

Create setup.py

A setup.py source file is necessary to make the package installable and compliant with PIP/setuptools.

Account metadata and storage

The Account class currently just acts as a proxy to the underlying backend object, and doesn't do more than that.

An account should keep metadata information related to a particular user account. The list of categories is part of this metadata. The currency, the account name ('cash', 'savings', etc.), the account type, should be also part of this metadata.

Account metadata can be stored as a special file in a particular format (JSON, YAML, XML, etc.).

The account storage can be a folder with a special structure (convention over configuration). It should contain something like "account.meta" for the metadata, and folders/excel spreadsheet files in some organized format (e.g. filename = year.xlxs)

For the SQL storage, there should be an account table. The account metadata can be just an string in the JSON format, or a JSON column if supported.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.