def before_handler(req, resp, err, instance): if err: resp.headers["X-Error"] = "Validation Error" def after_handler(req, resp, err, instance): resp.headers["X-Validation"] = "Pass" def method_handler(req, resp, err, instance): resp.headers["X-Name"] = instance.name api = SpecTree("starlette", before=before_handler, after=after_handler) class Ping(HTTPEndpoint): name = "Ping" @api.validate( headers=Headers, resp=Response(HTTP_200=StrDict), tags=["test", "health"], after=method_handler, ) def get(self, request): """summary description""" return JSONResponse({"msg": "pong"})
def before_handler(req, resp, err, _): if err: resp.headers["X-Error"] = "Validation Error" def after_handler(req, resp, err, _): resp.headers["X-Validation"] = "Pass" def api_after_handler(req, resp, err, _): resp.headers["X-API"] = "OK" api = SpecTree("flask", before=before_handler, after=after_handler, annotations=True) app = Flask(__name__) app.config["TESTING"] = True @app.route("/ping") @api.validate(headers=Headers, resp=Response(HTTP_200=StrDict), tags=["test", "health"]) def ping(): """summary description""" return jsonify(msg="pong")
from enum import Enum from random import random from flask import Flask, abort, jsonify, request from pydantic import BaseModel, Field from spectree import Response, SpecTree app = Flask(__name__) api = SpecTree("flask") class Query(BaseModel): text: str = "default query strings" class Resp(BaseModel): label: int score: float = Field( ..., gt=0, lt=1, ) class Data(BaseModel): uid: str limit: int = 5 vip: bool class Config:
from spectree import SpecTree spectree = SpecTree("flask", title='IPA api documentation')
"""Utilities for providing API payload validation.""" from pydantic.fields import Field from pydantic.main import BaseModel from spectree import SpecTree api = SpecTree("starlette", TITLE="Python Discord Forms", PATH="docs") class ErrorMessage(BaseModel): error: str = Field(description="The details on the error") class OkayResponse(BaseModel): status: str = "ok"
import uvicorn from pydantic import BaseModel, Field from starlette.applications import Starlette from starlette.endpoints import HTTPEndpoint from starlette.responses import JSONResponse from starlette.routing import Mount, Route from spectree import Response, SpecTree api = SpecTree("starlette") class Query(BaseModel): text: str class Resp(BaseModel): label: int = Field( ..., ge=0, le=9, ) score: float = Field( ..., gt=0, lt=1, ) class Data(BaseModel): uid: str
from flask import Blueprint from spectree import SpecTree from pcapi.serialization.utils import before_handler native_v1 = Blueprint("native_v1", __name__) api = SpecTree("flask", MODE="strict", before=before_handler, PATH="/") api.register(native_v1)
from flask import Flask, request, jsonify, abort from pydantic import BaseModel, Field from random import random from enum import Enum from spectree import SpecTree, Response app = Flask(__name__) api = SpecTree('flask') class Query(BaseModel): text: str class Resp(BaseModel): label: int score: float = Field( ..., gt=0, lt=1, ) class Data(BaseModel): uid: str limit: int vip: bool class Language(str, Enum):
from random import randint import pytest import falcon from falcon import testing from spectree import SpecTree, Response from .common import Query, Resp, JSON, Headers, Cookies api = SpecTree('falcon') class Ping: @api.validate(headers=Headers, tags=['test', 'health']) def on_get(self, req, resp): """summary description """ resp.media = {'msg': 'pong'} class UserScore: def extra_method(self): pass def on_get(self, req, resp, name): self.extra_method() resp.media = {'name': name} @api.validate(query=Query, json=JSON,
import logging import json import falcon from wsgiref import simple_server from pydantic import BaseModel, Field from random import random from spectree import SpecTree, Response api = SpecTree( 'falcon', title='Demo Service', version='0.1.2', ) class Query(BaseModel): text: str = Field( ..., max_length=100, ) class Resp(BaseModel): label: int = Field( ..., ge=0, le=9, ) score: float = Field( ...,
import json import logging from random import random from wsgiref import simple_server import falcon from pydantic import BaseModel, Field from spectree import Response, SpecTree api = SpecTree( "falcon", title="Demo Service", version="0.1.2", ) class Query(BaseModel): text: str = Field( ..., max_length=100, ) class Resp(BaseModel): label: int = Field( ..., ge=0, le=9, ) score: float = Field(
def before_handler(req, resp, err, _): if err: resp.headers["X-Error"] = "Validation Error" def after_handler(req, resp, err, _): resp.headers["X-Validation"] = "Pass" def api_after_handler(req, resp, err, _): resp.headers["X-API"] = "OK" api = SpecTree("flask", before=before_handler, after=after_handler, annotations=True) app = Flask(__name__) app.config["TESTING"] = True api_secure = SpecTree("flask", security_schemes=SECURITY_SCHEMAS) app_secure = Flask(__name__) app_secure.config["TESTING"] = True api_global_secure = SpecTree( "flask", security_schemes=SECURITY_SCHEMAS, security={"auth_apiKey": []} ) app_global_secure = Flask(__name__) app_global_secure.config["TESTING"] = True @app.route("/ping")
# self.config.spec_url, # lambda request: JSONResponse(self.spectree.spec), # ) # except: # some weirdness in the spectree library # pass # for ui in PAGES: # if ui in UI_ROUTES: # self.app.add_route( # f'/{self.config.PATH}/{UI_ROUTES[ui]}', # lambda request, ui=ui: HTMLResponse( # PAGES[ui].format(self.config.spec_url) # ), # ) _app = SpecTree('starlette', path='docs', backend=CustomPlugin, MODE='strict') class ValidationErrorMessage(BaseModel): loc: List[str] msg: str type: str class ValidationErrorList(BaseModel): __root__: List[ValidationErrorMessage] #class Profile(BaseModel): # name: constr(min_length=2, max_length=40) # Constrained Str # age: int = Field(
import uvicorn from starlette.applications import Starlette from starlette.endpoints import HTTPEndpoint from starlette.routing import Route, Mount from starlette.responses import JSONResponse from pydantic import BaseModel, Field from spectree import SpecTree, Response api = SpecTree('starlette') class Query(BaseModel): text: str class Resp(BaseModel): label: int = Field( ..., ge=0, le=9, ) score: float = Field( ..., gt=0, lt=1, ) class Data(BaseModel): uid: str
sentry_sdk.init( dsn=settings.SENTRY_DSN, integrations=[ FlaskIntegration(), RedisIntegration(), RqIntegration(), SqlalchemyIntegration() ], release=read_version_from_file(), environment=settings.ENV, traces_sample_rate=settings.SENTRY_SAMPLE_RATE, ) app = Flask(__name__, static_url_path="/static") api = SpecTree("flask", MODE="strict", before=before_handler) api.register(app) login_manager = LoginManager() admin = Admin(name="Back Office du Pass Culture", url="/pc/back-office/", template_mode="bootstrap3") if settings.PROFILE_REQUESTS: profiling_restrictions = [settings.PROFILE_REQUESTS_LINES_LIMIT] app.config["PROFILE"] = True app.wsgi_app = ProfilerMiddleware( # type: ignore app.wsgi_app, restrictions=profiling_restrictions, )
def before_handler(req, resp, err, _): if err: resp.headers["X-Error"] = "Validation Error" def after_handler(req, resp, err, _): resp.headers["X-Validation"] = "Pass" def api_after_handler(req, resp, err, _): resp.headers["X-API"] = "OK" api = SpecTree("flask", before=before_handler, after=after_handler) app = Flask(__name__) @app.route("/ping") @api.validate(headers=Headers, tags=["test", "health"]) def ping(): """summary description""" return jsonify(msg="pong") @app.route("/api/user/<name>", methods=["POST"]) @api.validate( query=Query, json=JSON,
from .common import Query, Resp, JSON, Headers, Cookies def before_handler(req, resp, err, instance): if err: resp.set_header('X-Error', 'Validation Error') def after_handler(req, resp, err, instance): print(instance.name) resp.set_header('X-Name', instance.name) print(resp.get_header('X-Name')) api = SpecTree('falcon', before=before_handler, after=after_handler) class Ping: name = 'health check' @api.validate(headers=Headers, tags=['test', 'health']) def on_get(self, req, resp): """summary description """ resp.media = {'msg': 'pong'} class UserScore: name = 'sorted random score'
def before_handler(req, resp, err, _): if err: resp.headers["X-Error"] = "Validation Error" def after_handler(req, resp, err, _): resp.headers["X-Validation"] = "Pass" def api_after_handler(req, resp, err, _): resp.headers["X-API"] = "OK" api = SpecTree("flask", before=before_handler, after=after_handler, title="Test API") app = Flask(__name__) @app.route("/ping") @api.validate(headers=Headers, tags=["test", "health"]) def ping(): """summary description""" return jsonify(msg="pong") @app.route("/api/user/<name>", methods=["POST"]) @api.validate( query=Query,
def create_app(infer, metric_registry, health_check, req_schema, resp_schema, use_msgpack, config): """ create :class:`falcon` application :param infer: model infer function (contains `preprocess`, `inference`, and `postprocess`) :param metric_registry: Prometheus metric registry :param health_check: model health check function (need examples provided in schema) :param req_schema: request schema defined with :class:`pydantic.BaseModel` :param resp_schema: request schema defined with :class:`pydantic.BaseModel` :param bool use_msgpack: use msgpack for serialization or not (default: JSON) :param config: configs :class:`ventu.config.Config` :return: a :class:`falcon` application """ if use_msgpack: handlers = media.Handlers({ 'application/msgpack': media.MessagePackHandler(), }) app = API(media_type='application/msgpack') app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers else: app = API() api = SpecTree('falcon', title=config.name, version=config.version) logger = logging.getLogger(__name__) VALIDATION_ERROR_COUNTER = Counter( 'validation_error_counter', 'numbers of validation errors', registry=metric_registry, ) def counter_hook(req, resp, resource): if resp.status == HTTP_422: VALIDATION_ERROR_COUNTER.inc() class Homepage: def on_get(self, req, resp): logger.debug('return service endpoints') resp.media = { 'health check': { '/health': 'GET' }, 'metrics': { '/metrics': 'GET' }, 'inference': { '/inference': 'POST' }, 'API document': { '/apidoc/redoc': 'GET', '/apidoc/swagger': 'GET' } } class Metrics: def __init__(self): if os.environ.get('prometheus_multiproc_dir'): multiprocess.MultiProcessCollector(metric_registry) def on_get(self, req, resp): resp.content_type = CONTENT_TYPE_LATEST resp.body = generate_latest(metric_registry) class HealthCheck: @api.validate(resp=Response(HTTP_200=ServiceStatus)) def on_get(self, req, resp): """ Health check """ status = ServiceStatus(inference=StatusEnum.ok) try: health_check() except AssertionError as err: status.inference = StatusEnum.error logger.warning(f'Service health check error: {err}') logger.debug(str(status)) resp.media = status.dict() class Inference: @after(counter_hook) @api.validate(json=req_schema, resp=Response(HTTP_200=resp_schema)) def on_post(self, req, resp): """ Deep learning model inference """ data = req.context.json logger.debug(str(data)) resp.media = infer(data) app.add_route('/', Homepage()) app.add_route('/health', HealthCheck()) app.add_route('/metrics', Metrics()) app.add_route('/inference', Inference()) api.register(app) return app