txboxdotnet
-----------

Twisted-based python async interface for `Box (box.net) API (version
2.0) <http://developers.box.com/>`_.

-  API docs: http://developers.box.com/docs/
-  API Auth docs: http://developers.box.com/oauth/

Usage Example
-------------

Following script will print listing of the root box.net folder, upload
"test.txt" file there, try to find it in updated folder listing and then
remove it.

::

    from twisted.internet import defer, reactor
    from txboxdotnet.api_v2 import txBoxAPI

    api = txBoxAPI(
        client_id='...',
        client_secret='...', ... )

    if not api.auth_code:
        print '\n'.join([
            'Visit the following URL in any web browser (firefox, chrome, safari, etc),',
                '  authorize there, confirm access permissions, and paste URL of an empty page',
                '  (starting with "https://success.box.com/") you will get',
                '  redirected to into "auth_code" value in "config" dict above.\n',
            'URL to visit:\n  {}'.format(api.auth_user_get_url()) ])
        exit()

    if re.search(r'^https?://', api.auth_code):
        api.auth_user_process_url(api.auth_code)

    @defer.inlineCallbacks
    def do_stuff():

        # Print root directory listing
        print list(e['name'] for e in (yield api.listdir()))

        # Upload "test.txt" file from local current directory
        file_info = yield api.put('test.txt')

        # Find just-uploaded "test.txt" file by name
        file_id = yield api.resolve_path('test.txt')

        # Check that id matches uploaded file
        assert file_info['id'] == file_id

        # Remove the file
        yield api.delete(file_id)

    do_stuff().addBoth(lambda ignored: reactor.stop())
    reactor.run()

Note that parameters passed to txBoxAPI class init above should contain
authentication data, which can/should be derived from "client\_id" and
"client\_secret", provided after app registration `on
box.net <http://www.box.net/developers/services>`_.

Service (at least now) has quite annoying requirement that the
"auth\_code" it will provide after authorizing API access request is
only valid for **30 seconds**. See `API auth
docs <http://developers.box.com/oauth/>`_ for more info on the process.

For more complete example (including oauth2 stuff), see
`api\_v2.py <https://github.com/mk-fg/txboxdotnet/blob/master/txboxdotnet/api_v2.py>`_
code after ``if __name__ == '__main__':`` (will need better examples in
the future, patches welcome!).

Installation
------------

It's a regular package for Python 2.7 (not 3.X).

Using `pip <http://pip-installer.org/>`_ is the best way:

::

    % pip install txboxdotnet

If you don't have it, use:

::

    % easy_install pip
    % pip install txboxdotnet

Alternatively (`see
also <http://www.pip-installer.org/en/latest/installing.html>`_):

::

    % curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python
    % pip install txboxdotnet

Or, if you absolutely must:

::

    % easy_install txboxdotnet

But, you really shouldn't do that.

Current-git version can be installed like this:

::

    % pip install 'git+https://github.com/mk-fg/txboxdotnet.git#egg=txboxdotnet'

Note that to install stuff in system-wide PATH and site-packages,
elevated privileges are often required. Use "install --user",
`~/.pydistutils.cfg <http://docs.python.org/install/index.html#distutils-configuration-files>`_
or `virtualenv <http://pypi.python.org/pypi/virtualenv>`_ to do
unprivileged installs into custom paths.

Requirements
~~~~~~~~~~~~

-  `Python 2.7 (not 3.X) <http://python.org>`_

-  `Twisted <http://twistedmatrix.com>`_ (core, web, at least 12.2.0)

Implemented methods
-------------------

Matrix of implemented API method wrappers (same order as in the
`docs <http://developers.box.com/docs/>`_):

-  folders

   -  [x] list: ``listdir``
   -  [x] create: ``mkdir``
   -  [x] get info: ``info_folder``
   -  [ ] copy
   -  [x] delete: ``delete_folder``
   -  [ ] update info
   -  [ ] create shared link
   -  [ ] view discussions
   -  [ ] view collaborations
   -  [ ] list from trash
   -  [ ] info from trash
   -  [ ] restore from trash
   -  [ ] delete permanently

-  files

   -  [x] upload: ``put``
   -  [x] download: ``get``
   -  [x] get info: ``info_file``
   -  [x] upload overwrite: ``put``
   -  [ ] upload rename
   -  [ ] view versions
   -  [ ] update info
   -  [x] delete: ``delete_file``
   -  [ ] copy
   -  [ ] create shared link
   -  [ ] view comments
   -  [ ] get thumbnail
   -  [ ] get from trash
   -  [ ] restore from trash
   -  [ ] delete permanently

-  comments
-  discussions
-  collaborations

-  users

   -  [x] current user info: ``info_user``
   -  [ ] all the rest ;)

-  search
-  shared items
-  events

Note that these wrappers tend to be very thin, just taking python method
arguments and translating these into appropriate API keys, typically
looking somewhat like this:

::

    def info_file(self, file_id):
      return self(join('files', file_id))

Any missing methods can also be replaced by calling api object in the
same way as above, passing all the appropriate (as per docs) parameters.

My purposes are quite narrow - I use service only for file storage - so
missing sharing/collaboration wrappers are unlikely to be implemented
here without patches from someone interested in having these.
