pythonweb开发项目经验_Python Web开发我的学习经验--2、Web API开发基础框架搭建

我的Flask Web开发主要参照《Flask Web开发:基于Python的Web应用开发实战(美Grinberg 2015)》(以后简称《Flask Web开发》),所以项目的目录结构以及相关配置基本上是原封不动照搬过来。

1、目录结构

参照《Flask Web开发》的7章大型程序的结构,具体实现目录结构如下:web目录结构

config.py:主要用来存放配置相关信息,数据库连接路径等

manage.py:同《Flask Web开发》中的manage.py一样,主要用于命令行

run.py:用于测试运行

home.py:主要用于tornado发布时用,暂时不做过多讲解

requirements.txt:存放用到的组件,在发布安装时使用

文件夹

database:主要用于Sqlite文件存放位置

tests:存放测试用例

doc:文档存放处

app:程序实现的位置

app\api:主要用于存放Web API所有请求的问题

2、配置以及辅助文件

配置以及辅助文件同《Flask Web开发》没有太多区别,如果想要入门请读《Flask Web开发》详细内容。

config.py

# 存储配置

import os

basedir = os.path.abspath(os.path.dirname(__file__))

class Cofig:

SECRET = os.environ.get("SECRET") or 'da***st'

SQLACHEMY_COMMIT_ON_TEARDOWN = True

@staticmethod

def init_app(app):

pass

class DevelopmentConfig(Cofig):

DEBUG = True

SQLALCHEMY_DATABASE_URI = os.environ.get("DEV_DATABASE_URL") or \

'sqlite:///' + os.path.join(basedir + '/database', "data-dev.db3")

class TestingConfig(Cofig):

TESTING = True

SQLALCHEMY_DATABASE_URI = os.environ.get("DEV_DATABASE_URL") or \

'sqlite:///' + os.path.join(basedir + '/database', "data-test.db3")

class ProductionConfig(Cofig):

SQLALCHEMY_DATABASE_URI = os.environ.get("DEV_DATABASE_URL") or \

'sqlite:///' + os.path.join(basedir + '/database', "data.db3")

config = {

"development": DevelopmentConfig,

"testing": TestingConfig,

"production": ProductionConfig,

"default": DevelopmentConfig

}

配置三个环境,development:开发环境;testing:测试环境;production:为正式产品环境;default对应开发环境。

basedir :对应当前文件夹,Sqlite数据库要指定到database:所以具体实现如下:

SQLALCHEMY_DATABASE_URI = os.environ.get("DEV_DATABASE_URL") or \

'sqlite:///' + os.path.join(basedir + '/database', "data-dev.db3")

manage.py没有做太多改变就不做说明,基本上就是原来一样的。

run.py:进行了简单的基础配置,保证能快速运行,代码如下:

import os

from app import create_app

config_name = os.getenv('APP_SETTINGS') or 'default'

app = create_app(config_name)

if __name__ == '__main__':

#app.run(host='0.0.0.0',port=5009)

app.run( port=5009)

3、搭建起简单环境

app\__init__.py文件中create_app起到创建app的主要工作,如run.py中显示,首先要导入create_app,其次是配置类型没有配置时是default,再次生成app。if __name__ == '__main__'类似于主函数入口,在c#中可能就类似于Program中的main方法(我的理解)。

由于只开发Web Api,也就省略掉UI相关的内容,从而净化了代码。只有与数据库相关的部分是我们最为关注的。因此,create_app中只引入了flask_restful和flask_sqlalchemy。

为了解耦,将API中用到的resource集中放到api\__init__.py中处理,因此要导入add_resources函数。

app\__init__.py代码如下:

from flask_sqlalchemy import SQLAlchemy

from flask import Flask

from config import config

from flask_restful import Api

db = SQLAlchemy()

restful = Api()

def create_app(config_name):

app = Flask(__name__)

app.config.from_object(config[config_name])

app.config.setdefault('SQLALCHEMY_TRACK_MODIFICATIONS', True)

config[config_name].init_app(app)

db.init_app(app)

db.create_all(app=app)

from .api import add_resources

add_resources(restful)

restful.init_app(app)

return app

app为Flask的实例

db 为SQLAlchemy的实例,db也相对于全局变量,在DbOperate中就要from. importdb

restful 是Api的实例,用flask_restful主要是节省开发时间,其可以直接将dict转换成Json,而不用像《Flask Web开发》中提到的那样写,如下:

@api.route('/posts/')

def get_post(id):

post = Post.query.get_or_404(id)

return jsonify(post.to_json())

jsonify去转换,比较麻烦。

用flask_restful就可以简化为如下:

def dosuccess(users):

response = Response()

response.setData(users)

return response.toDict() , 200

前面说明toDict()函数是将response转换为 dict,所以flask_restful能直接返回dict并转为json。

app\api\__init__.py

主要的作用为对api进行resource的添加

from .authresource import AuthResource

from .usersviews import UsersResouce, UserResouce

from .developersviews import DeveloperResouce, DevelopersResouce

from .modulesviews import ModuleInfoResouce, ModuleInfosResouce

from .moduleversionsviews import ModuleVersionResouce, ModuleVersionsResouce

from .tokenviews import TokenResource

from .testview import TodoList, Todo

from .uploadviews import UploadResource

def add_resources(api):

api.add_resource(TodoList, '/todos')

api.add_resource(Todo, '/todos/')

api.add_resource(AuthResource, "/api/v1.0/auth")

api.add_resource(TokenResource, "/api/v1.0/token")

api.add_resource(UsersResouce, "/api/v1.0/users")

api.add_resource(UserResouce, "/api/v1.0/users/")

api.add_resource(DevelopersResouce, "/api/v1.0/developers")

api.add_resource(DeveloperResouce, "/api/v1.0/developers/")

api.add_resource(ModuleInfosResouce, "/api/v1.0/modules")

api.add_resource(ModuleInfoResouce, "/api/v1.0/modules/")

api.add_resource(ModuleVersionsResouce, "/api/v1.0/versions")

api.add_resource(ModuleVersionResouce, "/api/v1.0/versions/")

api.add_resource(UploadResource, "/api/v1.0/uploads")

而具体的实现分配在各自文件中。

以Todo和TodoList方例:

from flask import abort

from flask_restful import Resource, reqparse

TODOS = {

'todo1': {'task': 'build an API'},

'todo2': {'task': '?????'},

'todo3': {'task': 'profit!'},

}

parser = reqparse.RequestParser()

parser.add_argument('task', type=str)

def abort_if_todo_doesnt_exist(todo_id):

if todo_id not in TODOS:

abort(404, message="Todo {} doesn't exist".format(todo_id))

class Todo(Resource):

def get(self, todo_id):

abort_if_todo_doesnt_exist(todo_id)

return TODOS[todo_id]

def delete(self, todo_id):

abort_if_todo_doesnt_exist(todo_id)

del TODOS[todo_id]

return '', 204

def put(self, todo_id):

args = parser.parse_args()

task = {'task': args['task']}

TODOS[todo_id] = task

return task, 201

class TodoList(Resource):

def get(self):

return TODOS

def post(self):

args = parser.parse_args()

todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1

todo_id = 'todo%i' % todo_id

TODOS[todo_id] = {'task': args['task']}

return TODOS[todo_id], 201

其中todo实现了三个Http动词:get、 delete、put,而TodoList实现了两个Http动词get 、post。

配置路径为:

api.add_resource(TodoList, '/todos')

api.add_resource(Todo, '/todos/')

获取todos:

获取单个实例:

到此整个Web API基础框架搭建完成,当然还不是标准的API

格式。在后面将进行详细说明。

请关注我的公众号:9i编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值