Skip to content

Commit 09f9886

Browse files
committed
add python example
1 parent fed3cc1 commit 09f9886

7 files changed

Lines changed: 389 additions & 1 deletion

File tree

‎README.md‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
emchat-server-examples
22
======================
33

4-
包含了环信服务器端API的示例代码, 请参考相应的子目录
4+
包含了环信服务器端API的示例代码, 请参考相应的子目录
5+
6+
本项目使用了一个测试的账号, 具体信息如下
7+
8+
appkey: easemob-playground#test1
9+
企业管理员账号: zhangjianguo
10+
企业管理员密码: zhangjianguo
11+
12+
client_id: YXA6wDs-MARqEeSO0VcBzaqg5A
13+
client_secret: YXA6JOMWlLap_YbI_ucz77j-4-mI0JA
14+
15+
app管理员账号: testuser1
16+
app管理员密码: testuser1

‎emchat-server-nodejs/README.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## 环信服务器端实例代码
2+
3+
本项目使用[Gradle](http://gradle.org)进行构建, 可以直接导入到IDE中, 例如
4+
5+
### 导入到eclipse中:
6+
7+
在命令行中运行
8+
9+
gradlew.bat eclipse
10+
11+
这个命令会生成eclipse的项目文件, 然后可以通过eclipse的import工具导入
12+
13+
### 导入到Intellij中:
14+
15+
在命令行运行
16+
17+
gradlew.bat idea
18+
19+
然后直接在Intellij中打开这个项目
20+
21+
### 获取本项目的所有依赖
22+
23+
我们建议您使用 [maven](http://maven.apache.org) 或者 [gradle](http://gradle.org) 来构建您的服务器项目,
24+
如果您没有使用上面的工具, 而是自己手工管理所依赖的jar包的话, 可以使用下面的命令来得到本项目使用到的jar包
25+
26+
27+
gradlew.bat distZip
28+
29+
这个会在 _build/distributions_ 目录下生成一个 easemob-server-example.zip 文件, 里面包含了本项目的所有依赖
30+
31+
### 直接编译
32+
33+
在命令行中运行
34+
35+
gradlew.bat clean compile
36+
37+
38+
39+

‎emchat-server-php/README.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## 环信服务器端实例代码
2+
3+
本项目使用[Gradle](http://gradle.org)进行构建, 可以直接导入到IDE中, 例如
4+
5+
### 导入到eclipse中:
6+
7+
在命令行中运行
8+
9+
gradlew.bat eclipse
10+
11+
这个命令会生成eclipse的项目文件, 然后可以通过eclipse的import工具导入
12+
13+
### 导入到Intellij中:
14+
15+
在命令行运行
16+
17+
gradlew.bat idea
18+
19+
然后直接在Intellij中打开这个项目
20+
21+
### 获取本项目的所有依赖
22+
23+
我们建议您使用 [maven](http://maven.apache.org) 或者 [gradle](http://gradle.org) 来构建您的服务器项目,
24+
如果您没有使用上面的工具, 而是自己手工管理所依赖的jar包的话, 可以使用下面的命令来得到本项目使用到的jar包
25+
26+
27+
gradlew.bat distZip
28+
29+
这个会在 _build/distributions_ 目录下生成一个 easemob-server-example.zip 文件, 里面包含了本项目的所有依赖
30+
31+
### 直接编译
32+
33+
在命令行中运行
34+
35+
gradlew.bat clean compile
36+
37+
38+
39+

‎emchat-server-python/README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 环信服务器端实例代码
2+
3+
本实例使用了[request](http://docs.python-requests.org/en/latest/)类库来调用环信的REST API, 在运行本示例代码之前, 请先参考[这里](http://docs.python-requests.org/en/latest/user/install/)安装.
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
__author__ = 'stliu'
4+
5+
import requests
6+
import json
7+
from time import time
8+
from requests.auth import AuthBase
9+
import string
10+
import random
11+
12+
JSON_HEADER = {'content-type': 'application/json'}
13+
EASEMOB_HOST = "https://a1.easemob.com"
14+
15+
DEBUG = False
16+
17+
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
18+
"""用来随机生成用户名, 仅仅用来测试用的"""
19+
return ''.join(random.choice(chars) for _ in range(size))
20+
21+
def parse_appkey(appkey):
22+
"""解析appkey, 从中得到org和app, 注意, appkey的规则是 {org}#{app}"""
23+
return tuple(appkey.split('#'))
24+
25+
def post(url, payload, auth=None):
26+
r = requests.post(url, data=json.dumps(payload), headers=JSON_HEADER, auth=auth)
27+
return http_result(r)
28+
29+
30+
def get(url, auth=None):
31+
r = requests.get(url, headers=JSON_HEADER, auth=auth)
32+
return http_result(r)
33+
34+
35+
def delete(url, auth=None):
36+
r = requests.delete(url, headers=JSON_HEADER, auth=auth)
37+
return http_result(r)
38+
39+
40+
def http_result(r):
41+
if DEBUG:
42+
error_log = {
43+
"method": r.request.method,
44+
"url": r.request.url,
45+
"request_header": dict(r.request.headers),
46+
"response_header": dict(r.headers),
47+
"response": r.text
48+
}
49+
if r.request.body:
50+
error_log["payload"] = r.request.body
51+
print json.dumps(error_log)
52+
53+
if r.status_code == requests.codes.ok:
54+
return True, r.json()
55+
else:
56+
return False, r.text
57+
58+
59+
class Token:
60+
"""表示一个登陆获取到的token对象"""
61+
def __init__(self, token, exipres_in):
62+
self.token = token
63+
self.exipres_in = exipres_in + int(time())
64+
65+
def is_not_valid(self):
66+
"""这个token是否还合法, 或者说, 是否已经失效了, 这里我们只需要
67+
检查当前的时间, 是否已经比或者这个token的时间过去了exipreis_in秒
68+
69+
即 current_time_in_seconds < (expires_in + token_acquired_time)
70+
"""
71+
return time() > self.exipres_in
72+
73+
class EasemobAuth(AuthBase):
74+
"""环信登陆认证的基类"""
75+
76+
def __call__(self, r):
77+
r.headers['Authorization'] = 'Bearer ' + self.get_token()
78+
return r
79+
80+
def get_token(self):
81+
"""在这里我们先检查是否已经获取过token, 并且这个token有没有过期"""
82+
if (self.token is None) or (self.token.is_not_valid()):
83+
self.token = self.acquire_token() #refresh the token
84+
return self.token.token
85+
86+
def acquire_token(self):
87+
"""真正的获取token的方法, 返回值是一个我们定义的Token对象
88+
这个留给子类去实现
89+
"""
90+
pass
91+
92+
class AppClientAuth(EasemobAuth):
93+
"""使用app的client_id和client_secret来获取app管理员token"""
94+
def __init__(self, org, app, client_id, client_secret):
95+
super(AppClientAuth, self).__init__()
96+
self.client_id = client_id
97+
self.client_secret = client_secret
98+
self.url = EASEMOB_HOST+("/%s/%s/token" % (org, app))
99+
self.token = None
100+
101+
def acquire_token(self):
102+
"""
103+
使用clieng_id / client_secret来获取token, 具体的REST API为
104+
105+
POST /{org}/{app}/token {'grant_type':'client_credentials', 'client_id':'xxxx', 'client_secret':'xxxxx'}
106+
"""
107+
payload = {'grant_type':'client_credentials', 'client_id': self.client_id, 'client_secret': self.client_secret}
108+
success, result = post(self.url, payload)
109+
if success:
110+
return Token(result['access_token'], result['expires_in'])
111+
else:
112+
# throws exception
113+
pass
114+
115+
class AppAdminAccountAuth(EasemobAuth):
116+
"""使用app的管理员账号和密码来获取token"""
117+
def __init__(self, org, app, username, password):
118+
super(AppAdminAccountAuth, self).__init__()
119+
self.username = username
120+
self.password = password
121+
self.url = EASEMOB_HOST+("/%s/%s/token" % (org, app))
122+
self.token = None
123+
124+
def acquire_token(self):
125+
"""
126+
使用 username / password 来获取token, 具体的REST API为
127+
128+
POST /{org}/{app}/token {'grant_type':'password', 'username':'xxxx', 'password':'xxxxx'}
129+
130+
这里和上面使用client_id不同的是, grant_type的类型是password, 然后还需要提供username和password
131+
"""
132+
payload = {'grant_type':'password', 'username': self.username, 'password': self.password}
133+
success, result = post(self.url, payload)
134+
if success:
135+
return Token(result['access_token'], result['expires_in'])
136+
else:
137+
# throws exception
138+
pass
139+
140+
141+
class OrgAdminAccountAuth(EasemobAuth):
142+
"""使用org的管理员账号和密码来获取token,
143+
和上面不同的是, 这里获取的是整个org的管理员账号,
144+
所以并没有appkey的概念
145+
146+
并且, 因为没有appkey的概念, 所以, URL也不相同,
147+
这里使用的URL是 https://a1.easemob.com/management/token
148+
149+
而app级别的token都是从 https://a1.easemob.com/{org}/{app}/token
150+
这个URL去获取的
151+
"""
152+
def __init__(self, username, password):
153+
super(OrgAdminAccountAuth, self).__init__()
154+
self.username = username
155+
self.password = password
156+
self.url = EASEMOB_HOST+"/management/token"
157+
self.token = None
158+
159+
def acquire_token(self):
160+
"""
161+
使用 username / password 来获取token, 具体的REST API为
162+
163+
POST /management/token {'grant_type':'password', 'username':'xxxx', 'password':'xxxxx'}
164+
"""
165+
payload = {'grant_type':'password', 'username': self.username, 'password': self.password}
166+
success, result = post(self.url, payload)
167+
if success:
168+
return Token(result['access_token'], result['expires_in'])
169+
else:
170+
# throws exception
171+
pass
172+
173+
174+
175+
def register_new_user(org, app, auth, username, password):
176+
"""注册新的app用户
177+
POST /{org}/{app}/users {"username":"xxxxx", "password":"yyyyy"}
178+
"""
179+
payload = {"username":username, "password":password}
180+
url = EASEMOB_HOST+("/%s/%s/users" % (org, app))
181+
return post(url, payload, auth)
182+
183+
def delete_user(org, app, auth, username):
184+
"""删除app用户
185+
DELETE /{org}/{app}/users/{username}
186+
"""
187+
url = EASEMOB_HOST+("/%s/%s/users/%s" % (org, app, username))
188+
return post(url, payload, auth)
189+
190+
191+
192+
if __name__ == '__main__':
193+
#测试数据
194+
f = file("../info.json")
195+
s = json.load(f)
196+
appkey = s['appkey']
197+
org, app = parse_appkey(appkey)
198+
org_admin_username = s['admin']['username']
199+
org_admin_password = s['admin']['password']
200+
client_id = s['app']['credentials']['client_id']
201+
client_secret = s['app']['credentials']['client_secret']
202+
app_admin_username = s['app']['admin']['username']
203+
app_admin_password = s['app']['admin']['password']
204+
# org_admin的认证方式
205+
org_admin_auth = OrgAdminAccountAuth(org_admin_username,org_admin_password)
206+
# 获取org管理员的token
207+
print "Get org admin token: " + org_admin_auth.get_token()
208+
# 获取app管理员的token
209+
app_admin_auth = AppAdminAccountAuth(org, app, app_admin_username, app_admin_password)
210+
print "Get app admin token:" + app_admin_auth.get_token()
211+
# 通过client id和secret来获取app管理员的token
212+
app_client_auth = AppClientAuth(org, app, client_id, client_secret)
213+
print "Get app admin tokey with client id/secret: " + app_client_auth.get_token()
214+
215+
print "now let's register some users...."
216+
app_users = []
217+
for i in range(10):
218+
username = id_generator()
219+
220+
password = '123456'
221+
success, result = register_new_user(org, app, app_admin_auth, username, password)
222+
if success:
223+
print "registered new user %s in appkey[%s]" % (username, appkey)
224+
app_users.append(username)
225+
else:
226+
print "failed to register new user %s in appkey[%s]" % (username, appkey)
227+
228+
print "now let's delete users just created, this time we're using app_client_auth"
229+
230+
for username in app_users:
231+
success, result = delete_user(org, app,app_client_auth, username)
232+
if success:
233+
print "user %s is deleted"
234+
else:
235+
print "failed to delete user %s"
236+

‎emchat-server-ruby/README.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## 环信服务器端实例代码
2+
3+
本项目使用[Gradle](http://gradle.org)进行构建, 可以直接导入到IDE中, 例如
4+
5+
### 导入到eclipse中:
6+
7+
在命令行中运行
8+
9+
gradlew.bat eclipse
10+
11+
这个命令会生成eclipse的项目文件, 然后可以通过eclipse的import工具导入
12+
13+
### 导入到Intellij中:
14+
15+
在命令行运行
16+
17+
gradlew.bat idea
18+
19+
然后直接在Intellij中打开这个项目
20+
21+
### 获取本项目的所有依赖
22+
23+
我们建议您使用 [maven](http://maven.apache.org) 或者 [gradle](http://gradle.org) 来构建您的服务器项目,
24+
如果您没有使用上面的工具, 而是自己手工管理所依赖的jar包的话, 可以使用下面的命令来得到本项目使用到的jar包
25+
26+
27+
gradlew.bat distZip
28+
29+
这个会在 _build/distributions_ 目录下生成一个 easemob-server-example.zip 文件, 里面包含了本项目的所有依赖
30+
31+
### 直接编译
32+
33+
在命令行中运行
34+
35+
gradlew.bat clean compile
36+
37+
38+
39+

0 commit comments

Comments
 (0)