معرفی شرکت ها


dos-1.6.0


Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر

توضیحات

Document and Validate Flask
ویژگی مقدار
سیستم عامل -
نام فایل dos-1.6.0
نام dos
نسخه کتابخانه 1.6.0
نگهدارنده []
ایمیل نگهدارنده []
نویسنده Peter Richards
ایمیل نویسنده dos@peter.net
آدرس صفحه اصلی https://github.com/pr/dos
آدرس اینترنتی https://pypi.org/project/dos/
مجوز MIT
# dos [![PyPi version](https://img.shields.io/pypi/v/dos.svg)](https://pypi.python.org/pypi/dos/) [![](https://img.shields.io/badge/python-3.1+-blue.svg)]((https://www.python.org/downloads/)) ![t](https://img.shields.io/badge/status-stable-green.svg) [![](https://img.shields.io/github/license/pr/dos.svg)](https://github.com/pr/dos/blob/master/LICENSE) ## Introduction dos is a Python package to make it easy to document and validate a Flask API. Write a single chunk of code to create endpoints with both built in validation and automatically generated documentation. The documentation is Open API 3.0 (formerly known as Swagger) in JSON form. ## Installation You can install the latest version of dos with pip. ```bash pip install dos ``` ## Hello World > All of this code is found in the [pet_shop](https://github.com/pr/dos/tree/master/examples/tutorial/pet_shop) example. > For a more substantive look at dos, please see [dos in depth](#dos-in-depth) Let's look at the structure of a typical dos endpoint. The following code defines the `/dog/get` endpoint. ```python from http import HTTPStatus from dos.schema import ErrorFields from pet_shop.model import DogFields def handler(): # ... database query looking for the dog ... if dog_found: dog = { "name": "Spot", "breed": "Poodle" } return HTTPStatus.OK, dog else: return HTTPStatus.NOT_FOUND, {"message": "No dog by that name found!"} def input_schema(): return DogFields().specialize(only=["name"]) def output_schema(): return { HTTPStatus.OK: DogFields().all(), HTTPStatus.NOT_FOUND: ErrorFields().all() } ``` Each endpoint is made up of 3 critical components. 1. `handler()` The handler defines the endpoint functionality. Adding to the database, calling another endpoint, it all happens here. 2. `input_schema()` The input_schema defines what fields the endpoint expects. These are typically defined elsewhere and imported, but they don't have to be. 3. `output_schema()` The output_schema defines what fields the endpoint is allowed to expose. Critically, if the handler sets a field that is not defined in the output_schema, that field will not be exposed by the API. Because endpoints can produce different HTTP statuses, the output_schema is a dictionary where the keys are all the statuses produced by the endpoint. --- The endpoints import fields typically defined in another file. Here is the DogFields class from above. ```python from dos import prop from dos.schema import Fields class DogFields(Fields): base_schema = { "name": prop.String("The dog's name."), "breed": prop.String("The dog's breed.") } def __init__(self): super().__init__(self.base_schema) ``` Every Fields class needs to have a base_schema, a dictionary made up of dos props. Read more about props [here](#props). The Field class gives additional functionality outlined [here](#the-field-class). --- Now that we've defined an endpoint, we can create out flask app. It will look something like this: ```python from dos.open_api import OpenAPI from dos.flask_wrappers import wrap_validation, wrap_handler, wrap_route from flask import Flask, jsonify, render_template from pet_shop.api.dog import get as dog_get def create_app(): app = Flask(__name__) open_api = OpenAPI("Pet Shop API", "1.0") handler_mapping = [ (dog_get, "/dog/get", "get"), ] for module, path, http_method in handler_mapping: handler = wrap_handler(module.__name__, module.handler) handler = wrap_validation(handler, module) wrap_route(app, handler, path, http_method) open_api.document(module, path, http_method) @app.route("/") def index(): return render_template("index.html") @app.route("/docs") def docs(): return render_template("docs.html") @app.route("/open_api.json") def open_api_endpoint(): return jsonify(open_api) return app ``` This will create a flask app with the endpoint we just defined, as well as documenting it with Open API 3.0 JSON. For more about the Flask Wrappers, please look [here](#flask-wrappers) That's all there is to it. Once the general structure is set up, each additional endpoint should be relatively simple to implement. To run the full working example, please see [pet_shop](https://github.com/pr/dos/tree/master/examples/tutorial/pet_shop). ## dos in Depth ### Props The foundation of dos is props. There are nine different prop types, 6 which are represented by Open API: Name | Python Type | OpenAPI Representation | Additional Notes --- | --- | --- | --- Integer | `int` | Yes Number | `int`, `float`, `decimal.Decimal` | Yes Numeric | `int`, `float`, `decimal.Decimal`, `str` | No | The string must contain a valid number String | `str` | Yes DateTime | `str`, `arrow.Arrow` | No | The string must contain a valid arrow DateTime Enum | `enum.Enum` | No Boolean | `bool` | Yes Object | `dict` | Yes Array | `list` | Yes Props are used to capture the structure of the inputs and outputs of endpoints. Initializing a Prop is simple, and is always done in the context of a python dictionary capturing the structure of the JSON. ```python from dos import prop base_schema = { "name": prop.String(), } ``` #### Customizing Props Props take four optional arguments. Description is a string explaining what the prop represents, and is displayed in the documentation. ```python from dos import prop base_schema = { "name": prop.String(description="The dog's name."), } ``` Required and nullable capture whether the prop is required and nullable. These are used for both validation and Open API. ```python from dos import prop base_schema = { "name": prop.String(required=False, nullable=True), } ``` All props have these three arguments, and a final one called validators. #### Prop Validation dos has a few validators built in as exemplars, but feel free to write your own Validators, specific to the domain your API is capturing. All validators define `supported_prop_classes`, because not all validation is applicable to every prop. (You wouldn't validate if an array was a Social Security Number!) Using a Validator looks like this: ```python from dos import prop from dos.validators import ExactLength base_schema = { "name": prop.String("This string must be 8 characters long", validators=ExactLength(8)), } ``` The validator itself looks like this: ```python from dos import prop from dos.validators import Validator class ExactLength(Validator): supported_prop_classes = [prop.String, prop.Number, prop.Numeric, prop.Integer] def __init__(self, exact_length=None): self.exact_length = exact_length def validate_prop(self, prop_class, prop_value): super().validate_prop(prop_class, prop_value) if len(prop_value) != self.exact_length: return (f"{prop_class.__name__} is not the correct length! The string \'{prop_value}\' is " f"{len(prop_value)} characters long, not {self.exact_length}!") return None ``` Every validator needs to define `supported_prop_classes` and a `validate_prop` function. If you have a good one, feel free to submit a pull request. #### Objects and Arrays Objects and Arrays take additional arguments, due to their special nature. Objects take their structure, looking something like this: ```python from dos import prop base_schema = { "name": prop.Object(structure={ "name": prop.String("The object has a string in it"), "boolean_field": prop.Boolean("And also a boolean") }), } ``` Structure is mandatory, and is a dictionary of props. Validation will look for dictionaries in the JSON that match the outlined structure. Array does a similar thing with the repeated_structure argument. ```python from dos import prop base_schema = { "names": prop.Array(repeated_structure=prop.String("just a list of strings")), } ``` You can even put these together, and have an array of objects! ```python from dos import prop base_schema = { "names": prop.Array(repeated_structure=prop.String("just a list of strings")), "array_of_objects": prop.Array( repeated_structure=prop.Object( structure={ "sub_string": prop.String("the string", required=True, nullable=False), "required_one": prop.String(required=True, nullable=False) } ), description="A list of plans." ) } ``` #### Prop Wrappers Prop Wrappers are another way to capture what a JSON field expects. Currently, they are used for fields with multiple valid inputs. Say a field can take either a string or a boolean. dos captures this idea with a prop wrapper. ```python from dos import prop from dos import prop_wrapper base_schema = { "boolean_or_string": prop_wrapper.OneOf([ prop.String(), prop.Boolean() ]), } ``` Critically, the OneOf prop wrapper is a just an array of props, meaning all the customization outlined above is still possible. A convoluted example could be something like this: ```python from dos import prop from dos import prop_wrapper from dos.validators import ExactLength base_schema = { "boolean_or_string": prop_wrapper.OneOf([ prop.String(validators=ExactLength(7)), prop.Boolean(required=False, nullable=False) ]), } ``` All of this is enforced and valid. ### The Field Class Fields are a collection of Props and Prop Wrappers that make up an object. They are a way to give semantically meaningful names to collections of Props and Prop Wrappers, and capture the object oriented nature of some APIs. ```python from dos import prop from dos.schema import Fields class DogFields(Fields): base_schema = { "name": prop.String("The dog's name."), "breed": prop.String("The dog's breed.") } def __init__(self): super().__init__(self.base_schema) ``` All fields need a base_schema, which is where the Props and Prop Wrappers that make up the collection are stored. #### Field Customization The Fields class gives many opportunities for customization of input and output schema. ```python from http import HTTPStatus from pet_shop.model import DogFields def input_schema(): return DogFields().specialize(only=["name"]) def output_schema(): return { HTTPStatus.OK: DogFields().all(), } ``` `specialize` allows picking and choosing props, while `all` will use every prop defined by the Field. `specialize` means any Field object can be customized to it's application, by overriding fields on specific props, only using some fields, and/or excluding other fields. ```python from pet_shop.model import DogFields def input_schema(): return DogFields().specialize(overrides={ "breed": { "required": False, }, }, exclude=["name"]) ``` Thus, it is possible to capture objects coming in and out of the API, while tailoring them to specific use cases. ### Flask Wrappers Flask Wrappers are how the modules that define API endpoints are integrated with Flask. ```python from dos.flask_wrappers import wrap_validation, wrap_handler, wrap_route from flask import Flask from pet_shop.api.dog import get as dog_get app = Flask(__name__) handler_mapping = [ (dog_get, "/dog/get", "get"), ] for module, path, http_method in handler_mapping: handler = wrap_handler(module.__name__, module.handler) handler = wrap_validation(handler, module) wrap_route(app, handler, path, http_method) ``` The handler_mapping is a list of every endpoint that needs to be documented and implemented with dos. The module, paired with a string representation of its path and the HTTP method it supports, is then processed with flask wrappers. `wrap_handler` takes the module and extracts the handler. `wrap_validation` parses the input_schema and the output_schema and adds validation to the handler to enforce their constraints. Finally, `wrap_route` adds the endpoint to the flask app itself. ### Open API In same place you create your Flask app, it is easy to also create Open API documentation for that app. ```python from dos.open_api import OpenAPI from flask import Flask def create_app(): app = Flask(__name__) open_api = OpenAPI("Your API Name", "1.0") ``` You can customize the Open API with contact information, a logo, and tags. ```python from dos.open_api import OpenAPI open_api = OpenAPI("Your API Name", "1.0") open_api.add_contact("Pet Shop Dev Team", "https://www.example.com", "pet_shop@example.com") open_api.add_logo("/static/pet_shop.png", "#7D9FC3", "Pet Shop", "/") open_api.add_tag( "introduction", "Welcome! This is the documentation for the API.", ) ``` Tags are important for organizing endpoints. If you have a `dog/create` and a `/dog/delete` endpoint, create a dog tag to group them together. ```python from dos.open_api import OpenAPI open_api = OpenAPI("Your API Name", "1.0") open_api.add_tag( "dog", "Endpoints for interacting with dogs.", ) ``` If you want to add text to the top of the Open API JSON, so others know how it was made, use the disclaimer functionality. ```python from dos.open_api import OpenAPI open_api = OpenAPI("Your API Name", "1.0") open_api.add_disclaimer( "This file is generated automatically. Do not edit it directly! Edit " "the input_schema and output_schema of the endpoint you are changing." ) ``` Finally, to take the `input_schema` and `output_schema` defined in each endpoint module and make Open API out of it, call document. ```python from dos.open_api import OpenAPI from pet_shop.api.dog import get as dog_get open_api = OpenAPI("Your API Name", "1.0") handler_mapping = [ (dog_get, "/dog/get", "get"), ] for module, path, http_method in handler_mapping: open_api.document(module, path, http_method) ``` The same code you used for validation will also be used for documentation! # Acknowledgements Developed at [Capital Rx](https://cap-rx.com/) with team input and assistance, open sourced with permission from [Ryan Kelley, CTO](https://github.com/f0rk).


نیازمندی

مقدار نام
- arrow
- flask


زبان مورد نیاز

مقدار نام
>=3.1 Python


نحوه نصب


نصب پکیج whl dos-1.6.0:

    pip install dos-1.6.0.whl


نصب پکیج tar.gz dos-1.6.0:

    pip install dos-1.6.0.tar.gz