Package: minik
A web framework that facilitates the development of serverless applications using
AWS resources. Minik natively supports request from the API Gateway and the
Application Load Balancer.InstallingInstall the latest release:>>> pip install minik
✨🍰✨OnlyPython 3.6+is supported.Simple ExampleIn it’s most basic form; quite honestly, it’s only form. This is how your lambda
function should look like:fromminik.coreimportMinik,BadRequestErrorapp=Minik()@app.route('/hello/{name}')defhello_view(name:str):ifname=='FINDME':# Returns a 400 status code with the message as the body.raiseBadRequestError(msg='This is not a supported name.')# A simple way of getting the current request as json.request_payload=app.request.json_bodyreturn{'hello':name}HTTP MethodsWith minik you can also specify the HTTP methods for a given view. If you don’t
define the methods, every single HTTP method will be allowed by default.fromminik.coreimportMinikapp=Minik()@app.route('/events/{location}')defevents_view(location:str):# This route will be invoked for GET, POST, PUT, PATCH, DELETE...return{'data':['granfondo MD','Silver Spring Century']}@app.route('/events',methods=['POST','PUT'])defcreate_event_view():create_event(app.request.json_body)return{'result':'complete'}If your view is associated with a single HTTP method, you can use the decorator
version.fromminik.coreimportMinikapp=Minik()@app.get('/events/{location}')defget_view(location:str):return{'data':['granfondo MD','Silver Spring Century']}@app.post('/events')defpost_view():create_event(app.request.json_body)return{'result':'complete'}Route Parameter ValidationMinik usesfunction annotationsto validate the value of a route. If the type
of an expected parameter is not valid, minik will respond with a 404 not found
status code.@app.route('/articles/{author}/{year}/')defget_articles_view(author:str,year:int):# Type conversion: isinstance(author, str) and isinstance(year, int)return{'author_name':author,'year':year}To learn more checkout out theroute validationpage.Custom HeadersTo update the values of the HTTP response, minik exposes a response object at
the app level. By default minik will create a Response instance with a status code
of 200 and a set of default headers. The headers include a default content-type
value ofapplication/json.For instance, to set the CORS headers in a view and change the content type, a
view would look like:app=Minik()@app.get('/articles/{author}/{year}/')defget_articles_view(author:str,year:int):app.response.headers={"Content-Type":"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET","Access-Control-Allow-Headers":"Content-Type,X-Amz-Date","Authorization":"X-Api-Key,X-Amz-Security-Token"}returnf"A very short article by{author}"Debug ModeFor unhandled exceptions, minik will respond with a 500 status code and
a generic error message. To get more details from the response including the stack
trace and information about the exception, run the app in debug mode.By default the debug mode is set to False.app=Minik(debug=True)Initializing the app in debug mode will relay the stack trace back to the consumer.ALB SupportAlong with having a native integration with the API Gateway, minik can now be used
to handle requests coming from an Application Load Balancer (ALB). The definition
of the web application is identical in both cases. There is no additional code required
to use minik with an ALB.If a lambda function is thetarget of an ALB, minik will parse the raw event,
find the view associated with the route and execute the view with the correct context.fromminik.coreimportMinikapp=Minik()@app.get('/greetings')defget_greetings():app.response.headers={"Content-Type":"text/html; charset=utf-8"}return"""
    <html>
    <head>
        <title>Hello World!</title>
        <style>
        html, body {
        margin: 0; padding: 0;
        font-family: arial; font-weight: 700; font-size: 3em;
        text-align: center;
        }
        </style>
    </head>
    <body>
        <p>Hello World!</p>
    </body>
    </html>"""Notice that there is nothing specific about the source that will eventually invoke
this lambda function. This codeblock can be used to handle a request either
from the API Gateway or from an ALB.Request ObjectAny view has access to theapp.requestinstance as a way to retrieve the general
information of a request. The fields of this object include the query parameters,
the path parameters, headers, payload… Given that different sources might have
a set of additional fields, minik will store a copy of the original event in theapp.requestinstance.For instance, the API Gateway has the concept of stage variables that is missing
from an event received from the ALB. In this case, the generic app.request instance will
not have a field called stage_variables. Instead, minik keeps a copy of the original
event and context objects in the request. In this case a developer can access these
values using the app.request.aws_event[‘StageVariables’]. Where the aws_event is
the event minik received as the handler of the lambda function.fromminik.coreimportMinikapp=Minik()@app.post('/events')defpost_view():# app.request.json_body: The payload of a post request as a JSON object.# app.request.aws_event: The raw event sent by a source to the lambda function.# app.request.aws_context: The context of the lambda function.return{'result':'complete'}MotivationThe team behind this framework is adopting a very minimal set of features to enhance
and streamline web development in the serverless space. These were the business
needs that encouraged us to build minik:Ability to write an API using a familiar (Flask like) syntax using serverless
services.Flexibility on how to build and deploy lambda functions. I do not want
my framework to dictate these processes for me. I want to own them!When installing a web framework, I want to get only the framework. I don’t
want any additional tooling or any additional process-based workflows.When using the microframework I am responsible for the configuration
required to associate my lambda function to its endpoints.The features of this library should be absolutely driven by a very specific
business need. So far, the minimal approach has been sufficient for our team to
write and expose an API using AWS services.Just the frameworkThings to be aware of when working using minik:When used in your lambda function, you’re responsible for including the source
code of minik in your .zip artifact. For packaging purposes we recommend usingJuniper.Minik is service agnostic, as a web framework it natively supports requests
from the API Gateway and an Application Load Balancer (ALB).Unlike other frameworks like Flask or Django, where using the decorator is
sufficient to define the routes of the web app, in minik, you’re responsible
for linking a lambda function to the API Gateway. We recommend using aSAMtemplate.Minik does not include a local development server! For testing purposes, you can
either deploy your lambda to AWS usingsam packageandsam deploy. For local
deployment purposes you can usesam local.QuickstartMinik is just one of the pieces that you need to build serverless APIs. If you
are curious to learn more about best practices and how to get started with this
microframework, checkout outgetting startedguide.The quickstart uses a very simple example, which is included in this codebase, as
a way to highlight the benefits of the framework.ContributingFor guidance on setting up a development environment and how to make a
contribution to Minik, see thecontributing guidelines.LinksDocumentation:https://eabglobal.github.io/minik/License:Apache Software LicenseCode:https://github.com/eabglobal/minikIssue tracker:https://github.com/eabglobal/minik/issuesTest status:Linux, Mac:https://circleci.com/gh/eabglobal/minik