树莓派播放音频

播放一个MP3文件,在命令行终端上用“cd”命令导航到.mp3文件所在的路径,然后输入以下命令:

omxplayer example.mp3

如果你没有听到任何声音,请确认你的耳机或者音箱已经正确连接上。注意omxplayer不使用ALSA(高级Linux声音体系),因此可以忽略audio Configuration中通过raspi-config或者amixer的设置。

如果omxplayer自动识别当前音频输出设备错误,你可以使用以下命令强制使用HDMI输出:

omxplayer -o hdmi example.mp3

或者你也可以强制使用耳机接口输出:

omxplayer -o local example.mp3

控制命令:

Key    Action  
2      加速  
1      减速  
j      上一条音轨  
k      下一条音轨  
i      上一节  
o      下一节  
n      上一条字幕轨  
m      下一条字幕轨  
s      显示/不显示字幕  
q      退出  
空格或p  暂停/继续  
-      减小音量  
+      增加音量  
左      后退30  
右      前进30  
上      后退600  
下      前进600  

 

 

引用地址:http://blog.csdn.net/qinxiandiqi/article/details/39155593

树莓派GPIO输入、输出控制

树莓派输入引脚控制输出引脚状态

#!/usr/bin/env python
# encoding: utf-8

import RPi.GPIO
#import RPi.GPIO as GPIO(重新命名引入库名字,减少文字输入)
import time

# 指定GPIO口的选定模式为GPIO引脚编号模式(而非主板编号模式)
RPi.GPIO.setmode(RPi.GPIO.BCM)

# 指定GPIO14(就是LED长针连接的GPIO针脚)的模式为输出模式
# 如果上面GPIO口的选定模式指定为主板模式的话,这里就应该指定8号而不是14号。
RPi.GPIO.setup(14, RPi.GPIO.OUT)
RPi.GPIO.setup(15, RPi.GPIO.IN, pull_up_down=RPi.GPIO.PUD_DOWN)#为输入引脚配置初始值,防止引脚悬空时抖动引起的电平变化



while True:
    if(RPi.GPIO.input(15) == 1):
        print("LED已开启!")
        RPi.GPIO.output(14, True)
    elif(RPi.GPIO.input(15) == 0):
        print("LED已关闭!")
        RPi.GPIO.output(14, False)

 

用flask框架搭建树莓派控制LED

最近做了个小玩意,在树莓派上搭建了一个简易的flask框架来控制led的开、关。

之前不太熟悉flask的搭建,代码写的乱糟糟的,功能跑通,代码将就着看吧。

树莓派需要安装三个组件
1、python运行环境

2、python-GPIO驱动库

3、flask框架

$ pip install flask

效果视频如下,代码在最后

乱糟糟的代码块


#!/usr/bin/env python
# encoding: utf-8

from flask import Flask
from flask import request


import RPi.GPIO
#import time

# 指定GPIO口的选定模式为GPIO引脚编号模式(而非主板编号模式)
RPi.GPIO.setmode(RPi.GPIO.BCM)

# 指定GPIO14(就是LED长针连接的GPIO针脚)的模式为输出模式
# 如果上面GPIO口的选定模式指定为主板模式的话,这里就应该指定8号而不是14号。
RPi.GPIO.setup(14, RPi.GPIO.OUT)


#RPi.GPIO.output(14, True)

app = Flask(__name__)

@app.route('/home', methods=['GET', 'POST'])
def home():
    return '<h1>Home</h1>'

@app.route('/', methods=['GET'])
def signin_form():
    return '''<form action="/signin" method="post">
              <h3>用户名:admin,密码:password</h3>
              <p><input name="username"></p>
              <p><input name="password" type="password"></p>
              <p><button type="submit">登录</button></p>
              </form>'''

@app.route('/signin', methods=['POST'])
def signin():
    # 需要从request对象读取表单内容:
    if request.form['username']=='admin' and request.form['password']=='password':
        return '''<form action="/on" method="POST">
                  <h3>请点击按钮控制LED</h3></p>
                  <button type="submit">打开LED</button>'''
    return '<h3>Bad username or password.</h3>'

@app.route('/on', methods=['POST'])
def on():
    RPi.GPIO.output(14, True)
    return '''<form action="/off" method="POST">
              <h3>请点击按钮控制LED</h3></p>
              <button type="submit">关闭LED</button>
              <h1>LED已开启</h1></p>'''

@app.route('/off', methods=['POST'])
def off():
    RPi.GPIO.output(14, False)
    return '''<form action="/on" method="POST">
              <h3>请点击按钮控制LED</h3></p>
              <button type="submit">打开LED</button>
              <h1>LED已关闭</h1></p>'''



if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

 

树莓派-python驱动GPIO

python GPIO
【开发语言】——python
【简单介绍】——该库更确切的名称为raspberry-gpio-python,树莓派官方资料中推荐且容易上手。python GPIO是一个小型的python库,可以帮助用户完成raspberry相关IO口操作。但是python GPIO库还没有支持SPI、I2C或者1-wire等总线接口。除了python GPIO之外,还有众多的python扩展库(例如webiopi),毫无疑问的说python非常适合树莓派,树莓派也非常适合python。

树莓派GPIO管脚定义
树莓派引脚定义
安装Python以及GPIO库

1、先安装python-dev,输入以下指令。

sudo apt-get install python-dev

 

2、安装RPi.GPIO,依次输入以下指令。特别说明,由于RPi.GPIO仍处于不断完善的过程中,推荐去官网下载最新代码。(本地安装)

# 下载
$ wget http://raspberry-gpio-python.googlecode.com/files/RPi.GPIO-0.5.3a.tar.gz
# 上面这句执行有可能不成功提示连接超时,原因是国内google被墙了
# 也可以直接去官网下载
# 解压缩
$ tar xvzf RPi.GPIO-0.5.3a.tar.gz
# 进入解压之后的目录
$ cd RPi.GPIO-0.5.3a
# 启动安装
$ sudo python setup.py install

3、在线安装gpio库
sudo apt-get install python-rpi.gpio

4、安装串口调试模块(也可不安装)
sudo apt-get install python-serial

示例代码一(效果视频在文章结尾)

#!/usr/bin/env python
# encoding: utf-8

import RPi.GPIO
import time

# 指定GPIO口的选定模式为GPIO引脚编号模式(而非主板编号模式)
RPi.GPIO.setmode(RPi.GPIO.BCM)

# 指定GPIO14(就是LED长针连接的GPIO针脚)的模式为输出模式
# 如果上面GPIO口的选定模式指定为主板模式的话,这里就应该指定8号而不是14号。
RPi.GPIO.setup(14, RPi.GPIO.OUT)

# 循环10次
for i in range(0, 10):
    # 让GPIO14输出高电平(LED灯亮)
    RPi.GPIO.output(14, True)
    # 持续一段时间
    time.sleep(0.5)
    # 让GPIO14输出低电平(LED灯灭)
    RPi.GPIO.output(14, False)
    # 持续一段时间
    time.sleep(0.5)

# 最后清理GPIO口(不做也可以,建议每次程序结束时清理一下,好习惯)
RPi.GPIO.cleanup()

示例代码二

# -- coding: utf-8 --
import RPi.GPIO as GPIO
import time
# BOARD编号方式,基于插座引脚编号
GPIO.setmode(GPIO.BOARD)
# 输出模式
GPIO.setup(11, GPIO.OUT)
while True:
GPIO.output(11, GPIO.HIGH)
ptime.sleep(1)
GPIO.output(11, GPIO.LOW)
time.sleep(1)

文章部分内容引用自《芒果爱吃胡萝卜》

地址http://blog.mangolovecarrot.net/2015/04/20/raspi-study01/

MVC框架在设计产品时的应用

产品汪(产品经理,业内称为产品汪)日常的工作中最多撕逼的就是程序猿(程序员,因“员”与“猿”谐音戏称“程序猿”),有人笑成汪和猿是天生一对(对手的对),这里其实更多的是产品以一产品的视角来看待产品的开发,有了需求改改就好了、很简单么,自己会coding该多好,而程序的思想是有一天不再需要coding了。

但问题的根源还是产品和开发的思维不同,如果产品用程序员的思维去写PRD,或许可以减少撕逼的过程,提高沟通效率!

那么在PRD中加入MVC框架概念,用软件工程的思维来梳理业务需求和原型设计,或许会是个比较好的方式。

如下将给大家谈谈程序开发中的MVC(Model-View-Controller)模式如何体现在产品设计中。

MVC模式作为软件工程的经典架构模式,已经被广泛应用到实际软件开发中,现在主流的开发框架(如Spring、Struts2等)都是采用了MVC的设计思想。简要介绍一下MVC模式:

【1】模型(Model):模型代表业务数据和业务规则,是应用程序的主体;

【2】视图(View):视图表示用户看到并与之交互的页面;

【3】控制器(Controller):控制器接受用户的输入,并调用模型和视图去完成用户的需求。

下面就按照我们分析需求、设计产品时考虑的点,介绍产品PRD所用的MVC模型

【1】Mode:业务数据和业务逻辑,产品考虑的是在填写表单的时候的数据类型,字段长度,哪些是必须输入的项、哪些是选填项,哪些数据是先产生、哪些是后产生的,哪些是依赖其他字段而存储的数据,这些就是模型层表现的。

【2】View:用户使用产品的入口、即界面。要考虑button、text等控件的摆放,icon的设计、配色的协调,让用户更快速的获取突出产品特点的内容。

【3】Controller:用户在填写表单的时候数据处理成功的时候跳转到什么页面、不成功提示什么错误信息,当用户从当前界面退出的时候跳转的页面是上一级界面还是其他继续需要阅览的界面,这些操作都是通过控制层去控制View而实现的。

以上就是MVC在撰写PRD时的应用,系统归纳、灵活运用,希望能对你有些帮助。

PM是产品的灵魂缔造者,面对产品要像面对自己的内心最渴望的梦想一样,坚定而执着,想尽一切办法、调动一切资源,而你需要掌握好航向,勇敢前行。

AI算法

算法定义
算法,顾名思义就是运算的法则。
在数学领域里,我们上学时老师告诉我们,1+1=2,“1”是输入的数值、“+”是运算符,“2”是结果,我们需要的是这个结果,而“+”这个运算符的运算法则就是算法,只不过这个算法比较简单,只由一个运算符组成,实际的算法要复杂得多。

算法的产生
数学上的运算符由一些数学家经过推导定义出来,总结后将运算符编进数学书籍固定下来,这我们不做过多阐述。
计算机程序的算法和数学上的运算符产生比较相似,不过高级一些。
起初程序员为了快速解决数学上的问题把数学公式编写成程序由计算机执行,这就是我们平时用的程序。程序的特性是固定下来运算法则,输入相应参数、经过运算后输出特定结果,这个过程是单一固定的,不出bug没有其他可变的结果出现。
AI(人工智能)需要的算法是需要像人类一样需要思考、需要判断、需要情感的,而这些特性是没有办法通过特定的单一过程得到的,若每种结果的产生都编写一个计算程序,显然是无法完成的任务。
人类为了尽可能的接近达到这些目标,发明了结果可变化的计算法则,特性就是“类似的输入数值经过算法计算产生类似的输出数值”,这为像人一样思考等特性提供了有可能的基础。
目前主流的类人方向研究的数据采集的算法有图像识别、声音识别等,这两种方式目前比较好的开始应用于商业。
拿图像识别中的人脸识别这一模块来说,算法实现其实并不过于复杂,分为以下几块:

1、编写从一张人脸图片中提取眼、耳、口、鼻、眉毛、及各器官的位置像素点特征值的程序
2、将这个程序的各个参数输入由卷积神经网络编写的算法生成器中,得到提取特征的算法
3、将一组图片喂给生成器并标注哪些位置是人脸检测点
4、给生成器一张之前喂过的图片并手动标注之前图片上的人脸和这张图片是同一人
5、生成器自动记录两张图片人脸位置并计算相似像素的关键点的特征值
6、重复多次这一过程,生成器找到一组规律并主动标记图片中的人脸位置并检测关键点的特征值进行比对
7、当生成器找到这一规律后即可将特征提取程序通过卷积神经网络程序重新组合成一套适用于大多数人脸特征提取的算法
8、理论上喂给生成器的人脸图片足够多可以提取人类所有面部特征用于比对,当然这一过程比较难

 

未完待续……..

【python】如何在某.py文件中调用其他.py内的函数

假设名为A.py的文件需要调用B.py文件内的C(x,y)函数

假如在同一目录下,则只需

import B
if __name__ == "__main__":
B.C(x,y)

 

若只需调用单个函数,也可以

from B import C
if __name__ == "__main__":
C(x,y)

 

若A.py和B.py位于不同的目录下,可以用以下方法

(假设B.py位于D盘的根目录下)

1.引用所在路径

import sys
sys.path.append('D:/')
import B
if __name__=="__main__":
print B.pr(x,y)

 

2.使用imp

import imp
B=imp.load_source('B','D:/B.py')
import B
if __name__=="__main__":
print B.pr(x,y)

 

python实现的json数据以HTTP GET,POST,PUT,DELETE方式页面请求

【转载】文章转载自光阴过客

一、JSON简介

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。
它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一个子集。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。
这些特性使JSON成为理想的数据交换语言。

二、HTTP的请求方法

HTTP/1.1协议中共定义了八种方法(有时也叫“动作”)来表明Request-URI指定的资源的不同操作方式:
. OPTIONS – 返回服务器针对特定资源所支持的HTTP请求方法。
也可以利用向Web服务器发送’*’的请求来测试服务器的功能性。
. HEAD    – 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。
这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。
. GET     – 向特定的资源发出请求。
注意:GET方法不应当被用于产生“副作用”的操作中,例如在web app.中。
其中一个原因是GET可能会被网络蜘蛛等随意访问。
. POST    – 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。
数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
. PUT     – 向指定资源位置上传其最新内容。
. DELETE  – 请求服务器删除Request-URI所标识的资源。
. TRACE   – 回显服务器收到的请求,主要用于测试或诊断。
. CONNECT – HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
. PATCH   – 用来将局部修改应用于某一资源,添加于规范RFC5789。

其中,GET,POST, PUT, DELETE常用于RESTful API的实现,所以下面做的代码实现

三、Python实现的json数据以HTTP GET,POST,PUT,DELETE方式进行页面请求

闲言少述,直接上代码.

1. GET方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# File: http_get.py

import urllib2

def http_get():
url=’http://192.168.1.13:9999/test’   #页面的地址
response = urllib2.urlopen(url)         #调用urllib2向服务器发送get请求
return response.read()                     #获取服务器返回的页面信息

ret = http_get()
print(“RET %r” % (ret))

2. POST方法

#!/usr/bin/env python
#  -*- coding:utf-8 -*-
# File http_post.py

import urllib
import urllib2
import json

def http_post():
url=’http://192.168.1.13:9999/test’
values ={‘user’:’Smith’,’passwd’:’123456}

jdata = json.dumps(values)             # 对数据进行JSON格式化编码
req = urllib2.Request(url, jdata)       # 生成页面请求的完整数据
response = urllib2.urlopen(req)       # 发送页面请求
return response.read()                    # 获取服务器返回的页面信息

resp = http_post()
print resp

3. PUT方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# File: http_put.py

import urllib2
import json

def http_put():
url=’http://192.168.1.13:9999/test’
values={”:”}

jdata = json.dumps(values)                  # 对数据进行JSON格式化编码
request = urllib2.Request(url, jdata)
request.add_header(‘Content-Type’, ‘your/conntenttype’)
request.get_method = lambda:’PUT’           # 设置HTTP的访问方式
request = urllib2.urlopen(request)
return request.read()

resp = http_put()
print resp

4. DELETE方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# File: http_delete.py

import urllib2
import json

def http_delete():
url=’http://192.168.1.13:9999/test’
values={‘user’:’Smith’}

jdata = json.dumps(values)
request = urllib2.Request(url, jdata)
request.add_header(‘Content-Type’, ‘your/conntenttype’)
request.get_method = lambda:’DELETE’        # 设置HTTP的访问方式
request = urllib2.urlopen(request)
return request.read()

resp = http_delete()
print resp

Python Flask Restful API

【转载】文章转载自bestallen

目前Web应用这块,restufl API用得非常普遍,因为,你手上的前端设备五花八门,各种系统的手机,pad等等,而且网站和手机APP经常会有需要资源共享的时候。

如果网站做个app,手机端再独立一个app,要保持2者同步,估计做开发的要做死了。

所以,RESTFUL API提出了一个概念,就是资源为上,通俗地讲:就是,我有一个资源A,可以作为接口来提供出来,那么,前端设备的B,C,D 都可以通过申请这个API接口的方式,来进行获取资源,而最后显示画面如何渲染,让客户看到是怎么样的一个样子,那是前端的事情了。

学习API之前,有两个前置技能需要去了解下,一个是JSON数据格式,另外一个是curl或者HTTPie这样的http调试工具,我这里用的是HTTPie

最简单的Web API

先来看看通过Python Flask做一个非常简单的Web API接口范例

[python] view plain copy

  1. from flask import Flask,jsonify
  2. app = Flask(__name__)
  3. tasks =[
  4.     {
  5.         ‘id’:1,
  6.         ‘title’: u‘Buy groceries’,
  7.         ‘description’: u‘Milk, Cheese, Pizza, Fruit, Tylenol’,
  8.         ‘done’False
  9.     },
  10.     {
  11.         ‘id’2,
  12.         ‘title’: u‘Learn Python’,
  13.         ‘description’: u‘Need to find a good Python tutorial on the web’,
  14.         ‘done’False
  15.     }]
  16. @app.route(‘/’)
  17. def index():
  18.     return ‘Hello,world!’
  19. @app.route(‘/todo/api/v1.0/tasks’,methods=[‘GET’])
  20. def get_tasks():
  21.     return jsonify({‘tasks’:tasks})

如上面代码,当你请求 /todo/api/v1.0/tasks 的时候,通过路由get_tasks,就能返回当前所有的数据信息

他是通过jsonify来进行返回的,这里需要注意的是,有2种方法可以返回json数据,一个是jsonify,还有一个是json.dumps()

那么2者有什么区别呢?可以看下图

jsonify直接返回的是Content-type:application/json的响应对象(Response对象)

json.dumps返回的,则是Content-type:text/html,charset=utf-8的HTML格式

我们可以看下jsonfiy的官方解释


来看下效果图及两者的区别

返回单个数据

刚才是获取了所有的任务,那如果我需要其中某一个数据的话,如何做呢?

[python] view plain copy

  1. @app.route(‘/todo/api/v1.0/tasks/<int:task_id>’,methods=[‘GET’])
  2. def get_task(task_id):
  3.     task = list(filter(lambda t:t[‘id’]==task_id,tasks))   #检查tasks内部元素,是否有元素的id的值和参数id相匹配
  4.     if len(task)==0:                                       #有的话,就返回列表形式包裹的这个元素,如果没有,则报错404
  5.         abort(404)
  6.     return jsonify({‘tasks’:task[0]})                      #否则,将这个task以JSON的响应形式返回

在URL里加入变量,通过检查tasks内部每个元素的id对应的值,是否有和输入的id匹配的,如果有匹配的,那就返回成一个list给task变量

比如下面,他就获取了id为2的这个数据的内容,当然,如果你在URL后面添加的是3,那他就会报错了,因为暂时还没有id为3的这个数据

上面的报错画面有些难看,而且,这样的报错格式,不太利于别人接口的使用。

一般像正规的接口,他都会以JSON格式返回error内容或者代码,所以,我们也要优化一下这样的错误信息。

[python] view plain copy

  1. @app.errorhandler(404)
  2. def not_found(error):
  3.     return jsonify({‘error’:‘Not found’}),404

 

这样,返回的格式,也是以JSON的格式,那样,如果别人调用你的接口,如果发生错误,别人就可以通过error信息,来进行渲染了。

POST方法添加信息

接下来,既然有数据,那肯定会涉及到添加数据,那我们就要用到POST方法了,就和上传FORM表单的性质是一样的

HTTPie的好处是,他默认的POST格式是JSON的,所以,你不必特意指定格式,只要写一个POST,就ok,如下

[python] view plain copy

  1. @app.route(‘/todo/api/v1.0/tasks’,methods=[‘POST’])
  2. def create_task():
  3.     if not request.json or not ‘title’ in request.json:   #如果请求里面没有JSON数据,或者在JSON数据里面,title的内容是空的
  4.         abort(404)                                    #返回404报错
  5.     task = {
  6.         ‘id’:tasks[-1][‘id’]+1,                       #取末尾task的id号,并加一作为新的数据的id号
  7.         ‘title’:request.json[‘title’],                #title必须要设置,不能为空
  8.         ‘description’:request.json.get(‘description’,””),     #描述可以添加,但是也可以不写,默认为空
  9.         ‘done’:False
  10.     }
  11.     tasks.append(task)                                    #完了以后,添加这个task进tasks列表
  12.     return jsonify({‘task’:task}),201                     #并返回这个添加的task内容,和状态码

 

后面加入的信息,你写title=test或者title=”test”都可以


PUT方法修改和DELETE方法删除

既然已经有了添加的功能,那么修改和删除的也必不可少,如下

[python] view plain copy

  1. @app.route(‘/todo/api/v1.0/tasks/<int:task_id>’,methods=[‘PUT’])
  2. def update_task(task_id):
  3.     task = list(filter(lambda t:t[‘id’]==task_id,tasks))     #检查是否有这个id的数据
  4.     if len(task)==0:
  5.         abort(404)
  6.     if not request.json:                                     #如果请求中没有附带json数据,则报错400
  7.         abort(400)
  8.     if ‘title’ in request.json and not isinstance(request.json[‘title’],str):   #如果title对应的值,不是字符串类型,则报错400
  9.         abort(400)
  10.     if ‘description’ in request.json and not isinstance(request.json[‘description’],str):  #同上,检查description对应的值是否为字符串
  11.         abort(400)
  12.     if ‘done’ in request.json and not isinstance(request.json[‘done’],bool):    #检查done对应的值是否是布尔值
  13.         abort(400)
  14.     task[0][‘title’] = request.json.get(‘title’,task[0][‘title’])          #如果上述条件全部通过的话,更新title的值,同时要设置默认值
  15.     task[0][‘description’] = request.json.get(‘description’, task[0][‘description’])  #修改description值
  16.     task[0][‘done’] = request.json.get(‘done’, task[0][‘done’])            #修改done的值
  17.     return jsonify({‘task’:task[0]})                                       #最后,返回修改后的数据
  18. @app.route(‘/todo/api/v1.0/tasks/<int:task_id>’,methods=[‘DELETE’])
  19. def delete_task(task_id):
  20.     task = list(filter(lambda t: t[‘id’]==task_id,tasks))     #检查是否有这个数据
  21.     if len(task) ==0:
  22.         abort(404)
  23.     tasks.remove(task[0])                                     #从tasks列表中删除这个值
  24.     return jsonify({‘result’True})                          #返回结果状态,自定义的result

优化接口

这样做接口系统,功能是达到了,但是你不见得让用户去背你的URL吧?这样不现实,像我们平时用的话,最好是可以自动生成URL

所以,这里我们需要写一个辅助函数,来返回一个完整的URL,这样可以就可以直接拿着URL用了

[python] view plain copy

  1. def make_public_task(task):
  2.     new_task={}             #新建一个对象,字典类型
  3.     for key in task:        #遍历字典内部的KEY
  4.         if key == ‘id’#当遍历到id的时候,为新对象增加uri的key,对应的值为完整的uri
  5.             new_task[‘uri’] = url_for(‘get_task’,task_id=task[‘id’],_external=True)
  6.         else:
  7.             new_task[key] = task[key]  #其他的key,分别一一对应加入新对象
  8.     return new_task                            #最后返回新对象数据

这样的话,你获取数据合集的路由,也需要修改了

[python] view plain copy

  1. @app.route(‘/todo/api/v1.0/tasks’,methods=[‘GET’])
  2. def get_tasks():
  3.     return jsonify({‘tasks’: list(map(make_public_task,tasks))})  #使用map函数,罗列出所有的数据,返回的数据信息,是经过辅助函数处理的

也就是说,经过辅助函数处理,你就可以直接获取整体URI了,而不是单个id号

接口安全性

接口的应用功能上,已经做得差不多了,但是现在的接口外圈是对外开放的,如果有人恶意破坏,数据就有可能有危险

所以,这里引入了认证机制,其实简单来说就是要求客户端的用户有使用使用权限,比如有账号和密码。

这里引入HTTPBasicAuth

auth=HTTPBasicAuth()

[python] view plain copy

  1. @auth.get_password
  2. def get_password(username):
  3.     if username == “allen”:
  4.         return “python”
  5.     return None
  6. @auth.error_handler
  7. def unauthorized():
  8.     return make_response(jsonify({‘error’:‘Unauthorized access’}),401)

通过客户端发送的用户名和密码,匹配get_password函数内部这个用户名和密码是否匹配

如果没有用户名密码,或者说是错误的,则返回401错误

于是,像查看资料啊这些的路由,都要给他挂一个login_required的装饰器了

[python] view plain copy

  1. @app.route(‘/todo/api/v1.0/tasks’,methods=[‘GET’])
  2. @auth.login_required
  3. def get_tasks():
  4.     return jsonify({‘tasks’: list(map(make_public_task,tasks))})

如果你没有附带用户名密码,那么,就会禁止访问了

附带了用户名和密码的话,就可以有权限进行操作