【问题标题】:Simple Python server to process GET and POST requests with JSON使用 JSON 处理 GET 和 POST 请求的简单 Python 服务器
【发布时间】:2016-02-13 06:28:22
【问题描述】:

我正在尝试创建一个简单的 Python 服务器来测试我的前端。它应该能够处理 GET 和 POST 请求。数据应始终为 JSON 格式,直到它们被转换为 HTTP 请求/响应。应调用具有相应名称的脚本来处理每个请求。

server.py

#!/usr/bin/env python

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import SocketServer
import json
import urlparse
import subprocess

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

    def do_GET(self):
        self._set_headers()
        parsed_path = urlparse.urlparse(self.path)
        request_id = parsed_path.path
        response = subprocess.check_output(["python", request_id])
        self.wfile.write(json.dumps(response))

    def do_POST(self):
        self._set_headers()
        parsed_path = urlparse.urlparse(self.path)
        request_id = parsed_path.path
        response = subprocess.check_output(["python", request_id])
        self.wfile.write(json.dumps(response))

    def do_HEAD(self):
        self._set_headers()

def run(server_class=HTTPServer, handler_class=S, port=8000):
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    print 'Starting httpd...'
    httpd.serve_forever()

if __name__ == "__main__":
    from sys import argv

    if len(argv) == 2:
        run(port=int(argv[1]))
    else:
        run()

testscript.py 处理请求的示例,在这种情况下它只返回一个 JSON 对象。

#!/usr/bin/env python
return {'4': 5, '6': 7}

例如,服务器应返回 {'4': 5, '6': 7} 以获取格式为 http://www.domainname.com:8000/testscript 的响应。

我的问题是我不知道如何在两者之间传递变量,我需要帮助才能让它工作。

【问题讨论】:

  • 你想在哪里传递变量?到服务器或类中的定义之间
  • 本题主要返回python脚本之间的变量。但理想情况下,我想在 Httprequest -> server -> handler script -> server -> http response 之间传递 json
  • 看看这个相关的帖子,它提供了一个工作 HTTP 服务器,为 Python2.7 提供 POST 支持stackoverflow.com/questions/31371166/…

标签: python json server httprequest httpresponse


【解决方案1】:

这里是python中服务器客户端的例子。我正在使用bottle 库来处理对服务器的请求并创建服务器。

服务器代码

import subprocess
from bottle import run, post, request, response, get, route

@route('/<path>',method = 'POST')
def process(path):
    return subprocess.check_output(['python',path+'.py'],shell=True)

run(host='localhost', port=8080, debug=True)

它在localhost:8080 上启动服务器。您可以传递要运行的文件名运行。确保该文件位于相同的路径中以使上述代码正常工作或适当地更改路径以从不同的目录运行。路径对应于文件名,当给出任何路径时它调用process 函数。如果找不到文件,则会引发异常内部服务器错误。您也可以从子目录调用脚本。

客户端代码

import httplib, subprocess

c = httplib.HTTPConnection('localhost', 8080)
c.request('POST', '/return', '{}')
doc = c.getresponse().read()
print doc

它调用一个 POST 请求到localhost:8080/return

return.py

def func():
    print {'4': 5, '6': 7}
func()

确保您打印输出响应,因为我们使用 subprocess.check_output(),因为它只捕获打印语句。

在subprocess 中使用Popen 打开连续连接,而不是使用check_output 将参数传递给服务器中的函数

查看documentation,了解如何提取 POST 或 GET 值

【讨论】:

  • @route('/&lt;path&gt;',method = 'GET') def process(path): response.content_type = 'text/html' return 'Hello World GET' 仍然给我一个内部服务器错误,并且无法调试它。您的服务器在端口 800 上运行,但没有任何活动迹象,而另一台服务器处于活动状态。
  • 你能详细说明你的问题吗? GET 您发布的方法不会在我的服务器上出现任何错误,并且服务器在 8080 而不是 800 上运行
  • 是的,它在localhost 上运行良好,我只是在从外部访问它时遇到了问题。将host='localhost' 更改为host='0.0.0.0' 解决了我的问题,我现在可以从外部资源访问。现在一切都很好。
  • 是的,在文档中将其更改为 0.0.0.0 将使服务器监听所有地址
  • 我是通过终端发现的,但是文档很好
【解决方案2】:

我用这个:

https://gist.github.com/earonesty/ab07b4c0fea2c226e75b3d538cc0dc55

from apiserve import ApiServer, ApiRoute

class MyServer(ApiServer): 
        @ApiRoute("/popup")
        def addbar(req):
            return {"boo":req["bar"]+1}

        @ApiRoute("/baz")
        def justret(req):
            if req:
                 raise ApiError(501,"no data in for baz")
            return {"obj":1}

MyServer("127.0.0.1",8000).serve_forever()

这个特定的包装器允许您轻松地侦听某些框架混淆的端口 0(随机高端口)。它自动处理所有路由的 GET/POST 请求,并将 URI 参数与顶级 JSON 对象参数合并。在大多数情况下,这对我来说已经足够了。

与大多数框架相比,它的重量要轻得多。要点中的测试用例更好地展示了它的工作原理。

【讨论】:

    【解决方案3】:

    对于喜欢Flask 的人来说,这只是一种选择。这个框架非常流行并且有很好的文档记录。

    创建文件wsgi.py(名称很重要,以后不用处理环境变量),内容如下:

    from flask import Flask, request
    
    app = Flask(__name__)
    
    
    @app.route('/object/<path_param>')
    def get_object(path_param):
        return {
            'path_param': path_param,
            'query_param': request.args.get('q', "'q' not set"),
        }
    
    
    if __name__ == '__main__':
        app.run()
    

    在终端中运行服务器,例如:flask run --reload --host "127.0.0.1" --port 7777

    发送如下查询:curl -i http://localhost:7777/object/something?q=q

    也不要忘记做pip3 install flask 来完成这项工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-09
      • 2017-03-16
      • 1970-01-01
      • 2019-06-26
      • 2012-03-14
      • 1970-01-01
      • 2014-04-17
      相关资源
      最近更新 更多