Tiny framework for building *good* API client libraries thanks to
`urllib3 <https://github.com/shazow/urllib3/>`_.
Highlights
==========
- Threadsafely reuses connections with Keep-Alive (via urllib3).
- Small and easy to understand codebase perfect for extending and building upon.
- Built-in support for rate limiting and request throttling.
- Functional examples for the
`Klout API <https://github.com/shazow/apiclient/blob/master/examples/klout.py>`_
and the
`Facebook OpenGraph API <https://github.com/shazow/apiclient/blob/master/examples/facebook.py>`_.
Examples
========
How to make your own super-simple client API library::
>>> from apiclient import APIClient
>>> class AcmePublicAPI(APIClient):
... BASE_URL = 'https://localhost:1234/'
>>> acme_api = AcmePublicAPI()
>>> acme_api.call('/hello')
{'what': 'world'}
>>> acme_api.call('/echo', params={"ping": "pong"})
{'ping': 'pong'}
How to add rate limiting to your client API library so that we don't exceed 10
requests per minute::
>>> from apiclient import RateLimiter
>>> lock = RateLimiter(max_messages=10, every_seconds=60)
>>> acme_api = AcmePublicAPI(rate_limit_lock=lock)
>>> # Get the first 100 pages
>>> for page in xrange(100):
... # Whenever our request rate exceeds the specifications of the API's
... # RateLimiter, the next request will block until the next request window
... r = acme_api.call('/stream', page=str(page))
For more specific API examples, see the
`examples/ <https://github.com/shazow/apiclient/blob/master/examples/>`_ directory.
Extending
=========
To handle different calling conventions, ``apiclient`` can be extended through
subclassing.
For example, if an API requires that all arguments be JSON encoded, the
``_compose_url`` method could be implemented like this::
>>> class JSONArgsAPIClient(APIClient):
... def _compose_url(self, path, params=None):
... if params is not None:
... params = dict((key, json.dumps(val))
... for (key, val) in params.iteritems())
... return APIClient._compose_url(self, path, params=params)
Or if an API returns YAML instead of JSON, the ``_handle_response`` method
could be overridden::
>>> class YAMLResponseAPIClient(APIClient):
... def _handle_response(self, response):
... return yaml.load(response.data)
TODO
====
- Tests.
- More documentation.
- More types of API handshakes, like OAuth and OAuth2.
- More examples.
Contributing
============
Any contribution is highly encouraged and desired. :)
#. Fork on Github.
#. Make the changes. Bonus points if changes include documentation and tests.
#. Send a pull request.
If you're unsure if it's a good idea,
`open an Issue <https://github.com/shazow/apiclient/issues>`_ or
`contact me <https://github.com/inbox/new/shazow>`_ to discuss your proposal.
Extra juicy bonus points if you pick off some of the items in the **TODO** list.
License
=======
`MIT <https://github.com/shazow/apiclient/blob/master/LICENSE>`_
Changes
=======
1.0.3 (2016-05-15)
------------------
* Python 3 fixes.
1.0.2 (2011-10-20)
------------------
* Fixed setup.py from failing upon not seeing README.rst when installing using
easy_install.
1.0.1 (2011-10-10)
------------------
* Fixed setup.py package not including a MANIFEST.in
1.0 (2011-10-03)
----------------
* Published decoupled code from SocialGrapple.
Raw data
{
"_id": null,
"home_page": "https://github.com/shazow/apiclient",
"name": "apiclient",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "api client urllib3 keepalive threadsafe http rest",
"author": "Andrey Petrov",
"author_email": "andrey.petrov@shazow.net",
"download_url": "https://files.pythonhosted.org/packages/f1/93/d36bc33f0b1cfbb7c2b5e3057586abc500aa49f0c1d8fb32af347319c1ca/apiclient-1.0.4.tar.gz",
"platform": "",
"description": "Tiny framework for building *good* API client libraries thanks to\n`urllib3 <https://github.com/shazow/urllib3/>`_.\n\nHighlights\n==========\n\n- Threadsafely reuses connections with Keep-Alive (via urllib3).\n- Small and easy to understand codebase perfect for extending and building upon.\n- Built-in support for rate limiting and request throttling.\n- Functional examples for the\n `Klout API <https://github.com/shazow/apiclient/blob/master/examples/klout.py>`_\n and the\n `Facebook OpenGraph API <https://github.com/shazow/apiclient/blob/master/examples/facebook.py>`_.\n\n\nExamples\n========\n\nHow to make your own super-simple client API library::\n\n >>> from apiclient import APIClient\n >>> class AcmePublicAPI(APIClient):\n ... BASE_URL = 'https://localhost:1234/'\n\n >>> acme_api = AcmePublicAPI()\n\n >>> acme_api.call('/hello')\n {'what': 'world'}\n >>> acme_api.call('/echo', params={\"ping\": \"pong\"})\n {'ping': 'pong'}\n\n\nHow to add rate limiting to your client API library so that we don't exceed 10\nrequests per minute::\n\n >>> from apiclient import RateLimiter\n >>> lock = RateLimiter(max_messages=10, every_seconds=60)\n >>> acme_api = AcmePublicAPI(rate_limit_lock=lock)\n\n >>> # Get the first 100 pages\n >>> for page in xrange(100):\n ... # Whenever our request rate exceeds the specifications of the API's\n ... # RateLimiter, the next request will block until the next request window\n ... r = acme_api.call('/stream', page=str(page))\n\nFor more specific API examples, see the\n`examples/ <https://github.com/shazow/apiclient/blob/master/examples/>`_ directory.\n\n\nExtending\n=========\n\nTo handle different calling conventions, ``apiclient`` can be extended through\nsubclassing.\n\nFor example, if an API requires that all arguments be JSON encoded, the\n``_compose_url`` method could be implemented like this::\n\n >>> class JSONArgsAPIClient(APIClient):\n ... def _compose_url(self, path, params=None):\n ... if params is not None:\n ... params = dict((key, json.dumps(val))\n ... for (key, val) in params.iteritems())\n ... return APIClient._compose_url(self, path, params=params)\n\nOr if an API returns YAML instead of JSON, the ``_handle_response`` method\ncould be overridden::\n\n >>> class YAMLResponseAPIClient(APIClient):\n ... def _handle_response(self, response):\n ... return yaml.load(response.data)\n\n\nTODO\n====\n\n- Tests.\n- More documentation.\n- More types of API handshakes, like OAuth and OAuth2.\n- More examples.\n\n\nContributing\n============\n\nAny contribution is highly encouraged and desired. :)\n\n#. Fork on Github.\n#. Make the changes. Bonus points if changes include documentation and tests.\n#. Send a pull request.\n\nIf you're unsure if it's a good idea,\n`open an Issue <https://github.com/shazow/apiclient/issues>`_ or\n`contact me <https://github.com/inbox/new/shazow>`_ to discuss your proposal.\nExtra juicy bonus points if you pick off some of the items in the **TODO** list.\n\n\nLicense\n=======\n\n`MIT <https://github.com/shazow/apiclient/blob/master/LICENSE>`_\n\n\nChanges\n=======\n\n1.0.3 (2016-05-15)\n------------------\n\n* Python 3 fixes.\n\n\n1.0.2 (2011-10-20)\n------------------\n\n* Fixed setup.py from failing upon not seeing README.rst when installing using\n easy_install.\n\n\n1.0.1 (2011-10-10)\n------------------\n\n* Fixed setup.py package not including a MANIFEST.in\n\n\n1.0 (2011-10-03)\n----------------\n\n* Published decoupled code from SocialGrapple.",
"bugtrack_url": null,
"license": "MIT",
"summary": "Framework for making good API client libraries using urllib3.",
"version": "1.0.4",
"split_keywords": [
"api",
"client",
"urllib3",
"keepalive",
"threadsafe",
"http",
"rest"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f193d36bc33f0b1cfbb7c2b5e3057586abc500aa49f0c1d8fb32af347319c1ca",
"md5": "4433cdad604736536b3d56a2dc633ff6",
"sha256": "2569c998191cd1a042beffa3cf7c1119277237b4ba1fa021d20c81fa98fa95e9"
},
"downloads": -1,
"filename": "apiclient-1.0.4.tar.gz",
"has_sig": false,
"md5_digest": "4433cdad604736536b3d56a2dc633ff6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 4912,
"upload_time": "2019-03-21T00:55:53",
"upload_time_iso_8601": "2019-03-21T00:55:53.521034Z",
"url": "https://files.pythonhosted.org/packages/f1/93/d36bc33f0b1cfbb7c2b5e3057586abc500aa49f0c1d8fb32af347319c1ca/apiclient-1.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2019-03-21 00:55:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "shazow",
"github_project": "apiclient",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "apiclient"
}