Flask RESTful API 简单的设计一个 GET 请求接口

  • 数据库:PostgreSQL
  • 框架:Flask
  • 语言:Python 3.6

前提

  • 之前我有每天定时爬取bing壁纸,写入postgresql数据库的,如下:
  • ER图

需要的Python环境

  • flask-sqlalchemy
  • flask-migrate
  • flask-script
  • flask-restful
  • flask
  • psycopg2

创建配置文件Config.py

里面设置数据库的引擎以及其它的一些需要配置的程序参数

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18/6/25 下午5:15
# @Author  : olei
# @File    : Config.py
# @Software: PyCharm
# @license : Copyright(C), olei.me
# @Contact : i@olei.me

DB_USER = "postgres"
DB_PASSWORD = "postgres"
HOST = "127.0.0.1"
DB_NAME = "bing"


DEBUG = True

SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_DATABASE_URI = 'postgresql://' + DB_USER + ':' + DB_PASSWORD + "@" + HOST + '/' + DB_NAME

这里设置的是postgresql的配置项

数据模型Model.py

根据数据库,来设置数据模型

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18/6/25 下午5:22
# @Author  : olei
# @File    : Model.py
# @Software: PyCharm
# @license : Copyright(C), olei.me
# @Contact : i@olei.me

from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()

class Bing(db.Model):
    __tablename__ = "psql_bing"
    id = db.Column(db.Integer,unique=True,primary_key=True)
    dates = db.Column(db.Date,nullable=False)
    bing_url = db.Column(db.String(10000),nullable=False)
    qiniu_url = db.Column(db.String(10000),nullable=False)
    image_name = db.Column(db.String(10000),nullable=False)

忽略我给的String的大小...,这个与flask中设计表结构的写法是一致的,用到flask的flask-sqlalchemy

数据库迁移文件migrate.py

使用Flask-Migrate和Flask-Script来实现数据迁移

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18/6/25 下午5:25
# @Author  : olei
# @File    : migrate.py
# @Software: PyCharm
# @license : Copyright(C), olei.me
# @Contact : i@olei.me

from flask import Flask
from flask_migrate import Migrate,MigrateCommand
from flask_script import Manager
from Model import db

app = Flask(__name__)
app.config.from_object('Config')

migrate = Migrate(app,db)
manager = Manager(app)
manager.add_command('db',MigrateCommand)

if __name__ == "__main__":
    manager.run()

这里的 app.config.from_object 是读取配置文件,里面写上配置文件的没有拓展名的文件名,就是上面的配置文件Config.py 的名字

  • 定义好数据迁移配置后,执行下面命令完成数据迁移:
$ python migrate.py db init

$ python migrate.py db migrate

$ python migrate.py db upgrade

结束之后会生成一个文件夹,里面也会生成一些文件,如下:

migrations
├── README
├── alembic.ini
├── env.py
├── script.py.mako
└── versions
    └── 79d73a8da1cf_.py

Flask-RESTful接口实现app.py

  • 先给出代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18/6/26 上午11:21
# @Author  : olei
# @File    : app.py
# @Software: PyCharm
# @license : Copyright(C), olei.me
# @Contact : i@olei.me

from flask import Flask, jsonify
from Model import db, Bing
from flask_restful import Resource, Api, reqparse, fields, marshal_with, abort, marshal

app = Flask(__name__)
app.config.from_object("Config")

db.init_app(app)

errors = {
    'BingAlreadyExistsError': {
        'message': "It is already exists.",
        'status': 409,
    },
    'ResourceDoesNotExist': {
        'message': "A resource with that ID no longer exists.",
        'status': 410,
        'extra': "Any extra information you want.",
    },
}

api = Api(app, catch_all_404s=True, errors=errors)

parser = reqparse.RequestParser()
parser.add_argument('dates', required=True)
parser.add_argument('bing_url', required=True)
parser.add_argument('qiniu_url', required=True)
# parser.add_argument('user_nickname')
parser.add_argument('image_name', required=True)

resource_full_fields = {
    'id': fields.Integer,
    'dates': fields.String,
    'bing_url': fields.String,
    'qiniu_url': fields.String,
    'image_name': fields.String
}


class Common:
    def returnTrueJson(self, data, msg="请求成功"):
        return jsonify({
            "status": 1,
            "data": data,
            "msg": msg
        })

    def returnFalseJson(self, data=None, msg="请求失败"):
        return jsonify({
            "status": 0,
            "data": data,
            "msg": msg
        })


class Hello(Resource):
    def get(self):
        return 'Hello Flask!'


class Bing_all(Resource):
    def get(self):
        # dates = Bing.query.filter_by()
        return Common.returnTrueJson(Common, marshal(Bing.query.all(), resource_full_fields))


class Bing_url(Resource):
    def get(self, dates):
        dates = Bing.query.filter_by(dates=dates).first()
        if (dates is None):
            abort(410, msg="找不到数据!", data=None, status=0)
        else:
            return Common.returnTrueJson(Common, marshal(dates, resource_full_fields))


api.add_resource(Hello, '/', '/hello')
api.add_resource(Bing_all, '/bing')
api.add_resource(Bing_url, '/bing/<string:dates>')

if __name__ == "__main__":
    app.run(debug=app.config['DEBUG'])

分析

  • 错误处理代码
errors = {
    'BingAlreadyExistsError': {
        'message': "It is already exists.",
        'status': 409,
    },
    'ResourceDoesNotExist': {
        'message': "A resource with that ID no longer exists.",
        'status': 410,
        'extra': "Any extra information you want.",
    },
}

api = Api(app, catch_all_404s=True, errors=errors)

调用是通过abort来调用的

 if (dates is None):
     abort(410, msg="找不到数据!", data=None, status=0)
  • 定义一个Common,来统一响应数据格式
  • 处理请求

Flask-RESTful的reqparse用于获取并转化客户端输入参数

parser = reqparse.RequestParser()
parser.add_argument('dates', required=True)
parser.add_argument('bing_url', required=True)
parser.add_argument('qiniu_url', required=True)
# parser.add_argument('user_nickname')
parser.add_argument('image_name', required=True)

上面代码定义了一个请求数据分析转化器(parser),然后指定参数的名称。 在获取参数数据时使用parse_args来转化所有的参数,并返回一个输入数据字典。 代码里面没有用到,这个是post,delete等请求会用到,就是增删改用

  • 处理响应

Flask-RESTful的fields用于规范响应字段,定制响应字段键名和键值数据类型,还可以对输出响应做更多复杂的处理。输出响应时,可以使用装饰器或函数式两种方式作处理:

装饰器方式:

@marshal_with(resource_full_fields, envelope=’data’)

函数方式:

marshal(User.query.all()

代码中用了函数方式来处理

运行

$ python app.py

后记

忽略app.py中我对dates的处理...

本文作者为olei,转载请注明。

flask postgresql RESTful API

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java学习之路

SSH框架完全整合 整合Spring和Hibernate:Spring整合Struts2

大三学期渐末,事情也挺多的,上周就开始着手整合SSH框架,到现在才真正的完成,过程中碰到了许多小问题(小问题大折腾,哭脸.jpg)。本着善始善终的原则,最终把它...

81450
来自专栏大魏分享(微信公众号:david-share)

JavaEE中资源注入松耦合的实现 | 从开发角度看应用架构13

上下文和依赖注入(CDI)规范是Java EE规范中的许多从属规范之一。虽然CDI是在Java EE 6中引入的,但CDI背后的概念已经出现在各种框架中,包括S...

11020
来自专栏Spark学习技巧

锁机制-java面试

何为同步?JVM规范规定JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。代码块同步是使用monitorenter和mo...

39560
来自专栏JAVA高级架构

spring和springMVC的面试问题总结

1.Spring中AOP的应用场景、Aop原理、好处? 答:AOP--Aspect Oriented Programming面向切面编程;用来封装横切关注点,具...

37490
来自专栏情情说

深入浅出MyBatis:MyBatis的所有配置

上一篇介绍了JDBC的相关概念、MyBatis的特性与Hibernate的区别、MyBatis的基本组件与生命周期,基本可以使用MyBatis了。

38180
来自专栏butterfly100

Java并发编程:synchronized和锁优化

1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,...

36770
来自专栏xingoo, 一个梦想做发明家的程序员

JSP中文乱码问题

之前总是碰到JSP页面乱码的问题,每次都是现在网上搜,然后胡乱改,改完也不明白原因。 这次正好作下总结,中文乱码就是因为编码不符,可能出现乱码有四个地方: ...

42490
来自专栏JMCui

SpringMVC 异常处理.

一、异常处理 Spring提供了多种方式将异常转换为响应: 特定的Spring异常将会自动映射为指定的HTTP状态码     在默认情况下,Spring会将自身...

35480
来自专栏公众号_薛勤的博客

史上最全面的Spring Boot配置文件详解

Spring Boot在工作中是用到的越来越广泛了,简单方便,有了它,效率提高不知道多少倍。Spring Boot配置文件对Spring Boot来说就是入门和...

2K20
来自专栏Java学习之路

Hibernate学习---基本介绍+作用+配置

从今天开始重新学习(以前学的太匆忙)Hibernate,这篇文章主要就一下几点进行讲解和说明: Hibernate的基本介绍 Hibernate的作用 Hibe...

29370

扫码关注云+社区

领取腾讯云代金券