Package: layab
Layab: Wonderful REST APIsLayab stands forWonderfulin Somali and is also a shortcut forLayabout(aren't we all lazy).This package provides functions and classes that can be used to facilitate the creation of APIs.If you were using layab 1.* (based onFlask-RestPlus, a project that is now dead and will not be compatible starting with Python 3.9), please refer to theMigration guideas layab now advocate the use ofStarlette.Why didn't you switched fromFlask-RestPlusto anotherStarlettebased all-in-one framework (such as FastAPI or Responder)?Modularity is a key principle in software development. However the use of such framework prevent such development.An all-in-one framework is more likely to requires hack to fit your usage.An all-in-one framework is more likely to have a slower development and release pace.By using layab 2, you can still use an all-in-one framework, but you also can chose what and if you want to:Generate an OpenAPI definition.Embed Swagger-UI.Validate data.Serialize / Deserialize data....Available featuresStarletteMiddlewareResponsesConfigurationStarletteMiddlewareYou can get a bunch of already createdStarlette middlewarethanks tolayab.starlette.middlewarefunction.fromstarlette.applicationsimportStarlettefromlayab.starletteimportmiddlewareapp=Starlette(middleware=middleware())By default you will have the followingmiddleware:LoggingMiddleware: Log requests upon reception and return (failure or success).CORSMiddleware: Allow cross origin requests.ProxyHeadersMiddleware: Handle requests passing by a reverse proxy.ResponsesDefaultresponsesare available to return standard responses.Location responsefromstarlette.applicationsimportStarlettefromlayab.starletteimportLocationResponseapp=Starlette()@app.route("/resource",methods=["POST","PUT"])defhandle_resource(request):resource_id=create_update_resource()# Implement this endpointreturnLocationResponse(request,"/resource/{resource_id}")@app.route("/resource/{resource_id}",methods=["GET"])defget_resource(request):pass# Implement this endpointConfigurationAPI and logging configuration should be stored in YAML format.Configuration is expected to be stored inside aconfigurationfolder located on the parent folder of the provided file path.API Configuration is expected to follow the "configuration_{env}.yml" naming where env is the value of the SERVER_ENVIRONMENT environment variable.If not found, environment will be considered as "default".Logging configuration is loaded using the same logic and the following naming: "logging_{env}.yml".importlayab# Load logging and service configurationservice_configuration=layab.load('path/to/a/file/in/module/folder')Note that in case your logging configuration file contains execution of Python code, you will need to provide theyaml.UnsafeLoaderloader.importlayabimportyaml# Load logging and service configurationservice_configuration=layab.load('path/to/a/file/in/module/folder',logging_loader=yaml.UnsafeLoader)Migration guideIf an information on something that was previously existing is missing, please open an issue.Create application and OpenAPI definition and Swagger-UI endpointsLayab 1.*importlayabapp,api=layab.create_api(__file__,compress_mimetypes=["text/csv","application/json"],title="My API.",description="My description.",)Layab 2.* usingflask-restximportflaskimportlayabfromlayab.flask_restximportenrich_flask,log_requests,Apiapp=flask.Flask(__name__)enrich_flask(app,compress_mimetypes=["text/csv","application/json"])api=Api(app,title="My API.",description="My description.",version="1.0.0",# You now have to set the version yourselfinfo={"x-server-environment":layab.get_environment()})log_requests(skip_paths=["/health"])Layab 2.* using Starletteimportlayabfromlayab.starletteimportmiddlewarefromstarlette.applicationsimportStarletteimportapispec_starletteapp=Starlette(middleware=middleware())spec=apispec_starlette.add_swagger_json_endpoint(app,title="My API.",version="1.0.0",# You now have to set the version yourselfinfo={"description":"My description.","x-server-environment":layab.get_environment(),})# You will however lose the Swagger-ui that was available on / (root endpoint)# We advise to install it on your Docker image first and then serve the directory as "/" as the last declared route.Monitoring endpointsLayab 1.*importlayabapi=Nonedefhealth_details():pass# Implement thislayab.add_monitoring_namespace(api,health_details)Layab 2.* usingflask-restximportos.pathfromhealthpy.flask_restximportadd_consul_health_endpointfromkeepachangelog.flask_restximportadd_changelog_endpointapi=Noneasyncdefhealth_check():pass# Implement thisnamespace=api.namespace("Monitoring",path="/",description="Monitoring operations")# You now have to set the release_id yourselfadd_consul_health_endpoint(namespace,health_check,release_id="1.0.0")# You now have to set the path to the changelog yourselfchangelog_path=os.path.join(os.path.abspath(os.path.dirname(__file__)),"..","CHANGELOG.md")add_changelog_endpoint(namespace,changelog_path)Layab 2.* using Starletteimportos.pathfromstarlette.applicationsimportStarlettefromhealthpy.starletteimportadd_consul_health_endpointfromkeepachangelog.starletteimportadd_changelog_endpointapp=Starlette()asyncdefhealth_check():pass# Implement thisadd_consul_health_endpoint(app,health_check)# You now have to set the path to the changelog yourselfchangelog_path=os.path.join(os.path.abspath(os.path.dirname(__file__)),"..","CHANGELOG.md")add_changelog_endpoint(app,changelog_path)You can now add only one of the two initially provided endpoints (in case you don't have or want to expose your changes).Refer tohealthpydocumentation for more information on what is possible to check API health.Refer tokeepachangelogdocumentation for more information on how changelog is handled.Created responseLayab 1.*importlayabapi=None@api.doc(**layab.created_response_doc(api))defendpoint():returnlayab.created_response("/this_is_the_location")Layab 2.* usingflask-restximportflask_restxfromlayab.flask_restximportlocation_responseapi=None@api.response(201,"Resource created",flask_restx.fields.String,headers={"location":"Resource location."})defendpoint():returnlocation_response("/this_is_the_location")Layab 2.* using Starlettefromlayab.starletteimportLocationResponsedefendpoint(request):"""responses:201:description: "Resource created"headers:location:description: "Resource location."type: stringschema:type: string"""returnLocationResponse(request,"/this_is_the_location")Updated responseLayab 1.*importlayabapi=None@api.doc(**layab.updated_response_doc(api))defendpoint():returnlayab.updated_response("/this_is_the_location")Layab 2.* usingflask-restximportflask_restxfromlayab.flask_restximportlocation_responseapi=None@api.response(201,"Resource updated",flask_restx.fields.String,headers={"location":"Resource location."})defendpoint():returnlocation_response("/this_is_the_location")Layab 2.* using Starlettefromlayab.starletteimportLocationResponsedefendpoint(request):"""responses:201:description: "Resource updated"headers:location:description: "Resource location."type: stringschema:type: string"""returnLocationResponse(request,"/this_is_the_location")Deleted responseLayab 1.*importlayabapi=None@api.response(*layab.deleted_response_doc)defendpoint():returnlayab.deleted_responseLayab 2.* usingflask-restximportflaskapi=None@api.response(204,"Resource deleted")defendpoint():returnflask.Response(b"",status=204)Layab 2.* using Starlettefromstarlette.responsesimportResponsedefendpoint(request):"""responses:204:description: "Resource deleted""""returnResponse(status_code=204)How to installpython 3.6+must be installedUse pip to install module:python-mpipinstalllayab