# KwikAPI
Quickly build API services to expose functionality in Python.
`KwikAPI` lets a python developer focus on writing their logic and not worrying about the service like funtionality (There are numerous things to address like serialization protocols, bulk requests, versioning, grouping API calls into logical sets etc).
## Installation
```bash
$ sudo pip3 install kwikapi
```
## Usage
### Quick example
Here is an example of how to use `KwikAPI` to expose `Calc` as a service. We will use `KwikAPI` with the `tornado` webserver in this example.
> To use KwikAPI with tornado install `sudo pip3 install kwikapi[tornado]`
```python
import tornado.ioloop
import tornado.web
from kwikapi.tornado import RequestHandler
from kwikapi import API
# Core logic that you want to expose as a service
class Calc(object):
def add(self, a: int, b: int) -> int:
return a + b
def subtract(self, a: int, b: int) -> int:
return a - b
# Standard boilerplate code to define the service. This
# code will remain more or less the same size regardless
# of how big the code/complexity of `BaseCalc` above is.
# Register BaseCalc with KwikAPI
api = API()
api.register(Calc(), 'v1')
# Passing RequestHandler to the KwikAPI
def make_app():
return tornado.web.Application([
(r'^/api/.*', RequestHandler, dict(api=api)),
])
# Starting the application
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
```
Making an API request
```bash
$ wget http://localhost:8888/api/v1/add?a=10&b=20
$ wget http://localhost:8888/api/v1/subtract?a=10&b=20
```
For more examples of KwikAPI with Tornado go through this [link](https://github.com/deep-compute/kwikapi.tornado/blob/master/README.md) and with Django go through this [link](https://github.com/deep-compute/kwikapi.django/blob/master/README.md)
## Mock request
To demonstrate the various features of `KwikAPI` and also to use the same examples
as living documentation and test cases, we use `MockRequest` so we don't need
`tornado` or `django`
```python
>>> import json
>>> from kwikapi import API, MockRequest, BaseRequestHandler
>>> class Calc(object):
... # Type information must be specified
... def add(self, a: int, b: int) -> int:
... return a + b
>>> api = API()
>>> api.register(Calc(), "v1") # `v1` is the version of this example
>>> req = MockRequest(url="/api/v1/add?a=10&b=20")
>>> res = json.loads(BaseRequestHandler(api).handle_request(req).decode('utf-8'))
>>> res['result']
30
>>> res['success']
True
```
## Features
- Versioning support
- Type checking
- Namespace
- Customizing request and response
- Streaming
- Protocol handling
- API Doc
- Bulk request handling
- KwikAPI Client
### Versioning support
Versioning support will be used if user wants different versions of functionality with slightly changed behaviour.
Specifying the version is mandatory for every class.
We can register the same class with different versions (for testing here)
```python
>>> import json
>>> from kwikapi import API, MockRequest, BaseRequestHandler
>>> class Calc(object):
... def add(self, a: int, b: int) -> int:
... return a + b
>>> api = API()
>>> api.register(Calc(), "v1")
>>> api.register(Calc(), "v2")
>>> req = MockRequest(url="/api/v1/add?a=10&b=20")
>>> res = json.loads(BaseRequestHandler(api).handle_request(req).decode('utf-8'))
>>> res['result']
30
>>> res['success']
True
>>> req = MockRequest(url="/api/v2/add?a=10&b=20")
>>> res = json.loads(BaseRequestHandler(api).handle_request(req).decode('utf-8'))
>>> res['result']
30
>>> res['success']
True
```
We can register different classes with different versions
```python
>>> import json
>>> from kwikapi import API, MockRequest, BaseRequestHandler
>>> class Calc(object):
... def add(self, a: int, b: int) -> int:
... return a + b
>>> class ConcStr(object):
... def add(self, a: str, b: str) -> str:
... return a+b
>>> api = API()
>>> api.register(Calc(), "v1")
>>> api.register(ConcStr(), "v2")
>>> req = MockRequest(url="/api/v1/add?a=10&b=20")
>>> res = json.loads(BaseRequestHandler(api).handle_request(req).decode('utf-8'))
>>> res['result']
30
>>> res['success']
True
>>> req = MockRequest(url="/api/v2/add?a=in&b=dia")
>>> res = json.loads(BaseRequestHandler(api).handle_request(req).decode('utf-8'))
>>> res['result']
'india'
>>> res['success']
True
```
We can specify the default version so that when you don't mention version in the request URL then default version will be used.
```python
>>> import json
>>> from kwikapi import API, MockRequest, BaseRequestHandler
>>> class Calc(object):
... # Type information must be specified
... def add(self, a: int, b: int) -> int:
... return a + b
>>> api = API(default_version='v1')
>>> api.register(Calc(), "v1")
>>> req = MockRequest(url="/api/add?a=10&b=20")
>>> res = json.loads(BaseRequestHandler(api).handle_request(req).decode('utf-8'))
>>> res['result']
30
>>> res['success']
True
```
### Type checking
Specifying type for parameters and for return value will exactly meet the functionality. This is mandatory in KwikAPI (If the method don't return anything then `None` should be specified as return type)
```python
>>> class Calc(object):
... # Type information must be specified
... def add(self, a: int, b: int) -> int:
... return a + b
... def sub(self, a: int, b: int) -> None:
... c = a - b
```
KwikAPI supports builtin types and types from typing such as Union, List, Tuple, Dict, Generator, Any and so on.
Here are some examples of how to use type hints.
- If a single argument expects two or more types then Union can be used
```python
>>> from typing import Union
>>> class Calc(object):
... def add(self, a: Union[int, float], b: int) -> Union[int, float]:
... return a + b
```
- If we want to pass same type of values in list then List type can be used. If the list values are different types then builtin list can be used as type annotation
```python
>>> from typing import List
>>> class Calc(object):
... def add(self, a: List[str], b: list) -> list:
... return a + b
```
- If we want to pass same type of keys and same type of values in dictionary then Dict type can be used. If the dictionary keys and values are different types then builtin dict can be used as type annotation
```python
>>> from typing import Dict
>>> class Calc(object):
... def add(self, a: Dict[str, int], b: dict) -> dict:
... return a.update(b)
```
- For cheking values inside tuple then we can use Tuple from typing other wise we can use builtin tuple
```python
>>> from typing import Tuple
>>> class Calc(object):
... def add(self, a: Tuple[str, int, float], b: tuple) -> tuple:
... return a + b
```
- If the method contains more than one return value then we can mention types in square brackets
```python
>>> from typing import List
>>> class Calc(object):
... def add(self, a: int, b: int) -> [int, int]:
... return a, b
```
- If request or response contains stream data then we can use Generator
```python
>>> from typing import Generator
>>> class Calc(object):
... def add(self, a: Generator) -> int:
... _sum = 0
... for i in a:
... _sum += i
... return _sum
```
- If we don't need to bother about type checking then we can simply use Any from typing
```python
>>> from typing import Any
>>> class Calc(object):
... def add(self, a: Any, b: Any) -> Any:
... return a, b
```
### Namespace
Register methods with different namespaces
```python
>>> import json
>>> from kwikapi import API, MockRequest, BaseRequestHandler
>>> class Calc(object):
... def add(self, a: int, b: int) -> int:
... return a + b
>>> class ConcStr(object):
... def add(self, a: str, b: str) -> str:
... return a+b
>>> api = API(default_version="v1")
>>> api.register(Calc(), "v1", "Calc")
>>
PyPI 官网下载 | kwikapi-0.3.6.tar.gz
版权申诉
107 浏览量
2022-02-01
05:39:11
上传
评论
收藏 12KB GZ 举报
挣扎的蓝藻
- 粉丝: 13w+
- 资源: 15万+
最新资源
- 数据库管理工具:dbeaver-ce-23.1.3-amd64.deb
- 数据库管理工具:dbeaver-ce-23.1.2-amd64.deb
- 数据库管理工具:dbeaver-ce-23.1.1-amd64.deb
- 基于SRM频谱模型的粗糙表面仿真
- 数据库管理工具:dbeaver-ce-23.1.0-amd64.deb
- 数据库管理工具:dbeaver-ce-23.0.4-amd64.deb
- nginx-deploy.yaml
- 编程项目实战:基于ASP.NET架构的学生信息管理系统(含源代码+毕设文档)
- 毕设项目:学生信息管理系统(asp.net+源代码+文档)
- 腾讯研究院2024向AI而行共筑新质生产力-行业大模型调研报告
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈