Stupeflask Documentation
Total Page:16
File Type:pdf, Size:1020Kb
Stupeflask Documentation Numberly Jan 20, 2020 Contents 1 Install 3 2 Comparison 5 3 Tests 7 4 License 9 5 Documentation 11 5.1 Better application defaults........................................ 11 5.2 Easier collection of configuration values................................. 13 5.3 Native ObjectId support......................................... 13 5.4 API Reference.............................................. 14 5.5 Cursor support.............................................. 18 6 Indices and tables 19 Python Module Index 21 Index 23 i ii Stupeflask Documentation a.k.a. « Flask on steroids » An opinionated Flask extension designed by and for web developers to reduce boilerplate code when working with Marshmallow, MongoDB and/or JSON. Documentation: https://flask-stupe.readthedocs.io • Return any object type in views, and it will be coerced to a flask.Response • Validate payloads through Marshmallow schemas • Easily add JSON converters for any custom type • Fetch all the blueprints from a whole module in one line • Native ObjectId support for both Flask and Marshmallow • Powerful configuration management • Decorators to handle authentication, permissions, and pagination • 100% coverage and no dependency Contents 1 Stupeflask Documentation 2 Contents CHAPTER 1 Install $ pip install flask-stupe 3 Stupeflask Documentation 4 Chapter 1. Install CHAPTER 2 Comparison Here is a comparison of a bare Flask application and its equivalent Stupeflask version. They both rely on MongoDB, handle input and output in JSON, and allow to create a user and retrieve one or more. 5 Stupeflask Documentation Bare Flask With Stupeflask from bson import ObjectId from flask import request from flask import abort, Flask, jsonify, from flask_stupe import paginate, schema_ ,!request ,!required from marshmallow import Schema from flask_stupe.json import Stupeflask from marshmallow.fields import String from marshmallow import Schema from pymongo import MongoClient from marshmallow.fields import String from pymongo import MongoClient app= Flask(__name__) users= MongoClient().database.users app= Stupeflask(__name__) users= MongoClient().database.users class UserSchema(Schema): username= String(required=True) class UserSchema(Schema): password= String() username= String(required=True) password= String() @app.route("/user", methods=["POST"]) def post_user(): @app.route("/user", methods=["POST"]) json= request.get_json(force=True) @schema_required(UserSchema()) validation_result= UserSchema(). def post_user(): ,!load(json) result= users.insert_one(request. if validation_result.errors: ,!schema) abort(400, validation_result. request.schema.update(_id=result. ,!errors) ,!inserted_id) result= users.insert_one(validation_ return request.schema ,!result.data) inserted_id= str(result.inserted_id) validation_result.data.update(_ @app.route("/user/<ObjectId:id>") ,!id=inserted_id) def get_user(id): return jsonify(validation_result. return users.find_one({"_id": id}) ,!data) @app.route("/users") @app.route("/user/<id>") @paginate(limit=100) def get_user(id): def get_users(): try: return users.find() id= ObjectId(id) except ValueError: abort(404) user= users.find_one({"_id": id}) user["_id"]= str(user["_id"]) return jsonify(user) @app.route("/users") def get_users(): limit= request.args.get("limit", ,!100, type=int) skip= request.args.get("skip",0, ,!type=int) cursor= users.find().limit(limit). ,!skip(skip) return jsonify(list(cursor)) 6 Chapter 2. Comparison CHAPTER 3 Tests To run Flask-Stupe tests: • install developers requirements with pip install -r requirements.txt; • run pytest. 7 Stupeflask Documentation 8 Chapter 3. Tests CHAPTER 4 License MIT 9 Stupeflask Documentation 10 Chapter 4. License CHAPTER 5 Documentation 5.1 Better application defaults Stupeflask makes it easy to use JSON to build APIs. A perfect example is the flask_stupe.json.Stupeflask application. 5.1.1 Better support for JSON based APIs Automatic conversion to JSON By using the JSON version of Stupeflask, every Python object your views returns that is not a Response object will be JSON serialized. With that in mind, you can do that kind of things: @app.route("/foo") def foo(): return {"foo":"bar"} This will be rendered as the equivalent JSON and sent to the client. Add JSON encoding for objects If you want to add serialization methods for other custom types, you can! You’ll need to call JSONEncoder. add_rule(). import uuid app.json_encoder.add_rule(uuid.UUID, lambda uuid: str(uuid)) This snippet shows how to add a serializer for UUIDs. 11 Stupeflask Documentation 5.1.2 Import all blueprints from a package You can easily add a bunch of blueprints by passing a package to the Stupeflask.register_blueprints(). It will search through all the package’s modules and import a variable named like the module. If this is a blueprint, it will be registered into the application. For example, this snippet: from application.views.user import user from application.views.pets import pets from application.views.family import family app.register_blueprint(user) app.register_blueprint(pets) app.register_blueprint(family) Becomes: from application import views app.register_blueprints(views) Metadata wrapping By default, returning {"foo": "bar"} from a route would produce such a response: { "code": 200, "data":{ "foo": "bar" } } As you can see, the data is wrapped within another JSON object containing the status code. You can add more metadata to that outter JSON object by modifying the metadata dictionary of the current flask. request. For example, this snippet will make all responses have a version field added to them: from flask import request @app.before_request def before_request(response): request.metadata.update(version="v1") The produced output will thus look like this: { "code": 200, "data":{ "foo": "bar" }, "version": "v1" } If, on the opposite, you don’t want any sort of metadata wrapping, and rather return a plain {"foo": "bar"} JSON object, just set the METADATA_WRAPPING configuration value to False. 12 Chapter 5. Documentation Stupeflask Documentation 5.1.3 Add path converters With Stupeflask, you can add path converters with Stupeflask.register_converter(). Please head towards werkzeug’s documentation about converters if you want to learn more. 5.2 Easier collection of configuration values Stupeflask makes it easier to collect configuration variables from different sources. 5.2.1 config.py If a file named config.py is present in the working directory, it will be imported and used as the configuration file for your application. 5.2.2 $CONFIG If an environment variable named CONFIG exists, its value will be imported as a Python configuration file. 5.2.3 Environment Any key present in the configuration at this point will be checked in the environment. If a corresponding variable is found in the environment, its value will override the current configuration. Since all environment variables are strings, the value will be cast in the type of the value present in the configuration in the first place. Let’s say you have a variable like so in the config.py file: DEBUG= True You can override it by putting that in the environment: DEBUG=1 In your code, it will not be treated a string or an integer, but as True, because Stupeflask will have detected that it was a boolean and cast it. If you want to invoke this behavior at another moment, use the from_env method. 5.3 Native ObjectId support The bson.ObjectId type is natively supported by Stupeflask. 5.3.1 Path parameter Stupeflask recognizes ObjectIds in path parameters. You can use it like this: @app.route("/user/<ObjectId:id>") 5.2. Easier collection of configuration values 13 Stupeflask Documentation 5.3.2 JSON Any ObjectIds a in JSON response will be coerced to string automaticaly. 5.3.3 Marshmallow field Stupeflask features a field (ObjectId) for ObjectIds. If the bson module exists (for example if you’re using MongoDB), you can use it with schema_required(). It allows to automaticaly cast indicated fields from string to ObjectId. 5.4 API Reference 5.4.1 App class flask_stupe.app.Stupeflask(*args, **kwargs) config_class alias of flask_stupe.config.Config register_blueprints(package, **options) Auto-discover blueprints and register them It will look recursively in every module of the package to find a variable that has the same name as its module. It means that if a file called foo.py has an exportable variable called foo, it will try to register that variable as a blueprint. register_converter(converter, name=None) Register a new converter that can be used in endpoints URLs A converter is a Werkzeug class that transforms a part of an URL to a Python object, passed as an argument to the endpoint function. Stupeflask currently implements the following converters: • /<ObjectId>/ with ::ObjectIdConverter See Werkzeug documentation about custom converters if you want to implement your own converter. register_converters(converter_list) Register multiple converters at once. See register_converter(). request_class alias of flask_stupe.request.Request 5.4.2 Auth flask_stupe.auth.auth_required(function) Decorator checking that the request is made by an authenticated user. If you want to use that function, you should set a before_request handler that authenticate requests when possi- ble. It must then expose a user attribute on the flask.request object. 14 Chapter 5. Documentation Stupeflask Documentation @app.before_request def get_user(): token= request.args.get("token") if verify_token(token): request.user={"username":"toto"} A view decorated with auth_required() will be aborted with a status code 401 if the