26

Click here to load reader

Python client api

Embed Size (px)

DESCRIPTION

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

Citation preview

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/