1.python利用flask框架和tornado框架搭建api微服务——HelloWorld的实现(一)
2.python利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post(二)
3.python利用flask框架和tornado框架搭建api微服务——连接数据库返回带参求情结果(三)
4.python利用flask框架和tornado框架搭建api微服务——python虚拟机启动API(四)
5.python利用flask框架和tornado框架搭建api微服务——Linux下查看某个端口对应的进程并kill进程的操作(关闭API服务进程)(五)
6.python利用flask框架和tornado框架搭建api微服务——完善API文档以及API调用(六)
python利用flask框架和tornado框架搭建api微服务——HelloWorld的实现(一)我们实现了大家最喜欢的HelloWorld,但是HelloWorld显然不满足客户大大传参数给我们,然后我们返回客户大大需要的这种常用场景,接下来就实现如何根据传入的参数来返回客户需要的结果。
既然是个小项目了,就要做一些准备工作,首先是我们构建一个日志,方便收集api服务的各种操作日志,就命名为logUtil.py吧,这个日志包需要在logUtil.py文件的当前目录下新建一个log文件夹,不然会报错,我偷懒了,应该写个如果没该文件,就创建一下的,logUtil.py的具体代码如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# vim:fenc=utf-8
"""
log module, need a ./log directory
"""
import logging.config
config = {
'version': 1,
'formatters': {
'simple': {
'format': '%(asctime)s-%(thread)d-%(filename)s[line:%(lineno)d]%(levelname)s: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
'encoding': 'utf-8',
'filemode': 'a'
}
# other formater
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'simple'
},
'file': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': './log/' + __name__ + '.log',
'level': 'DEBUG',
'formatter': 'simple',
'when': 'h',
'interval': 1
}
# other handler
},
'loggers': {
'StreamLogger': {
'handlers': ['console'],
'level': 'DEBUG',
},
'FileLogger': {
# have console and file
'handlers': ['console', 'file'],
'level': 'DEBUG',
}
# other logger
}
}
logging.config.dictConfig(config)
StreamLogger = logging.getLogger("StreamLogger")
FileLogger = logging.getLogger("FileLogger")
每次我们下载一个软件解压后,都可以看到各个文件和文件夹井然有序,当然我们自己构建的项目也自然不能太low,不然对不起我们这张帅气的脸对吧,文件夹分布如下:
flask_tornado_api/ # 总文件夹
├ HelloWorld.py # 应用启动程序,大家最欢的helloworld
├ logUtil.py # 日志包
├ log/ # log文件夹,存放操作日志
│ ├ logUtil.log
│ └ main.logUtil.log
├ templates/ #flask规定,不能改名,存放html文件
│ ├ get.html
│ └ post.html
├ conf/ #自定义,用来存放配置文件
└ myconfig,ini
接着上一篇的HelloWorld.py,把get和post对应的路由写出来,具体代码如下:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
"""
a flask sample module
"""
from flask import Flask
from flask import render_template
from flask import request
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
import json
import logUtil
app = Flask(__name__) #初始化flask的app对象
logger = logUtil.FileLogger #初始化日志对象
# set route
@app.route('/') #设置默认的helloworld路由
def hello_world(): #编写\路由对应的方法
return 'Hello, World!'
# render_template search templates dir default
@app.route('/get.html') #设置/get.html路由
def get_html(): #编写/get.html路由的方法
return render_template('get.html') #返回get.html触发的事件,详情请看templates文件夹下get.html的设计
@app.route('/post.html') #设置/post.html路由
def post_html(): #编写/post.html路由对应的方法
return render_template('post.html') #返回post.html触发的事件,详情请看templates文件夹下post.html的设计
#定义/deal_request路由,其实看了templates的html你会发现,最后都是来调用这个路由对应的方法
@app.route('/deal_request', methods = ['GET', 'POST'])
def deal_request(): #编写/deal_request对应的方法
if request.method == "GET":
# get通过request.args.get("param_name","")形式获取参数值
logger.info('a GET request') #利用日志对象logger收集日志
for key,value in request.args.items():
logger.info('{key}:{value}'.format(key = key, value = value)) #利用日志对象logger收集日志html上出过来的key和walue
get_params = json.dumps(request.args) #利用日志对象logger收集日志html上出过来的key和walue#利用日志对象logger收集日志html上出过来的key和walue
return get_params #返回最终的处理参数
elif request.method == "POST":
# post通过request.form["param_name"]形式获取参数值
logger.info('a POST request') #利用日志对象logger收集日志
for key,value in request.form.items():
logger.info('{key}:{value}'.format(key = key, value = value)) #利用日志对象logger收集日志html上出过来的key和walue
post_params = json.dumps(request.form) #利用日志对象logger收集日志html上出过来的表单form数据
return post_params #返回最终组装的json串post_params
else:
logger.warn('a request is neither a GET nor a POST')
if __name__ == '__main__':
#app.run(port=5000) #直接启动
#利用tornado启动程序
port=5000
http_server = HTTPServer(WSGIContainer(app)) #将api的初始化对应委托给tornado的HTTPServer
http_server.listen(port) #监听端口
logger.info('Listening on {}'.format(port))
IOLoop.instance().start() #启动微服务
为了更好的让我们调试,可以自己设计一个简单的网页来辅助,但是后续真正的api是不需要的哟,但这种做法也反馈了另一项技术,就是网页设计,对于那些非技术人员,这个界面操作再好不过了。
<html>
<head>
<meta charset="utf-8">
<title>get sampletitle>
head>
<body>
<p>
<h1>This is a get sample for flask in tornadoh1>
p>
<p>
<form action="/deal_request" method="get">
<div>
<p>param1: <input type="text" name="param1" /> p>
div>
<div>
<p>param2: <input type="text" name="param2" /> p>
div>
<input type="submit" value="submit" />
form>
p>
body>
html>
用浏览器打开templates/get.html网页效果如图1。
<html>
<head>
<meta charset="utf-8">
<title>post sampletitle>
head>
<body>
<p>
<h1>This is a post sample for flask in tornadoh1>
p>
<p>
<form action="/deal_request" method="post">
<div>
<p>param1: <input type="text" name="param1" /> p>
div>
<div>
<p>param2: <input type="text" name="param2" /> p>
div>
<input type="submit" value="submit" />
form>
p>
body>
html>
用浏览器打开templates/post.html网页效果如下图2。
和第一篇一样,利用指令python helloworld.py将微服务api开起来,具体如下,成功启动后会提示Running on http://127.0.0.1:5000/,就是说明这个端口就是我们的微服务,如果要中止,就按Ctrl + C。
python helloworld.py
* Serving Flask app "helloworld" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
如果5000端口起不来,确保之前的程序是否已经终止或者5000端口是否被占用,成功启动后,打开浏览器,输入localhost:5000,还是会跳转图3的helloworld。
在图4的param1和怕param2参数文本框随意输入一点文本字符,然后点击submit,就会返回界面5,注意图5浏览器上地址栏url的变化以及界面上的内容,其中url就是触发了HelloWorld.py的/deal_request路由。
到此简单的根据传入参数来返回相应结果也就做完了,但是实际运用肯定不会这么简单,敬请期待python利用flask框架和tornado框架搭建api微服务——连接数据库返回带参求情结果(三)