python利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post带参请求的服务(二)

目 录

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() #启动微服务

实战之templates下html的设计

  为了更好的让我们调试,可以自己设计一个简单的网页来辅助,但是后续真正的api是不需要的哟,但这种做法也反馈了另一项技术,就是网页设计,对于那些非技术人员,这个界面操作再好不过了。

  • templates/get.html设计代码

<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。
python利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post带参请求的服务(二)_第1张图片

图1 templates/get.html浏览器效果
  • templates/post.html设计代码

<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利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post带参请求的服务(二)_第2张图片

图2 templates/post.html浏览器效果

实战之开启微服务

  和第一篇一样,利用指令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。python利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post带参请求的服务(二)_第3张图片

图3 helloworld界面
   但是这个不是我们的重点了,这时,我们在浏览器地址栏输入:localhost:5000/post.html,就会跳转图4。

python利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post带参请求的服务(二)_第4张图片

图4 微服务post.html界面

  在图4的param1和怕param2参数文本框随意输入一点文本字符,然后点击submit,就会返回界面5,注意图5浏览器上地址栏url的变化以及界面上的内容,其中url就是触发了HelloWorld.py的/deal_request路由。
在这里插入图片描述

图5 post.html点击submit得到的json串结果
   当然在浏览器地址栏输入localhost:5000/get.html,效果是一样的,但是点击submit后返回的结果如图6,发现有什么不同吗?   注意:图6的浏览器地址栏上的url竟然会带出来”?param1=hello¶m2=world“,这个 就是经典的get请求和post有啥区别中其中的一条:get请求会在url打印参数,post则不会,所以如果我参数很长,那么浏览器地址栏肯定不会无限制让你去写,很多请浏览器都会限制get请求的参数长度,注意是浏览器做的限制,get请求本身并没有这种限制,不要混淆了。

python利用flask框架和tornado框架搭建api微服务——结合html网页实现get和post带参请求的服务(二)_第5张图片

图6 get.html点击submit得到的json串结果

  到此简单的根据传入参数来返回相应结果也就做完了,但是实际运用肯定不会这么简单,敬请期待python利用flask框架和tornado框架搭建api微服务——连接数据库返回带参求情结果(三)

你可能感兴趣的:(Python,微服务API)