Compare commits

...

10 commits

Author SHA1 Message Date
Bradley M. Kuhn
d199b5dd42 Add basic install instructions for Debian wheezy. 2014-02-22 11:34:13 -08:00
Joar Wandborg
816099ad55 [ledgercli] Do not remove the old transaction on invalid update 2013-12-29 22:14:59 +01:00
Joar Wandborg
86a6bec585 [ledgercli] Store posting metadata 2013-12-29 21:22:51 +01:00
Joar Wandborg
8abbe3462f [tests] Check transactions for errors before being added
- Added support for Exception-specific HTTP response codes for
  AccountinExceptions.
2013-12-26 21:48:45 +01:00
Joar Wandborg
ef12c232ad [doc] Updated restapi documentation 2013-12-26 21:07:17 +01:00
Joar Wandborg
fcec13c548 [ledgercli] Versioning, error handling
- Switched to passing the command via argv instead of stdin to ledger. We
  might as well as we don't use ledger's long-running mode in an effective
  manner.
- Added version control of the ledger file using pygit2.A
- Added error handling in the case of an unbalanced ledger, and cruder
  error handling in the case of any stderr output from ledger.
- [web] Separated transaction_get into transaction_get and
  transaction_get_all.
2013-12-26 20:48:23 +01:00
Joar Wandborg
4fce6b4fea [tests] Added bin/runtests 2013-12-26 13:26:23 +01:00
Joar Wandborg
3620d97f9d [tests] Added tests and updated storage.ledgercli
- [ledgercli] Log info messages for operations such as add, delete, update
  transactions
2013-12-26 13:22:27 +01:00
Joar Wandborg
0108548b4b [doc] Changed the README title for better inclusion in doc 2013-12-26 13:21:26 +01:00
Joar Wandborg
0e72c2b543 [doc] Updated and added precompiled html output 2013-12-26 13:20:07 +01:00
38 changed files with 1225 additions and 496 deletions

View file

@ -1,8 +1,8 @@
.. vim: textwith=80
.. vim: textwidth=80
====================
The Accounting API
====================
=======================
accounting-api README
=======================
--------------
Dependencies
@ -69,6 +69,17 @@ on ``irc.freenode.net``.
sudo apt-get update
sudo apt-get install ledger
~~~~~~~~~~~~~
Debian wheezy
~~~~~~~~~~~~~
.. code-block:: bash
# git python 3.3, virtualenvwrapper, sphinx (and related modules)
sudo aptitude install git-core python3.3 virtualenvwrapper sphinx python-sphinxcontrib-httpdomain python-flask python-flaskext.wtf python3-sqlalchemy python-sqlalchemy-doc
# ledger 3
# Build this from upstream sources
.. _usage:

View file

@ -19,7 +19,11 @@ def jsonify_exceptions(func):
try:
return func(*args, **kw)
except AccountingException as exc:
return jsonify(error=exc)
response = jsonify(error=exc)
response.status_code = exc.http_code
return response
return wrapper

View file

@ -7,6 +7,7 @@ class AccountingException(Exception):
Used as a base for exceptions that are returned to the caller via the
jsonify_exceptions decorator
'''
http_code = 500
def __init__(self, message, **kw):
self.message = message
for key, value in kw.items():
@ -14,4 +15,12 @@ class AccountingException(Exception):
class TransactionNotFound(AccountingException):
pass
http_code = 404
class LedgerNotBalanced(AccountingException):
http_code = 400
class TransactionIDCollision(AccountingException):
http_code = 400

View file

@ -2,22 +2,30 @@
# https://gitorious.org/conservancy/accounting-api
# License: AGPLv3-or-later
import os
import sys
import subprocess
import logging
import time
import re
from datetime import datetime
from xml.etree import ElementTree
from contextlib import contextmanager
from accounting.exceptions import AccountingException, TransactionNotFound
from accounting.exceptions import AccountingException, TransactionNotFound, \
LedgerNotBalanced, TransactionIDCollision
from accounting.models import Account, Transaction, Posting, Amount
from accounting.storage import Storage
_log = logging.getLogger(__name__)
HAS_PYGIT = False
try:
import pygit2
HAS_PYGIT = True
except ImportError:
_log.warning('Failed to import pygit2')
class Ledger(Storage):
def __init__(self, app=None, ledger_file=None, ledger_bin=None):
@ -31,141 +39,99 @@ class Ledger(Storage):
self.ledger_file = ledger_file
_log.info('ledger file: %s', ledger_file)
self.locked = False
self.ledger_process = None
self.init_pygit()
@contextmanager
def locked_process(self):
r'''
Context manager that checks that the ledger process is not already
locked, then "locks" the process and yields the process handle and
unlocks the process when execution is returned.
def init_pygit(self):
if not HAS_PYGIT:
return False
Since this decorated as a :func:`contextlib.contextmanager` the
recommended use is with the ``with``-statement.
try:
self.repository = pygit2.Repository(
os.path.join(os.path.dirname(self.ledger_file), '.git'))
except KeyError:
self.repository = None
_log.warning('ledger_file directory does not contain a .git'
' directory, will not track changes.')
.. code-block:: python
with self.locked_process() as p:
p.stdin.write(b'bal\n')
output = self.read_until_prompt(p)
# The signature used as author and committer in git commits
self.signature = pygit2.Signature(
name='accounting-api',
email='accounting-api@accounting.example')
def commit_changes(self, message):
'''
if self.locked:
raise RuntimeError('The process has already been locked,'
' something\'s out of order.')
Commits any changes to :attr:`self.ledger_file` to the git repository
'''
if self.repository is None:
return
# XXX: This code has no purpose in a single-threaded process
timeout = 5 # Seconds
# Add the ledger file
self.repository.index.read()
self.repository.index.add(os.path.basename(self.ledger_file))
tree_id = self.repository.index.write_tree()
self.repository.index.write()
for i in range(1, timeout + 2):
if i > timeout:
raise RuntimeError('Ledger process is already locked')
parents = []
try:
parents.append(self.repository.head.target)
except pygit2.GitError:
_log.info('Repository has no head, creating initial commit')
if not self.locked:
break
else:
_log.info('Waiting for one second... %d/%d', i, timeout)
time.sleep(1)
commit_id = self.repository.create_commit(
'HEAD',
self.signature,
self.signature,
message,
tree_id,
parents)
process = self.get_process()
self.locked = True
_log.debug('Lock enabled')
yield process
self.locked = False
_log.debug('Lock disabled')
def assemble_arguments(self):
def assemble_arguments(self, command=None):
'''
Returns a list of arguments suitable for :class:`subprocess.Popen`
based on :attr:`self.ledger_bin` and :attr:`self.ledger_file`.
'''
return [
args = [
self.ledger_bin,
'-f',
self.ledger_file,
]
if command is not None:
args.append(command)
def init_process(self):
return args
def run_command(self, command):
'''
Creates a new (presumably) ledger subprocess based on the args from
:meth:`Ledger.assemble_arguments()` and then runs
:meth:`Ledger.read_until_prompt()` once (which should return the banner
text) and discards the output.
Creates a new ledger process with the specified :data:`command` and
returns the output.
Raises an :class:`~accounting.exceptions.AccountingException`-based
Exception based on the ledger-cli stderr.
'''
_log.debug('Starting ledger process...')
self.ledger_process = subprocess.Popen(
self.assemble_arguments(),
_log.debug('Sending command: %r', command)
_log.debug('Starting ledger...')
p = subprocess.Popen(
self.assemble_arguments(command=command),
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
# Swallow the banner
with self.locked_process() as p:
self.read_until_prompt(p)
output = p.stdout.read()
stderr = p.stderr.read().decode('utf8')
return self.ledger_process
if stderr:
lines = stderr.split('\n')
if 'While balancing transaction from' in lines[1]:
raise LedgerNotBalanced('\n'.join(lines[2:]))
def get_process(self):
'''
Returns :attr:`self.ledger_process` if it evaluates to ``True``. If
:attr:`self.ledger_process` is not set the result of
:meth:`self.init_process() <Ledger.init_process>` is returned.
'''
return self.ledger_process or self.init_process()
raise AccountingException(stderr)
def read_until_prompt(self, process):
r'''
Reads from the subprocess instance :data:`process` until it finds a
combination of ``\n]\x20`` (the prompt), then returns the output
without the prompt.
'''
output = b''
while True:
line = process.stdout.read(1) # XXX: This is a hack
if len(line) > 0:
pass
#_log.debug('line: %s', line)
output += line
if b'\n] ' in output:
_log.debug('Found prompt!')
break
output = output[:-3] # Cut away the prompt
_log.debug('output: %s', output)
p.send_signal(subprocess.signal.SIGTERM)
_log.debug('Waiting for ledger to shut down')
p.wait()
return output
def send_command(self, command):
output = None
with self.locked_process() as p:
if isinstance(command, str):
command = command.encode('utf8')
_log.debug('Sending command: %r', command)
p.stdin.write(command + b'\n')
p.stdin.flush()
output = self.read_until_prompt(p)
self.ledger_process.send_signal(subprocess.signal.SIGTERM)
_log.debug('Waiting for ledger to shut down')
self.ledger_process.wait()
self.ledger_process = None
return output
def add_transaction(self, transaction):
'''
Writes a transaction to the ledger file by opening it in 'ab' mode and
@ -177,6 +143,13 @@ class Ledger(Storage):
_log.debug('No ID found. Generating an ID.')
transaction.generate_id()
exists = self.get_transaction(transaction.id)
if exists is not None:
raise TransactionIDCollision(
'A transaction with the id %s already exists: %s' %
(transaction.id, exists))
transaction.metadata.update({'Id': transaction.id})
transaction_template = ('\n{date} {t.payee}\n'
@ -185,38 +158,61 @@ class Ledger(Storage):
metadata_template = ' ;{0}: {1}\n'
# TODO: Generate metadata for postings
posting_template = (' {account} {p.amount.symbol}'
' {p.amount.amount}\n')
output = b''
out_postings = ''
for posting in transaction.postings:
out_postings += posting_template.format(
p=posting,
account=posting.account + ' ' * (
80 - (len(posting.account) + len(posting.amount.symbol) +
len(str(posting.amount.amount)) + 1 + 2))
)
if len(posting.metadata):
for k, v in posting.metadata.items():
out_postings += metadata_template.format(str(k), str(v))
# XXX: Even I hardly understands what this does, however I indent it it
# stays unreadable.
output += transaction_template.format(
date=transaction.date.strftime('%Y-%m-%d'),
t=transaction,
metadata=''.join([
metadata_template.format(k, v)
metadata_template.format(str(k), str(v))
for k, v in transaction.metadata.items()]),
postings=''.join([posting_template.format(
p=p,
account=p.account + ' ' * (
80 - (len(p.account) + len(p.amount.symbol) +
len(str(p.amount.amount)) + 1 + 2)
)) for p in transaction.postings
])
postings=out_postings
).encode('utf8')
with open(self.ledger_file, 'ab') as f:
f.write(output)
# Check to see that no errors were introduced
try:
self.get_transactions()
except AccountingException as exc:
# TODO: Do a hard reset on the repository using Repository.reset,
# this is on hold because of
# https://github.com/libgit2/pygit2/issues/271.
# This solution will work in the meantime
self.delete_transaction(transaction.id)
setattr(exc, 'transaction', transaction)
raise exc
self.commit_changes('Added transaction %s' % transaction.id)
_log.info('Added transaction %s', transaction.id)
_log.debug('written to file: %s', output)
return transaction.id
def bal(self):
output = self.send_command('xml')
output = self.run_command('xml')
if output is None:
raise RuntimeError('bal call returned no output')
@ -269,11 +265,8 @@ class Ledger(Storage):
if transaction.id == transaction_id:
return transaction
raise TransactionNotFound(
'No transaction with id {0} found'.format(transaction_id))
def reg(self):
output = self.send_command('xml')
output = self.run_command('xml')
if output is None:
raise RuntimeError('reg call returned no output')
@ -419,12 +412,19 @@ class Ledger(Storage):
# Delete the preceding line to make the file
del_start -= 1
_log.info('Removing transaction with ID: %s (lines %d-%d)',
transaction_id,
del_start,
semantic_lines['next_transaction_or_eof'])
del lines[del_start:semantic_lines['next_transaction_or_eof']]
with open(self.ledger_file, 'w') as f:
for line in lines:
f.write(line)
self.commit_changes('Removed transaction %s' % transaction_id)
def update_transaction(self, transaction):
'''
Update a transaction in the ledger file.
@ -442,8 +442,13 @@ class Ledger(Storage):
self.delete_transaction(transaction.id)
self.add_transaction(transaction)
try:
self.add_transaction(transaction)
except AccountingException as exc:
self.add_transaction(old_transaction)
raise exc
_log.info('Updated transaction %s', transaction.id)
_log.debug('Updated transaction from: %s to: %s', old_transaction,
transaction)

View file

View file

@ -0,0 +1,355 @@
'''
Tests for accounting-api
'''
import os
import unittest
import tempfile
import logging
import copy
import uuid
from datetime import datetime
from decimal import Decimal
from flask import json
from accounting.web import app, init_ledger
from accounting.transport import AccountingEncoder, AccountingDecoder
from accounting.models import Transaction, Posting, Amount
#logging.basicConfig(level=logging.DEBUG)
class TransactionTestCase(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
self.fd, app.config['LEDGER_FILE'] = tempfile.mkstemp()
init_ledger()
self.simple_transaction = Transaction(
date=datetime.today(),
payee='Joar',
postings=[
Posting('Assets:Checking', Amount('-133.7', 'USD')),
Posting('Expenses:Foo', Amount('133.7', 'USD'))
]
)
def tearDown(self):
os.close(self.fd)
os.unlink(app.config['LEDGER_FILE'])
def test_get_transactions(self):
open(app.config['LEDGER_FILE'], 'w').write(
'1400-12-21 Old stuff\n'
' ;Id: foo\n'
' Assets:Checking -100 USD\n'
' Expenses:Tax 100 USD\n')
rv = self.app.get('/transaction')
json_transaction = (
b'{\n'
b' "transactions": [\n'
b' {\n'
b' "__type__": "Transaction", \n'
b' "date": "1400-12-21", \n'
b' "id": "foo", \n'
b' "metadata": {}, \n'
b' "payee": "Old stuff", \n'
b' "postings": [\n'
b' {\n'
b' "__type__": "Posting", \n'
b' "account": "Assets:Checking", \n'
b' "amount": {\n'
b' "__type__": "Amount", \n'
b' "amount": "-100", \n'
b' "symbol": "USD"\n'
b' }, \n'
b' "metadata": {}\n'
b' }, \n'
b' {\n'
b' "__type__": "Posting", \n'
b' "account": "Expenses:Tax", \n'
b' "amount": {\n'
b' "__type__": "Amount", \n'
b' "amount": "100", \n'
b' "symbol": "USD"\n'
b' }, \n'
b' "metadata": {}\n'
b' }\n'
b' ]\n'
b' }\n'
b' ]\n'
b'}')
self.assertEqual(rv.get_data(), json_transaction)
def _post_json(self, path, data, expect=200, **kw):
response = self.app.post(
path,
content_type='application/json',
data=json.dumps(data, cls=AccountingEncoder),
**kw
)
self.assertEqual(response.status_code, expect)
return self._decode_response(response)
def _decode_response(self, response):
return json.loads(response.data, cls=AccountingDecoder)
def _get_json(self, path, expect=200, **kw):
response = self.app.get(path, **kw)
self.assertEqual(response.status_code, expect)
return self._decode_response(response)
def _open_json(self, method, path, expect=200, **kw):
response = self.app.open(
path,
method=method.upper(),
**kw
)
self.assertEqual(response.status_code, expect)
return self._decode_response(response)
def _add_simple_transaction(self, transaction_id=None):
if transaction_id is None:
transaction_id = str(uuid.uuid4())
transaction = copy.deepcopy(self.simple_transaction)
transaction.id = transaction_id
response = self._post_json('/transaction', transaction)
self.assertEqual(len(response['transaction_ids']), 1)
self.assertEqual(response['status'], 'OK')
response = self._get_json('/transaction/' + transaction.id)
self.assertEqual(transaction_id, response['transaction'].id)
self.assertEqual(response['transaction'], transaction)
return transaction
def test_post_transaction_without_id(self):
transaction = copy.deepcopy(self.simple_transaction)
response = self._post_json('/transaction', transaction)
self.assertEqual(len(response['transaction_ids']), 1)
self.assertEqual(response['status'], 'OK')
transaction.id = response['transaction_ids'][0]
response = self._get_json('/transaction/' + transaction.id)
self.assertEqual(response['transaction'], transaction)
def test_delete_transaction(self):
transaction = copy.deepcopy(self.simple_transaction)
response = self._post_json('/transaction', transaction)
transaction_id = response['transaction_ids'][0]
self.assertIsNotNone(transaction_id)
response = self._open_json('DELETE',
'/transaction/' + transaction_id)
self.assertEqual(response['status'], 'OK')
with self.assertRaises(ValueError):
# ValueError thrown because the response does not contain any JSON
response = self._get_json('/transaction/' + transaction_id, 404)
def test_post_multiple_transactions(self):
transactions = [
Transaction(
date=datetime.today(),
payee='Rent',
postings=[
Posting(
account='Assets:Checking',
amount=Amount(amount='-4600.00', symbol='SEK')
),
Posting(
account='Expenses:Rent',
amount=Amount(amount='4600.00', symbol='SEK')
)
]
),
Transaction(
date=datetime.today(),
payee='Hosting',
postings=[
Posting(
account='Assets:Checking',
amount=Amount(amount='-700.00', symbol='SEK')
),
Posting(
account='Expenses:Hosting',
amount=Amount(amount='700.00', symbol='SEK')
)
]
)
]
response = self._post_json('/transaction',
{'transactions': transactions})
self.assertEqual(len(response['transaction_ids']), 2)
transactions[0].id = response['transaction_ids'][0]
transactions[1].id = response['transaction_ids'][1]
response = self._get_json('/transaction/' + transactions[0].id)
self.assertEqual(transactions[0], response['transaction'])
response = self._get_json('/transaction/' + transactions[1].id)
self.assertEqual(transactions[1], response['transaction'])
def test_update_transaction_payee(self):
transaction = self._add_simple_transaction()
transaction.payee = 'not Joar'
response = self._post_json('/transaction/' + transaction.id,
{'transaction': transaction})
self.assertEqual(response['status'], 'OK')
response = self._get_json('/transaction/'+ transaction.id)
self.assertEqual(response['transaction'], transaction)
def test_update_transaction_postings(self):
transaction = self._add_simple_transaction()
postings = [
Posting(account='Assets:Checking',
amount=Amount(amount='-733.10', symbol='SEK')),
Posting(account='Expenses:Bar',
amount=Amount(amount='733.10', symbol='SEK'))
]
transaction.postings = postings
response = self._post_json('/transaction/' + transaction.id,
{'transaction': transaction})
self.assertEqual(response['status'], 'OK')
response = self._get_json('/transaction/' + transaction.id)
self.assertEqual(response['transaction'], transaction)
def test_post_unbalanced_transaction(self):
transaction = Transaction(
date=datetime.today(),
payee='Unbalanced Transaction',
postings=[
Posting(account='Assets:Checking',
amount=Amount(amount='100.00', symbol='USD')),
Posting(account='Income:Foo',
amount=Amount(amount='-100.01', symbol='USD'))
]
)
response = self._post_json('/transaction', transaction, expect=400)
self.assertEqual(response['error']['type'], 'LedgerNotBalanced')
def test_update_transaction_amounts(self):
transaction = self._add_simple_transaction()
response = self._get_json(
'/transaction/' + transaction.id)
transaction = response['transaction']
for posting in transaction.postings:
posting.amount.amount *= Decimal(1.50)
response = self._post_json('/transaction/' + transaction.id,
{'transaction': transaction})
self.assertEqual(response['status'], 'OK')
response = self._get_json('/transaction/' + transaction.id)
self.assertEqual(response['transaction'], transaction)
def test_delete_nonexistent_transaction(self):
response = self._open_json('DELETE', '/transaction/I-do-not-exist',
expect=404)
self.assertEqual(response['error']['type'], 'TransactionNotFound')
def test_post_transaction_with_metadata(self):
transaction = copy.deepcopy(self.simple_transaction)
transaction.metadata.update({'foo': 'bar'})
response = self._post_json('/transaction', transaction)
transaction_id = response['transaction_ids'][0]
response = self._get_json('/transaction/' + transaction_id)
self.assertEqual(
response['transaction'].metadata,
transaction.metadata)
def test_post_transaction_with_posting_metadata(self):
transaction = copy.deepcopy(self.simple_transaction)
postings = [
Posting(account='Assets:Checking', metadata={'assets': 'checking'},
amount=Amount(amount='-100.10', symbol='$')),
Posting(account='Expenses:Foo', metadata={'expenses': 'foo'},
amount=Amount(amount='100.10', symbol='$'))
]
transaction.postings = postings
response = self._post_json('/transaction', transaction)
transaction_id = response['transaction_ids'][0]
response = self._get_json('/transaction/' + transaction_id)
for posting in response['transaction'].postings:
if posting.account == 'Expenses:Foo':
self.assertEqual(posting.metadata, {'expenses': 'foo'})
elif posting.account == 'Assets:Checking':
self.assertEqual(posting.metadata, {'assets': 'checking'})
else:
assert False, \
'Something about this transaction\'s postings is' \
' unexpected'
def test_invalid_update_transaction_does_not_remove_existing(self):
transaction = self._add_simple_transaction()
old_transaction = copy.deepcopy(transaction)
transaction.postings[0].amount.amount = '9001.01'
response = self._post_json('/transaction/' + transaction.id,
{'transaction': transaction}, 400)
self.assertEqual(response['error']['type'], 'LedgerNotBalanced')
response = self._get_json('/transaction/' + transaction.id)
self.assertEqual(response['transaction'], old_transaction)
if __name__ == '__main__':
unittest.main()

View file

@ -44,7 +44,8 @@ class AccountingEncoder(json.JSONEncoder):
elif isinstance(o, AccountingException):
return dict(
type=o.__class__.__name__,
message=o.message
message=o.message,
transaction=getattr(o, 'transaction', None)
)
return json.JSONEncoder.default(self, o)

View file

@ -63,21 +63,26 @@ def transaction_by_id_options(transaction_id=None):
@app.route('/transaction', methods=['GET'])
@cors()
@jsonify_exceptions
def transaction_get_all(transaction_id=None):
'''
Returns the JSON-serialized output of :meth:`accounting.Ledger.reg`
'''
return jsonify(transactions=app.ledger.get_transactions())
@app.route('/transaction/<string:transaction_id>', methods=['GET'])
@cors()
@jsonify_exceptions
def transaction_get(transaction_id=None):
'''
Returns the JSON-serialized output of :meth:`accounting.Ledger.reg`
'''
if transaction_id is None:
return jsonify(transactions=app.ledger.get_transactions())
transaction = app.ledger.get_transaction(transaction_id)
try:
return jsonify(transaction=app.ledger.get_transaction(transaction_id))
except TransactionNotFound:
if transaction is None:
abort(404)
return jsonify(transaction=transaction)
@app.route('/transaction/<string:transaction_id>', methods=['POST'])
@cors()

3
bin/runtests Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
python -m unittest $@

View file

@ -6,7 +6,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The Accounting API &mdash; Accounting API 0.1-beta documentation</title>
<title>accounting-api README &mdash; Accounting API 0.1-beta documentation</title>
<link rel="stylesheet" href="_static/flasky.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -24,8 +24,8 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Accounting API 0.1-beta documentation" href="index.html" />
<link rel="next" title="REST API" href="restapi.html" />
<link rel="prev" title="Welcome to Accounting APIs documentation!" href="index.html" />
<link rel="next" title="REST API Documentation" href="restapi.html" />
<link rel="prev" title="Accounting API - Documentation" href="index.html" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9">
@ -48,10 +48,10 @@
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="restapi.html" title="REST API"
<a href="restapi.html" title="REST API Documentation"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to Accounting APIs documentation!"
<a href="index.html" title="Accounting API - Documentation"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
@ -62,8 +62,8 @@
<div class="bodywrapper">
<div class="body">
<div class="section" id="the-accounting-api">
<h1>The Accounting API<a class="headerlink" href="#the-accounting-api" title="Permalink to this headline"></a></h1>
<div class="section" id="accounting-api-readme">
<h1>accounting-api README<a class="headerlink" href="#accounting-api-readme" title="Permalink to this headline"></a></h1>
<div class="section" id="dependencies">
<h2>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this headline"></a></h2>
<ul class="simple">
@ -149,7 +149,7 @@ sudo apt-get install ledger
</a></p>
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">The Accounting API</a><ul>
<li><a class="reference internal" href="#">accounting-api README</a><ul>
<li><a class="reference internal" href="#dependencies">Dependencies</a><ul>
<li><a class="reference internal" href="#gtk-client-dependencies">GTK Client Dependencies</a></li>
</ul>
@ -165,8 +165,8 @@ sudo apt-get install ledger
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="index.html" title="previous chapter">Welcome to Accounting API&#8217;s documentation!</a></li>
<li>Next: <a href="restapi.html" title="next chapter">REST API</a></li>
<li>Previous: <a href="index.html" title="previous chapter">Accounting API - Documentation</a></li>
<li>Next: <a href="restapi.html" title="next chapter">REST API Documentation</a></li>
</ul></li>
</ul>
<h3>This Page</h3>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
@ -66,6 +66,13 @@
<span class="sd"> Used as a base for exceptions that are returned to the caller via the</span>
<span class="sd"> jsonify_exceptions decorator</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">kw</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</div>
<div class="viewcode-block" id="TransactionNotFound"><a class="viewcode-back" href="../../api/accounting.html#accounting.exceptions.TransactionNotFound">[docs]</a><span class="k">class</span> <span class="nc">TransactionNotFound</span><span class="p">(</span><span class="n">AccountingException</span><span class="p">):</span>
<span class="k">pass</span></div>
</pre></div>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
@ -60,14 +60,18 @@
<span class="c"># Part of accounting-api project:</span>
<span class="c"># https://gitorious.org/conservancy/accounting-api</span>
<span class="c"># License: AGPLv3-or-later</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">uuid</span>
<span class="kn">from</span> <span class="nn">decimal</span> <span class="kn">import</span> <span class="n">Decimal</span>
<div class="viewcode-block" id="Transaction"><a class="viewcode-back" href="../../api/accounting.html#accounting.models.Transaction">[docs]</a><span class="k">class</span> <span class="nc">Transaction</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">date</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">payee</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">postings</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">metadata</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">_generate_id</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">date</span><span class="p">)</span> <span class="o">==</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">:</span>
<span class="n">date</span> <span class="o">=</span> <span class="n">date</span><span class="o">.</span><span class="n">date</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">date</span> <span class="o">=</span> <span class="n">date</span>
<span class="bp">self</span><span class="o">.</span><span class="n">payee</span> <span class="o">=</span> <span class="n">payee</span>
@ -80,6 +84,9 @@
<div class="viewcode-block" id="Transaction.generate_id"><a class="viewcode-back" href="../../api/accounting.html#accounting.models.Transaction.generate_id">[docs]</a> <span class="k">def</span> <span class="nf">generate_id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())</span>
</div>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__dict__</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s">&#39;&lt;{self.__class__.__name__} {self.id} {date}&#39;</span> <span class="o">+</span>
<span class="s">&#39; {self.payee} {self.postings}&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
@ -93,6 +100,9 @@
<span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">=</span> <span class="n">amount</span>
<span class="bp">self</span><span class="o">.</span><span class="n">metadata</span> <span class="o">=</span> <span class="n">metadata</span> <span class="k">if</span> <span class="n">metadata</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="k">else</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__dict__</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s">&#39;&lt;{self.__class__.__name__} &quot;{self.account}&quot;&#39;</span> <span class="o">+</span>
<span class="s">&#39; {self.amount}&gt;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
@ -103,6 +113,9 @@
<span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">symbol</span> <span class="o">=</span> <span class="n">symbol</span>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__dict__</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s">&#39;&lt;{self.__class__.__name__} {self.symbol}&#39;</span> <span class="o">+</span>
<span class="s">&#39; {self.amount}&gt;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
@ -114,6 +127,9 @@
<span class="bp">self</span><span class="o">.</span><span class="n">amounts</span> <span class="o">=</span> <span class="n">amounts</span>
<span class="bp">self</span><span class="o">.</span><span class="n">accounts</span> <span class="o">=</span> <span class="n">accounts</span>
<span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">__dict__</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="s">&#39;&lt;{self.__class__.__name__} &quot;{self.name}&quot; {self.amounts}&#39;</span> <span class="o">+</span>
<span class="s">&#39; {self.accounts}&gt;&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span></div>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
@ -63,8 +63,6 @@
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABCMeta</span><span class="p">,</span> <span class="n">abstractmethod</span>
<span class="kn">from</span> <span class="nn">accounting.exceptions</span> <span class="kn">import</span> <span class="n">AccountingException</span>
<div class="viewcode-block" id="Storage"><a class="viewcode-back" href="../../api/accounting.storage.html#accounting.storage.Storage">[docs]</a><span class="k">class</span> <span class="nc">Storage</span><span class="p">:</span>
<span class="sd">&#39;&#39;&#39;</span>
@ -105,11 +103,7 @@
</div>
<span class="nd">@abstractmethod</span>
<div class="viewcode-block" id="Storage.reverse_transaction"><a class="viewcode-back" href="../../api/accounting.storage.html#accounting.storage.Storage.reverse_transaction">[docs]</a> <span class="k">def</span> <span class="nf">reverse_transaction</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transaction_id</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span>
</div></div>
<div class="viewcode-block" id="TransactionNotFound"><a class="viewcode-back" href="../../api/accounting.storage.html#accounting.storage.TransactionNotFound">[docs]</a><span class="k">class</span> <span class="nc">TransactionNotFound</span><span class="p">(</span><span class="n">AccountingException</span><span class="p">):</span>
<span class="k">pass</span></div>
<span class="k">raise</span> <span class="ne">NotImplementedError</span></div></div>
</pre></div>
</div>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../storage.html" accesskey="U">accounting.storage</a> &raquo;</li>
@ -72,9 +72,9 @@
<span class="kn">from</span> <span class="nn">xml.etree</span> <span class="kn">import</span> <span class="n">ElementTree</span>
<span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">contextmanager</span>
<span class="kn">from</span> <span class="nn">accounting.exceptions</span> <span class="kn">import</span> <span class="n">AccountingException</span>
<span class="kn">from</span> <span class="nn">accounting.exceptions</span> <span class="kn">import</span> <span class="n">AccountingException</span><span class="p">,</span> <span class="n">TransactionNotFound</span>
<span class="kn">from</span> <span class="nn">accounting.models</span> <span class="kn">import</span> <span class="n">Account</span><span class="p">,</span> <span class="n">Transaction</span><span class="p">,</span> <span class="n">Posting</span><span class="p">,</span> <span class="n">Amount</span>
<span class="kn">from</span> <span class="nn">accounting.storage</span> <span class="kn">import</span> <span class="n">Storage</span><span class="p">,</span> <span class="n">TransactionNotFound</span>
<span class="kn">from</span> <span class="nn">accounting.storage</span> <span class="kn">import</span> <span class="n">Storage</span>
<span class="n">_log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span>
@ -189,6 +189,10 @@
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">process</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c"># XXX: This is a hack</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">pass</span>
<span class="c">#_log.debug(&#39;line: %s&#39;, line)</span>
<span class="n">output</span> <span class="o">+=</span> <span class="n">line</span>
<span class="k">if</span> <span class="n">b</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">] &#39;</span> <span class="ow">in</span> <span class="n">output</span><span class="p">:</span>
@ -208,6 +212,8 @@
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">command</span> <span class="o">=</span> <span class="n">command</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf8&#39;</span><span class="p">)</span>
<span class="n">_log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;Sending command: </span><span class="si">%r</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">command</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">command</span> <span class="o">+</span> <span class="n">b</span><span class="s">&#39;</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
@ -265,6 +271,8 @@
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ledger_file</span><span class="p">,</span> <span class="s">&#39;ab&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#39;Added transaction </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">transaction</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="n">_log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;written to file: </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">output</span><span class="p">)</span>
<span class="k">return</span> <span class="n">transaction</span><span class="o">.</span><span class="n">id</span>
@ -323,8 +331,8 @@
<span class="k">if</span> <span class="n">transaction</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="n">transaction_id</span><span class="p">:</span>
<span class="k">return</span> <span class="n">transaction</span>
<span class="k">raise</span> <span class="n">TransactionNotFound</span><span class="p">(</span><span class="s">&#39;No transaction with id </span><span class="si">%s</span><span class="s"> found&#39;</span><span class="p">,</span>
<span class="n">transaction_id</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">TransactionNotFound</span><span class="p">(</span>
<span class="s">&#39;No transaction with id {0} found&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">transaction_id</span><span class="p">))</span>
</div>
<div class="viewcode-block" id="Ledger.reg"><a class="viewcode-back" href="../../../api/accounting.storage.html#accounting.storage.ledgercli.Ledger.reg">[docs]</a> <span class="k">def</span> <span class="nf">reg</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_command</span><span class="p">(</span><span class="s">&#39;xml&#39;</span><span class="p">)</span>
@ -473,6 +481,11 @@
<span class="c"># Delete the preceding line to make the file</span>
<span class="n">del_start</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#39;Removing transaction with ID: </span><span class="si">%s</span><span class="s"> (lines </span><span class="si">%d</span><span class="s">-</span><span class="si">%d</span><span class="s">)&#39;</span><span class="p">,</span>
<span class="n">transaction_id</span><span class="p">,</span>
<span class="n">del_start</span><span class="p">,</span>
<span class="n">semantic_lines</span><span class="p">[</span><span class="s">&#39;next_transaction_or_eof&#39;</span><span class="p">])</span>
<span class="k">del</span> <span class="n">lines</span><span class="p">[</span><span class="n">del_start</span><span class="p">:</span><span class="n">semantic_lines</span><span class="p">[</span><span class="s">&#39;next_transaction_or_eof&#39;</span><span class="p">]]</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ledger_file</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
@ -498,6 +511,7 @@
<span class="bp">self</span><span class="o">.</span><span class="n">add_transaction</span><span class="p">(</span><span class="n">transaction</span><span class="p">)</span>
<span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&#39;Updated transaction </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">transaction</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="n">_log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&#39;Updated transaction from: </span><span class="si">%s</span><span class="s"> to: </span><span class="si">%s</span><span class="s">&#39;</span><span class="p">,</span> <span class="n">old_transaction</span><span class="p">,</span>
<span class="n">transaction</span><span class="p">)</span>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../../index.html" >Module code</a> &raquo;</li>
<li><a href="../storage.html" accesskey="U">accounting.storage</a> &raquo;</li>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../../../index.html" >Module code</a> &raquo;</li>
<li><a href="../../storage.html" >accounting.storage</a> &raquo;</li>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
@ -65,6 +65,7 @@
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">json</span>
<span class="kn">from</span> <span class="nn">accounting.exceptions</span> <span class="kn">import</span> <span class="n">AccountingException</span>
<span class="kn">from</span> <span class="nn">accounting.models</span> <span class="kn">import</span> <span class="n">Amount</span><span class="p">,</span> <span class="n">Transaction</span><span class="p">,</span> <span class="n">Posting</span><span class="p">,</span> <span class="n">Account</span>
@ -99,10 +100,10 @@
<span class="n">amount</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">o</span><span class="o">.</span><span class="n">amount</span><span class="p">),</span>
<span class="n">symbol</span><span class="o">=</span><span class="n">o</span><span class="o">.</span><span class="n">symbol</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">o</span><span class="p">,</span> <span class="ne">Exception</span><span class="p">):</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">o</span><span class="p">,</span> <span class="n">AccountingException</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">dict</span><span class="p">(</span>
<span class="n">__type__</span><span class="o">=</span><span class="n">o</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span>
<span class="n">args</span><span class="o">=</span><span class="n">o</span><span class="o">.</span><span class="n">args</span>
<span class="nb">type</span><span class="o">=</span><span class="n">o</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span>
<span class="n">message</span><span class="o">=</span><span class="n">o</span><span class="o">.</span><span class="n">message</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONEncoder</span><span class="o">.</span><span class="n">default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
@ -117,7 +118,7 @@
<span class="k">return</span> <span class="n">d</span>
<span class="n">types</span> <span class="o">=</span> <span class="p">{</span><span class="n">c</span><span class="o">.</span><span class="n">__name__</span><span class="p">:</span> <span class="n">c</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="p">[</span><span class="n">Amount</span><span class="p">,</span> <span class="n">Transaction</span><span class="p">,</span> <span class="n">Posting</span><span class="p">,</span>
<span class="n">Account</span><span class="p">]}</span>
<span class="n">Account</span><span class="p">,</span> <span class="n">AccountingException</span><span class="p">]}</span>
<span class="n">_type</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s">&#39;__type__&#39;</span><span class="p">)</span>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
<li><a href="../index.html" accesskey="U">Module code</a> &raquo;</li>
</ul>
@ -69,7 +69,7 @@
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">argparse</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">jsonify</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">render_template</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">jsonify</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">abort</span>
<span class="kn">from</span> <span class="nn">flask.ext.script</span> <span class="kn">import</span> <span class="n">Manager</span>
<span class="kn">from</span> <span class="nn">flask.ext.migrate</span> <span class="kn">import</span> <span class="n">Migrate</span><span class="p">,</span> <span class="n">MigrateCommand</span>
@ -78,32 +78,18 @@
<span class="kn">from</span> <span class="nn">accounting.storage.ledgercli</span> <span class="kn">import</span> <span class="n">Ledger</span>
<span class="kn">from</span> <span class="nn">accounting.storage.sql</span> <span class="kn">import</span> <span class="n">SQLStorage</span>
<span class="kn">from</span> <span class="nn">accounting.transport</span> <span class="kn">import</span> <span class="n">AccountingEncoder</span><span class="p">,</span> <span class="n">AccountingDecoder</span>
<span class="kn">from</span> <span class="nn">accounting.exceptions</span> <span class="kn">import</span> <span class="n">AccountingException</span>
<span class="kn">from</span> <span class="nn">accounting.exceptions</span> <span class="kn">import</span> <span class="n">AccountingException</span><span class="p">,</span> <span class="n">TransactionNotFound</span>
<span class="kn">from</span> <span class="nn">accounting.decorators</span> <span class="kn">import</span> <span class="n">jsonify_exceptions</span><span class="p">,</span> <span class="n">cors</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="s">&#39;accounting&#39;</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">from_pyfile</span><span class="p">(</span><span class="s">&#39;config.py&#39;</span><span class="p">)</span>
<span class="n">storage</span> <span class="o">=</span> <span class="n">Storage</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">SQLStorage</span><span class="p">):</span>
<span class="c"># TODO: Move migration stuff into SQLStorage</span>
<span class="n">db</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="n">db</span>
<span class="n">migrate</span> <span class="o">=</span> <span class="n">Migrate</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">db</span><span class="p">)</span>
<span class="n">manager</span> <span class="o">=</span> <span class="n">Manager</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
<span class="n">manager</span><span class="o">.</span><span class="n">add_command</span><span class="p">(</span><span class="s">&#39;db&#39;</span><span class="p">,</span> <span class="n">MigrateCommand</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">ledger</span> <span class="o">=</span> <span class="n">Storage</span><span class="p">()</span>
<span class="nd">@app.before_request</span>
<div class="viewcode-block" id="init_ledger"><a class="viewcode-back" href="../../api/accounting.html#accounting.web.init_ledger">[docs]</a><span class="k">def</span> <span class="nf">init_ledger</span><span class="p">():</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> :py:meth:`flask.Flask.before_request`-decorated method that initializes an</span>
<span class="sd"> :py:class:`accounting.Ledger` object.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">global</span> <span class="n">ledger</span>
<span class="c">#ledger = Ledger(ledger_file=app.config[&#39;LEDGER_FILE&#39;])</span>
<span class="n">app</span><span class="o">.</span><span class="n">ledger</span> <span class="o">=</span> <span class="n">Ledger</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
<span class="c"># These will convert output from our internal classes to JSON and back</span></div>
@ -144,9 +130,12 @@
<span class="sd"> Returns the JSON-serialized output of :meth:`accounting.Ledger.reg`</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">transaction_id</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">transactions</span><span class="o">=</span><span class="n">storage</span><span class="o">.</span><span class="n">get_transactions</span><span class="p">())</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">transactions</span><span class="o">=</span><span class="n">app</span><span class="o">.</span><span class="n">ledger</span><span class="o">.</span><span class="n">get_transactions</span><span class="p">())</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">transaction</span><span class="o">=</span><span class="n">storage</span><span class="o">.</span><span class="n">get_transaction</span><span class="p">(</span><span class="n">transaction_id</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">transaction</span><span class="o">=</span><span class="n">app</span><span class="o">.</span><span class="n">ledger</span><span class="o">.</span><span class="n">get_transaction</span><span class="p">(</span><span class="n">transaction_id</span><span class="p">))</span>
<span class="k">except</span> <span class="n">TransactionNotFound</span><span class="p">:</span>
<span class="n">abort</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span>
</div>
<span class="nd">@app.route</span><span class="p">(</span><span class="s">&#39;/transaction/&lt;string:transaction_id&gt;&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;POST&#39;</span><span class="p">])</span>
@ -164,7 +153,7 @@
<span class="k">elif</span> <span class="n">transaction</span><span class="o">.</span><span class="n">id</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="n">transaction</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">transaction_id</span>
<span class="n">storage</span><span class="o">.</span><span class="n">update_transaction</span><span class="p">(</span><span class="n">transaction</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">ledger</span><span class="o">.</span><span class="n">update_transaction</span><span class="p">(</span><span class="n">transaction</span><span class="p">)</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="s">&#39;OK&#39;</span><span class="p">)</span>
@ -176,7 +165,7 @@
<span class="k">if</span> <span class="n">transaction_id</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">AccountingException</span><span class="p">(</span><span class="s">&#39;Transaction ID cannot be None&#39;</span><span class="p">)</span>
<span class="n">storage</span><span class="o">.</span><span class="n">delete_transaction</span><span class="p">(</span><span class="n">transaction_id</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">ledger</span><span class="o">.</span><span class="n">delete_transaction</span><span class="p">(</span><span class="n">transaction_id</span><span class="p">)</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="s">&#39;OK&#39;</span><span class="p">)</span>
@ -243,7 +232,7 @@
<span class="n">transaction_ids</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">transaction</span> <span class="ow">in</span> <span class="n">transactions</span><span class="p">:</span>
<span class="n">transaction_ids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">storage</span><span class="o">.</span><span class="n">add_transaction</span><span class="p">(</span><span class="n">transaction</span><span class="p">))</span>
<span class="n">transaction_ids</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">ledger</span><span class="o">.</span><span class="n">add_transaction</span><span class="p">(</span><span class="n">transaction</span><span class="p">))</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="s">&#39;OK&#39;</span><span class="p">,</span> <span class="n">transaction_ids</span><span class="o">=</span><span class="n">transaction_ids</span><span class="p">)</span>
@ -260,8 +249,7 @@
<span class="n">help</span><span class="o">=</span><span class="p">(</span><span class="s">&#39;Filter logging output. Possible values:&#39;</span> <span class="o">+</span>
<span class="s">&#39; CRITICAL, ERROR, WARNING, INFO, DEBUG&#39;</span><span class="p">))</span>
<span class="k">global</span> <span class="n">storage</span>
<span class="n">storage</span> <span class="o">=</span> <span class="n">Ledger</span><span class="p">(</span><span class="n">app</span><span class="o">=</span><span class="n">app</span><span class="p">)</span>
<span class="n">init_ledger</span><span class="p">()</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">(</span><span class="n">argv</span><span class="p">)</span>

View file

@ -39,12 +39,12 @@
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>

View file

@ -1,8 +1,8 @@
.. vim: textwith=80
.. vim: textwidth=80
====================
The Accounting API
====================
=======================
accounting-api README
=======================
--------------
Dependencies

View file

@ -1,10 +1,6 @@
.. Accounting API documentation master file, created by
sphinx-quickstart on Thu Dec 12 14:02:01 2013.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Accounting API's documentation!
==========================================
=======
Index
=======
-----------------------
Accounting API

View file

@ -1,14 +1,16 @@
==========
REST API
==========
========================
REST API Documentation
========================
Get transactions
The accounting-api projects main application provides a REST API for accounting
data. This is the documentation for the various REST endpoints that the
accounting-api application provides.
Get all transactions
----------------
.. http:get:: /transaction
Get all transactions
**Example request**
.. code-block:: http
@ -28,63 +30,63 @@ Get transactions
{
"transactions": [
{
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"postings": [
{
"__type__": "Posting",
"account": "Income:Foo:Donation",
"__type__": "Posting",
"account": "Income:Foo:Donation",
"amount": {
"__type__": "Amount",
"amount": "-100",
"__type__": "Amount",
"amount": "-100",
"symbol": "$"
},
},
"metadata": {
"Invoice": "Projects/Foo/Invoices/Invoice20100101.pdf"
}
},
},
{
"__type__": "Posting",
"account": "Assets:Checking",
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "100",
"__type__": "Amount",
"amount": "100",
"symbol": "$"
},
},
"metadata": {}
}
]
},
},
{
"__type__": "Transaction",
"date": "2011-03-15",
"id": "but mind you if they collide.",
"metadata": {},
"payee": "Another J. Donor",
"__type__": "Transaction",
"date": "2011-03-15",
"id": "but mind you if they collide.",
"metadata": {},
"payee": "Another J. Donor",
"postings": [
{
"__type__": "Posting",
"account": "Income:Foo:Donation",
"__type__": "Posting",
"account": "Income:Foo:Donation",
"amount": {
"__type__": "Amount",
"amount": "-400",
"__type__": "Amount",
"amount": "-400",
"symbol": "$"
},
},
"metadata": {
"Approval": "Projects/Foo/earmark-record.txt"
}
},
},
{
"__type__": "Posting",
"account": "Assets:Checking",
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "400",
"__type__": "Amount",
"amount": "400",
"symbol": "$"
},
},
"metadata": {}
}
]
@ -92,6 +94,59 @@ Get transactions
]
}
Get a single transaction
------------------------
.. http:get:: /transaction/<string:transaction_id>
**Example request**
.. code-block:: http
GET /transaction/2aeea63b-0996-4ead-bc4c-e15505dff226 HTTP/1.1
Host: accounting.example
Accept: application/json
**Example response**
.. code-block:: http
HTTP/1.0 200 OK
Content-Type: application/json
{
"transaction": {
"__type__": "Transaction",
"date": "2013-12-26",
"id": "2aeea63b-0996-4ead-bc4c-e15505dff226",
"metadata": {},
"payee": "January Rent",
"postings": [
{
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "-424.24",
"symbol": "USD"
},
"metadata": {}
},
{
"__type__": "Posting",
"account": "Expenses:Rent",
"amount": {
"__type__": "Amount",
"amount": "424.24",
"symbol": "USD"
},
"metadata": {}
}
]
}
}
Add transactions
----------------
@ -111,36 +166,36 @@ Add transactions
{
"transactions": [
{
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"postings": [
{
"__type__": "Posting",
"account": "Income:Foo:Donation",
"__type__": "Posting",
"account": "Income:Foo:Donation",
"amount": {
"__type__": "Amount",
"amount": "-100",
"__type__": "Amount",
"amount": "-100",
"symbol": "$"
},
},
"metadata": {
"Invoice": "Projects/Foo/Invoices/Invoice20100101.pdf"
}
},
},
{
"__type__": "Posting",
"account": "Assets:Checking",
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "100",
"__type__": "Amount",
"amount": "100",
"symbol": "$"
},
},
"metadata": {}
}
]
},
},
]
}
@ -184,3 +239,61 @@ Delete a transaction
{
"status": "OK"
}
Update a transaction
--------------------
.. http:post:: /transaction/<string:transaction_id>
**Example request**
.. code-block:: http
POST /transaction/2aeea63b-0996-4ead-bc4c-e15505dff226 HTTP/1.1
Host: accounting.example
Content-Type: application/json
Accept: application/json
{
"transaction": {
"__type__": "Transaction",
"date": "2013-12-26",
"id": "2aeea63b-0996-4ead-bc4c-e15505dff226",
"metadata": {},
"payee": "February Rent",
"postings": [
{
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "-424.24",
"symbol": "USD"
},
"metadata": {}
},
{
"__type__": "Posting",
"account": "Expenses:Rent",
"amount": {
"__type__": "Amount",
"amount": "424.24",
"symbol": "USD"
},
"metadata": {}
}
]
}
}
**Example response**
.. code-block:: http
HTTP/1.0 200 OK
Content-Type: application/json
{
"status": "OK"
}

View file

@ -39,12 +39,12 @@
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>
@ -189,12 +189,30 @@ exceptions which are returned to the client as JSON.</p>
<span id="accounting-exceptions-module"></span><h2>accounting.exceptions module<a class="headerlink" href="#module-accounting.exceptions" title="Permalink to this headline"></a></h2>
<dl class="exception">
<dt id="accounting.exceptions.AccountingException">
<em class="property">exception </em><tt class="descclassname">accounting.exceptions.</tt><tt class="descname">AccountingException</tt><a class="reference internal" href="../_modules/accounting/exceptions.html#AccountingException"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.exceptions.AccountingException" title="Permalink to this definition"></a></dt>
<em class="property">exception </em><tt class="descclassname">accounting.exceptions.</tt><tt class="descname">AccountingException</tt><big>(</big><em>message</em>, <em>**kw</em><big>)</big><a class="reference internal" href="../_modules/accounting/exceptions.html#AccountingException"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.exceptions.AccountingException" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">builtins.Exception</span></tt></p>
<p>Used as a base for exceptions that are returned to the caller via the
jsonify_exceptions decorator</p>
</dd></dl>
<dl class="exception">
<dt id="accounting.exceptions.LedgerNotBalanced">
<em class="property">exception </em><tt class="descclassname">accounting.exceptions.</tt><tt class="descname">LedgerNotBalanced</tt><big>(</big><em>message</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#accounting.exceptions.LedgerNotBalanced" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#accounting.exceptions.AccountingException" title="accounting.exceptions.AccountingException"><tt class="xref py py-class docutils literal"><span class="pre">accounting.exceptions.AccountingException</span></tt></a></p>
</dd></dl>
<dl class="exception">
<dt id="accounting.exceptions.TransactionIDCollision">
<em class="property">exception </em><tt class="descclassname">accounting.exceptions.</tt><tt class="descname">TransactionIDCollision</tt><big>(</big><em>message</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#accounting.exceptions.TransactionIDCollision" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#accounting.exceptions.AccountingException" title="accounting.exceptions.AccountingException"><tt class="xref py py-class docutils literal"><span class="pre">accounting.exceptions.AccountingException</span></tt></a></p>
</dd></dl>
<dl class="exception">
<dt id="accounting.exceptions.TransactionNotFound">
<em class="property">exception </em><tt class="descclassname">accounting.exceptions.</tt><tt class="descname">TransactionNotFound</tt><big>(</big><em>message</em>, <em>**kw</em><big>)</big><a class="reference internal" href="../_modules/accounting/exceptions.html#TransactionNotFound"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.exceptions.TransactionNotFound" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="#accounting.exceptions.AccountingException" title="accounting.exceptions.AccountingException"><tt class="xref py py-class docutils literal"><span class="pre">accounting.exceptions.AccountingException</span></tt></a></p>
</dd></dl>
</div>
<div class="section" id="module-accounting.gtkclient">
<span id="accounting-gtkclient-module"></span><h2>accounting.gtkclient module<a class="headerlink" href="#module-accounting.gtkclient" title="Permalink to this headline"></a></h2>
@ -217,11 +235,6 @@ jsonify_exceptions decorator</p>
<tt class="descname">on_show_about_activate</tt><big>(</big><em>widget</em><big>)</big><a class="reference internal" href="../_modules/accounting/gtkclient.html#AccountingApplication.on_show_about_activate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.gtkclient.AccountingApplication.on_show_about_activate" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="method">
<dt id="accounting.gtkclient.AccountingApplication.on_transaction_new_activate">
<tt class="descname">on_transaction_new_activate</tt><big>(</big><em>widget</em><big>)</big><a class="reference internal" href="../_modules/accounting/gtkclient.html#AccountingApplication.on_transaction_new_activate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.gtkclient.AccountingApplication.on_transaction_new_activate" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="method">
<dt id="accounting.gtkclient.AccountingApplication.on_transaction_refresh_activate">
<tt class="descname">on_transaction_refresh_activate</tt><big>(</big><em>widget</em><big>)</big><a class="reference internal" href="../_modules/accounting/gtkclient.html#AccountingApplication.on_transaction_refresh_activate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.gtkclient.AccountingApplication.on_transaction_refresh_activate" title="Permalink to this definition"></a></dt>
@ -330,9 +343,7 @@ and the Flask endpoints.</p>
<dl class="function">
<dt id="accounting.web.init_ledger">
<tt class="descclassname">accounting.web.</tt><tt class="descname">init_ledger</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/web.html#init_ledger"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.web.init_ledger" title="Permalink to this definition"></a></dt>
<dd><p><a class="reference external" href="http://flask.pocoo.org/docs/api/#flask.Flask.before_request" title="(in Flask v0.10)"><tt class="xref py py-meth docutils literal"><span class="pre">flask.Flask.before_request()</span></tt></a>-decorated method that initializes an
<tt class="xref py py-class docutils literal"><span class="pre">accounting.Ledger</span></tt> object.</p>
</dd></dl>
<dd></dd></dl>
<dl class="function">
<dt id="accounting.web.main">
@ -352,6 +363,11 @@ and the Flask endpoints.</p>
<dl class="function">
<dt id="accounting.web.transaction_get">
<tt class="descclassname">accounting.web.</tt><tt class="descname">transaction_get</tt><big>(</big><em>transaction_id=None</em><big>)</big><a class="reference internal" href="../_modules/accounting/web.html#transaction_get"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.web.transaction_get" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="accounting.web.transaction_get_all">
<tt class="descclassname">accounting.web.</tt><tt class="descname">transaction_get_all</tt><big>(</big><em>transaction_id=None</em><big>)</big><a class="headerlink" href="#accounting.web.transaction_get_all" title="Permalink to this definition"></a></dt>
<dd><p>Returns the JSON-serialized output of <tt class="xref py py-meth docutils literal"><span class="pre">accounting.Ledger.reg()</span></tt></p>
</dd></dl>

View file

@ -39,12 +39,12 @@
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>
@ -89,7 +89,7 @@ writing a ledger transaction based on the
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.assemble_arguments">
<tt class="descname">assemble_arguments</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.assemble_arguments"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.assemble_arguments" title="Permalink to this definition"></a></dt>
<tt class="descname">assemble_arguments</tt><big>(</big><em>command=None</em><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.assemble_arguments"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.assemble_arguments" title="Permalink to this definition"></a></dt>
<dd><p>Returns a list of arguments suitable for <a class="reference external" href="http://docs.python.org/3.3/library/subprocess.html#subprocess.Popen" title="(in Python v3.3)"><tt class="xref py py-class docutils literal"><span class="pre">subprocess.Popen</span></tt></a>
based on <tt class="xref py py-attr docutils literal"><span class="pre">self.ledger_bin</span></tt> and <tt class="xref py py-attr docutils literal"><span class="pre">self.ledger_file</span></tt>.</p>
</dd></dl>
@ -99,6 +99,12 @@ based on <tt class="xref py py-attr docutils literal"><span class="pre">self.led
<tt class="descname">bal</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.bal"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.bal" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.commit_changes">
<tt class="descname">commit_changes</tt><big>(</big><em>message</em><big>)</big><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.commit_changes" title="Permalink to this definition"></a></dt>
<dd><p>Commits any changes to <tt class="xref py py-attr docutils literal"><span class="pre">self.ledger_file</span></tt> to the git repository</p>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.delete_transaction">
<tt class="descname">delete_transaction</tt><big>(</big><em>transaction_id</em><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.delete_transaction"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.delete_transaction" title="Permalink to this definition"></a></dt>
@ -116,14 +122,6 @@ ledger file.</p>
</ul>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.get_process">
<tt class="descname">get_process</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.get_process"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.get_process" title="Permalink to this definition"></a></dt>
<dd><p>Returns <tt class="xref py py-attr docutils literal"><span class="pre">self.ledger_process</span></tt> if it evaluates to <tt class="docutils literal"><span class="pre">True</span></tt>. If
<tt class="xref py py-attr docutils literal"><span class="pre">self.ledger_process</span></tt> is not set the result of
<a class="reference internal" href="#accounting.storage.ledgercli.Ledger.init_process" title="accounting.storage.ledgercli.Ledger.init_process"><tt class="xref py py-meth docutils literal"><span class="pre">self.init_process()</span></tt></a> is returned.</p>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.get_transaction">
<tt class="descname">get_transaction</tt><big>(</big><em>transaction_id</em><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.get_transaction"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.get_transaction" title="Permalink to this definition"></a></dt>
@ -134,39 +132,6 @@ ledger file.</p>
<tt class="descname">get_transactions</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.get_transactions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.get_transactions" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.init_process">
<tt class="descname">init_process</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.init_process"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.init_process" title="Permalink to this definition"></a></dt>
<dd><p>Creates a new (presumably) ledger subprocess based on the args from
<a class="reference internal" href="#accounting.storage.ledgercli.Ledger.assemble_arguments" title="accounting.storage.ledgercli.Ledger.assemble_arguments"><tt class="xref py py-meth docutils literal"><span class="pre">Ledger.assemble_arguments()</span></tt></a> and then runs
<a class="reference internal" href="#accounting.storage.ledgercli.Ledger.read_until_prompt" title="accounting.storage.ledgercli.Ledger.read_until_prompt"><tt class="xref py py-meth docutils literal"><span class="pre">Ledger.read_until_prompt()</span></tt></a> once (which should return the banner
text) and discards the output.</p>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.locked_process">
<tt class="descname">locked_process</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.locked_process"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.locked_process" title="Permalink to this definition"></a></dt>
<dd><p>Context manager that checks that the ledger process is not already
locked, then &#8220;locks&#8221; the process and yields the process handle and
unlocks the process when execution is returned.</p>
<p>Since this decorated as a <a class="reference external" href="http://docs.python.org/3.3/library/contextlib.html#contextlib.contextmanager" title="(in Python v3.3)"><tt class="xref py py-func docutils literal"><span class="pre">contextlib.contextmanager()</span></tt></a> the
recommended use is with the <tt class="docutils literal"><span class="pre">with</span></tt>-statement.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">locked_process</span><span class="p">()</span> <span class="k">as</span> <span class="n">p</span><span class="p">:</span>
<span class="n">p</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">b</span><span class="s">&#39;bal</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">)</span>
<span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">read_until_prompt</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.read_until_prompt">
<tt class="descname">read_until_prompt</tt><big>(</big><em>process</em><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.read_until_prompt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.read_until_prompt" title="Permalink to this definition"></a></dt>
<dd><p>Reads from the subprocess instance <tt class="xref py py-data docutils literal"><span class="pre">process</span></tt> until it finds a
combination of <tt class="docutils literal"><span class="pre">\n]\x20</span></tt> (the prompt), then returns the output
without the prompt.</p>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.reg">
<tt class="descname">reg</tt><big>(</big><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.reg"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.reg" title="Permalink to this definition"></a></dt>
@ -175,7 +140,11 @@ without the prompt.</p>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.send_command">
<tt class="descname">send_command</tt><big>(</big><em>command</em><big>)</big><a class="reference internal" href="../_modules/accounting/storage/ledgercli.html#Ledger.send_command"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.ledgercli.Ledger.send_command" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dd><p>Creates a new ledger process with the specified <tt class="xref py py-data docutils literal"><span class="pre">command</span></tt> and
returns the output.</p>
<p>Raises an <a class="reference internal" href="accounting.html#accounting.exceptions.AccountingException" title="accounting.exceptions.AccountingException"><tt class="xref py py-class docutils literal"><span class="pre">AccountingException</span></tt></a>-based
Exception based on the ledger-cli stderr.</p>
</dd></dl>
<dl class="method">
<dt id="accounting.storage.ledgercli.Ledger.update_transaction">
@ -244,12 +213,6 @@ the old transaction using <tt class="xref py py-data docutils literal"><span cla
</dd></dl>
<dl class="exception">
<dt id="accounting.storage.TransactionNotFound">
<em class="property">exception </em><tt class="descclassname">accounting.storage.</tt><tt class="descname">TransactionNotFound</tt><a class="reference internal" href="../_modules/accounting/storage.html#TransactionNotFound"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#accounting.storage.TransactionNotFound" title="Permalink to this definition"></a></dt>
<dd><p>Bases: <a class="reference internal" href="accounting.html#accounting.exceptions.AccountingException" title="accounting.exceptions.AccountingException"><tt class="xref py py-class docutils literal"><span class="pre">accounting.exceptions.AccountingException</span></tt></a></p>
</dd></dl>
</div>
</div>

View file

@ -39,12 +39,12 @@
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="../http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="../index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>

View file

@ -40,12 +40,12 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>
@ -244,6 +244,10 @@
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="api/accounting.storage.html#accounting.storage.ledgercli.Ledger.commit_changes">commit_changes() (accounting.storage.ledgercli.Ledger method)</a>
</dt>
<dt><a href="api/accounting.html#accounting.decorators.cors">cors() (in module accounting.decorators)</a>
</dt>
@ -299,14 +303,10 @@
<dt><a href="api/accounting.storage.html#accounting.storage.Storage.get_accounts">get_accounts() (accounting.storage.Storage method)</a>
</dt>
<dt><a href="api/accounting.html#accounting.client.Client.get_balance">get_balance() (accounting.client.Client method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="api/accounting.storage.html#accounting.storage.ledgercli.Ledger.get_process">get_process() (accounting.storage.ledgercli.Ledger method)</a>
<dt><a href="api/accounting.html#accounting.client.Client.get_balance">get_balance() (accounting.client.Client method)</a>
</dt>
@ -375,10 +375,6 @@
<dt><a href="api/accounting.html#accounting.web.init_ledger">init_ledger() (in module accounting.web)</a>
</dt>
<dt><a href="api/accounting.storage.html#accounting.storage.ledgercli.Ledger.init_process">init_process() (accounting.storage.ledgercli.Ledger method)</a>
</dt>
</dl></td>
</tr></table>
@ -400,13 +396,13 @@
</dt>
<dt><a href="api/accounting.html#accounting.gtkclient.AccountingApplication.load_ui">load_ui() (accounting.gtkclient.AccountingApplication method)</a>
<dt><a href="api/accounting.html#accounting.exceptions.LedgerNotBalanced">LedgerNotBalanced</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="api/accounting.storage.html#accounting.storage.ledgercli.Ledger.locked_process">locked_process() (accounting.storage.ledgercli.Ledger method)</a>
<dt><a href="api/accounting.html#accounting.gtkclient.AccountingApplication.load_ui">load_ui() (accounting.gtkclient.AccountingApplication method)</a>
</dt>
</dl></td>
@ -460,16 +456,12 @@
</dt>
<dt><a href="api/accounting.html#accounting.gtkclient.AccountingApplication.on_transaction_new_activate">on_transaction_new_activate() (accounting.gtkclient.AccountingApplication method)</a>
<dt><a href="api/accounting.html#accounting.gtkclient.AccountingApplication.on_transaction_refresh_activate">on_transaction_refresh_activate() (accounting.gtkclient.AccountingApplication method)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
<dt><a href="api/accounting.html#accounting.gtkclient.AccountingApplication.on_transaction_refresh_activate">on_transaction_refresh_activate() (accounting.gtkclient.AccountingApplication method)</a>
</dt>
<dt><a href="api/accounting.html#accounting.gtkclient.AccountingApplication.on_transaction_view_cursor_changed">on_transaction_view_cursor_changed() (accounting.gtkclient.AccountingApplication method)</a>
</dt>
@ -518,10 +510,6 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
<dt><a href="api/accounting.storage.html#accounting.storage.ledgercli.Ledger.read_until_prompt">read_until_prompt() (accounting.storage.ledgercli.Ledger method)</a>
</dt>
<dt><a href="api/accounting.storage.html#accounting.storage.ledgercli.Ledger.reg">reg() (accounting.storage.ledgercli.Ledger method)</a>
</dt>
@ -591,6 +579,10 @@
<dt><a href="api/accounting.html#accounting.web.transaction_get">transaction_get() (in module accounting.web)</a>
</dt>
<dt><a href="api/accounting.html#accounting.web.transaction_get_all">transaction_get_all() (in module accounting.web)</a>
</dt>
</dl></td>
<td style="width: 33%" valign="top"><dl>
@ -610,7 +602,11 @@
</dt>
<dt><a href="api/accounting.storage.html#accounting.storage.TransactionNotFound">TransactionNotFound</a>
<dt><a href="api/accounting.html#accounting.exceptions.TransactionIDCollision">TransactionIDCollision</a>
</dt>
<dt><a href="api/accounting.html#accounting.exceptions.TransactionNotFound">TransactionNotFound</a>
</dt>
</dl></td>

View file

@ -46,12 +46,12 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="#" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="#" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>
@ -72,21 +72,31 @@
<tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
<tr class="cap" id="cap-/transaction"><td></td><td>
<strong>/transaction</strong></td><td></td></tr>
<tr>
<td></td>
<td>
<a href="restapi.html#post--transaction"><tt class="xref">POST /transaction</tt></a></td><td>
<em></em></td></tr>
<tr>
<td></td>
<td>
<a href="restapi.html#get--transaction"><tt class="xref">GET /transaction</tt></a></td><td>
<em></em></td></tr>
<tr>
<td></td>
<td>
<a href="restapi.html#post--transaction"><tt class="xref">POST /transaction</tt></a></td><td>
<em></em></td></tr>
<tr>
<td></td>
<td>
<a href="restapi.html#delete--transaction--string-transaction_id-"><tt class="xref">DELETE /transaction/&lt;string:transaction_id&gt;</tt></a></td><td>
<em></em></td></tr>
<tr>
<td></td>
<td>
<a href="restapi.html#get--transaction--string-transaction_id-"><tt class="xref">GET /transaction/&lt;string:transaction_id&gt;</tt></a></td><td>
<em></em></td></tr>
<tr>
<td></td>
<td>
<a href="restapi.html#post--transaction--string-transaction_id-"><tt class="xref">POST /transaction/&lt;string:transaction_id&gt;</tt></a></td><td>
<em></em></td></tr>
</table>

View file

@ -6,7 +6,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome to Accounting APIs documentation! &mdash; Accounting API 0.1-beta documentation</title>
<title>Index &mdash; Accounting API 0.1-beta documentation</title>
<link rel="stylesheet" href="_static/flasky.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -24,7 +24,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Accounting API 0.1-beta documentation" href="#" />
<link rel="next" title="The Accounting API" href="README.html" />
<link rel="next" title="accounting-api README" href="README.html" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9">
@ -42,14 +42,14 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="README.html" title="The Accounting API"
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="README.html" title="accounting-api README"
accesskey="N">next</a> |</li>
<li><a href="#">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
@ -60,36 +60,38 @@
<div class="bodywrapper">
<div class="body">
<div class="section" id="welcome-to-accounting-api-s-documentation">
<h1>Welcome to Accounting API&#8217;s documentation!<a class="headerlink" href="#welcome-to-accounting-api-s-documentation" title="Permalink to this headline"></a></h1>
<div class="section" id="index">
<h1>Index<a class="headerlink" href="#index" title="Permalink to this headline"></a></h1>
<div class="section" id="accounting-api">
<h2>Accounting API<a class="headerlink" href="#accounting-api" title="Permalink to this headline"></a></h2>
<p>Contents:</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="README.html">The Accounting API</a><ul>
<li class="toctree-l1"><a class="reference internal" href="README.html">accounting-api README</a><ul>
<li class="toctree-l2"><a class="reference internal" href="README.html#dependencies">Dependencies</a></li>
<li class="toctree-l2"><a class="reference internal" href="README.html#installation-i-e-development-setup">Installation (i.e. Development Setup)</a></li>
<li class="toctree-l2"><a class="reference internal" href="README.html#usage">Usage</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="restapi.html">REST API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="restapi.html#get-transactions">Get transactions</a></li>
<li class="toctree-l1"><a class="reference internal" href="restapi.html">REST API Documentation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="restapi.html#get-all-transactions">Get all transactions</a></li>
<li class="toctree-l2"><a class="reference internal" href="restapi.html#get-a-single-transaction">Get a single transaction</a></li>
<li class="toctree-l2"><a class="reference internal" href="restapi.html#add-transactions">Add transactions</a></li>
<li class="toctree-l2"><a class="reference internal" href="restapi.html#delete-a-transaction">Delete a transaction</a></li>
<li class="toctree-l2"><a class="reference internal" href="restapi.html#update-a-transaction">Update a transaction</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="section" id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
<h3>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
<li><a class="reference internal" href="py-modindex.html"><em>Module Index</em></a></li>
<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
</ul>
</div>
</div>
</div>
@ -103,18 +105,18 @@
</a></p>
<h3><a href="#">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Welcome to Accounting API&#8217;s documentation!</a><ul>
<li><a class="reference internal" href="#">Index</a><ul>
<li><a class="reference internal" href="#accounting-api">Accounting API</a><ul>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>Related Topics</h3>
<ul>
<li><a href="#">Documentation overview</a><ul>
<li>Next: <a href="README.html" title="next chapter">The Accounting API</a></li>
<li>Next: <a href="README.html" title="next chapter">accounting-api README</a></li>
</ul></li>
</ul>
<h3>This Page</h3>

Binary file not shown.

View file

@ -42,12 +42,12 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="#" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>

View file

@ -6,7 +6,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>REST API &mdash; Accounting API 0.1-beta documentation</title>
<title>REST API Documentation &mdash; Accounting API 0.1-beta documentation</title>
<link rel="stylesheet" href="_static/flasky.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
@ -24,7 +24,7 @@
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Accounting API 0.1-beta documentation" href="index.html" />
<link rel="prev" title="The Accounting API" href="README.html" />
<link rel="prev" title="accounting-api README" href="README.html" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9">
@ -40,14 +40,14 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="README.html" title="The Accounting API"
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="README.html" title="accounting-api README"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
@ -58,15 +58,17 @@
<div class="bodywrapper">
<div class="body">
<div class="section" id="rest-api">
<h1>REST API<a class="headerlink" href="#rest-api" title="Permalink to this headline"></a></h1>
<div class="section" id="get-transactions">
<h2>Get transactions<a class="headerlink" href="#get-transactions" title="Permalink to this headline"></a></h2>
<div class="section" id="rest-api-documentation">
<h1>REST API Documentation<a class="headerlink" href="#rest-api-documentation" title="Permalink to this headline"></a></h1>
<p>The accounting-api projects main application provides a REST API for accounting
data. This is the documentation for the various REST endpoints that the
accounting-api application provides.</p>
<div class="section" id="get-all-transactions">
<h2>Get all transactions<a class="headerlink" href="#get-all-transactions" title="Permalink to this headline"></a></h2>
<dl class="get">
<dt id="get--transaction">
<tt class="descname">GET </tt><tt class="descname">/transaction</tt><a class="headerlink" href="#get--transaction" title="Permalink to this definition"></a></dt>
<dd><p>Get all transactions</p>
<p><strong>Example request</strong></p>
<dd><p><strong>Example request</strong></p>
<div class="highlight-http"><div class="highlight"><pre><span class="nf">GET</span> <span class="nn">/transaction</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">accounting.example</span>
<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span>
@ -146,6 +148,57 @@
</div>
</dd></dl>
</div>
<div class="section" id="get-a-single-transaction">
<h2>Get a single transaction<a class="headerlink" href="#get-a-single-transaction" title="Permalink to this headline"></a></h2>
<dl class="get">
<dt id="get--transaction--string-transaction_id-">
<tt class="descname">GET </tt><tt class="descname">/transaction/&lt;string:transaction_id&gt;</tt><a class="headerlink" href="#get--transaction--string-transaction_id-" title="Permalink to this definition"></a></dt>
<dd><p><strong>Example request</strong></p>
<div class="highlight-http"><div class="highlight"><pre><span class="nf">GET</span> <span class="nn">/transaction/2aeea63b-0996-4ead-bc4c-e15505dff226</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">accounting.example</span>
<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span>
</pre></div>
</div>
<p><strong>Example response</strong></p>
<div class="highlight-http"><div class="highlight"><pre><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">200</span> <span class="ne">OK</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
<span class="p">{</span>
<span class="nt">&quot;transaction&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Transaction&quot;</span><span class="p">,</span>
<span class="nt">&quot;date&quot;</span><span class="p">:</span> <span class="s2">&quot;2013-12-26&quot;</span><span class="p">,</span>
<span class="nt">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;2aeea63b-0996-4ead-bc4c-e15505dff226&quot;</span><span class="p">,</span>
<span class="nt">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{},</span>
<span class="nt">&quot;payee&quot;</span><span class="p">:</span> <span class="s2">&quot;January Rent&quot;</span><span class="p">,</span>
<span class="nt">&quot;postings&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Posting&quot;</span><span class="p">,</span>
<span class="nt">&quot;account&quot;</span><span class="p">:</span> <span class="s2">&quot;Assets:Checking&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Amount&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="s2">&quot;-424.24&quot;</span><span class="p">,</span>
<span class="nt">&quot;symbol&quot;</span><span class="p">:</span> <span class="s2">&quot;USD&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{}</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Posting&quot;</span><span class="p">,</span>
<span class="nt">&quot;account&quot;</span><span class="p">:</span> <span class="s2">&quot;Expenses:Rent&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Amount&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="s2">&quot;424.24&quot;</span><span class="p">,</span>
<span class="nt">&quot;symbol&quot;</span><span class="p">:</span> <span class="s2">&quot;USD&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{}</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</dd></dl>
</div>
<div class="section" id="add-transactions">
<h2>Add transactions<a class="headerlink" href="#add-transactions" title="Permalink to this headline"></a></h2>
@ -245,6 +298,62 @@
</div>
</dd></dl>
</div>
<div class="section" id="update-a-transaction">
<h2>Update a transaction<a class="headerlink" href="#update-a-transaction" title="Permalink to this headline"></a></h2>
<dl class="post">
<dt id="post--transaction--string-transaction_id-">
<tt class="descname">POST </tt><tt class="descname">/transaction/&lt;string:transaction_id&gt;</tt><a class="headerlink" href="#post--transaction--string-transaction_id-" title="Permalink to this definition"></a></dt>
<dd><p><strong>Example request</strong></p>
<div class="highlight-http"><div class="highlight"><pre><span class="nf">POST</span> <span class="nn">/transaction/2aeea63b-0996-4ead-bc4c-e15505dff226</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">accounting.example</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span>
<span class="p">{</span>
<span class="nt">&quot;transaction&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Transaction&quot;</span><span class="p">,</span>
<span class="nt">&quot;date&quot;</span><span class="p">:</span> <span class="s2">&quot;2013-12-26&quot;</span><span class="p">,</span>
<span class="nt">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;2aeea63b-0996-4ead-bc4c-e15505dff226&quot;</span><span class="p">,</span>
<span class="nt">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{},</span>
<span class="nt">&quot;payee&quot;</span><span class="p">:</span> <span class="s2">&quot;February Rent&quot;</span><span class="p">,</span>
<span class="nt">&quot;postings&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Posting&quot;</span><span class="p">,</span>
<span class="nt">&quot;account&quot;</span><span class="p">:</span> <span class="s2">&quot;Assets:Checking&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Amount&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="s2">&quot;-424.24&quot;</span><span class="p">,</span>
<span class="nt">&quot;symbol&quot;</span><span class="p">:</span> <span class="s2">&quot;USD&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{}</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Posting&quot;</span><span class="p">,</span>
<span class="nt">&quot;account&quot;</span><span class="p">:</span> <span class="s2">&quot;Expenses:Rent&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;__type__&quot;</span><span class="p">:</span> <span class="s2">&quot;Amount&quot;</span><span class="p">,</span>
<span class="nt">&quot;amount&quot;</span><span class="p">:</span> <span class="s2">&quot;424.24&quot;</span><span class="p">,</span>
<span class="nt">&quot;symbol&quot;</span><span class="p">:</span> <span class="s2">&quot;USD&quot;</span>
<span class="p">},</span>
<span class="nt">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{}</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p><strong>Example response</strong></p>
<div class="highlight-http"><div class="highlight"><pre><span class="kr">HTTP</span><span class="o">/</span><span class="m">1.0</span> <span class="m">200</span> <span class="ne">OK</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/json</span>
<span class="p">{</span>
<span class="nt">&quot;status&quot;</span><span class="p">:</span> <span class="s2">&quot;OK&quot;</span>
<span class="p">}</span>
</pre></div>
</div>
</dd></dl>
</div>
</div>
@ -259,17 +368,19 @@
</a></p>
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">REST API</a><ul>
<li><a class="reference internal" href="#get-transactions">Get transactions</a></li>
<li><a class="reference internal" href="#">REST API Documentation</a><ul>
<li><a class="reference internal" href="#get-all-transactions">Get all transactions</a></li>
<li><a class="reference internal" href="#get-a-single-transaction">Get a single transaction</a></li>
<li><a class="reference internal" href="#add-transactions">Add transactions</a></li>
<li><a class="reference internal" href="#delete-a-transaction">Delete a transaction</a></li>
<li><a class="reference internal" href="#update-a-transaction">Update a transaction</a></li>
</ul>
</li>
</ul>
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="README.html" title="previous chapter">The Accounting API</a></li>
<li>Previous: <a href="README.html" title="previous chapter">accounting-api README</a></li>
</ul></li>
</ul>
<h3>This Page</h3>

View file

@ -47,12 +47,12 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="http-routingtable.html" title="HTTP Routing Table"
>routing table</a> |</li>
<li><a href="index.html">Accounting API 0.1-beta documentation</a> &raquo;</li>
</ul>
</div>

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,6 @@
.. Accounting API documentation master file, created by
sphinx-quickstart on Thu Dec 12 14:02:01 2013.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Accounting API's documentation!
==========================================
=======
Index
=======
-----------------------
Accounting API

View file

@ -1,14 +1,16 @@
==========
REST API
==========
========================
REST API Documentation
========================
Get transactions
The accounting-api projects main application provides a REST API for accounting
data. This is the documentation for the various REST endpoints that the
accounting-api application provides.
Get all transactions
----------------
.. http:get:: /transaction
Get all transactions
**Example request**
.. code-block:: http
@ -28,63 +30,63 @@ Get transactions
{
"transactions": [
{
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"postings": [
{
"__type__": "Posting",
"account": "Income:Foo:Donation",
"__type__": "Posting",
"account": "Income:Foo:Donation",
"amount": {
"__type__": "Amount",
"amount": "-100",
"__type__": "Amount",
"amount": "-100",
"symbol": "$"
},
},
"metadata": {
"Invoice": "Projects/Foo/Invoices/Invoice20100101.pdf"
}
},
},
{
"__type__": "Posting",
"account": "Assets:Checking",
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "100",
"__type__": "Amount",
"amount": "100",
"symbol": "$"
},
},
"metadata": {}
}
]
},
},
{
"__type__": "Transaction",
"date": "2011-03-15",
"id": "but mind you if they collide.",
"metadata": {},
"payee": "Another J. Donor",
"__type__": "Transaction",
"date": "2011-03-15",
"id": "but mind you if they collide.",
"metadata": {},
"payee": "Another J. Donor",
"postings": [
{
"__type__": "Posting",
"account": "Income:Foo:Donation",
"__type__": "Posting",
"account": "Income:Foo:Donation",
"amount": {
"__type__": "Amount",
"amount": "-400",
"__type__": "Amount",
"amount": "-400",
"symbol": "$"
},
},
"metadata": {
"Approval": "Projects/Foo/earmark-record.txt"
}
},
},
{
"__type__": "Posting",
"account": "Assets:Checking",
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "400",
"__type__": "Amount",
"amount": "400",
"symbol": "$"
},
},
"metadata": {}
}
]
@ -92,6 +94,59 @@ Get transactions
]
}
Get a single transaction
------------------------
.. http:get:: /transaction/<string:transaction_id>
**Example request**
.. code-block:: http
GET /transaction/2aeea63b-0996-4ead-bc4c-e15505dff226 HTTP/1.1
Host: accounting.example
Accept: application/json
**Example response**
.. code-block:: http
HTTP/1.0 200 OK
Content-Type: application/json
{
"transaction": {
"__type__": "Transaction",
"date": "2013-12-26",
"id": "2aeea63b-0996-4ead-bc4c-e15505dff226",
"metadata": {},
"payee": "January Rent",
"postings": [
{
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "-424.24",
"symbol": "USD"
},
"metadata": {}
},
{
"__type__": "Posting",
"account": "Expenses:Rent",
"amount": {
"__type__": "Amount",
"amount": "424.24",
"symbol": "USD"
},
"metadata": {}
}
]
}
}
Add transactions
----------------
@ -111,36 +166,36 @@ Add transactions
{
"transactions": [
{
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"__type__": "Transaction",
"date": "2010-01-01",
"id": "Ids can be anything",
"metadata": {},
"payee": "Kindly T. Donor",
"postings": [
{
"__type__": "Posting",
"account": "Income:Foo:Donation",
"__type__": "Posting",
"account": "Income:Foo:Donation",
"amount": {
"__type__": "Amount",
"amount": "-100",
"__type__": "Amount",
"amount": "-100",
"symbol": "$"
},
},
"metadata": {
"Invoice": "Projects/Foo/Invoices/Invoice20100101.pdf"
}
},
},
{
"__type__": "Posting",
"account": "Assets:Checking",
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "100",
"__type__": "Amount",
"amount": "100",
"symbol": "$"
},
},
"metadata": {}
}
]
},
},
]
}
@ -184,3 +239,61 @@ Delete a transaction
{
"status": "OK"
}
Update a transaction
--------------------
.. http:post:: /transaction/<string:transaction_id>
**Example request**
.. code-block:: http
POST /transaction/2aeea63b-0996-4ead-bc4c-e15505dff226 HTTP/1.1
Host: accounting.example
Content-Type: application/json
Accept: application/json
{
"transaction": {
"__type__": "Transaction",
"date": "2013-12-26",
"id": "2aeea63b-0996-4ead-bc4c-e15505dff226",
"metadata": {},
"payee": "February Rent",
"postings": [
{
"__type__": "Posting",
"account": "Assets:Checking",
"amount": {
"__type__": "Amount",
"amount": "-424.24",
"symbol": "USD"
},
"metadata": {}
},
{
"__type__": "Posting",
"account": "Expenses:Rent",
"amount": {
"__type__": "Amount",
"amount": "424.24",
"symbol": "USD"
},
"metadata": {}
}
]
}
}
**Example response**
.. code-block:: http
HTTP/1.0 200 OK
Content-Type: application/json
{
"status": "OK"
}