Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Comments

add JSON provider interface#4692

Merged
davidism merged 1 commit intomainfrom
json-provider
Jul 13, 2022
Merged

add JSON provider interface#4692
davidism merged 1 commit intomainfrom
json-provider

Conversation

@davidism
Copy link
Member

@davidismdavidism commentedJul 13, 2022
edited
Loading

This adds the ability to fully customize the JSON implementation used by a Flask application. Using a different JSON implementation can greatly speed up API applications that need to work with JSON in most requests.

app.json is an instance ofFlask.json_provider_class.flask.json.provider.JSONProvider is the base class that definesdumps,dump,loads,load, andresponse methods, of which onlydumps andloads need to be implemented. For example, here's a provider fororjson:

fromflask.json.providerimportJSONProviderimportorjsonclassOrJSONProvider(JSONProvider):defdumps(self,obj,*,option=None,**kwargs):ifoptionisNone:option=orjson.OPT_APPEND_NEWLINE|orjson.OPT_NAIVE_UTCreturnorjson.dumps(obj,option=option).decode()defloads(self,s,**kwargs):returnorjson.loads(s)# assign to an app instanceapp.json=OrJSONProvider(app)# or assign in a subclassclassMyFlask(Flask):json_provider_class=OrJSONProviderapp=MyFlask(__name__)

The methods inflask.json call the methods onapp.json if an app context is active, or fall back to thejson library.jsonify callsapp.json.response. The|tojson filter usesapp.json.dumps.Request.json usesapp.json.loads andResponse.json usesapp.json.dumps; the test client uses these as well.

Customizingjson_encoder orjson_decoder on an app or blueprint, and theJSONEncoder andJSONDecoder classes, are deprecated. This was not an effective way to use other libraries. Customizing per blueprint was requested by an API extension that is no longer maintained and didn't appear to use the feature. It's not clear how it would work with the new provider interface and added overhead to every request. Instead, API frameworks should be using a dedicated object serialization library, then taking advantage of a fast JSON serializer at the application level.

TheDefaultJSONProvider is the existing implementation using the built-injson library. Theapp.config keysJSON_AS_ASCII,JSON_SORT_KEYS,JSONIFY_MIMETYPE, andJSONIFY_PRETTYPRINT_REGULAR are deprecated and have moved to attributes on the default provider. Other providers are not required to support these options.

Abdur-rahmaanJ, Yourun-proger, HarshCasper, and jackwardell reacted with rocket emoji
@davidismdavidism added this to the2.2.0 milestoneJul 13, 2022
@davidismdavidism merged commit67310ab intomainJul 13, 2022
@davidismdavidism deleted the json-provider branchJuly 13, 2022 16:55
:param kwargs: Treat as a dict to serialize.
"""
obj = self._prepare_response_obj(args, kwargs)
return self._app.response_class(self.dumps(obj), mimetype="application/json")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Worth a cls default_mimetype here to save extensions having to override this method and as matching with responses?

Copy link
MemberAuthor

@davidismdavidismJul 13, 2022
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Discussed this more here:#1728 (comment)

I'm not sure this should actually be configurable at all. The original issue seemed to be about a specific type of response, not all JSON responses.Maybe if you want your whole API to have a different vendor type, like GitHub does, but even GitHub applies different mimetypes to different parts. APIs complex enough to use vendor types usually have versioning as well, so they still wouldn't apply globally.

I did originally have this as aJSONProvider.mimetype attribute, but I ended up moving all existing behavior toDefaultProvider and keeping the base very simple.

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

not know how to serialize. It should return a valid JSON type or
raise a ``TypeError``.
"""

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What do you think about adding a dict_to_object hook here as well (for the loads side). Allows something like this,

classMoneyJSONProvider(DefaultJSONProvider):@staticmethoddefdefault(object_):ifisinstance(object_,date):returnhttp_date(object_)ifisinstance(object_, (Decimal,UUID)):returnstr(object_)ifis_dataclass(object_):returnasdict(object_)ifhasattr(object_,"__html__"):returnstr(object_.__html__())ifisinstance(object_,Money):return {'amount':object_.amount,'currency':object_.currency}raiseTypeError(f"Object of type{type(object_).__name__} is not JSON serializable")@staticmethoddefdict_to_object(dict_):if'amount'indict_and'currency'indict_:returnMoney(Decimal(dict_['amount']),dict_['currency'])else:returndict_

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I left it out for a few reasons.object_hook is not as consistently supported by different libraries asdefault is, and I didn't want to put a perceived requirement for it on all other providers. You usually want to perform validation when deserializing, and that gets very messy trying to cram it all inobject_hook along with proper error collection. Instead, any project should use a serialization library, leaving the provider to only handle the JSON and basic types.

@github-actionsgithub-actionsbot locked asresolvedand limited conversation to collaboratorsAug 2, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@pgjonespgjonespgjones left review comments

+1 more reviewer

@Yourun-progerYourun-progerYourun-proger left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

Projects

None yet

Milestone

2.2.0

Development

Successfully merging this pull request may close these issues.

3 participants

@davidism@pgjones@Yourun-proger

[8]ページ先頭

©2009-2026 Movatter.jp