{ "info": { "author": "Andr\u00e9 Tavares", "author_email": "github@andretavares.com", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content" ], "description": "===============\ndjango-yapi\n===============\n\nYAPI == Yet/Why Another API Framework\n\nThis is a mini-framework for creating RESTful APIs in Django.\n\n\nInstallation\n============\n\n1. Download dependencies:\n - Python 2.6+\n - Django 1.5+\n \n2. ``pip install django-yapi`` or ``easy_install django-yapi``\n\n\n\nConfiguration\n=============\n\nsettings.py\n-----------\n\n1. Add \"yapi\" to your INSTALLED_APPS setting like this::\n\n INSTALLED_APPS = (\n # all other installed apps\n 'yapi',\n )\n \n2. Add logger handler::\n\n LOGGING = {\n 'version': 1,\n 'disable_existing_loggers': False,\n 'handlers': {\n # all other handlers\n 'log_file_yapi': {\n 'level': 'DEBUG',\n 'class': 'logging.handlers.RotatingFileHandler',\n 'filename': os.path.join(os.path.join(os.path.dirname( __file__ ), '..'), 'logs/yapi.log'),\n 'maxBytes': '16777216', # 16megabytes\n },\n },\n 'loggers': {\n # all other loggers\n 'yapi': {\n 'handlers': ['log_file_yapi'],\n 'propagate': True,\n 'level': 'DEBUG',\n }\n }\n }\n \n3. Make sure you have a 'HOST_URL' setting containing the address in which the app is deployed:\n ``HOST_URL = 'http://localhost:8000'`` (example)\n \n4. If you want to use the middleware that enables CORS, you have to configure it by adding the following settings::\n\n MIDDLEWARE_CLASSES = (\n ...\n 'yapi.middleware.XsSharing'\n )\n\n YAPI = {\n \t...\n \n 'XS_SHARING_ALLOWED_ORIGINS': '*', # The allowed domains\n 'XS_SHARING_ALLOWED_METHODS': ['POST','GET','OPTIONS', 'PUT', 'DELETE'] # ... and methods\n }\n \n5. If you wish to disable ENTIRELY (be careful! :P) CSRF Validation, add the following settings::\n\n YAPI = {\n \t...\n \t\n 'CSRFValidation': False\n }\n\nLogs\n----\n\nCreate a 'logs' folder in your project's root folder (if you don't have one already).\nYour project folder should look something like this::\n\n myproject/\n __init__.py\n settings.py\n urls.py\n wsgi.py\n logs/\n manage.py\n\nDatabase\n--------\n\nRun ``python manage.py syncdb`` to create the yapi models.\n\n\nAPI Namespace\n=============\n\nNow, you will have to decide the URL \"namespace\" from which your API will be available and add it to\nyour top-level ``urls.py``.\n\nYapi's **convention** is that everything that regards to the API (urls, handlers, serializers, etc) should be in a\npackage named \"api\" inside the respective app package. This way, the API namespace should point to a urls.py\ninside an \"api\" package in your project's main package::\n\n myapp/\n api/\n __init__.py\n handlers.py\n serializers.py\n urls.py\n __init__.py\n models.py\n urls.py\n views.py\n myproject/\n api/\n __init__.py\n urls.py\n __init__.py\n settings.py\n urls.py\n wsgi.py\n logs/\n manage.py\n\nAdd namespace to the top-level ``urls.py``::\n\n # myproject/urls.py\n # ============\n\n urlpatterns = patterns('',\n # all other url mappings\n url(r'^api', include('myproject.api.urls', namespace='api')),\n )\n \nIn this example, we have an app called \"myapp\" which has an API. In order for it to be \"acessible\", its URLs must be\nadded to the top-level API namespace::\n\n # myproject/api/urls.py\n # ============\n \n urlpatterns = patterns('',\n # all other api url mappings\n url(r'^/myapp', include('myapp.api.urls', namespace='myapp')),\n )\n \nResources\n=========\n\nA \"Resource\" maps an URL to the code that will handle the requests made to it.\n\nBy convention, Resource handlers reside in a file called ``handlers.py`` in the api package::\n\n # myapp/api/handlers.py\n # ============\n\n\tfrom yapi.resource import Resource\n from yapi.response import HTTPStatus, Response\n\n class ResourceIndex(Resource):\n \"\"\"\n API endpoint handler.\n \"\"\"\n \n # HTTP methods allowed.\n allowed_methods = ['GET']\n \n def get(self, request):\n \"\"\"\n Process GET request.\n \"\"\"\n \n # Return.\n return Response(request=request,\n data={ 'hello': 'world' },\n serializer=None,\n status=HTTPStatus.SUCCESS_200_OK)\n \nNow we map the handler to a given URL::\n\n # myapp/api/urls.py\n # ============\n \n from django.conf.urls import patterns, url\n from yapi.resource import Resource\n\n from handlers import ResourceIndex\n\n urlpatterns = patterns('',\n url(r'^/?$', ResourceIndex.as_view(), name='index'),\n )\n \nThis way, if put ``http://localhost:8000/api/myapp`` in the address bar of your browser, you should get a JSON object\nin return containing ``{ 'hello': 'world' }``.\n\nBasic Schema\n------------\n\nFrom the example above we can see how easy it is to write a Resource class. You just need to set the ``allowed_methods``\narray with the HTTP verbs that the handler supports and then, for each allowed verb, write the respective method.\n\nYapi's **convention** is to use POST/GET/PUT/DELETE to CREATE/READ/UPDATE/DELETE.\n\n- ``POST`` -> ``def post(request)``\n- ``GET`` -> ``def get(request)``\n- ``PUT`` -> ``def put(request)``\n- ``DELETE`` -> ``def delete(request)``\n\n**IMPORTANT:** In this example there isn't any additional value being passed by the URL, therefore the only data received\nby the methods is the standard Django ``request``. Make sure to include in the method any other additional parameter\nthat may be passed by the URL.\n\nAuthentication & Authorization\n------------------------------\n\nIf the resource should only be accessible via authenticated users, then a variable ``authentication`` should be set\nwith an array of the valid authentication types. Yapi ships with the following authentication methods:\n\n- ``yapi.authentication.SessionAuthentication`` -> Validates if the request is made by a browser with a valid Django session (i.e. user is logged in to the site)\n- ``yapi.authentication.ApiKeyAuthentication`` -> Validates if the request is made with a valid ``api_key`` provided as a GET parameter.\n\nWhen several authentication methods are accepted, **the request is considered authenticated as soon as one checks**\n(e.g. SessionAuthentication fails, but APIKeyAuthentication validates). If the user is authenticated, it is added to\nthe ``request`` object and can be accessed by ``request.auth['user']``.\n\nIf the resource should only be acessible by authenticated users that match a specifc ruleset, then ``permissions``\nshould be set with an array of all the authorization credentials required. Yapi ships with the following authorization\nmethods:\n\n- ``yapi.permissions.IsStaff`` -> Checks if user has Staff permission.\n\n**In order for the authorization to be validated all authorization classes must check**.\n\nIf we wanted to make the Resource in the example above only available to authenticated staff users, it would look\nsomething like this::\n\n # myapp/api/handlers.py\n # ============\n\n from yapi.authentication import SessionAuthentication, ApiKeyAuthentication\n from yapi.resource import Resource\n from yapi.response import HTTPStatus, Response\n\n class ResourceIndex(Resource):\n \"\"\"\n API endpoint handler.\n \"\"\"\n \n # HTTP methods allowed.\n allowed_methods = ['GET']\n \n # Authentication & Authorization.\n authentication = [SessionAuthentication, ApiKeyAuthentication]\n permissions = [IsStaff]\n \n def get(self, request):\n \"\"\"\n Process GET request.\n \"\"\"\n \n # Return.\n return Response(request=request,\n data={ 'hello': 'world' },\n serializer=None,\n status=HTTPStatus.SUCCESS_200_OK)\n \nRequest Body\n------------\n\nWhen the request is a ``POST`` or a ``PUT``, it is assumed that there is a request body and, if it isn't present or fails\nparsing, the request fails.\n\n**IMPORTANT** Currently, the only format accepted for the request body is a JSON payload.\n\nThe request body is parsed into a native Python ``dict`` and can be acessible in ``request.data``.\n \nResource Listing\n----------------\n\nIn trying to follow some HATEOAS principles, we suggest that the API's root URL should return a listing of the available\nresources and respective URLs::\n\n # myproject/api/resources.py\n # ============\n \n from django.conf import settings\n from django.core.urlresolvers import reverse\n\n def get_api_resources_list(user):\n return {\n 'url': settings.HOST_URL + reverse('api:index'),\n 'resources': {\n 'myapp': {\n 'url': settings.HOST_URL + reverse('api:myapp:index')\n }\n }\n }\n \nNow, add it to the API's root URL::\n\n # myproject/api/urls.py\n # ============\n \n urlpatterns = patterns('',\n # all other api url mappings\n url(r'^/?$', ResourcesListHandler.as_view(), name='index'),\n url(r'^/myapp', include('myapp.api.urls', namespace='myapp')),\n )\n \nAnd write the respective handler::\n\n # myproject/api/handlers.py\n # ============\n \n \tfrom yapi.resource import Resource\n from yapi.response import HTTPStatus, Response\n from resources import get_api_resources_list\n\n class ResourcesListHandler(Resource):\n \"\"\"\n API endpoint handler.\n \"\"\"\n \n # HTTP methods allowed.\n allowed_methods = ['GET']\n \n def get(self, request):\n \"\"\"\n Process GET request.\n \"\"\"\n \n # Return.\n return Response(request=request,\n data=get_api_resources_list(request.auth['user']),\n serializer=None,\n status=HTTPStatus.SUCCESS_200_OK)\n \nDon't forget to keep this list updated everytime you make changes to your resources.\n\nResponse\n=========\n\n``yapi.response.Response`` is the prefered way of returning a call to a given handler (Django's ``HTTPResponse`` also works)\n\n- ``request`` -> The request that originated this response.\n- ``data`` -> The raw response data (a Python *dict*, with all data in native types)\n- ``serializer`` -> The serializer that will be used to serialize the data.\n- ``status`` -> The HTTP status code of the response (preferably from ``yapi.response.HTTPStatus``)\n- ``pagination`` (optional) -> When the response data is a QuerySet, this states if the response should be paginated or not. Default is True.\n- ``filters`` (optional) -> When the response data is a QuerySet and it was filtered by given parameters, they are provided in this field.\n\nSerializers\n-----------\n\nWhen the response ``data`` is a *complex* Python object, it must first be serialized to native Python types. This way,\neach for every resource that may be returned, a serializer that implements ``yapi.serializers.BaseSerializer`` must be\nwritten.\n\nBasically, a ``to_simple(self, obj, user=None)`` method has to be implemented.\n\n- ``obj`` -> The object instance that will be serialized.\n- ``user`` (optional) -> The user that made the request. This is useful when the instance representation varies according to the user/permissions.\n\nLets look at an example for serializing a user::\n\n from apps.api.serializers import BaseSerializer\n\n class UserSerializer(BaseSerializer):\n \"\"\"\n Adds methods required for instance serialization.\n \"\"\"\n \n def to_simple(self, obj, user=None):\n \"\"\"\n Please refer to the interface documentation.\n \"\"\"\n # Build response.\n simple = {\n 'email': obj.email,\n 'name': obj.name,\n 'last_login': obj.last_login.strftime(\"%Y-%m-%d %H:%M:%S\")\n }\n \n # Return.\n return simple\n\nIn this case, an example response could be::\n\n return Response(request=request,\n data=request.auth['user'],\n serializer=UserSerializer,\n status=HTTPStatus.SUCCESS_200_OK)\n", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "UNKNOWN", "keywords": null, "license": "BSD License", "maintainer": null, "maintainer_email": null, "name": "django-yapi", "package_url": "https://pypi.org/project/django-yapi/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-yapi/", "project_urls": { "Download": "UNKNOWN", "Homepage": "UNKNOWN" }, "release_url": "https://pypi.org/project/django-yapi/0.3.4/", "requires_dist": null, "requires_python": null, "summary": "A mini-framework for Django for creating RESTful APIs.", "version": "0.3.4" }, "last_serial": 1103604, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "0166d2d2b1cdaa64ae40d12a569bc74f", "sha256": "8bbb683f27e541dd41917327e7f157727e60b46806910e4eb9fccea5affdfaf2" }, "downloads": -1, "filename": "django-yapi-0.1.tar.gz", "has_sig": false, "md5_digest": "0166d2d2b1cdaa64ae40d12a569bc74f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12596, "upload_time": "2014-01-14T16:26:01", "url": "https://files.pythonhosted.org/packages/f6/8b/84cc97c51792c2c834f88982512a348ee66008b5dbafeb2b0f9196736846/django-yapi-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "5b822f3175259d20b59c25118d11fa52", "sha256": "b9854d815bfda90d8ea8bcd2d414cd6f18d3a22665a92f9caf4ed5c1cbe74bf1" }, "downloads": -1, "filename": "django-yapi-0.2.tar.gz", "has_sig": false, "md5_digest": "5b822f3175259d20b59c25118d11fa52", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13281, "upload_time": "2014-03-12T16:27:41", "url": "https://files.pythonhosted.org/packages/d0/cd/715aa25821920b49bfa30a4e8b25765944892cc3cd9f3f1efb86d0a61907/django-yapi-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "e8419015549ae8b56af2d7ef5d9b6a30", "sha256": "b3551a53bf37f23b327d1d8b2da53992edffda4c0e7e7db066de896f327f4515" }, "downloads": -1, "filename": "django-yapi-0.2.1.tar.gz", "has_sig": false, "md5_digest": "e8419015549ae8b56af2d7ef5d9b6a30", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13336, "upload_time": "2014-03-17T17:19:53", "url": "https://files.pythonhosted.org/packages/c9/64/a623c64be476c449fa7d0c6e2b77afe696d970d73975d42a4adebcea05e5/django-yapi-0.2.1.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "40df8244077a5b0e3e0f8e3c40fbdf91", "sha256": "ed4fb7777684de5aff5b7546595d441f8619945f2b13425cbb239614bf6e2bed" }, "downloads": -1, "filename": "django-yapi-0.3.tar.gz", "has_sig": false, "md5_digest": "40df8244077a5b0e3e0f8e3c40fbdf91", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14056, "upload_time": "2014-05-18T21:27:53", "url": "https://files.pythonhosted.org/packages/19/3e/c1b5f3a8ac4b0c8c6a973ebb73dc79e59c0312a8b3a1101c79c732975a96/django-yapi-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "8ff91bbe559e66be7892ad5f20fc1e90", "sha256": "41df2f649331847126fcf4dc19662125e87f7aaa5310d013a50405cae2b8841e" }, "downloads": -1, "filename": "django-yapi-0.3.1.tar.gz", "has_sig": false, "md5_digest": "8ff91bbe559e66be7892ad5f20fc1e90", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14047, "upload_time": "2014-05-18T21:44:36", "url": "https://files.pythonhosted.org/packages/1c/ef/5a0c9771fb3de3a4e0aa0f8095e06df783062829b46cc8cfd016624c535e/django-yapi-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "47f6e044a7a4469f6082e6f7a16b20e5", "sha256": "d2b2d99378c18f87d90f68e8fd3fb2883b2ec45a8a343f7d346a9fb91968361e" }, "downloads": -1, "filename": "django-yapi-0.3.2.tar.gz", "has_sig": false, "md5_digest": "47f6e044a7a4469f6082e6f7a16b20e5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14074, "upload_time": "2014-05-21T08:48:33", "url": "https://files.pythonhosted.org/packages/54/89/efc9be95418e5bc5f920c7af8e81eadfb3e39ddc915feae347bd6ec11786/django-yapi-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "e5dcbed93ac98d988cfdc1353f43131c", "sha256": "fa764fb6a65314dee3d339497f51797c8951c4cdffa1fd2a9cc16160211cf9fb" }, "downloads": -1, "filename": "django-yapi-0.3.3.tar.gz", "has_sig": false, "md5_digest": "e5dcbed93ac98d988cfdc1353f43131c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14223, "upload_time": "2014-05-23T14:21:05", "url": "https://files.pythonhosted.org/packages/cc/4f/3b9c86ef3b3625368501d2e147ed576784c5140b6ed409ee7e9ba48bac7b/django-yapi-0.3.3.tar.gz" } ], "0.3.4": [ { "comment_text": "", "digests": { "md5": "638c86950d0e7991be2c834de7c24f5e", "sha256": "d95933ceb641dc189eeef8d3e3ff07b66cf527d787cf6b3320fad4b186fb6dc8" }, "downloads": -1, "filename": "django-yapi-0.3.4.tar.gz", "has_sig": false, "md5_digest": "638c86950d0e7991be2c834de7c24f5e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14278, "upload_time": "2014-05-25T11:22:59", "url": "https://files.pythonhosted.org/packages/fa/dd/51d3be16f6dedc08c7706573b88ac884c70e85371ef70ac2fb3b8b38d5a0/django-yapi-0.3.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "638c86950d0e7991be2c834de7c24f5e", "sha256": "d95933ceb641dc189eeef8d3e3ff07b66cf527d787cf6b3320fad4b186fb6dc8" }, "downloads": -1, "filename": "django-yapi-0.3.4.tar.gz", "has_sig": false, "md5_digest": "638c86950d0e7991be2c834de7c24f5e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14278, "upload_time": "2014-05-25T11:22:59", "url": "https://files.pythonhosted.org/packages/fa/dd/51d3be16f6dedc08c7706573b88ac884c70e85371ef70ac2fb3b8b38d5a0/django-yapi-0.3.4.tar.gz" } ] }