.. _getting-started:
Getting Started
================
Installation
------------
* Stable releases are uploaded to pypi:
``_. You
can install it in the usual way:
.. code-block:: bash
pip install -i pyramid_jsonapi
* Development releases are also uploaded to pypi. These have versions with
'.devN' appended, where 'N' is the number of commits since the stable tag. You
can install the latest one (perhaps into a virtualenv for play purposes) with
.. code-block:: bash
pip install --pre -i pyramid_jsonapi
* See the :ref:`developing` documentation for details.
* Since pyramid_jsonapi is pure python, You can download the latest code from
``_ and add the directory you
downloaded/cloned to to your PYTHONPATH.
Generating an API From Your Models
----------------------------------
First import the ``pyramid_jsonapi`` module and any model classes or modules which
you would like to expose as API collection endpoints. In your application's
``__init__.py``:
.. code-block:: python
import pyramid_jsonapi
from . import models
Then instantiate an api object:
.. code-block:: python
pj_api = pyramid_jsonapi.PyramidJSONAPI(config, models, [get_db_session])
This is the class that encapsulates a whole API representing a set of models.
The constructor has two mandatory and one optional arguments:
* ``config`` is the usual Configurator object used in pyramid.
* ``models`` can either be a module (as in the example above) defining classes
which inherit from :py:func:`declarative_base` or an iterable of such classes.
* ``get_dbsession`` (optional) should be a
callable which accepts an instance of
:class:`pyramid_jsonapi.CollectionViewBase` and returns a
:class:`sqlalchemy.orm.session.Session` (or an equivalent, like a
:func:`sqlalchemy.orm.scoped_session`)
Once you have an instance of ``PyramidJSONAPI`` you instruct it to build
endpoints (routes and views) with the method
``api.create_jsonapi_using_magic_and_pixie_dust()`` (or ``api.create_jsonapi()``). This
is deliberately a two step affair to give you the chance to manipulate certain
things (like the list of available endpoints) before the endpoints are
constructed:
.. code-block:: python
pj_api = pyramid_jsonapi.PyramidJSONAPI(config, models)
# Do something here like add a view for OPTIONS requests.
pj_api.create_jsonapi_using_magic_and_pixie_dust()
Auto-Create Assumptions
-----------------------
#. Your model classes all inherit from a base class returned by sqlalchemy's
``declarative-base()``.
#. Each model has a single primary_key column. This will be auto-detected and
stored in ``__pyramid_jsonapi__`` dict attr in the model.
#. Use a separate primary key for association objects rather than the
composite key defined by the left and right referenced foreign keys.
#. You are happy to give your collection end-points the same name as the
corresponding database table (can be overridden).
#. You have defined any relationships to exposed via the API using
``sqlalchemy.orm.relationship()`` (or ``backref()``).
#. You are happy to expose any so defined relationship via a relationship URL.
#. API endpoints will be provided at ``/api/...`` by default.
#. Metadata endpoints will be provided at ``/metadata/...`` by default.
Some of those behaviours can be adjusted, see :ref:`customisation`.
Trying Your API Out
-------------------
You should now have a working JSON-API. A quick test. The following assumes that
you have already created and set up a pyramid project in development mode
(``python setup.py develop`` in pyramid 1.6, ``pip install -e`` in pyramid 1.7).
Make sure you have activated your virtualenv:
.. code-block:: bash
$ source env/bin/activate
Start the server:
.. code-block:: bash
$ pserve your_project/development.ini
Assuming you have a collection named 'people' and are using the rather lovely
`httpie `_ to test:
.. code-block:: bash
$ http http://localhost:6543/api/people
HTTP/1.1 200 OK
Content-Length: 1387
Content-Type: application/vnd.api+json; charset=UTF-8
Date: Fri, 28 Aug 2015 20:22:46 GMT
Server: waitress
.. code-block:: json
{
"data": [
{
"type": "people",
"id": "1",
"attributes": {
"name": "alice"
},
"links": {
"self": "http://localhost:6543/api/people/1"
},
"relationships": {
"": {
"data": {"type": "", "id": ""}
}
}
},
{""}
]
}
See ``test_project/test_project/__init__.py`` for a fully working
``__init__.py`` file.
You don't need a ``views.py`` unless you have some other routes and views.
There's also some metadata available at ``http://localhost:6543/metadata``.
pyramid_jsonapi currently includes metadata modules to produce JSONSchema and
OpenAPI/Swagger. See the :ref:`metadata` section.
The following will fetch the JSONSchema for a successful response to a GET on the
people endpoint:
.. code-block:: bash
$ http http://localhost:6543/metadata/JSONSchema/endpoint/people?method=get&direction=response&code=200
.. code-block:: json
{
"type": "object",
"additionalProperties": false,
"properties": {
"meta": {
"$ref": "#/definitions/meta"
},
"included": {
"type": "array",
"uniqueItems": true,
"description": "To reduce the number of HTTP requests, servers **MAY** allow responses that include related resources along with the requested primary resources. Such responses are called \"compound documents\".",
"items": {
"$ref": "#/definitions/resource"
}
},
"jsonapi": {
"$ref": "#/definitions/jsonapi"
},
"data": {
"$ref": "#/definitions/people_data"
},
"links": {
"allOf": [
{
"$ref": "#/definitions/links"
},
{
"$ref": "#/definitions/pagination"
}
],
"description": "Link members related to the primary data."
}
},
"required": [
"data"
]
}