{"id":13837315,"url":"https://github.com/flosch/simpleapi","last_synced_at":"2025-05-12T04:30:31.860Z","repository":{"id":874070,"uuid":"615414","full_name":"flosch/simpleapi","owner":"flosch","description":"A simple API-framework to provide an easy to use, consistent and portable client/server-architecture (standalone and also for django, Flask, AppEngine and all WSGI-compatible implementations like gunicorn).","archived":false,"fork":false,"pushed_at":"2014-07-06T13:33:09.000Z","size":548,"stargazers_count":145,"open_issues_count":2,"forks_count":18,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-01T00:06:08.656Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://simpleapi.readthedocs.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flosch.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-04-17T19:39:08.000Z","updated_at":"2023-12-11T06:16:59.000Z","dependencies_parsed_at":"2022-08-16T11:15:25.353Z","dependency_job_id":null,"html_url":"https://github.com/flosch/simpleapi","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flosch%2Fsimpleapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flosch%2Fsimpleapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flosch%2Fsimpleapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flosch%2Fsimpleapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flosch","download_url":"https://codeload.github.com/flosch/simpleapi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253675048,"owners_count":21945888,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T15:01:06.181Z","updated_at":"2025-05-12T04:30:31.205Z","avatar_url":"https://github.com/flosch.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":".. image:: https://travis-ci.org/flosch/simpleapi.svg?branch=master\n    :target: https://travis-ci.org/flosch/simpleapi\n.. image:: http://img.shields.io/pypi/dm/simpleapi.svg\n    :target: https://pypi.python.org/pypi/simpleapi\n.. image:: http://img.shields.io/pypi/v/simpleapi.svg\n    :target: https://pypi.python.org/pypi/simpleapi\n.. image:: http://img.shields.io/badge/gittip-support%20simpleapi-brightgreen.svg\n    :target: https://www.gittip.com/flosch/\n\n=========\nsimpleapi\n=========\n\n:dev-version: 0.1\n:latest stable: 0.0.9\n:author: Florian Schlachter \u003cflori@n-schlachter.de\u003e\n:website: http://www.florian-schlachter.de\n:license: MIT-license / see LICENSE file for more\n:mailinglist: subscribe: simpleapi@librelist.com\n:documentation: http://simpleapi.readthedocs.org\n\nAbout\n=====\n\nsimpleapi is an **easy to use, consistent, transparent and portable** way of\nproviding an API. It supports **several transport formats** (e. g. json, jsonp,\nxml, yaml) and provides **server** (standalone and also django, Flask, Google AppEngine and any WSGI-compatible implementation like gunicorn) and **client libraries** (PHP, Python) to interact seamlessly. You can also use nearly every **Ajax framework** (e. g. jQuery, ExtJS, etc.) to access the API.\n\n* server support for **django**, **Flask** and **Google AppEngine**\n* client support for **python**, **php** and **javascript**\n* dynamic key authentication / ip restriction\n* type-conversion / constraints\n* object serialization of django model instances, django queryset instances, \n  mongoengine documents, mongoengine queryset instances\n* inheritance / multiple versions of one API\n* several encoding/decoding formats (json, jsonp, xml, yaml, etc.)\n* several result formats (ie. for ExtJS forms, etc.)\n* features: caching, throttling\n* debugging and profiling capabilities\n* examples\n\nInstallation\n============\n\n::\n    \n    pip install --upgrade simpleapi\n\nFrom GitHub\n-----------\n\n::\n    \n    git clone git://github.com/flosch/simpleapi.git\n\nDependencies\n============\n\n* **server**: django \u003e= 1.1.1, Flask \u003e= 0.1 or Google AppEngine\n* Python 2.5 or greater\n* simplejson (if you're using Python \u003c= 2.5)\n* python-dateutil\n* pyyaml (optional, for YAML-support)\n* sphinx (optional, for the docs)\n\n(see requirements.txt as well)\n\nExamples\n========\n\nSMS-System\n----------\n\nServer (handler.py)::\n\n    from simpleapi import Namespace, serialize\n    from models import SMS, APIUser\n    \n    class SMSAPI(Namespace):\n        __authentication__ = lambda namespace, access_key: \\\n            APIUser.objects.filter(access_key=access_key).count() \u003e 0\n\n        def send(self, to, msg, from='testsender'):\n            sms = SMS.objects.create(\n                to=to\n                msg=msg,\n                from=from\n            )\n            return {\n                'sent': sms.send(),\n                'obj': serialize(sms, excludes=[re.compile('^date'),])\n            }\n        send.published = True\n        send.constraints = {'to': re.compile(r'^\\+\\d{2,}\\ \\d{3,}\\ \\d{5,}')}\n        \n        def status(self, id):\n            return SMS.objects.get(id=id)\n        status.published = True\n        status.constraints = {'id': int}\n        \n        def last(self, numbers=5):\n            return SMS.objects.all()[:numbers]\n        last.published = True\n        last.constraints = {'numbers': int}\n\n**Standalone-Server** (app.py)::\n\n    from simpleapi import Route\n    from handlers import SMSAPI\n\n    route = Route(SMSAPI, framework='standalone', path=r'^/api/')\n    route.serve() # serves on port 5050 by default\n\nGunicorn (**WSGI-compatible implementation**) (app.py)::\n\n    from simpleapi import Route\n    from handlers import SMSAPI\n\n    route = Route(SMSAPI, framework='wsgi', path=r'^/api/')\n    \n    # start Gunicorn (with 5 workers):\n    # gunicorn -w 5 app:route\n\n**Django-Server** (urls.py)::\n\n    from handlers import SMSAPI\n    urlpatterns = patterns('',\n        (r'^api/$', Route(SMSAPI))\n    )\n\n**Flask-Server** (app.py)::\n\n    from flask import Flask\n    from simpleapi import Route\n    from handlers import SMSAPI\n\n    app = Flask(__name__)\n    app.route('/api/')(Route(SMSAPI, framework='flask'))\n\n    if __name__ == '__main__':\n        app.run()\n\n**Google AppEngine** (main.py)::\n\n    from google.appengine.ext import webapp\n    from google.appengine.ext.webapp import util\n\n    from simpleapi import Route\n    from handlers import SMSAPI\n\n    def main():\n        application = webapp.WSGIApplication(\n            [('/api/', Route(SMSAPI, framework='appengine'))]\n        )\n        util.run_wsgi_app(application)\n\n    if __name__ == '__main__':\n        main()\n\nClient (python/**remote**)::\n\n    from simpleapi import Client\n    \n    client = Client(ns='http://remote.tld:8888/api/', access_key='mysecret',\n                    transport_type='xml')\n    \n    sms = client.sms(to='555123', msg='Hey yo! This is simpleapi calling.')\n    print \"Sent successful?\", sms['sent']\n    \n    sms = client.sms(to='555123', msg='2nd test with own sender',\n                     sender='simpleapi')\n    print \"Sent successful?\", sms['sent']\n    print \"Which sender?\", sms['obj']['sender']\n\nClient (python/**local**)::\n\n    from simpleapi import DummyClient, Route\n    from handlers import SMSAPI\n    \n    client = DummyClient(Route(SMSAPI, framework='dummy'),\n                         access_key='mysecret')\n    \n    sms = client.sms(to='555123', msg='Hey yo! This is simpleapi calling.')\n    print \"Sent successful?\", sms['sent']\n    \n    sms = client.sms(to='555123', msg='2nd test with own sender',\n                     sender='simpleapi')\n    print \"Sent successful?\", sms['sent']\n    print \"Which sender?\", sms['obj']['sender']\n\nClient (PHP)::\n\n    require_once(\"class.client.php\");\n    \n    $client = new Client($ns=\"http://localhost:8888/api/\",\n                         $access_key='mysecret');\n    print(\"Sent? \".$client-\u003esms(array(\n        'to' =\u003e '555123',\n        'msg' =\u003e 'Hey yo! This is the PHP client sending you a SMS.'\n    ))-\u003e{'sent'});\n\nClient (jQuery)::\n\n    jQuery.get(\n        \"/api/\",\n        {_call: 'send', to: '555123', 'msg': 'Hey ya!'},\n        function (return) {\n            if (return.result.sent)\n                alert('Sent successfully!');\n            else\n                alert('Sending failed!');\n        }\n    )\n\nCalculator\n----------\n\nServer (handler.py)::\n\n    from simpleapi import Namespace\n    \n    class CalculatorAPI(Namespace):\n        __ip_restriction__ = ['127.0.0.*',]\n        __authentication__ = \"lets_calc\"\n        \n        def power(self, a, b):\n            return a ** b\n        power.published = True\n        power.constraints = lambda namespace, key, value: float(value)\n        \n        def sum(self, **kwargs)\n            return sum(kwargs.values())\n        sum.published = True\n        sum.constraints = lambda namespace, key, value: float(value)\n\n**Standalone-Server** (app.py)::\n\n    from simpleapi import Route\n    from handlers import CalculatorAPI\n\n    route = Route(CalculatorAPI, framework='standalone', path=r'^/api/')\n    route.serve() # serves on port 5050 by default\n\nGunicorn (**WSGI-compatible implementation**) (app.py)::\n\n    from simpleapi import Route\n    from handlers import CalculatorAPI\n\n    route = Route(CalculatorAPI, framework='wsgi', path=r'^/api/')\n    \n    # start Gunicorn (with 5 workers):\n    # gunicorn -w 5 app:route\n\n**Django-Server** (urls.py)::\n\n    from handlers import CalculatorAPI\n    urlpatterns = patterns('',\n        (r'^api/$', Route(CalculatorAPI))\n    )\n\n**Flask-Server** (app.py)::\n\n    from flask import Flask\n    from simpleapi import Route\n    from handlers import CalculatorAPI\n\n    app = Flask(__name__)\n    app.route('/api/')(Route(CalculatorAPI, framework='flask'))\n\n    if __name__ == '__main__':\n        app.run()\n\n**Google AppEngine** (main.py)::\n\n    from google.appengine.ext import webapp\n    from google.appengine.ext.webapp import util\n\n    from simpleapi import Route\n    from handlers import CalculatorAPI\n\n    def main():\n        application = webapp.WSGIApplication(\n            [('/api/', Route(CalculatorAPI, framework='appengine'))]\n        )\n        util.run_wsgi_app(application)\n\n    if __name__ == '__main__':\n        main()\n\nClient (python/**remote**)::\n\n    from simpleapi import Client\n    \n    client = Client(ns='http://remote.tld:8888/api/', access_key='lets_calc')\n    \n    print \"5 ** 8 =\", client.power(a=5, b=8)\n    print \"1+2+3+4+5+6+7 =\", client.sum(a=1, b=2, c=3, d=4, e=5, f=6, g=7)\n\nClient (python/**local**)::\n\n    from simpleapi import DummyClient, Route\n    from handlers import CalculatorAPI\n    \n    client = DummyClient(Route(CalculatorAPI, framework='dummy'),\n                         access_key='lets_calc')\n    \n    print \"5 ** 8 =\", client.power(a=5, b=8)\n    print \"1+2+3+4+5+6+7 =\", client.sum(a=1, b=2, c=3, d=4, e=5, f=6, g=7)\n\nClient (PHP)::\n\n    require_once(\"class.client.php\");\n    \n    $client = new Client($ns=\"http://localhost:8888/api/\",\n                         $access_key='lets_calc');\n    print(\"5 ** 8 = \".$client-\u003epower(array('a'=\u003e5, 'b'=\u003e8)));\n\nClient (jQuery)::\n\n    jQuery.get(\n        \"/api/\",\n        {_call: 'power', a: 5, b: 8, _access_key: \"lets_calc\"},\n        function (return) {\n            alert('5 ** 8 = ' + return.result)\n        }\n    )\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflosch%2Fsimpleapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflosch%2Fsimpleapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflosch%2Fsimpleapi/lists"}