-
Notifications
You must be signed in to change notification settings - Fork 58
/
__init__.py
executable file
·128 lines (100 loc) · 3.35 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# -*- coding: utf-8 -*-
"""
flask_marshmallow
~~~~~~~~~~~~~~~~~
Integrates the marshmallow serialization/deserialization library
with your Flask application.
:copyright: (c) 2014-2016 by Steven Loria
:license: MIT, see LICENSE for more details.
"""
import warnings
from marshmallow import (
fields as base_fields,
exceptions,
pprint
)
from . import fields
from .schema import Schema
has_sqla = False
try:
import flask_sqlalchemy # flake8: noqa
except ImportError:
has_sqla = False
else:
try:
from . import sqla
except ImportError:
warnings.warn(
'Flask-SQLAlchemy integration requires '
'marshmallow-sqlalchemy to be installed.'
)
else:
has_sqla = True
__version__ = '0.8.0'
__author__ = 'Steven Loria'
__license__ = 'MIT'
__all__ = [
'EXTENSION_NAME',
'Marshmallow',
'Schema',
'fields',
'exceptions',
'pprint'
]
EXTENSION_NAME = 'flask-marshmallow'
def _attach_fields(obj):
"""Attach all the marshmallow fields classes to ``obj``, including
Flask-Marshmallow's custom fields.
"""
for attr in base_fields.__all__:
if not hasattr(obj, attr):
setattr(obj, attr, getattr(base_fields, attr))
for attr in fields.__all__:
setattr(obj, attr, getattr(fields, attr))
class Marshmallow(object):
"""Wrapper class that integrates Marshmallow with a Flask application.
To use it, instantiate with an application::
from flask import Flask
app = Flask(__name__)
ma = Marshmallow(app)
The object provides access to the :class:`Schema` class,
all fields in :mod:`marshmallow.fields`, as well as the Flask-specific
fields in :mod:`flask_marshmallow.fields`.
You can declare schema like so::
class BookSchema(ma.Schema):
class Meta:
fields = ('id', 'title', 'author', 'links')
author = ma.Nested(AuthorSchema)
links = ma.Hyperlinks({
'self': ma.URLFor('book_detail', id='<id>'),
'collection': ma.URLFor('book_list')
})
In order to integrate with Flask-SQLAlchemy, this extension must by initialized *after*
`flask_sqlalchemy.SQLAlchemy`. ::
db = SQLAlchemy(app)
ma = Marshmallow(app)
This gives you access to `ma.ModelSchema`, which generates a marshmallow
`~marshmallow.Schema` based on the passed in model. ::
class AuthorSchema(ma.ModelSchema):
class Meta:
model = Author
:param Flask app: The Flask application object.
"""
def __init__(self, app=None):
self.Schema = Schema
if has_sqla:
self.ModelSchema = sqla.ModelSchema
self.HyperlinkRelated = sqla.HyperlinkRelated
_attach_fields(self)
if app is not None:
self.init_app(app)
def init_app(self, app):
"""Initializes the application with the extension.
:param Flask app: The Flask application object.
"""
app.extensions = getattr(app, 'extensions', {})
# If using Flask-SQLAlchemy, attach db.session to ModelSchema
if has_sqla and 'sqlalchemy' in app.extensions:
db = app.extensions['sqlalchemy'].db
self.ModelSchema.OPTIONS_CLASS.session = db.session
app.extensions[EXTENSION_NAME] = self