Falcon构建轻量级的REST API服务
Falcon构建轻量级的REST API服务
文章目录
- Falcon构建轻量级的REST API服务
- 安装falcon
- 构建falcon项目
- 应用托管(Hosting Your App)
- 简单示例
- 内容服务(Serving Text)
- JSON请求和响应处理
- 路由和 URI 参数
- 中间件
- 异常处理
- 图像服务(Serving Images)
- 创建图像资源
- 关联资源
- 请求和响应对象
- 图像下载
- 最佳实践
Falcon 是一个轻量级的Python Web框架,专注于构建RESTful API,它被设计为简单而快速,致力于提供高性能的API服务。
Falcon Tutorial文档
https://falcon.readthedocs.io/en/stable/user/tutorial.html
安装falcon
在开始之前,先得保证falcon已经安装。
$ pip install falcon
构建falcon项目
项目文件结构目录构造,如下:
image-classify
├── .venv
└── image-classify├── __init__.py└── app.py
现在创建并打开app.py文件,作为应用的入口,编辑修改如下代码:
import falconapp = application = falcon.App()
这就创建了一个 WSGI 应用,以app作为别名。 可以使用任何变量名,Gunicorn希望默认使用application。
WSGI应用只是一个可调用的明确定义的签名,可以在任何支持WSGI协议的web server上托管应用。
Falcon框架包含大量的内联文档,可以通过使用python模块查看技巧来查询。经过Falcon团队对文档可读性的大量优化,可以很快浏览和查找我们需要的。
应用托管(Hosting Your App)
前面已经创建了一个简单的Falcon应用,我们可以让它运行在WSGI server上。Python包含一个自托管的参考server,但是我们还是使用实际部署时使用的server。
$ pip install gunicorn
$ gunicorn app
应用服务部署后,可以检验服务效果,现在我们使用curl尝试查询它:
$ curl localhost:8000 -v
如果不出不意外,你应当将会获取到404。网络访问不到,怎么回事?
一方面,说明应用服务已经运行,已经有返回值404。Falcon包含默认的404响应处理(response handler),用来处理没有匹配到任何路由的请求地址。另一方面,返回404,这很正常,因为应用还没有设定任何路由(route)。
简单示例
下面是一个简单的Hello World示例,展示了Falcon框架的基本用法:
import falconclass HelloWorldResource:def on_get(self, req, resp):resp.status = falcon.HTTP_200resp.text = 'Hello, Falcon!'# 创建Falcon应用
app = falcon.App()# 指定资源路由
app.add_route('/', HelloWorldResource())
在上面的示例中,我们定义了一个名为HelloWorldResource的资源类,它包含一个处理HTTP GET请求的方法 on_get。然后,创建了一个Falcon应用,并将资源路由到根路径’/'。
内容服务(Serving Text)
JSON请求和响应处理
Falcon使用请求(req)和响应(resp)对象来处理HTTP请求和构建HTTP响应。以下是一个处理GET请求并返回JSON响应的示例:
import falcon
import jsonclass JsonResource:def on_get(self, req, resp):# 构建JSON响应resp.status = falcon.HTTP_200resp.content_type = 'application/json'resp.body = json.dumps({'message': 'Hello, Falcon!'})
路由和 URI 参数
Falcon使用路由来映射URI到资源。可以通过add_route方法或者使用装饰器 @app.route 来定义路由。以下是一个使用URI参数的示例:
import falconclass GreetResource:def on_get(self, req, resp, name):resp.status = falcon.HTTP_200resp.text = f'Hello, {name}!'app = falcon.App()
app.add_route('/greet/{name}', GreetResource())
在上面的示例中,URI参数{name}将会传递给on_get方法。
中间件
Falcon允许使用中间件来执行在请求处理前后的一些逻辑。以下是一个简单的中间件示例,记录请求处理时间:
import falcon
import timeclass TimingMiddleware:def process_request(self, req, resp):req.start_time = time.time()def process_resource(self, req, resp, resource, params):resource.processing_time = time.time() - req.start_timedef process_response(self, req, resp, resource, req_succeeded):resp.set_header('X-Processing-Time', str(resource.processing_time))app = falcon.App(middleware=[TimingMiddleware()])
异常处理
Falcon允许通过抛出自定义异常来处理错误。以下是一个示例,当请求的资源不存在时抛出HTTPNotFound异常:
import falconclass ResourceNotFound(Exception):def __init__(self, resource_name):self.resource_name = resource_nameclass CustomResource:def on_get(self, req, resp, name):if name != 'custom':raise ResourceNotFound(name)resp.status = falcon.HTTP_200resp.text = f'Hello, {name}!'# 在应用中添加错误处理
app.add_error_handler(ResourceNotFound, lambda ex, req, resp, params: self.handle_not_found(req, resp, ex))def handle_not_found(self, req, resp, ex):resp.status = falcon.HTTP_404resp.text = f'Resource "{ex.resource_name}" not found.'
图像服务(Serving Images)
创建图像资源
Falcon从REST架构风格引入一些术语,REST概念。Falcon的设计理念是,尽可能直观地让所有人理解HTTP基本原理。
在Falcon中,可以把传入的请求(incoming requests)称为资源(Resources)。资源只是一个常规Class,包含一些遵循一定命名规则的方法(Method)。每个方法对应一个动作(API客户端为了获取或转换资源,去请求执行的动作)。
现在项目需要在构建一个图片分享API,那可以创建一个image资源。在项目目录中,创建一个image.py的文件,可以在里面添加下面的代码:
import falconclass ImgResource(object): def on_get(self, req, resp):resp.body = '{"message":"Hello woeld!"}'resp.status = falcon.HTTP_200
Resource只是一个很常规的class,类名可以任意取。Falcon使用duck-typing,所以不需要继承任何特定的基类。
上面的image资源定义单一方法on_get。对于resource想要支持的任何HTTP方法,只需要简单在resource上加on_x类方法(class method),x可以是标准HTTP方法中的任何一个,例如on_get,on_put,on_head(小写)等等。
方法称作responders(响应器),每个responder至少需要两个参数,一个代表HTTP请求,另一个代表对应请求的HTTP响应。根据习惯,一般缩写作req和resp。如果是route(路由)和hooks(钩子)可以添加一些额外的参数。
例程中,image资源对GET请求作出响应:200 OK 和一个JSON对象。Falcon默认是application/json作为互联网媒体类型,但是可以设置成任何使用的类型。例如,可以使用MessagePack或者其他序列化格式。
关联资源
现在再把应用服务关联上resource,在app.py,增加资源描述,并关联请求URI,将其修改成如下:
import falcon
import imagesapi = application = falcon.API()images = images.ImgResource()
api.add_route('/images', images)
现在,如果传入一个“/images”的请求,Falcon请会调用images的资源中的响应器(responder)–对应所需要的HTTP方法。
重启gunicorn,并且尝试向resource(资源)发送一个GET请求:
$ curl localhost:8000/images -v
duck-typing:动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。在duck typing中,关注的不是对象的类型本身,而是它是如何使用的。
请求和响应对象
资源(resource)中的每个响应器(responder)接收一个请求对象(request object),可以被用作读取headers、查询参数和请求的body。
每个响应器(responder)也能接收一个响应对象(response object),可以被用作设置HTTP状态码、headers和响应的body。
可以使用help函数去列举Request,Response类的成员。
让我们探究一下如何运作。当客户端(client)POST到images集合(collection)时,需要创建一个新的image资源。首先,需指定images保存在什么地方。
实现POST响应器(responder):
编辑images.py 文件,添加下列代码到ImgResource:
import os
import time
import uuid
import falcondef _media_type_to_ext(media_type):#剥离'/images/'前缀return media_type[6:]def _generate_id():return str(uuid.uuid4())class ImgResource(object):def __init__(self, storage_path):self.storage_path = storage_pathdef on_post(self, req, resp):image_id = _generate_id()ext = _media_type_to_ext(req.content_type)filename = image_id + '.' + extimage_path = os.path.join(self.storage_path, filename)with open(image_path, 'wb') as image_file:while True:chunk = req.stream.read(4096)if not chunk:breakimage_file.write(chunk)resp.status = falcon.HTTP_201resp.location = '/images/' + image_id
程序给新图片生成了一个唯一的ID和文件名,然后从req.stream 中读取文件数据,再写入磁盘。调用stream而不是body去强调事实,正在从输入流读取;Falcon不会输出(spool)或解码(decode)请求数据(request data),而是直接访问由WSGI server提供的二进制输入流(incoming binary stream)。
注意,将HTTP response status code设置为“201 Created”。预定义的状态字符清单,可以通过对falcon.status_codes调用help函数来查看。
在on_post响应器的最后一行,给新创建的资源设置Location Header。创建一个路由(route))注意,Request类和Response类包含一些读取和设置通用header的便利属性,但是通过声明req.get_header和resp.set_header方法,总是可以使用任何header。
重启gunicorn,然后尝试给resource发送一个POST请求(可以将test.jpg替换成任何你想操作的JPEG文件的路径)
图像下载
已经完成上传图片到服务器,接下来是要能获取它们,通过带有文件路径的请求,让服务器返回一张图片到Location header,就像这样:
localhost:8000/images/87db45ff42
接下来,可以在images资源中添加on_get响应器。按照这个思路,如果要处理多张图片,除了表示单张图片资源的类以外,还需要新建一个类。我们可以在新的类中添加on_get响应器。
需要注意到on_get响应器中的name参数。任何在路由中指定的URL参数都将被转换成对应的kwargs参数,同时传递到目标响应器(responder)中。
在on_get响应器中,按照文件名扩展去设置内容类型的header,然后通过打开文件操作来直接以数据流形式输出图片。还有需要注意resp.stream_len 的用法。每当使用resp.stream来代替resp.body或resp.data的时候,必须给数据流指定一个预期的长度,以便web客户端知道从响应(response)中读取的数据有多大。
如果resp.status没有明确地设定,其默认值为200 OK,确切的说,这应该是应该在on_get响应器去做的。
现在将事件关联上,然后尝试运行一下。首先按照下面的例子来编辑app.py:
import falcon
import imagesapi = application = falcon.API()storage_path = '/usr/local/var/look'image_collection = images.ImgResource(storage_path)
image = image.Item(storage_path)api.add_route('/images', image_collection)
api.add_route('/images/(name)', image)
定义了一个新的路由/images/{name}。这会让Falcon将所有的对应的响应器(responder)和获取的name参数关联起来。
Falcon还支持更加复杂的参数化路径段(包含多个值)。例如,类Grasshopper(GH-like,可以通过参数的调整,直接改变模型形态)的API能够使用下面的模板为两个分支添加一个路由。
/repo/{org}/{repo}/compare/{usr0}:{branch0}…{usr1}:{branch1}
可以继续在浏览器中输入URL,图片会被正确的显示出来。
最佳实践
- 使用装饰器简化路由定义: Falcon提供了@app.route装饰器,可以简化路由的定义。
- 使用 Request 和 Response 模型: Falcon提供了Request和Response对象的模型,它们对原始HTTP请求和响应进行了封装,提供更便捷的处理方式。
- 使用中间件处理通用逻辑: 中间件是Falcon的强大功能之一,可用于处理日志、鉴权等通用逻辑。
- 异常处理的一致性: 使用自定义异常来处理错误,确保API的一致性和可维护性。
End
决策引擎-利用Drools实现简单防火墙策略
GPT专栏文章:
GPT实战系列-ChatGLM3本地部署CUDA11+1080Ti+显卡24G实战方案
GPT实战系列-ChatGLM2模型的微调训练参数解读
GPT实战系列-如何用自己数据微调ChatGLM2模型训练
GPT实战系列-ChatGLM2部署Ubuntu+Cuda11+显存24G实战方案
GPT实战系列-Baichuan2本地化部署实战方案
相关文章:
Falcon构建轻量级的REST API服务
Falcon构建轻量级的REST API服务 文章目录 Falcon构建轻量级的REST API服务安装falcon构建falcon项目应用托管(Hosting Your App)简单示例内容服务(Serving Text)JSON请求和响应处理路由和 URI 参数中间件异常处理 图像服务(Serving Images)创建图像资源关联资源请求和响应对象…...
【Python】python读取,显示,保存图像的几种方法
一、PIL:Python Imaging Library(pillow) PIL读取图片不直接返回numpy对象,可以用numpy提供的函数np.array()进行转换,亦可用Image.fromarray()再从numpy对象转换为原来的Image对象,读取,显示&…...
k8s系列-kuboard 该操作平台的使用操作
文章目录 一、相关平台,以及账号和密码镜像打包服务器仓库地址K8s平台数据库mysql 二、平台概述1.集群导入2.集群管理3.名称空间4.访问控制授权5.集群用户操作审计 三、kuboard平台操作手册一、部署服务操作1.名称空间部署2.工作负载部署 一、相关平台,以…...
基于讯飞星火大语言模型开发的智能插件:小策问答
星火大语言模型是一种基于深度学习的自然语言处理技术,它能够理解和生成人类语言。这种模型的训练过程涉及到大量的数据和复杂的算法,但最终的目标是让机器能够像人一样理解和使用语言。 小策问答是一款基于星火大语言模型的定制化GPT插件小工具。它的主…...
笔记:AI量化策略开发流程-基于BigQuant平台(二)
五、模型训练股票预测 完成了数据处理,接下来就可利用平台集成的各算法进行模型训练和模型预测啦。本文将详细介绍“模型训练”、“模型预测”两大模块操作、原理。 模型训练和模型预测是AI策略区别于传统量化策略的核心,我们通过模型训练模块利用训练…...
100127. 给小朋友们分糖果 II
给你两个正整数 n 和 limit 。 请你将 n 颗糖果分给 3 位小朋友,确保没有任何小朋友得到超过 limit 颗糖果,请你返回满足此条件下的 总方案数 。 示例 1: 输入:n 5, limit 2 输出:3 解释:总共有 3 种方…...
【2】Spring Boot 3 项目搭建
目录 【2】Spring Boot 3 初始项目搭建项目生成1. 使用IDEA商业版创建2. 使用官方start脚手架创建 配置与启动Git版本控制 个人主页: 【⭐️个人主页】 需要您的【💖 点赞关注】支持 💯 【2】Spring Boot 3 初始项目搭建 项目生成 1. 使用IDEA商业版创…...
【第七章】软件设计师 之 程序设计语言与语言程序处理程序基础
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 1、前言 正规式 2、编译过程 编译型&…...
如何判断一个角是否大于180度(2)
理论计算见上一篇: 如何判断一个角是否大于180度?_kv1830的博客-CSDN博客 此篇为代码实现 一。直接上代码: import cv2 as cv import numpy as np import mathdef get_vector(p_from, p_to):return p_to[0] - p_from[0], p_to[1] - p_from…...
ASAM OpenDRIVE V1.7协议超详解(一)
文章目录 前言一、仿真场景的构成二、openDRIVE框架三、g_additionalData四、openDRIVE-header五、openDRIVE-road1、Road总拓扑结构2、Road-link介绍1)link的拓扑结构2)link链接示例3)link前继后继4)道路link规则 3、road-type介…...
springboot的配置信息的设置和读取(application.properties/application.yml)
springboot提供了两种配置信息的文件格式,application.properties和application.yml,基于直接明了,使用方便和高效的前提下下面的配置均采用yml格式配置, 注意 yml采用缩减方式来排列键后面紧跟冒号,然后空格&#x…...
Deepsort项目详解
一、目标追踪整体代码 代码目录如下图所示: 、 追踪相关代码: 检测相关代码和权重 调用 检测 和 追踪的代码: 首先代码分为三个部分: 目标追踪的相关代码和权重目标检测相关代码和权重,这里用的是yolov5.5目标检…...
C语言证明一个偶数总能表示为两个素数之和。输入一个偶数并将其分解为两个素数
完整代码: // 一个偶数总能表示为两个素数之和。输入一个偶数并将其分解为两个素数#include<stdio.h>//判断一个数n是否为素数 int isPrimeNumber(int n){//1不是素数if (n1){return 0;}for (int i 2; i <(n/2); i){//当有n能被整除时,不是素…...
Python 的 datetime 模块
目录 简介 一、date类 (一)date 类属性 (二)date 类方法 (三)实例属性 (四)实例的方法 二、time类 (一)time 类属性 (二)tim…...
Termius for Mac:掌控您的云端世界,安全高效的SSH客户端
你是否曾经在Mac上苦苦寻找一个好用的SSH客户端,让你能够远程连接到Linux服务器,轻松管理你的云端世界?现在,我们向你介绍一款强大而高效的SSH客户端——Termius。 Termius是一款专为Mac用户设计的SSH客户端,它提供了…...
Ubuntu 下监控并自动重启网卡
很多时候网站服务器挂掉也可能是因为网卡挂掉了,如果你网站不能访问时 SSH 也无效了一般都是这个问题。这时可以通过一个定时脚本监控网络并进行自动重启。 1 创建脚本 auto_restart_network.sh 4 5 6 7 8 9 #!/bin/bash ping www.baidu.com -c 1 >/dev/null i…...
377. 组合总和 Ⅳ
给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1: 输入:nums [1,2,3], target 4 输出:7 解释&#…...
【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK
一、介绍 计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法,cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数,用于计算稀疏光流。它实现的是Lucas-Kanade方法,这是一种常用的光流计算方法。 光流是图像中物体运动的近似表示&#…...
C语言进阶
数组 在基础篇说过,数组实际上是构造类型之一,是连续存放的。 一维数组 定义 定义格式:[存储类型] 数据类型 数组名标识符[下标]; 下面分模块来介绍一下数组的定义部分的内容。 1、初始化和元素引用: 可以看到数组是连续存储…...
Linux之gdb
gdb就是一个Linux的调试工具,类似与vs里面的调试 可执行程序也有格式,不是简单的二进制堆砌...
揭秘Informer:如何通过ProbSparse注意力机制革新长序列预测
1. 长序列预测的困境与Transformer的瓶颈 想象一下你正在管理一个大型电网系统,需要预测未来30天的电力消耗。面对长达720小时的历史数据(每小时一个数据点),传统的LSTM模型在预测超过48小时后的结果就开始出现明显偏差࿰…...
《算法题讲解指南:动态规划算法--回文串问题》--35.回文子串,36. 最长回文子串,37.分割回文串 IV,38.分割回文串 II,39.最长回文子序列,40.让字符串成为回文串的最少插入次数
🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》《C入门到进阶&自我学习过程记录》 《算法题讲解指南》--优选算法 《算法题讲解指南》--递归、搜索与回溯算法 《算法题讲解指南》--动态规划算法 ✨未择之路࿰…...
国家中小学智慧教育平台电子课本解析工具:快速获取教材资源的完整方案
国家中小学智慧教育平台电子课本解析工具:快速获取教材资源的完整方案 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本内…...
破解重庆企业数据治理困局:基于本地化定制的大数据平台如何构建统一主数据标准
引言 在数字化转型浪潮席卷全国的背景下,重庆作为西部重要的制造业与商贸枢纽,正加速推进“智造重镇”和“智慧名城”建设。然而,众多中大型企业在迈向数据驱动的过程中,普遍面临数据孤岛林立、标准不一、质量低下、合规风险高等核…...
避坑指南:RK3588部署YOLOv8时,模型转换与板端环境那些容易忽略的细节
RK3588部署YOLOv8避坑实战:模型转换与板端环境的七个关键陷阱 当你在RK3588上部署YOLOv8时,是否遇到过这样的场景:按照官方文档一步步操作,却在模型转换或板端推理时莫名失败?这很可能是因为忽略了某些"隐藏规则…...
dom-to-image技术突破:浏览器端DOM渲染的图像化解决方案
dom-to-image技术突破:浏览器端DOM渲染的图像化解决方案 【免费下载链接】dom-to-image Generates an image from a DOM node using HTML5 canvas 项目地址: https://gitcode.com/gh_mirrors/do/dom-to-image 在现代Web开发中,将DOM元素转换为图像…...
别再轮询了!STM32 ADC多通道采集,用DMA+定时器实现后台自动搬运数据(附CubeMX配置)
STM32 ADC多通道采集:DMA定时器实现零CPU占用的数据搬运方案 在工业传感器监测或物联网设备开发中,ADC多通道采集是基础但关键的技术环节。传统轮询方式不仅占用大量CPU资源,还会因处理延迟导致数据丢失。本文将分享一种基于DMA和定时器触发的…...
Qwen-Ranker Pro效果展示:‘猫洗澡’vs‘狗洗澡’语义陷阱精准识别案例
Qwen-Ranker Pro效果展示:‘猫洗澡’vs‘狗洗澡’语义陷阱精准识别案例 1. 引言:当搜索遇到语义陷阱 你有没有遇到过这样的情况:在搜索引擎中输入"猫洗澡的注意事项",结果却给你推荐了一大堆"给狗洗澡"的内…...
电子电路中的“心脏”:电源猛
前言 Kubernetes 本身并不复杂,是我们把它搞复杂的。无论是刻意为之还是那种虽然出于好意却将优雅的原语堆砌成 鲁布戈德堡机械 的狂热。平台最初提供的 ReplicaSets、Services、ConfigMaps,这些基础组件简单直接,甚至显得有些枯燥。但后来我…...
【系统架构师-案例题-建模分析】21年下(4)预约挂号管理系统 UML 建模案例分析
文章目录题目【问题1】(6分)【问题2】(10分)【问题3】(9分)答案与解答【问题1】答案解答【问题2】答案顺序图与协作图的区别解答【问题3】答案1. 三种模型的定义2. 三种模型的关联关系3. 需求分析阶段的适用性解答题目 某医院拟委托软件公司开发一套预约挂号管理系统ÿ…...
