一、开发环境搭建

1、安装python

请在python官网下载根据机器选择下载python2.7.14。参考链接https://www.python.org/downloads/release/python-2714/。x86 64位机器下载地址(https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi)

请将python目录安装在当前用户拥有可写目录下。windows系统用户建议装在除C盘外的其他盘。

将python的目录以及脚本目录添加至环境变量中。

例如:将python安装在E:\Python27

则将当前目录E:\Python27与脚本目录E:\Python27\Scripts添加至环境变量中。

2、安装ulord平台层SDK

git clone https://github.com/UlordChain/py-ulord-api.git

cd py-ulord-api

python setup.py install

二、SDK调用

1、角色确定

根据个人开发能力确定角色。SDK分为初级开发用户和中级开发用户两种。初级开发用户SDK帮助其创建了基本的数据库,涵盖用户表,资源表,标签表。开发者可以通过修改配置去修改数据库连接。由于使用flask-sqlalchemy所以支持大部分关系型数据库,包括mysql,sqlite,oracle,postgresql等等。默认使用sqlite。而中级开发者没有数据库创建的操作,他所拥有的功能仅仅是对平台层资源上链所需的http接口封装以及资源上传至UDFS的接口封装。

以初级开发者开发博客为例:

导入初级开发者类

from ulordapi.user import Junior

创建一个初级发开者实例,appkey与secret都是需要你在ulord平台注册用户并创建应用程序所生成的。如果你是ulord平台用户并且创建了一个应用,平台会返回给你一个appkey与secret。这是在ulord平台开发所必不可少的东西。

junior = Junior(appkey="8326648868ad11e8b894fa163e37b4c3", secret="8326648968ad11e8b894fa163e37b4c3")

2、配置修改

SDK支持配置文件直接修改以及通过接口进行修改。配置文件会在初次运行时在

以python接口修改为例,在创建初级开发者实例之后,可以根据自己的需要将配置写成一个字典传入config_edit方法中。

代码示例:

blog_config = {

'baseconfig':{

'config_file':'E:\ulord\ulord-blog-demo\config'

},

'logconfig':{

'log_file_path': "E:\ulord\ulord-blog-demo\junior.log"

}

}

junior.config_edit(blog_config)

3、创建数据库

在当前目录下创建数据库,初级开发者提供创建数据库接口,参数为数据库位置。

代码示例:

dbpath = os.getcwd()

junior.create_database(dbpath)

4、用户验证

用户验证采用token 的形式,用户登录注册都会生成一个有生效时限的token。用户在登出时会重新刷新token的是生效时限。所有接口都需要在head中传入token信息。

代码示例:

def auth_login_required():

head_token = request.headers.get('token')

if not head_token:

return {

'errcode':60103,

'reason': "需要token"

}

login_user = User.query.filter_by(token=head_token).first()

if not login_user:

return return_result(60104)

if int(login_user.timestamp) < time.time():

return return_result(60104)

return login_user

5、创建对应web接口

根据业务需求创建所需的web接口。博客案例使用flask模块开发。你也可以使用其他web开发框架进行开发。

5.1、获取公钥

信息加密采用RSA加密方式,后台SDK会在初次调用时生成一对密钥对,前端发送数据时先获取公钥对数据进行加密,然后输出加密信息,后台收到后用私钥进行解密。

注意1:相同数据用相同公钥加密会得到不同结果,用对应的私钥均可解密。

注意2:SDK加密需要加密之后通过base64编码进行编码。前端RSA加密工具jsencrypt已在内部实现编码,所以不要再进行编码。

形成一个get接口获取公钥,一个post接口验证加密信息。前端通过get接口回去公钥,用公钥加密后通过post接口验证是否加密成功。

代码示例:

@app.route('/user/password', methods=['GET', 'POST'])

def get_pubkey():

log.info("start get password")

if request.method == 'GET':

return jsonify(return_result(0, result={"pubkey":junior.rsahelper.pubkeybytes}))

elif request.method == 'POST':

message = request.json.get("password")

return jsonify(return_result(0, result={'password': junior.rsahelper._encry(message)}))

5.2、加密数据

实现该web接口便于开发阶段的测试。

代码示例:

@app.route('/user/encrypt',methods=['POST'])

def encrypt():

messages = request.json.get("messages")

result = {}

for message in messages:

message = message.encode('utf-8')

result.update({

message:junior.rsahelper._encry(message)

})

return jsonify(result)

5.3、用户注册

通过调用SDK的注册功能完成。初级开发者调用user_regist接口,中级开发者调用regist接口完成用户注册。

代码示例:

@app.route('/user/regist',methods=['POST'])

def regist():

username = request.json.get('username')

password = request.json.get('password')

cellphone = request.json.get('cellphone')

email = request.json.get('email')

if username is None or password is None:

return jsonify(return_result(60100))

args = junior.decrypt([username, password, cellphone, email])

if args:

result = junior.user_regist(username=args[0],password=args[1],cellphone=args[2],email=args[3])

return jsonify(result)

else:

return jsonify(return_result(60100))

5.4、优惠活动

新注册的用户通过开发者赠送其一定量的ulord。该接口调用成功前提为开发者拥有一定数量的ulord。为每位新注册的用户赠送指定数量的ulord(默认为10,可以修改配置文件中的webconfig的amount,同时activity字段控制是否开启赠送活动。)初级开发者调用user_activity接口实现,中级开发者调用paytouser接口实现。

代码示例:

@app.route('/user/activity', methods=['GET'])

def activity():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

return jsonify(junior.user_activity(current_user.token))

5.5、用户登录

用户登录验证用户名密码,成功之后刷新token的有效时限。初级开发者调用user_login接口,中级开发者无此接口。

代码示例:

@app.route('/user/login',methods=['POST'])

def login():

username = request.json.get('username')

password = request.json.get('password')

if username is None or password is None:

return jsonify({

'errcode': 60100,

'reason': "缺少参数"

})

username = junior.decrypt(username)

return jsonify(junior.user_login(username=username, password=password,encrypted=True))

5.6、用户登出

用户登出将token的过期时间设置为过去的一秒。即失效。初级开发者调用user_logout接口,中级开发者无此接口。

代码示例:

@app.route('/user/logout',methods=['POST','GET'])

def logout():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

return jsonify(junior.user_logout(current_user.token))

5.7、博客发布

用户将博客发布到链上,内容将上传至UDFS上,获得一个UDFS的哈希值,ulord链存储博客的简介以及费用说明等相关信息。初级开发者调用udfs_upload接口resource_publish接口,中级开发者调用udfs_upload接口与publish接口。udfs_uplord负责将内容上传至UDFS接口,获得的哈希值组成发布字段传入发布接口中。

示例代码如下:

@app.route('/blog/publish',methods=['POST'])

def blog_publish():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

title = request.json.get('title')

body = request.json.get('body')

amount = request.json.get('amount')

tags = request.json.get('tag')

description = request.json.get('description')

body_hash = junior.udfs_upload([body])

if body_hash and body_hash.get(body):

return jsonify(junior.resource_publish(title=title, udfshash=body_hash.get(body),amount=amount,tags=tags,des=description,

usercondition={'usertoken':current_user.token}))

else:

return jsonify(return_result(errcode=60400))

5.8、博客更新

用户将博客信息进行更新,如果更新内容则需要重新将新内容上传至UDFS平台获取哈希值再更新链上字段值。所需参数为用户密码与博客在平台数据库中的ID值,以及所需更新的值。初级开发者使用resource_update接口,中级开发者直接调用update接口。

代码示例:

def blog_update():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

id = request.json.get('id')

if id:

try:

id = str(id)

except:

return return_result(60100)

pay_password = request.json.get('password')

if not id and not pay_password:

return jsonify(return_result(60100))

title = request.json.get('title')

body = request.json.get('body')

amount = request.json.get('amount')

tags = request.json.get('tag')

description = request.json.get('description')

return jsonify(junior.resource_update(id=id,pay_password=pay_password,encrypted=True,title=title,body=body,price=amount,tags=tags,des=description))

5.9、博客删除

只是将链上的数据进行重定向。初级开发者与中级开发者均调用delete接口进行博客的删除,所需参数为博客的平台数据ID和用户密码。

示例代码如下:

@app.route('/blog/delete', methods=['POST'])

def blog_delete():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

id = request.json.get('id')

password = request.json.get('password')

if not id and not password:

return return_result(60100)

password = junior.decrypt(password)

if not current_user.verify_password(password):

return jsonify(return_result(60003))

return jsonify(junior.delete(id, current_user.pay_password))

5.10、获取博客列表

获取所有博客信息,该信息为应用所有资源数据列表。返回资源的基本信息列表。初级开发者与中级开发者使用queryresource接口实现。

示例代码如下:

@app.route('/blog/all/list',methods=['POST'])

def blog_list():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

try:

page = request.json.get('page')

num = request.json.get('num')

except:

page = 1

num = 10

if not page:

page = 1

if not num:

num = 10

return jsonify(junior.queryresource(page, num))

5.11、根据ID查询博客信息

根据ID去查询博客的相关信息。开发者使用query_resource_by_ID去实现。

示例代码如下:

@app.route('/blog/condition/id',methods=['POST'])

def blog_list_by_ID():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

ids = request.json.get('ids')

if not ids and not isinstance(ids, list):

return jsonify(return_result())

return jsonify(junior.query_resourc_by_ID(ids))

5.11、查询资源是否已经购买

查询当前用户是否已经购买过该资源。通过调用checkisbought接口实现。

示例代码如下:

@app.route('/blog/isbought',methods=['POST'])

def check_bought():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

claim_ids = request.json.get('claim_ids')

if claim_ids is None:

return jsonify({

'errcode': 60100,

'reason': '缺少参数'

})

return jsonify(junior.checkisbought(current_user.wallet, claim_ids))

5.12、添加博客浏览量

仅支持初级开发者。初级开发者调用resource_views接口实现。前端调用该接口为对应的数据库访问添加1。

示例代码如下:

@app.route('/blog/views',methods=['POST'])

def add_views():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

title = request.json.get('title')

if title is None:

return jsonify({

'errcode': 60100,

'reason': '缺少参数'

})

# add blog views

return jsonify(junior.resouce_views(title))

5.13、用户支付博客

用户支付博客。用户根据博客信息支付对应的价格,购买成功后返回给用户哈希值,初级开发者通过调用pay_resources接口实现,中级开发者通过调用transaction接口实现。

@app.route('/pay/blogs',methods=['POST'])

def pay_blogs():

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

password = request.json.get('password')

claim_id = request.json.get('claim_id')

if password is None or claim_id is None:

return jsonify({

'errcode':60100,

'reason':"缺少参数"

})

return jsonify(junior.pay_resources(current_user, claim_id, password, encrypted=True))

5.14、用户获得广告收益

用户浏览广告会的到广告费用,广告由用户通过发布接口发布,价格为负数即为广告,广告主需要支付给浏览者一定数量的ulord。初级开发者通过调用pay_ads接口实现。中级开发者通过调用transaction接口实现。

示例代码如下:

@app.route('/pay/ads',methods=['POST'])

def pay_ads():

"""

get ulord from ads

:return: ads hash

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

claim_id = request.json.get('claim_id')

authorname = request.json.get('author')

if claim_id is None or authorname is None:

return jsonify({

'errcode': 60100,

'reason': "缺少参数"

})

return jsonify(junior.pay_ads(current_user.wallet, claim_id, authorname))

5.15、用户获得账号信息

此功能仅为初级开发者才支持实现,通过调用user_info_query接口实现。

示例代码如下:

@app.route('/user/info',methods=['GET'])

def get_userinfo():

"""

get user infor

:return: dict.User information

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

return jsonify(junior.user_info_query(token=current_user.token))

5.16、用户获得余额信息

获取用户的余额信息,在区块链中,由于区块是需要被确认的,所以余额拥有总余额,已确认余额,未确认余额,未成熟的余额四个部分,讲以字典的形式返回。开发者可以通过调用querybalance接口实现。

示例代码如下:

@app.route('/user/balance',methods=['GET'])

def get_userbalance():

"""

get user balance

:return: user balance

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

return jsonify(junior.querybalance(payer=current_user.wallet, pay_password=current_user.pay_password))

5.16、用户获取发布过的内容

用户获取自己所发布过的内容列表。开发者调用queryuserpublished接口实现。

示例代码如下:

@app.route('/user/published',methods=['POST'])

def get_userpublished():

"""

get blog list the user has published

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

try:

page = request.json.get('page')

num = request.json.get('num')

category = request.json.get('category')

except:

page = 1

num = 10

if not page:

page = 1

if not num:

num = 10

return jsonify(junior.queryuserpublished(current_user.wallet, page, num))

5.17、用户获取发布过的内容总数

用户获取发布过的内容总数。开发者调用ulord_published_num实现。

示例代码如下:

@app.route('/user/published/num',methods=['GET'])

def get_userpublishednum():

"""

get the num of the blogs that user has published

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

return jsonify(junior.ulord_published_num(current_user.wallet))

5.18、用户获取账单

用户获取账单信息,涵盖用户的两种角色的总计四种收支情况,涵盖作为消费者的支出(浏览收费资源)与收入(浏览广告),作为发布者的支出(发布广告)与收入(发布收费资源)四种情况。开发者可以通过调用querybillings接口实现。

示例代码如下:

@app.route('/user/billings',methods=['POST'])

def get_billings():

"""

query user's billing

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

sdate = request.json.get('sdate')

edate = request.json.get('edate')

if not sdate or not edate:

return jsonify(return_result(60100))

return jsonify(junior.querybillings(current_user.wallet, sdate, edate))

5.19、用户获取账单详情

用户获取收支账单详情。列出用户的每条消费记录,用户作为发布者(即消费记录中auther为当前用户),价格为正时表示资源收入,价格为负时表示广告支出。与此相反,如果用户作为消费者(即消费记录中auther不是当前用户),价格为正时表示资源支出,价格为负时表示广告收入。这一部分逻辑需要前端整理清楚方便展示。开发者通过调用querybillingsdetail接口实现功能。

示例代码如下:

@app.route('/user/billings/details',methods=['POST'])

def get_billingsdetail():

"""

query user billing detail

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

try:

page = request.json.get('page')

num = request.json.get('num')

except:

page = 1

num = 10

if not page:

page = 1

if not num:

num = 10

return jsonify(junior.querybillingsdetail(current_user.wallet, page, num))

5.20、用户获取收入账单

用户获取收入的账单详情,列出用户作为消费者点击广告的收入以及作为发布者他人浏览收费资源收到的费用。开发者通过调用queryincomebillings接口实现这部分功能。

示例代码如下:

@app.route('/user/billings/income',methods=['POST'])

def get_incomebillings():

"""

get user income billing information

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

try:

page = request.json.get('page')

except:

page = 1

try:

num = request.json.get('num')

except:

num = 10

try:

category = request.json.get('category')

except:

category = 2

sdate = request.json.get('sdate')

edate = request.json.get('edate')

if not page:

page = 1

if not num:

num = 10

if not category:

category = 2

if not sdate or not edate:

return jsonify(return_result(60100))

return jsonify(junior.queryincomebillings(current_user.wallet, sdate, edate, page, num, category=category))

5.21、用户获取支出账单

与用户获取收入账单相似,此功能为用户获取支出账单。包含用户作为消费者点击收费资源的支出以及作为发布者发布广告的支出。(注意:用户作为发布者发布广告时定价之后浏览者点击后会从发布者账户扣除对应费用转到浏览者账户中)。开发者通过调用queryoutgobillings接口实现功能。

示例代码如下:

@app.route('/user/billings/outgo',methods=['POST'])

def get_expensebillings():

"""

get user expense billing information

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

try:

page = request.json.get('page')

except:

page = 1

try:

num = request.json.get('num')

except:

num = 10

try:

category = request.json.get('category')

except:

category = 2

sdate = request.json.get('sdate')

edate = request.json.get('edate')

if not page:

page = 1

if not num:

num = 10

if not category:

category = 2

if not sdate or not edate:

return jsonify(return_result(60100))

return jsonify(junior.queryoutgobillings(current_user.wallet, sdate, edate ,page, num, category=category))

5.22、用户修改信息

用户修改个人信息,包括用户密码,用户手机号与邮箱。该功能仅支持初级开发者用户,初级开发者通过调用user_infor_modify实现功能。这部分操作主要是修改本地数据库内容,所以中级开发者需要自己实现。

@app.route('/user/modify',methods=['POST'])

def modify_userinfo():

"""

Delete modify username.It will make publish error

"""

current_user = auth_login_required() # check token

if type(current_user) is dict:

return jsonify(current_user)

# change demand: cann't change username

# username = request.json.get('username')

password = request.json.get('password')

cellphone = request.json.get('cellphone')

email = request.json.get('email')

new_password = request.json.get('new_password')

if not password:

# missing arguments

return jsonify({

'errcode': 60100,

'reason': '缺少参数'

})

if cellphone:

cellphone = junior.decrypt(cellphone)

if email:

email = junior.decrypt(email)

return jsonify(junior.user_infor_modify(username=current_user.username, encrypted=True, password=password,cellphone=cellphone,email=email,new_password=new_password))

python如何使用sdk_如何使用SDK开发一个博客相关推荐

  1. Django完整的开发一个博客系统

    今天花了一些时间搭了一个博客系统,虽然并没有相关于界面的美化,但是发布是没问题的. 开发环境 操作系统:windows 7 64位 Django: 1.96 Python:2.7.11 IDE: Py ...

  2. 如何快速开发一个博客

    https://hexo.io/zh-cn/ https://wordpress.org/ https://www.gohugo.org/ https://vuepress.vuejs.org/zh/ ...

  3. 【Python】100行Python代码轻松开发个人博客

    ❝ 本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes ❞ 1 简介 这是我的系列教程「Python+Dash ...

  4. Python Flask框架-开发简单博客-认证蓝图

    作者:Eason_LYC 悲观者预言失败,十言九中. 乐观者创造奇迹,一次即可. 一个人的价值,在于他所拥有的.可以不学无术,但不能一无所有! 技术领域:WEB安全.网络攻防 关注WEB安全.网络攻防 ...

  5. 安卓开发实战,用华为HMS MLKit 图像分割 SDK开发一个证件照DIY小程序

    文章目录 引子 ==**核心提示:此SDK免费,安卓全机型覆盖!**== 证件照DIY开发实战 1 开发准备 1.1 在项目级gradle里添加华为maven仓 1.2 在应用级的build.grad ...

  6. Flask开发轻博客(一):欢迎来到-Flask-的世界

    作者:chen_h 微信号 & QQ:862251340 微信公众号:coderpai 目录 Flask开发轻博客(一):欢迎来到 Flask 的世界 Flask开发轻博客(二):Flask ...

  7. Microsoft .NET Compact Framework 开发常见问题解答 - 专注.NET技术及其相关应用开发! - 博客园...

    Microsoft .NET Compact Framework 开发常见问题解答 发布日期: 3/30/2005 | 更新日期: 3/30/2005 Microsoft .NET Compact F ...

  8. 一周开发一个轻量级客服系统(代码开源)

    文章目录 前言 一.聊天系统为什么使用短连接? 二.技术方案 后端技术方案: 前端技术方案 原生端 三.代码详细设计 1.数据库设计 2.后端程序 3.前端程序 四.效果展示 五.源码-GitHub ...

  9. Flask开发轻博客(一):欢迎来到 Flask 的世界

    目录 Flask开发轻博客(一):欢迎来到 Flask 的世界 Flask开发轻博客(二):Flask 模板 Flask开发轻博客(三):Flask 的 Web 表单 Flask开发轻博客(四):数据 ...

最新文章

  1. 使用Python,OpenCV计算图像直方图(cv2.calcHist)
  2. SAP 电商云 Spartacus UI 单元测试的依赖隔离设置举例
  3. maven与spring_与Spring和Maven签约首个SOAP服务
  4. Mask R-CNN论文理解
  5. python-类的基本知识
  6. Redhat linux 5.3 基于bond的heartbeat
  7. 源商城系统V1.0仿卡盟
  8. Django 3实战: 仿链家二手房信息查询网(附GitHub源码) - 文末有送书活动啦!
  9. .NET:持续进化的统一开发平台
  10. [个人笔记]FDTD100
  11. 24点游戏开发实例(Qt含源码)
  12. linux 查看 man 路径配置文件 man.config,linux中的man(zz)
  13. Laravel 5.5 注册登录
  14. 2016基于百度地图定位
  15. PCB设计电源平面处理要点
  16. 贵州学计算机,在贵州省计算机学校学习计算机专业如何?
  17. Java生成word文档|综合
  18. 咨询答疑:从产品设计到康威定律
  19. KB,Kb单位换算,网络带宽中的Kbps和KB/s到底是什么意思?
  20. win7系统备份还原软件_易数一键还原是一款免费的、功能强大的备份还原软件,支持EFI架构的操作系统和安全启动。...

热门文章

  1. 中文编程软件-习语言2013版 发布啦
  2. matlab踩坑 自带surf 函数找不了 surf 作为函数执行
  3. kafka外网映射 公司有公网ip kafka外网访问 kafka外网配置
  4. UDN_CanvasHUD
  5. java-php-python-ssm政府机关门禁管理系统计算机毕业设计
  6. 25款最佳响应式HTML5前端开发框架
  7. [MySQL]-压力测试之Sysbench
  8. mysql 占用cpu过高
  9. 【经验之谈】一个已婚男人分享找老婆的经验!
  10. 微型计算机怎么没声音,电脑没有声音是怎么回事 电脑失声怎么解决【解决方法】...