All Projects → bagrat → Calm

bagrat / Calm

Licence: mit
It is always Calm before a Tornado!

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Calm

Restfm
RESTful web services for FileMaker server.
Stars: ✭ 76 (+52%)
Mutual labels:  rest-api, rest, restful-api, restful
Restful Api Design References
RESTful API 设计参考文献列表,可帮助你更加彻底的了解REST风格的接口设计。
Stars: ✭ 4,830 (+9560%)
Mutual labels:  rest-api, rest, restful-api, restful
Api Strategy
Equinor API Strategy
Stars: ✭ 56 (+12%)
Mutual labels:  rest-api, rest, restful-api, restful
Graphql2rest
GraphQL to REST converter: automatically generate a RESTful API from your existing GraphQL API
Stars: ✭ 181 (+262%)
Mutual labels:  rest-api, rest, restful-api, restful
Generator Http Fake Backend
Yeoman generator for building a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 49 (-2%)
Mutual labels:  rest-api, rest, restful-api, restful
Http Fake Backend
Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 253 (+406%)
Mutual labels:  rest-api, rest, restful-api, restful
Codeigniter Jwt Sample
CodeIgniter JWT Sample
Stars: ✭ 144 (+188%)
Mutual labels:  rest-api, rest, restful-api, restful
Blogbackendproject
Backend code for my blogs, develop with Django Rest framework.
Stars: ✭ 204 (+308%)
Mutual labels:  rest-api, rest, restful-api, restful
Apidoc
RESTful API 文档生成工具,支持 Go、Java、Swift、JavaScript、Rust、PHP、Python、Typescript、Kotlin 和 Ruby 等大部分语言。
Stars: ✭ 785 (+1470%)
Mutual labels:  rest-api, rest, restful-api, restful
Rest Api Design Guide
NBB's REST-ish API Design Guide
Stars: ✭ 643 (+1186%)
Mutual labels:  rest-api, rest, restful-api, restful
Node Express Mongoose Passport Jwt Rest Api Auth
Node, express, mongoose, passport and JWT REST API authentication example
Stars: ✭ 146 (+192%)
Mutual labels:  rest-api, rest, restful-api, restful
Gen
Converts a database into gorm structs and RESTful api
Stars: ✭ 825 (+1550%)
Mutual labels:  rest-api, rest, restful-api, restful
Ngx Restangular
Restangular for Angular 2 and higher versions
Stars: ✭ 787 (+1474%)
Mutual labels:  rest-api, rest, restful-api, restful
Farwest
Framework for building RESTful HATEOAS-driven applications.
Stars: ✭ 18 (-64%)
Mutual labels:  rest-api, rest, restful-api, restful
Clevergo
👅 CleverGo is a lightweight, feature rich and high performance HTTP router for Go.
Stars: ✭ 246 (+392%)
Mutual labels:  rest-api, restful-api, restful
Proteus
Lean, mean, and incredibly fast JVM framework for web and microservice development.
Stars: ✭ 178 (+256%)
Mutual labels:  rest-api, rest, restful-api
Jaguar
Jaguar, a server framework built for speed, simplicity and extensible. ORM, Session, Authentication & Authorization, OAuth
Stars: ✭ 286 (+472%)
Mutual labels:  rest-api, rest, restful
Json Server Heroku
Deploy json-server to Heroku & Azure 🆙 🆓
Stars: ✭ 310 (+520%)
Mutual labels:  rest-api, rest, restful-api
Finale
Create flexible REST endpoints and controllers from Sequelize models in your Express app
Stars: ✭ 167 (+234%)
Mutual labels:  rest-api, rest, restful-api
Gramework
Fast and Reliable Golang Web Framework
Stars: ✭ 354 (+608%)
Mutual labels:  rest-api, rest, restful-api

Calm

Calm Logo

PyPI Build Status Coverage Status Code Health Gitter License

Introduction

Calm is an extension to Tornado Framework that provides decorators and other tools to easily implement RESTful APIs. The purpose of Calm is to ease the process of defining your API, parsing argument values in the request handlers, etc.

Installation

Calm installation process is dead simple with pip:

$ pip install calm

Note: Calm works only with Python 3.5

Let's code!

Here is a basic usage example of Calm:

import tornado.ioloop
from calm import Application


app = Application()


@app.get('/hello/:your_name')
async def hello_world(request, your_name):
    return {'hello': your_name}


tornado_app = app.make_app()
tornado_app.listen(8888)
tornado.ioloop.IOLoop.current().start()

Now go ahead and try your new application! Navigate to http://localhost:8888/hello/YOUR_NAME_HERE and see what you get.

Now that you built your first Calm RESTful API, let us dive deeper and see more features of Calm. Go ahead and add the following code to your first application.

# Calm has the notion of a Service. A Service is nothing more than a URL prefix for
# a group of endpoints.
my_service = app.service('/my_service')


# So when usually you would define your handler with `@app.get`
# (or `post`, `put`, `delete`), with Service you use the same named methods of
# the Service instance
@my_service.post('/body_demo')
async def body_demo(request):
    """
    The request body is automatically parsed to a dict.

    If the request body is not a valid JSON, `400` HTTP error is returned.

    When the handler returns not a `dict` object, the return value is nested
    into a JSON, e.g.:

        {"result": YOUR_RETURN_VALUE}

    """
    return request.body['key']


@my_service.get('/args_demo/:number')
async def args_demo(request, number: int, arg1: int, arg2='arg2_default'):
    """
    You can specify types for your request arguments.

    When specified, Calm will parse the arguments to the appropriate type. When
    there is an error parsing the value, `400` HTTP error is returned.

    Any function parameters that do not appear as path arguments, are
    considered query arguments. If a default value is assigned for a query
    argument it is considered optional. And finally if not all required query
    arguments are passed, `400` HTTP error is returned.
    """
    return {
        'type(number)': str(type(number)),
        'type(arg1)': str(type(arg1)),
        'arg2': arg2
    }

If you followed the comments in the example, then we are ready to play with it!

First let us see how Calm treats request and response bodies:

$ curl -X POST --data '{"key": "value"}' 'localhost:8888/my_service/body_demo'
{"result": "value"}

$ curl -X POST --data '{"another_key": "value"}' 'localhost:8888/my_service/body_demo'
{"error": "Oops our bad. We are working to fix this!"}

$ curl -X POST --data 'This is not JSON' 'localhost:8888/my_service/body_demo'
{"error": "Malformed request body. JSON is expected."}

Now it's time to observe some request argument magic!

$ curl 'localhost:8888/my_service/args_demo/0'
{"error": "Missing required query param 'arg1'"}

$ curl 'localhost:8888/my_service/args_demo/0?arg1=12'
{"type(arg1)": "<class 'int'>", "type(number)": "<class 'int'>", "arg2": "arg2_default"}

$ curl 'localhost:8888/my_service/args_demo/0?arg1=not_a_number'
{"error": "Bad value for integer: not_a_number"}

$ curl 'localhost:8888/my_service/args_demo/0?arg1=12&arg2=hello'
{"type(arg1)": "<class 'int'>", "type(number)": "<class 'int'>", "arg2": "hello"}

Adding custom RequestHandler implementations

If you have a custom Tornado RequestHandler implementation, you can easily add them to your Calm application in one of the two ways:

  • using the Application.add_handler method
  • using the Application.custom_handler decorator

For the first option, you can just define the custom handler and manually add it to the Calm application, just like you would define a Tornado application:

class MyHandler(RequestHandler):
    def get(self):
        self.write('Hello Custom Handler!')

app.add_handler('/custom_handler', MyHandler)

The second option might look more consistent with other Calm-style definitions:

@app.custom_handler('/custom_handler')
class MyHandler(RequestHandler):
    def get(self):
        self.write('Hello Custom Handler!')

You can also use the custom_handler decorator of services, e.g.:

custom_service = app.service('/custom')

@custom_service.custom_handler('/custom_handler')
class MyHandler(RequestHandler):
    def get(self):
        self.write('Hello Custom Handler!')

Contributions

Calm loves Pull Requests and welcomes any contribution be it an issue, documentation or code. A good start for a contribution can be reviewing existing open issues and trying to fix one of them.

If you find nothing to work on but cannot kill the urge, jump into the gitter channel and ask "what can I do?".

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].