-
-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable view function annotation based type detection #100
Conversation
aef28f6
to
7ad03b2
Compare
7ad03b2
to
d4f2dc3
Compare
d4f2dc3
to
b2b8a44
Compare
if this is done just to make # anywhere, eg. spectree/plugins/flask_plugin.py
+ from flask import Request, request as request_
+ class SpecTreeRequest(Request):
+ context: Context
+ request: SpecTreeRequest = request_ # myapp.py
- from flask import abort
+ from spectree.plugins.flask_plugin import request
# this will now pass without mypy error
payload = request.context.json |
This works well but it's limited to Personally, I think linter is very useful (although Python linter still has a long way to go). Meanwhile, FastAPI is quite popular. I think a lot of people will accept this annotation approach. One possible problem is that users should avoid using these keywords as path variables. One possible benefit is that it may make it easy to implement #96. |
This is not just about making
During development, concern about having same keyword in path variables also came to my mind. I don't have a concrete answer to this. For now, if I were in that position, I'll pass them in params to Another approach would be to provide option to alias params name for query/json/headers/cookies through app.route("/search/{query}/")
api.validate(..., alias={"query": "q", "json": "body"})
def viewfunc(query: str, q: QueryModel, body: BodyModel):
... |
I'm not opposing that, I like the benefits type annotations provide too, but from your comment it seemed like the motivation for this is just to make mypy pass.
That's sure useful, but I'm not sure if the tradeoff of inflating each function with 4 parameters is worth it, considering some of them are barely used (how many views really use
...in fact I can imagine passing |
Thanks for your answer. You are right, users can still use the |
Actually the PR requires you to only put annotations for what you want, not all four. So if you only want to parse @route('/keys')
@api.validate(resp=Response("HTTP_200"))
def viewfunc(json: BodyModel):
return json.keys() So the rest of objections are moot. I'm of the believe that libraries should absorb the complexity and provide clean contract. Also this is a public library, I can't propose something that breaks entire existing api. Also if you look at def search(
q: str = Query(..., description="query string"),
page: int = Query(0, description="pagination page number"),
limit: int = Query(10, description="results per page"),
):
... |
LGTM. Can you add some documents to the README? |
Examples and description added in README. |
Thanks. |
The current implementation of spectree uses arguments to validate method for declaration of types for query params, request body, cookies and headers and in turn adds a context attribute to request object for all three framework implementations like following:
While this is good, but static linters like mypy complain about
context
attribute missing from flask request object. If view functions itself are annotated with their type and we additionally inject kwargs in view, linters are happy and longrequest.context.query.order
access is now justquery.order
. Following is an example of annotated view function:Current implementation is an opt-in feature disabled by default. To opt-in simple instantiate
SpecTree
instance with an additional parameter like following:This feature doesn't change anything if not opted in. Once opted it, user can have a nice API.
I'm willing to discuss the merits, demerits of this approach. It's much closer to FaskAPI usage and since we are already using
pydantic
and annotations insidespectree
, why stop there.All tests are in place.