Python client api

26

Click here to load reader

description

This slide cover the how to implement of an python client api and it's Description

Transcript of Python client api

Page 1: Python client api

茴香豆的茴有几种写法记Python的⼀一个客户端实现

dreampuf Jul, 2012

Page 2: Python client api
Page 3: Python client api

main

printf scanf

本地调用

Page 4: Python client api

远程调用

Client

ServerA ServerB

Protocol Stream

Page 5: Python client api

class MockAPI(API): api_url = 'http://host' api_version = 'v1' def etsy_home(self): return Test.scratch_dir def get_method_table(self, *args): return [{'name': 'testMethod', 'uri': '/test/{test_id}', 'http_method': 'GET', 'params': { 'limit': 'int', 'test_id': 'user_id_or_name', 'offset': 'int', 'fizz': 'enum(foo, bar, baz)', 'buzz': 'float', 'blah': 'unknown type', 'kind': 'string', }, 'type': 'int', 'description': 'test method.'}] def _get_url(self, url, http_method, content_type, body): return '{ "count": 1, "results": [3] }'

Esty-python

Page 6: Python client api

class MockAPI(API): api_url = 'http://host' api_version = 'v1' def etsy_home(self): return Test.scratch_dir def get_method_table(self, *args): return [{'name': 'testMethod', 'uri': '/test/{test_id}', 'http_method': 'GET', 'params': { 'limit': 'int', 'test_id': 'user_id_or_name', 'offset': 'int', 'fizz': 'enum(foo, bar, baz)', 'buzz': 'float', 'blah': 'unknown type', 'kind': 'string', }, 'type': 'int', 'description': 'test method.'}] def _get_url(self, url, http_method, content_type, body): return '{ "count": 1, "results": [3] }'

Esty-python

重用不依赖URL

类型验证

不直观缺乏语法检查

不易调试URL拓展

Page 7: Python client api

GuokrAPI v1

class GuokrAPI(API): HOST = "http://localhost/" METHODS = [{ "name": "get_tag", "url": "tags", "method": "GET", "description": "Get the tag instance list", }, { "name": "get_tags", "url": "tags/%(tagname)s", "method": "GET", "description": "Get a tag instance", }]

Page 8: Python client api

GuokrAPI v1

class GuokrAPI(API): HOST = "http://localhost/" METHODS = [{ "name": "get_tag", "url": "tags", "method": "GET", "description": "Get the tag instance list", }, { "name": "get_tags", "url": "tags/%(tagname)s", "method": "GET", "description": "Get a tag instance", }]

不直观缺乏语法检查

不易调试

重用不依赖URL

URLLIB3

URL拓展类型验证

Page 9: Python client api

GuokrAPI v2

mercury.group.mixin(minerva.taggable)

# POST on url /tagscall = resources.tags.create().format('jsonp')

# POST on url /taggings/tags/科学/group/654321call = resources.taggings.update({    'tag': '科学',    'taggable': group,    'user': 'afsrgx',})

tagging = guokr.type(    'tagging').fields({    'id': 'int',    'tag': 'string',    'taggable': 'taggable',    'tag': 'string',    'user': 'ukey',    'date_create': 'datetime',    'date_deleted': 'datetime',}).keys([  'id']).end()

import guokrimport minerva.types as minerva

tags = guokr.resources([    minerva.tag])

taggings = guokr.resources([    minerva.tag,    minerva.taggable,]).namespace(    'taggings')

Page 10: Python client api

GuokrAPI v2

tagging = guokr.type(    'tagging').fields({    'id': 'int',    'tag': 'string',    'taggable': 'taggable',    'tag': 'string',    'user': 'ukey',    'date_create': 'datetime',    'date_deleted': 'datetime',}).keys([  'id']).end()

import guokrimport minerva.types as minerva

tags = guokr.resources([    minerva.tag])

taggings = guokr.resources([    minerva.tag,    minerva.taggable,]).namespace(    'taggings')

mercury.group.mixin(minerva.taggable)

# POST on url /tagscall = resources.tags.create().format('jsonp')

# POST on url /taggings/tags/科学/group/654321call = resources.taggings.update({    'tag': '科学',    'taggable': group,    'user': 'afsrgx',})

URL拓展抽象繁多

重用类型验证链式语法清晰

Page 11: Python client api

GuokrAPI v2

Page 12: Python client api

GuokrAPI v2

Python

Page 13: Python client api

GuokrAPI v2

Pythonic

Page 14: Python client api

GuokrAPI v3

TUPLE_TAGGINGABLE = ("article", "post", "blog", "group", "question")class GuokrAPI(API): HOST = "http://localhost:5000/" @GET("tags/%(tag)s") def get_tag(tag): pass @GET("tags/%(tag)s/feeds") def get_tag_feeds(tag, filter=str): pass @POST("tags/") def add_tag(tag, synonym=str, logo=str, description=str): pass @POST("tag/%(tag)s") def post_tag(tag, logo=str, description=str): pass

class GuokrCMSAPI(GuokrAPI): @GET("cms/tags/filter:%(prefix)s") def get_tag_prefix(prefix): pass #Duplicate #@POST("cms/tags") #def add_tag(self, tag, synonym=None, logo=None, description=None): pass @POST("cms/tags/%(tag)s") def post_tag(tag, logon=str, synonyms=str): pass #synonyms VS synonym @POST("cms/tags/%(tag)s/lock")

Page 15: Python client api

GuokrAPI v3

重用类型验证清晰调试/直观

TUPLE_TAGGINGABLE = ("article", "post", "blog", "group", "question")class GuokrAPI(API): HOST = "http://localhost:5000/" @GET("tags/%(tag)s") def get_tag(tag): pass @GET("tags/%(tag)s/feeds") def get_tag_feeds(tag, filter=str): pass @POST("tags/") def add_tag(tag, synonym=str, logo=str, description=str): pass @POST("tag/%(tag)s") def post_tag(tag, logo=str, description=str): pass

class GuokrCMSAPI(GuokrAPI): @GET("cms/tags/filter:%(prefix)s") def get_tag_prefix(prefix): pass #Duplicate #@POST("cms/tags") #def add_tag(self, tag, synonym=None, logo=None, description=None): pass @POST("cms/tags/%(tag)s") def post_tag(tag, logon=str, synonyms=str): pass #synonyms VS synonym @POST("cms/tags/%(tag)s/lock")

Page 16: Python client api

•统⼀一 随时注意前后接口⼀一致•抽象 隐藏不必要的细节•充要 只接受充分且必须的参数•直观 对人友好,对机器友好(调试)•原生 Pythonic

结论

Page 17: Python client api

DATA ENTRY

Page 18: Python client api

Data Entry v1

a = (1, 2, 3)

Page 19: Python client api

Data Entry v2

a = {“a”:1, “b”:2, “c”:3)

Page 20: Python client api

Data Entry v3

class uDict(dict): def __getattr__(self, name): return self.__getitem__(name)

Page 21: Python client api

Data Entry v4

class uDict(dict): def __getattr__(self, name, default=None): try: return self.__getitem__(name) except KeyError: return default

a = uDict(a=1, b=2, c=3)print a.bprint a.g

Page 22: Python client api

Data Entry v5

class Entry(object): def __init__(self, a, b, c): self.a = a self.b = b self.c = c

Page 23: Python client api

Data Entry v6

from collections import namedtupleEntry = namedtuple("Entry", "a b c")a = Entry(a=1, b=2, c=3)

Page 24: Python client api

Data Entry v7

class Entry(namedtuple("Entry", "a b c")): def __new__(cls, a=None, b=None, c=None): return super(Entry, cls).__new__(cls, a, b, c)

Page 25: Python client api

谢谢!

Page 26: Python client api

REFERENCE

•Etsy-python https://github.com/mcfunley/etsy-python•Lambda Picturehttp://www.flickr.com/photos/rofi/2097239111/