API
===
K4ever has a REST-like API. This means every URL represents an object which has
four functions: ``read``, ``create``, ``update`` and ``delete``. These functions
are mapped to the ``HTTP``-Methods ``GET``, ``POST``, ``PUT`` and ``DELETE``.
Most of the functionality uses only ``GET`` and ``POST``, so everything is
accessible via ``wget``.

The API enables you to list available items, buy them and transact money to
your accout. To get an idea what functions are available and how they are used
scroll down to the URLs section. Some URLs take arguments. For a ``GET``-request
you can attach them normally, e.g. `/buyable/item/?barcode=4029764001807`.
For a ``POST``, ``PUT`` or ``DELETE`` request the parameters have to be put in
the ``HTTP``-request's body. They can be provided url, JSON or YAML-encoded -
dealer's choice.

Authentication can be done either per HTTP Basic Auth or, for AJAX-Requests,
per cookie (as in "logged in via the webinterface"). Note that most
``HTTP``-libraries like python's urllib2 (or as a tool ``wget``) don't send
authentication data except when being challenged with a
``HTTP 401 - Authentication required``, meaning that every API-call requires
the library to make two requests. In general this behaviour can be turned off.


Plugins
--------------
k4evers API also has a *plugin* concept. :class:`Plugins <main.models.Plugin>`
can be allowed by users to buy items on their behalf, e.g. after scanning the
user's unique barcode. To do this the user has to allow the plugin via the 
webinterface. A :class:`PluginPermission <main.models.PluginPermission>` object
will be created to keep track of this.

Each :class:`PluginPermission <main.models.PluginPermission>` object has an
:attr:`authblob <main.models.PluginPermission.authblob>` in which the plugin
can save or access arbitrary data on a per-user basis. The plugin has several
configuration options for the `authblob`. They control read/write access for 
plugin (via API) or user (via webinterface) to the `authblob` and whether the 
`authblob` has to be unique. The latter one can be useful if the `authblob`
is needed to be primary key and identify exactly one user
(see also :ref:`apilink <authblob-authentication>`).

To do something as another user the plugin can, if allowed by the user, add
the `user`-parameter with the **username** (not the id) to all its requests.
E.g. to get the account balance of the user *cat* this would look like
`user/account/?user=cat`.

URLs
----
For more information about a specific method you can click on the url/method to get
to the handler or the responsible method for more documentation or code.

**buyable/**
  :class:`item/[itemId]/ <api2.handlers.BuyableItemHandler>`
  	:func:`GET <api2.handlers.BuyableItemHandler.read>`
  		Get a specific item or a full/type item list.

		=========	=======================
		Parameter	Description
  		=========	=======================
  		type		item belonging to type-group
		barcode		item with this barcode
  		=========	=======================

   	:func:`POST <api2.handlers.BuyableItemHandler.buyItem>`
   		Buy a :class:`Buyable <buyable.models.Buyable>` (requires an ItemId)

		=========	=======================================================
		Parameter	Description
		=========	=======================================================
		deposit		Set to 0 for no deposit, 1 for deposit and 2 for item+deposit (default 0)
   		amount		amount of items to buy (default 1)
		=========	=======================================================

  :class:`item/bulkbuy/ <api2.handlers.BuyableItemHandler>`
   	:func:`POST <api2.handlers.BuyableItemHandler.bulkBuy>`
   		Buy multiple :class:`Buyables <buyable.models.Buyable>`.
		To buy multiple items, the body of this ``POST``-request has to
		be either JSON or YAML. In case of doubt, see the :ref:`curl examples <curl-examples>` below.

		=========	=======================================================
		Parameter	Description
		=========	=======================================================
		items		A list of ids for items to buy.
		deposits	A list of ids for items to buy as deposit.
		=========	=======================================================

  :class:`types/ <api2.handlers.BuyableTypeHandler>`
   	:func:`GET <api2.handlers.BuyableTypeHandler.read>`
   		List all types which an item can belong to.
   
  :class:`history/ <api2.handlers.HistoryHandler>`
   	:func:`GET <api2.handlers.HistoryHandler.read>`
   		List the user's last orders

		=========	=================
		Parameter	Description
		=========	=================
   		num			Number of entries
		=========	=================

  **img/**
	:class:`sizes/ <api2.handlers.ImgSizesHandler>`
   		:func:`GET <api2.handlers.ImgSizeHandler.read>`
			List all available sizes for thumbnails

	:class:`thumb/[itemId]/[xSize]x[ySize]/ <api2.handlers.ImgThumbHandler>`
   		:func:`GET <api2.handlers.ImgThumbHandler.read>`
			Returns the url to a thumbnail for [itemId] of size[xSize]x[ySize].
			E.g. thumb/1/64x64/ returns the path to an image for the first item
			and a dimension of 64x64. If the size is not available an error
			is raised.

**account/**
  **transactions/**
	:class:`transact/ <api2.handlers.TransactionTransactHandler>`
   		:func:`GET <api2.handlers.TransactionTransactHandler.read>`
   			List the user's last transactions

			=========	=================
			Parameter	Description
			=========	=================
   			num			Number of entries
			=========	=================

   		:func:`POST <api2.handlers.TransactionTransactHandler.create>`
   			Transact money to an account

			=========	=================
			Parameter	Description
			=========	=================
   			amount		[required] Amount to add to the user's account
   			type		[required] Type of transaction (id)
			=========	=================

	:class:`types/ <api2.handlers.TransactionTypeHandler>`
		:func:`GET <api2.handlers.TransactionTypeHandler.read>`
			List all available :class:`Transaction Types <buyable.models.TransactionType>`
	:class:`balance/ <api2.handlers.AccountBalanceHandler>`
		:func:`GET <api2.handlers.AccountBalanceHandler.read>`
			Get user's account balance
	:class:`virtual/ <api2.handlers.TransactionVirtualHandler>`
		:func:`GET <api2.handlers.TransactionVirtualHandler.read>`
			Return the user's last virtual transactions (inbound and outbound)

			=========	=================
			Parameter	Description
			=========	=================
			num			Number of entries to return
			=========	=================

		:func:`POST <api2.handlers.TransactionVirtualHandler.create>`
			Transact money from the users to another users account.

			=========	=================
			Parameter	Description
			=========	=================
			amount		[required] Amount to transact
			recipient	[required] User that will get the money
			comment		[required] Comment, why the money was transacted
			=========	=================

**auth/**
 :class:`blob/ <api2.handlers.AuthBlobHandler>`
   	:func:`GET <api2.handlers.AuthBlobHandler.read>`
   		Only available for plugins. Username needs to be specified with ?user=`name`
		Return authblob of a specific user if allowed by plugin configuration
		(currently only allowed for Plugin users)
	:func:`POST <api2.handlers.AuthBlobHandler.create>`
   		Set authblob if allowed by plugin configuration

 .. _authblob-authentication:

 :class:`user/ <api2.handlers.AuthUserHandler>`
   	:func:`GET <api2.handlers.AuthUserHandler.read>`
   		Get user who corresponds to a specific authblob string, e.g. to identify him -
		this works only when the plugin has set the :attr:`unique authblob 
		<main.models.Plugin.uniqueAuthblob>` flag

		=========	=================
		Parameter	Description
		=========	=================
   		authblob	[required] authblob to search
		=========	=================

:class:`config/ <api2.handlers.ConfigHandler>`
   :func:`GET <api2.handlers.ConfigHandler.read>`
   		Display API configuration variables
 

Handler
-------
.. automodule:: api2.handlers
	:members:

Plugin Models
-------------
.. autoclass:: main.models.Plugin
	:members:

.. autoclass:: main.models.PluginPermission
	:members:

Decorators
----------
.. automodule:: api2.decorators
	:members:

Examples
--------
Here are some code examples of how to use the API with different clients or languages.
In these examples we use *frundy*/*foobar* as authentication for a normal user and *testplugin*/*maunz* as a plugin.


WGET
""""
``wget`` comes in handy at this task. At some point it might be that ``wget`` cannot provide full access to the API cause it is unable to send ``PUT`` and ``DELETE`` requests. For debugging purposes the flags `-Sd` are recommended.

.. code-block:: bash

    # find item with barcode
	wget -qS -O- --auth-no-challenge --http-user=frundy --http-password=foobar http://server/api/buyable/item/?barcode=4029764001807
	# buy the item with id 3 10 times
	wget -qS -O- --auth-no-challenge --http-user=frundy --http-password=foobar http://server/api/buyable/item/3/ --post-data "amount=10"
	# as plugin, get user's account balance
	wget -qS -O- --auth-no-challenge --http-user=testplugin --http-password=maunz http://server/api/buyable/account/balance/?user=frundy
	# as plugin, buy item with id 3 10 times
	wget -qS -O- --auth-no-challenge --http-user=testplugin --http-password=maunz http://server/api/buyable/item/3/ --post-data "amount=10&user=frundy

CURL
""""
As one might see, ``curl`` is quite nice for accessing the API. ``curl`` also supports the ``HTTP``, ``PUT`` and ``DELETE`` methods.

.. _curl-examples:
.. code-block:: bash

    # find item with barcode
	curl --basic http://frundy:foobar@server/api/buyable/item/?barcode=4029764001807
	# buy the item with id 3 10 times
	curl --basic -X POST --data "amount=10" http://fruny:foobar@server/api/buyable/item/3/
	# as plugin get user's account balance
	curl --basic http://testplugin:maunz@server/api/buyable/account/balance/?user=frundy
	# as plugin, buy item with id 3 10 times
	curl --basic -X POST --data "amount=10" http://testplugin:maunz@server/api/buyable/item/3/?user=frundy
	# buy multiple items by sending JSON-data
	curl --basic -X POST -H "Content-Type: application/json" --data '{"items": [1,2,4], "deposits": [1, 3]}' http://frundy:foobar@server/api/buyable/item/bulkbuy/

