Skip to content

Commit 354686e

Browse files
committed
fix api examples, update docs
1 parent 1a74380 commit 354686e

File tree

6 files changed

+250
-280
lines changed

6 files changed

+250
-280
lines changed

README.rst

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
.. image:: https://github.com/AdCombo/flask-combo-jsonapi/workflows/Python%20tests%20and%20coverage/badge.svg
2-
:target: https://github.com/AdCombo/flask-combo-jsonapi/actions
2+
:alt: flask-combo-jsonapi actions
3+
:target: https://github.com/AdCombo/flask-combo-jsonapi/actions
34
.. image:: https://coveralls.io/repos/github/AdCombo/flask-combo-jsonapi/badge.svg
4-
:target: https://coveralls.io/github/AdCombo/flask-combo-jsonapi
5+
:alt: flask-combo-jsonapi coverage
6+
:target: https://coveralls.io/github/AdCombo/flask-combo-jsonapi
7+
.. image:: https://img.shields.io/pypi/v/flask-combo-jsonapi.svg
8+
:alt: PyPI
9+
:target: http://pypi.org/p/flask-combo-jsonapi
510

611

712
Flask-COMBO-JSONAPI
813
###################
914

1015
Flask-COMBO-JSONAPI is a flask extension for building REST APIs. It combines the power of `Flask-Restless <https://flask-restless.readthedocs.io/>`_ and the flexibility of `Flask-RESTful <https://flask-restful.readthedocs.io/>`_ around a strong specification `JSONAPI 1.0 <http://jsonapi.org/>`_. This framework is designed to quickly build REST APIs and fit the complexity of real life projects with legacy data and multiple data storages.
1116

12-
The main goal is to make it flexible using `plugin system <https://github.com/AdCombo/combojsonapi/blob/develop/docs/en/create_plugins.rst>`_
17+
The main goal is to make it flexible using `plugin system <https://combojsonapi.readthedocs.io/>`_
1318

1419

1520
Install
1621
=======
1722

1823
pip install Flask-COMBO-JSONAPI
1924

20-
Installation from pypi is not ready yet. Refer to the `installation manual <https://github.com/AdCombo/flask-combo-jsonapi/blob/develop/docs/installation.rst/>`_
21-
2225

2326
A minimal API
2427
=============
@@ -107,7 +110,7 @@ Flask-COMBO-JSONAPI vs `Flask-Restless <https://flask-restless.readthedocs.io/en
107110
Documentation
108111
=============
109112

110-
Documentation available here: http://Flask-COMBO-JSONAPI.readthedocs.io/en/latest/
113+
Documentation available here: https://flask-combo-jsonapi.readthedocs.io/
111114

112115
Thanks
113116
======

docs/index.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
Flask-COMBO-JSONAPI
22
==================
3+
.. image:: https://github.com/AdCombo/flask-combo-jsonapi/workflows/Python%20tests%20and%20coverage/badge.svg
4+
:alt: flask-combo-jsonapi actions
5+
:target: https://github.com/AdCombo/flask-combo-jsonapi/actions
6+
.. image:: https://coveralls.io/repos/github/AdCombo/flask-combo-jsonapi/badge.svg
7+
:alt: flask-combo-jsonapi coverage
8+
:target: https://coveralls.io/github/AdCombo/flask-combo-jsonapi
9+
.. image:: https://img.shields.io/pypi/v/flask-combo-jsonapi.svg
10+
:alt: PyPI
11+
:target: http://pypi.org/p/flask-combo-jsonapi
312

4-
.. module:: flask_combo_jsonapi
513

614
**Flask-COMBO-JSONAPI** is an extension for Flask that adds support for quickly building REST APIs with huge flexibility around the JSONAPI 1.0 specification. It is designed to fit the complexity of real life environments so Flask-COMBO-JSONAPI helps you to create a logical abstraction of your data called "resource" and can interface any kind of ORMs or data storage through data layer concept.
715

docs/installation.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,3 @@ The development version can be downloaded from `its page at GitHub
2626
If you don't have virtualenv please install it before
2727

2828
$ pip install virtualenv
29-
30-
31-
Flask-RESTful requires Python version 2.7, 3.4 or 3.5.

docs/quickstart.rst

Lines changed: 2 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -14,166 +14,8 @@ First example
1414

1515
An example of Flask-COMBO-JSONAPI API looks like this:
1616

17-
.. code-block:: python
18-
19-
# -*- coding: utf-8 -*-
20-
21-
from flask import Flask
22-
from flask_combo_jsonapi import Api, ResourceDetail, ResourceList, ResourceRelationship
23-
from flask_combo_jsonapi.exceptions import ObjectNotFound
24-
from flask_sqlalchemy import SQLAlchemy
25-
from sqlalchemy.orm.exc import NoResultFound
26-
from marshmallow_jsonapi.flask import Schema, Relationship
27-
from marshmallow_jsonapi import fields
28-
29-
# Create the Flask application
30-
app = Flask(__name__)
31-
app.config['DEBUG'] = True
32-
33-
34-
# Initialize SQLAlchemy
35-
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
36-
db = SQLAlchemy(app)
37-
38-
39-
# Create data storage
40-
class Person(db.Model):
41-
id = db.Column(db.Integer, primary_key=True)
42-
name = db.Column(db.String)
43-
email = db.Column(db.String)
44-
birth_date = db.Column(db.Date)
45-
password = db.Column(db.String)
46-
47-
48-
class Computer(db.Model):
49-
id = db.Column(db.Integer, primary_key=True)
50-
serial = db.Column(db.String)
51-
person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
52-
person = db.relationship('Person', backref=db.backref('computers'))
53-
54-
db.create_all()
55-
56-
57-
# Create logical data abstraction (same as data storage for this first example)
58-
class PersonSchema(Schema):
59-
class Meta:
60-
type_ = 'person'
61-
self_view = 'person_detail'
62-
self_view_kwargs = {'id': '<id>'}
63-
self_view_many = 'person_list'
64-
65-
id = fields.Integer(as_string=True, dump_only=True)
66-
name = fields.Str(required=True, load_only=True)
67-
email = fields.Email(load_only=True)
68-
birth_date = fields.Date()
69-
display_name = fields.Function(lambda obj: "{} <{}>".format(obj.name.upper(), obj.email))
70-
computers = Relationship(self_view='person_computers',
71-
self_view_kwargs={'id': '<id>'},
72-
related_view='computer_list',
73-
related_view_kwargs={'id': '<id>'},
74-
many=True,
75-
schema='ComputerSchema',
76-
type_='computer')
77-
78-
79-
class ComputerSchema(Schema):
80-
class Meta:
81-
type_ = 'computer'
82-
self_view = 'computer_detail'
83-
self_view_kwargs = {'id': '<id>'}
84-
85-
id = fields.Integer(as_string=True, dump_only=True)
86-
serial = fields.Str(required=True)
87-
owner = Relationship(attribute='person',
88-
self_view='computer_person',
89-
self_view_kwargs={'id': '<id>'},
90-
related_view='person_detail',
91-
related_view_kwargs={'computer_id': '<id>'},
92-
schema='PersonSchema',
93-
type_='person')
94-
95-
96-
# Create resource managers
97-
class PersonList(ResourceList):
98-
schema = PersonSchema
99-
data_layer = {'session': db.session,
100-
'model': Person}
101-
102-
103-
class PersonDetail(ResourceDetail):
104-
def before_get_object(self, view_kwargs):
105-
if view_kwargs.get('computer_id') is not None:
106-
try:
107-
computer = self.session.query(Computer).filter_by(id=view_kwargs['computer_id']).one()
108-
except NoResultFound:
109-
raise ObjectNotFound({'parameter': 'computer_id'},
110-
"Computer: {} not found".format(view_kwargs['computer_id']))
111-
else:
112-
if computer.person is not None:
113-
view_kwargs['id'] = computer.person.id
114-
else:
115-
view_kwargs['id'] = None
116-
117-
schema = PersonSchema
118-
data_layer = {'session': db.session,
119-
'model': Person,
120-
'methods': {'before_get_object': before_get_object}}
121-
122-
123-
class PersonRelationship(ResourceRelationship):
124-
schema = PersonSchema
125-
data_layer = {'session': db.session,
126-
'model': Person}
127-
128-
129-
class ComputerList(ResourceList):
130-
def query(self, view_kwargs):
131-
query_ = self.session.query(Computer)
132-
if view_kwargs.get('id') is not None:
133-
try:
134-
self.session.query(Person).filter_by(id=view_kwargs['id']).one()
135-
except NoResultFound:
136-
raise ObjectNotFound({'parameter': 'id'}, "Person: {} not found".format(view_kwargs['id']))
137-
else:
138-
query_ = query_.join(Person).filter(Person.id == view_kwargs['id'])
139-
return query_
140-
141-
def before_create_object(self, data, view_kwargs):
142-
if view_kwargs.get('id') is not None:
143-
person = self.session.query(Person).filter_by(id=view_kwargs['id']).one()
144-
data['person_id'] = person.id
145-
146-
schema = ComputerSchema
147-
data_layer = {'session': db.session,
148-
'model': Computer,
149-
'methods': {'query': query,
150-
'before_create_object': before_create_object}}
151-
152-
153-
class ComputerDetail(ResourceDetail):
154-
schema = ComputerSchema
155-
data_layer = {'session': db.session,
156-
'model': Computer}
157-
158-
159-
class ComputerRelationship(ResourceRelationship):
160-
schema = ComputerSchema
161-
data_layer = {'session': db.session,
162-
'model': Computer}
163-
164-
165-
# Create endpoints
166-
api = Api(app)
167-
api.route(PersonList, 'person_list', '/persons')
168-
api.route(PersonDetail, 'person_detail', '/persons/<int:id>', '/computers/<int:computer_id>/owner')
169-
api.route(PersonRelationship, 'person_computers', '/persons/<int:id>/relationships/computers')
170-
api.route(ComputerList, 'computer_list', '/computers', '/persons/<int:id>/computers')
171-
api.route(ComputerDetail, 'computer_detail', '/computers/<int:id>')
172-
api.route(ComputerRelationship, 'computer_person', '/computers/<int:id>/relationships/owner')
173-
174-
if __name__ == '__main__':
175-
# Start application
176-
app.run(debug=True)
17+
.. literalinclude:: ../examples/api.py
18+
:language: python
17719

17820
This example provides this api:
17921

0 commit comments

Comments
 (0)