Skip to content

Commit

Permalink
Add Config field for dumping Flask configuration values (#281)
Browse files Browse the repository at this point in the history
* Add Config field for dumping Flask configuration values

Migrate the Config field from APIFlask.

* Test error case; update changelog

---------

Co-authored-by: Steven Loria <[email protected]>
  • Loading branch information
greyli and sloria authored Jan 15, 2024
1 parent 9d37375 commit 8b2eece
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Changelog
0.16.0 (unreleased)
*******************

Features:

* Add field ``Config`` for serializing Flask configuration values (:issue:`280`, :pr:`281`).
Thanks :user:`greyli` for the PR.

Support:

* Support marshmallow-sqlalchemy>=0.29.0.
Expand Down
42 changes: 41 additions & 1 deletion src/flask_marshmallow/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@
import re

from flask import url_for
from flask import current_app
from marshmallow import fields
from marshmallow import missing


__all__ = ["URLFor", "UrlFor", "AbsoluteURLFor", "AbsoluteUrlFor", "Hyperlinks"]
__all__ = [
"URLFor",
"UrlFor",
"AbsoluteURLFor",
"AbsoluteUrlFor",
"Hyperlinks",
"Config",
]


_tpl_pattern = re.compile(r"\s*<\s*(\S*)\s*>\s*")
Expand Down Expand Up @@ -178,3 +186,35 @@ def __init__(self, schema, **kwargs):

def _serialize(self, value, attr, obj):
return _rapply(self.schema, _url_val, key=attr, obj=obj)


class Config(fields.Field):
"""A field for Flask configuration values.
Examples: ::
from flask import Flask
app = Flask(__name__)
app.config['API_TITLE'] = 'Pet API'
class FooSchema(Schema):
user = String()
title = Config('API_TITLE')
This field should only be used in an output schema. A ``ValueError`` will
be raised if the config key is not found in the app config.
:param str key: The key of the configuration value.
"""

_CHECK_ATTRIBUTE = False

def __init__(self, key, **kwargs):
fields.Field.__init__(self, **kwargs)
self.key = key

def _serialize(self, value, attr, obj, **kwargs):
if self.key not in current_app.config:
raise ValueError(f"The key {self.key!r} is not found in the app config.")
return current_app.config[self.key]
12 changes: 12 additions & 0 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,15 @@ def test_aliases(ma):

assert UrlFor is URLFor
assert AbsoluteUrlFor is AbsoluteURLFor


def test_config_field(ma, app, mockauthor):
app.config["NAME"] = "test"
field = ma.Config(key="NAME")

result = field.serialize("config_value", mockauthor)
assert result == "test"

field = ma.Config(key="DOES_NOT_EXIST")
with pytest.raises(ValueError, match="not found in the app config"):
field.serialize("config_value", mockauthor)

0 comments on commit 8b2eece

Please sign in to comment.