前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >python - 本地mocker服务

python - 本地mocker服务

作者头像
千往
发布于 2020-06-18 08:16:40
发布于 2020-06-18 08:16:40
56800
代码可运行
举报
运行总次数:0
代码可运行

本地mocker服务

技术选型

python3 + http.server

流程

  1. 获取请求
  2. 通过请求的path,params(query_params+body_params),method去匹配对应的response
    1. 本地的response需要事先设置好
  3. 将response返回

代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/python
# coding=utf-8


import os
import re
import threading
import time
import logging
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from urllib.parse import urlparse, parse_qs, urlsplit


class S(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def _respond(self):

        path = self.path
        self._set_headers()
        response = self._mock_content(path)
        if isinstance(response, str):
            response = str.encode(response)

        self.wfile.write(response if response else '')

    def do_HEAD(self):
        self._set_headers()

    def do_GET(self):
        self._respond()

    def do_POST(self):
        self._respond()

    def do_PUT(self):
        self._respond()

    def do_DELETE(self):
        self._respond()

    def _get_filename(self, code, format='json'):
        return "%s_%s.%s" % (self.command, code, format)

    def _mock_content(self, url_path):

        # 记录请求的参数
        query_dict, body_dict = self.save_query_body(url_path)

        # 根据url_path来匹配content_path
        content_path = self.get_content_path()
        rep = self.get_mock_response(url_path, content_path)
        return rep

    def get_content_path(self):
        http_method = self.command
        json_name = "/" + http_method + "_200.json"
        pre_dirname = "../mocker_response"
        file_name = pre_dirname + urlsplit(self.path).path + json_name

        if os.path.exists(file_name):
            return file_name
        else:
            return None

    def save_query_body(self, url_path):
        # 获取实际url query
        query = urlsplit(url_path).query

        query_dict = dict([(k, v[0]) for k, v in parse_qs(query).items()])
        # 获取实际url body
        content_len = int(self.headers.get('content-length', 0))
        body = self.rfile.read(content_len)

        body_dict = dict([(k, v[0]) for k, v in parse_qs(body.decode('utf-8')).items()])

        # 写入 MOCK_REQUEST
        MOCK_REQUEST = {}
        path = re.sub("/{1,}", "", urlparse(url_path).path, count=1)
        MOCK_REQUEST[path] = {}
        MOCK_REQUEST[path]['query'] = query_dict
        MOCK_REQUEST[path]['body'] = body_dict

        print(MOCK_REQUEST)

        return query_dict, body_dict

    @staticmethod
    def get_mock_response(url_path, content_path):
        rep = ''
        if content_path is None:
            logging.warning("can NOT find the response. please check.")
            return '{"code":404, "msg":"can NOT find the response. please check."}'

        # 读取整个文件
        with open(content_path, 'r+') as f:
            for line in f:
                rep += line

        # 内容为空
        if not rep:
            logging.warning("empty file for path: %s" % url_path)
            rep = "{'code':400, 'msg':'empty file for path: %s'}" % url_path

        return rep


class ThreadingHttpServer(ThreadingMixIn, HTTPServer):
    # 多线程
    pass


class Mocker(threading.Thread):

    def __init__(self, address, port, dir):
        """
        :param address: server 地址
        :param port: 端口
        :param dir: mock文件地址
        """
        threading.Thread.__init__(self)

        server_class = ThreadingHttpServer
        self.httpd = server_class((address, port), S)

    def run(self):
        try:
            self.httpd.serve_forever()
        except Exception as e:
            logging.error(e)
            self.mock_stop()

    def mock_start(self):
        print('Starting  mock server...')
        self.start()

    def mock_stop(self):
        print('Stopping  mock server...')
        self.httpd.shutdown()
        self.httpd.server_close()


# test
if __name__ == '__main__':
    dsp = Mocker('127.0.0.1', 8099, '')
    dsp.mock_start()
    while True:
        try:
            time.sleep(1)
            print("wait")
        except(KeyboardInterrupt) as e:
            dsp.mock_stop()

代码解析

核心模块是http.server 官方文档: https://docs.python.org/zh-cn/3/library/http.server.html 需要自己自定义一个requestHandler,就是在这里处理mocker的核心服务代码

备注

  1. 看官方文档,在python3.7+后就支持**ThreadingHTTPServer **了,不需要自己去继承ThreadingMixIn了的 ,后续可以优化了的
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Web服务器-Nginx解决跨域问题
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
运维小路
2025/04/20
1370
Web服务器-Nginx解决跨域问题
网络请求与数据解析
urllib是Python自带的标准库中用于网络请求的库 ,无需安装,直接引用即可。通常用于爬虫开发、API(应用程序编程接口)数据获取和测试。
@小森
2024/03/15
1360
网络请求与数据解析
用python写的agent
#/usr/bin/python #Filename:agent.py #siyu@2012-6-29
py3study
2020/01/06
2.1K0
21天打造分布式爬虫-urllib库(一)
urlparse和urlsplit都是用来对url的各个组成部分进行分割的,唯一不同的是urlsplit没有"params"这个属性.
zhang_derek
2018/08/01
3270
21天打造分布式爬虫-urllib库(一)
Python实现简单的API接口
get方法 代码实现 # coding:utf-8 import json from urlparse import parse_qs from wsgiref.simple_server import make_server # 定义函数,参数是函数的两个参数,都是python本身定义的,默认就行了。 def application(environ, start_response): # 定义文件请求的类型和当前请求成功的code start_response('200 OK', [
py3study
2020/01/09
7K0
Python实现简单的API接口
多监控平台统一 | Hawkeye
近年来出现越来越多的监控平台, 每一个监控平台都是其擅长的地方, 比方说 zabbix 监控收集, 并监控基础服务。 grafana 监控平台可以很好的展示数据, kibana 又是日志相关的监控, 可以很出色的自定义很多业务监控。 总而言之基本上大多数有一定技术规模的公司, 运维都有很多监控平台。
用户1416054
2018/08/02
1.7K2
多监控平台统一 | Hawkeye
云函数各种使用方式
云函数代理蚁剑流量 1.创建云函数 #!/usr/bin/env # -*- coding:utf-8 -*- import requests import json from urllib.parse import urlsplit def geturl(urlstr): jurlstr = json.dumps(urlstr) dict_url = json.loads(jurlstr) return dict_url['url'] def main_handler(e
R0A1NG
2022/02/19
1.4K0
云函数各种使用方式
爬虫学习之第一章网络请求
HTTP协议:全称是HyperText Transfer Protocol,中文意思是超文本传输协议,是一种发布和接收HTML页面的方法。服务器端口号是80端口。 HTTPS协议:是HTTP协议的加密版本,在HTTP下加入了SSL层。服务器端口号是443端口。
py3study
2020/01/15
6790
python:记一次简单的模拟flas
1, pyton:pep-0333 2, flask作者博客文章:getting-started-with-wsgi 3, 自己写一个 wsgi 服务器运行 Django 、Tornado 等框架应用 4, 500L:a-simple-web-server 5, python wsgi简介 6, 从零开始搭建论坛(二):Web服务器网关接口 7, python的 WSGI 简介 8,本文github源码
py3study
2020/01/05
5040
wsgi 协议
本来没打算这么早就学习 wsgi 的,因为想要学习python 是如何处理网络请求的绕不开 wsgi,所以只好先学习一下 wsgi。先对 wsgi 有个印象,到了学习 Django 运行方式以及如何处理网络请求数据的时候就会感觉很顺畅了。本文参考
py3study
2020/01/19
8560
爬虫中网络请求的那些事之urllib库
urllib库是Python中一个最基本的网络请求库。可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据
HammerZe
2022/03/25
6300
爬虫中网络请求的那些事之urllib库
基于host的http代理--hproxy
本文主要讲述,如何实现一个基于host方式的http代理,以及它与普通代理之间的区别。这种方式的代理主要可以应用于哪些实际的测试场景。
上帝De助手
2019/09/17
2.6K0
基于host的http代理--hproxy
物联网控制台数据同步--客户端Python脚本
用户的个性化业务需求需要将产品下所有设备上报的数据传输至用户自有的服务器上进行处理,平台提供了 HTTP 转发服务,将设备上报数据实时 POST 到用户的 HTTP 服务器的能力。
用户8662632
2021/07/29
6410
如何抓取汽车之家的车型库
实际上,关于「如何抓取汽车之家的车型库」,我已经在「使用 Mitmproxy 分析接口」一文中给出了方法,不过那篇文章里讲的是利用 API 接口来抓取数据,一般来说,因为接口不会频繁改动,相对 WEB 页面而言更稳定,所以通常这是数据抓取的最佳选择,不过利用 API 接口来抓取数据有一些缺点,比如有的数据没有 API 接口,亦可能虽然有 API 接口,但是数据使用了加密格式,此时只能通过 WEB 页面来抓取数据。
LA0WAN9
2021/12/14
1.7K0
如何抓取汽车之家的车型库
python-urllib.parse
小编最近在编写接口自动化测试用例的过程中,需要将get请求url中的部分参数替换成预设的数据,将url中的具有时效性的auth替换成auth生成方法返回值。经过一番调研,最后选取了python的urllib库的parse模块。
用户5521279
2020/07/03
1.5K0
传统框架部署到 Serverless 架构的利与弊
Serverless 是一个比较新的概念、架构,让开发者放弃之前的开发习惯、放弃现有的 Express、Koa、Flask、Django 等框架,无缝转向 Serverless 架构,显然是不可能的,必须得有一段过渡和适应的时间。在这段时间内,开发者需要思考是否可以将现有的框架部署到 Serverless 架构上?如果要部署,如何才能顺利上云呢?
腾讯云serverless团队
2020/06/15
9350
Python爬虫urllib详解
学习爬虫,最初的操作便是模拟浏览器向服务器发出请求,那么我们需要从哪个地方做起呢?请求需要我们自己来构造吗?需要关心请求这个数据结构的实现吗?需要了解 HTTP、TCP、IP 层的网络传输通信吗?需要知道服务器的响应和应答原理吗?
仲君Johnny
2024/02/05
3180
Python爬虫urllib详解
【python】urllib库之四大模块
【前言】 有好一段时间都没敲py了, 今天将urllib库算是较全的学习了一下老实说还是敲py比较舒服,当然还有requests,Beautiful库,正则表达式这些对于进行对爬去文章的处理都是不可避免的。
全栈程序员站长
2022/11/15
1K0
Python爬虫之网络请求
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
村雨遥
2019/09/09
5910
用 Python 写一个简单的Web框架
在Python中,WSGI(Web Server Gateway Interface)定义了Web服务器与Web应用(或Web框架)之间的标准接口。在WSGI的规范下,各种各样的Web服务器和Web框架都可以很好的交互。
诸葛青云
2019/05/31
5620
用 Python 写一个简单的Web框架
相关推荐
Web服务器-Nginx解决跨域问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档