Comments (11)
Are there some reasons for choosing to add both request.form or request.json in the same
@api.validate(json=Schema)
? Instead of declaring the two different schemas?
The request body can be either JSON data (maybe other serialized type) or a file.
There is a PR related to this:
This PR doesn't have activities for a long time. Hope we can work together to improve it.
from spectree.
Thanks for your feedback.
Pydantic doesn't have a file
type. Actually, flask will create a werkzeug.datastructures.FileStorage
object. To support this, you need to provide a File
type.
from werkzeug.datastructures import FileStorage
from pydantic import BaseModel
class File:
file: FileStorage
class Config:
arbitrary_types_allowed = True
Let's say if you have multiple items in the form, then you may need to create the schema like this:
from werkzeug.datastructures import FileStorage
from pydantic import BaseModel
class Form:
file: FileStorage
user: str
addr: str
class Config:
arbitrary_types_allowed = True
I'll create a PR to support this.
from spectree.
The problem is that spectree only parse request body for json on docs generation.
if hasattr(func, "json"):
data = {"content": {"application/json": {"schema": {"$ref": f"#/components/schemas/{func.json}"}}}}
In the request context, spectree convert both request.form
and request.json
in the same request.context.json
.
I'm start to use spectree in my work and I made some modifications to put @api.validate(json=JsonSchema)
or @api.validate(form=FormSchema)
, using that, I modificate the request body parser for docs, to diferentiate the two types
if hasattr(func, "json"):
data = {"content": {"application/json": {"schema": {"$ref": f"#/components/schemas/{func.json}"}}}}
if hasattr(func, "form"):
data = {"content": {"multipart/form-data": {"schema": {"$ref": f"#/components/schemas/{func.form}"}}}}
After do that, you will be able to create a pydantic custom schema for file that has a customized schema that returns the openapi spec for file upload.
class UploadedFile:
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
return v
@classmethod
def __modify_schema__(cls, field_schema):
field_schema["type"] = "file"
field_schema["format"] = "binary"
from spectree.
Interesting, maybe I can help you, I don't have knowledge about starlette or falcon, but I can give you some ideas about the modifications that I made in the flask plugin.
from spectree.
Pydantic doesn't have a file type. Actually, flask will create a werkzeug.datastructures.FileStorage object. To support this, you need to provide a File type.
The problem is that cannot generate the schema because FileStorage
is not a pydantic model.
I guess we need to create another model like this:
class FlaskFile(BaseModel):
filename: str
name: str
content_length: int
content_type: str
mimetype: str
stream: bytes
from spectree.
Thank you for your help but I was still unable to create a functioning swagger doc that can upload a file.
When I try to add it to a spectree.validate
as json or header an error accurs:
Value not declarable with JSON Schema, field: name='file' type=FileStorage required=True
As I understood you we need to add FlaskFile
into spectree so it can handle it. Is there any way I could help with that?
from spectree.
I found a solution. It may not be elegant.
from werkzeug.datastructures import FileStorage
from pydantic import BaseModel
FlaskFile = FileStorage
def file_modify_schame(cls, field_schema):
field_schema.update(format='file-storage')
FlaskFile.__modify_schema__ = classmethod(file_modify_schame)
class Form(BaseModel):
user: str
file: FlaskFile
class Config:
arbitrary_types_allowed = True
The code above will work with this commit: 53936d4
Let me know if you have any ideas.
from spectree.
Thank you again for your help but I was still not able to make it work.
Here is the complete flask application where I tried to make it work:
from flask import Flask
from spectree import SpecTree
from werkzeug.datastructures import FileStorage
from pydantic import BaseModel
FlaskFile = FileStorage
def file_modify_schame(cls, field_schema):
field_schema.update(format='file-storage')
FlaskFile.__modify_schema__ = classmethod(file_modify_schame)
class Form(BaseModel):
user: str
file: FlaskFile
class Config:
arbitrary_types_allowed = True
app = Flask(__name__)
api = SpecTree('flask')
@app.route('/', methods=['POST'])
@api.validate(json=Form)
def hello_world():
return 'Hello World!'
api.register(app)
if __name__ == '__main__':
app.run()
Is there anything wrong that I am doing?
from spectree.
Hi, I think your code is correct. But sadly swagger doesn't support the customized type of object. I think you can find the definition in swagger schemas below or redoc page (/apidoc/redoc
).
from spectree.
Are there some reasons for choosing to add both request.form or request.json in the same @api.validate(json=Schema)
? Instead of declaring the two different schemas?
from spectree.
closing, solved via #225
from spectree.
Related Issues (20)
- [BUG] Spectree flask plugin is logging request validation errors twice HOT 2
- [Question] Is it possible to specify a BaseModel class as a Redoc Model? HOT 1
- Potentially leaky tests HOT 1
- Falcon: before in validate decorator not working?
- [Question] Skip validation for real? HOT 8
- Key appended to Schema Component HOT 5
- Exclude routes from OpenAPI spec HOT 1
- Feature Request: Remove Duplicate Schema Components HOT 3
- feat: support `msgspec` as another schema definition
- feat: Disable publishing of /apidoc route HOT 1
- bug: annotations NameError issue caused by python bug HOT 1
- bug: spectree doesn't support pydantic 2.x but doesn't restrict in pyproject.toml HOT 1
- bug: don't support pydantic v2 HOT 5
- feat: add an abstract layer to support pydantic[v1]/pydantic[v2]/msgspec
- bug: Flask Response Validation Error Results in Exception, Unintended 500 content HOT 1
- bug: An empty request is not validated / the content type is not enforced HOT 1
- bug: SecuritySchemeData root_validator conflicts with alias HOT 2
- bug: field alias no longer respected (regression) HOT 6
- bug: List[int] in query params does not accept a list of size 1 in flask app HOT 2
- bug: resp_validation_error is not passed in after handler of flask plugin
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spectree.