{ "info": { "author": "Joe Cross", "author_email": "joe.mcross@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries", "Topic :: Internet :: WWW/HTTP :: WSGI", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware", "Topic :: Internet :: WWW/HTTP :: WSGI :: Server", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# pyservice 0.8.0\n\n[![Build Status]\n(https://travis-ci.org/numberoverzero/pyservice.svg?branch=master)]\n(https://travis-ci.org/numberoverzero/pyservice)[![Coverage Status]\n(https://coveralls.io/repos/numberoverzero/pyservice/badge.png?branch=master)]\n(https://coveralls.io/r/numberoverzero/pyservice?branch=master)\n\nDownloads https://pypi.python.org/pypi/pyservice\n\nSource https://github.com/numberoverzero/pyservice\n\nMicroservice framework for high tps, designed for readability and code re-use\n\n# Installation\n\n`pip install pyservice`\n\n# Getting Started\n\npyservice was designed from the ground up to minimize request overhead, while\nstill exposing the relevant pieces of the request chain for extension. The\nfile is less than 1000 lines including docstrings and comments\n(566 @ 12/12/14), which makes the source a great reference when you've got\nquestions.\n\nLet's get some code going. First, we'll define a small api. These are just\nnested dictonaries - feel free to load them from a json file.\n\n```python\n# Service/Client just use a dict for specifying an api\napi = {\n \"debug\": True,\n \"endpoint\": {\n \"scheme\": \"http\",\n \"host\": \"localhost\",\n \"port\": 8080,\n \"path\": \"/api/{version}/{operation}\"\n },\n \"operations\": [\"get_item\", \"put_item\"],\n \"exceptions\": [\"IDRequired\", \"DoesNotExist\", \"ItemRequired\"]\n}\n```\n\nNext we'll set up the service, and define the get/put operations:\n\n```python\nimport uuid\nimport pyservice\n\nservice = pyservice.Service(**api)\nitems = {}\n\n\n@service.operation(name=\"put_item\")\ndef put_item(request, response, context):\n if item not in request:\n raise service.exceptions.ItemRequired(\"Need an item to put\")\n id = uuid.uuid4()\n items[id] = request.item\n response.id = id\n\n\n@service.operation(name=\"get_item\")\ndef get_item(request, response, context):\n if id not in request:\n raise service.exceptions.IDRequired(\"Can't get an item without an ID\")\n try:\n item = items[request.id]\n except KeyError:\n raise service.exceptions.DoesNotExist(\"No item with id \" + response.id)\n else:\n response.item = item\n```\n\nFinally, to get a server running, we'll use the wsgiref reference server:\n\n```python\nfrom wsgiref.simple_server import make_server\n\ndef run_server():\n print(\"Starting Server...\")\n host, port = api[\"endpoint\"][\"host\"], api[\"endpoint\"][\"port\"]\n httpd = make_server(host, port, service.wsgi_application)\n httpd.serve_forever()\n\nif __name__ == \"__main__\":\n run_server()\n```\n\nTo make a call from a client, we'll use the same `api` defined above. The\nclient calls are even simpler:\n\n```python\nimport pyservice\n\n# ... Same api definition above\n\nclient = pyservice.Client(**api)\n\n# put\nitem = \"some string\"\nid = client.put_item(item=item)\n\n# get\nsame_item = client.get_item(id=id)\n\nassert item == same_item\n```\n\nWe can plug into calls in two scopes:\n\n* `request`, which is before the request and response bodies\n have been created and after they've been consumed\n* `operation`, which is after the request and response bodies\n have been created and before they've been consumed.\n\nThe difference is important for things like sqlalchemy, where serialization\nshould occur before the connection is closed.\n\n```python\n\n@service.plugin(scope=\"request\")\ndef some_plugin(context):\n print(\"Before request '{}'\".format(context.operation))\n context.process_request()\n print(\"After request '{}'\".format(context.operation))\n\n@service.plugin(scope=\"operation\")\ndef some_plugin(request, response, context):\n print(\"Before operation '{}'\".format(context.operation))\n print(\"Request: {}\".format(request))\n context.process_request()\n print(\"Response: {}\".format(response))\n print(\"After operation '{}'\".format(context.operation))\n```\n\n# Contributing\nContributions welcome! Please make sure `tox` passes (including flake8) before submitting a PR.\n\n### Development\npyservice uses `tox`, `pytest` and `flake8`. To get everything set up:\n\n```\n# RECOMMENDED: create a virtualenv with:\n# mkvirtualenv pyservice\ngit clone https://github.com/numberoverzero/pyservice.git\npip install tox\ntox\n```\n\n### TODO\n* Documentation (0.9.0)\n * Better README\n * Better docstrings\n * Examples\n * Plugins\n * Additional metadata\n * Subclassing Client/Service\n * Multiple versions\n* Plugins (1.0.0)\n * Caching\n * Auth[N/Z] + Whitelisting\n * Logging\n * Throttling\n * SqlAlchemy\n * Structures\n * Redaction\n * Patching\n * Function unpacking decoration\n\n# API\n\n### Client\n\nTODO\n\n### Service\n\nTODO\n\n### Plugins\n\nTODO", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/numberoverzero/pyservice/", "keywords": "wsgi web api framework soa", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "pyservice", "package_url": "https://pypi.org/project/pyservice/", "platform": "any", "project_url": "https://pypi.org/project/pyservice/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/numberoverzero/pyservice/" }, "release_url": "https://pypi.org/project/pyservice/0.8.0/", "requires_dist": null, "requires_python": null, "summary": "web services with python made easy", "version": "0.8.0" }, "last_serial": 1342304, "releases": { "0.8.0": [] }, "urls": [] }