首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何向Flasgger添加POST请求?

如何向Flasgger添加POST请求?
EN

Stack Overflow用户
提问于 2020-12-14 22:38:38
回答 1查看 1.5K关注 0票数 0

我是Flasgger的新手,我正在努力弄清楚如何在其中添加POST请求。

下面是我的Flasgger应用程序(app.py):

代码语言:javascript
复制
import datetime
import numpy as np
import pandas as pd
from flask import Flask, jsonify, make_response, Response, request, json
from flasgger import Swagger

def upload_data(file):
    df = pd.read_json(file)
    df['Rate'] = pd.to_datetime(df['Rate'], format="%Y-%d-%m %H:%M:%S")
    df['SI'] = np.nan
    return df

server = Flask(__name__)
Swagger(server)


@server.route('/results', methods=['POST', 'GET'])
def ML_results_get():
    """post endpoint
    ---
    tags:
      - ML-KA-results
    parameters:
      - name: body
        in: body
        required: true
        schema:
          id: ML-KA-results
          type: "object"
          required:
            - Rate
            - KE
            - SU
            - ML-PC 1
            - ML-PC 2
            - ML-PC 3
            - ML-PC 4
            - ML-PC 5
            - ML-PC 6
            - ML-Totals
            - LL-PC 1
            - LL-PC 2
            - LL-PC 3
            - LL-PC 4
            - LL-PC 5
            - LL-PC 6
            - LL-Totals
          properties:
            Rate:
              type: string
              default: "9/20/2020 8:50"
            KE:
              type: string
              default: "1"
            SU:
              type: string
              default: " GgG"
            ML-PC 1:
              type: string
              default: "154.11"
            ML-PC 2:
              type: string
              default: "0"
            ML-PC 3:
              type: string
              default: "0"
            ML-PC 4:
              type: string
              default: "0"
            ML-PC 5:
              type: string
              default: "0"
            ML-PC 6:
              type: string
              default: "0"
            ML-Totals:
              type: string
              default: "154.11"
            LL-PC 1:
              type: string
              default: "0"
            LL-PC 2:
              type: string
              default: "0"
            LL-PC 3:
              type: string
              default: "0"
            LL-PC 4:
              type: string
              default: "0"
            LL-PC 5:
              type: string
              default: "0"
            LL-PC 6:
              type: string
              default: "0"
            LL-Totals:
              type: string
              default: "0"
    responses:
      200:
        description: The product inserted in the database
        schema:
          $ref: '#/definitions/Product'
    """
    with server.test_request_context('/results'):
        if request.method == 'POST':
            reqData = request.get_json(force=True)
            df_ML = upload_data(reqData)
            return df_ML.to_json()
        else:
            return print('GET is not supported')

if __name__ == '__main__':
    server.run(debug=True, port=85)

现在我想试试Flasgger是如何工作的。当我转到http://localhost:85/apidocs/#/ML-KA-results/post_results时,单击“试试看”并复制以下json文件:

代码语言:javascript
复制
[
 {
   "Rate": "9/20/2020 8:50",
   "KE": 1,
   "SU": " GgG",
   "ML-PC 1": 154.11,
   "ML-PC 2": 0,
   "ML-PC 3": 0,
   "ML-PC 4": 0,
   "ML-PC 5": 0,
   "ML-PC 6": 0,
   "ML-Totals": 154.11,
   "LL-PC 1": 0,
   "LL-PC 2": 0,
   "LL-PC 3": 0,
   "LL-PC 4": 0,
   "LL-PC 5": 0,
   "LL-PC 6": 0,
   "LL-Totals": 0
 },
 {
   "Rate": "9/20/2020 8:50",
   "KE": 2,
   "SU": " GgG",
   "ML-PC 1": 154.27,
   "ML-PC 2": 0,
   "ML-PC 3": 0,
   "ML-PC 4": 0,
   "ML-PC 5": 0,
   "ML-PC 6": 0,
   "ML-Totals": 154.27,
   "LL-PC 1": 0,
   "LL-PC 2": 0,
   "LL-PC 3": 0,
   "LL-PC 4": 0,
   "LL-PC 5": 0,
   "LL-PC 6": 0,
   "LL-Totals": 0
 }
]

当我单击"Execute“时,我将得到以下错误:

代码语言:javascript
复制
Error: INTERNAL SERVER ERROR
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title>TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement. // Werkzeug Debugger</title>
    <link rel="stylesheet" href="?__debugger__=yes&amp;cmd=resource&amp;f=style.css"
        type="text/css">
    <!-- We need to make sure this has a favicon so that the debugger does
         not by accident trigger a request to /favicon.ico which might
         change the application state. -->
    <link rel="shortcut icon"
        href="?__debugger__=yes&amp;cmd=resource&amp;f=console.png">
    <script src="?__debugger__=yes&amp;cmd=resource&amp;f=jquery.js"></script>
    <script src="?__debugger__=yes&amp;cmd=resource&amp;f=debugger.js"></script>
    <script type="text/javascript">
      var TRACEBACK = 2439966170584,
          CONSOLE_MODE = false,
          EVALEX = true,
          EVALEX_TRUSTED = false,
          SECRET = "AhMBlga2HAcS1uO5N5Tz";
    </script>
  </head>
  <body style="background-color: #fff">
    <div class="debugger">
<h1>TypeError</h1>
<div class="detail">
  <p class="errormsg">TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.</p>
</div>
<h2 class="traceback">Traceback <em>(most recent call last)</em></h2>
<div class="traceback">
  
  <ul><li><div class="frame" id="frame-2439967649920">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">2464</em>,
      in <code class="function">__call__</code></h4>
  <div class="source "><pre class="line before"><span class="ws"></span> </pre>
<pre class="line before"><span class="ws">    </span>def __call__(self, environ, start_response):</pre>
<pre class="line before"><span class="ws">        </span>&quot;&quot;&quot;The WSGI server calls the Flask application object as the</pre>
<pre class="line before"><span class="ws">        </span>WSGI application. This calls :meth:`wsgi_app` which can be</pre>
<pre class="line before"><span class="ws">        </span>wrapped to applying middleware.&quot;&quot;&quot;</pre>
<pre class="line current"><span class="ws">        </span>return self.wsgi_app(environ, start_response)</pre>
<pre class="line after"><span class="ws"></span> </pre>
<pre class="line after"><span class="ws">    </span>def __repr__(self):</pre>
<pre class="line after"><span class="ws">        </span>return &quot;&lt;%s %r&gt;&quot; % (self.__class__.__name__, self.name)</pre></div>
</div>

<li><div class="frame" id="frame-2439967650760">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">2450</em>,
      in <code class="function">wsgi_app</code></h4>
  <div class="source "><pre class="line before"><span class="ws">            </span>try:</pre>
<pre class="line before"><span class="ws">                </span>ctx.push()</pre>
<pre class="line before"><span class="ws">                </span>response = self.full_dispatch_request()</pre>
<pre class="line before"><span class="ws">            </span>except Exception as e:</pre>
<pre class="line before"><span class="ws">                </span>error = e</pre>
<pre class="line current"><span class="ws">                </span>response = self.handle_exception(e)</pre>
<pre class="line after"><span class="ws">            </span>except:  # noqa: B001</pre>
<pre class="line after"><span class="ws">                </span>error = sys.exc_info()[1]</pre>
<pre class="line after"><span class="ws">                </span>raise</pre>
<pre class="line after"><span class="ws">            </span>return response(environ, start_response)</pre>
<pre class="line after"><span class="ws">        </span>finally:</pre></div>
</div>

<li><div class="frame" id="frame-2439967650032">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">1867</em>,
      in <code class="function">handle_exception</code></h4>
  <div class="source "><pre class="line before"><span class="ws">            </span># if we want to repropagate the exception, we can attempt to</pre>
<pre class="line before"><span class="ws">            </span># raise it with the whole traceback in case we can do that</pre>
<pre class="line before"><span class="ws">            </span># (the function was actually called from the except part)</pre>
<pre class="line before"><span class="ws">            </span># otherwise, we just raise the error again</pre>
<pre class="line before"><span class="ws">            </span>if exc_value is e:</pre>
<pre class="line current"><span class="ws">                </span>reraise(exc_type, exc_value, tb)</pre>
<pre class="line after"><span class="ws">            </span>else:</pre>
<pre class="line after"><span class="ws">                </span>raise e</pre>
<pre class="line after"><span class="ws"></span> </pre>
<pre class="line after"><span class="ws">        </span>self.log_exception((exc_type, exc_value, tb))</pre>
<pre class="line after"><span class="ws">        </span>server_error = InternalServerError()</pre></div>
</div>

<li><div class="frame" id="frame-2439967650144">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\_compat.py"</cite>,
      line <em class="line">39</em>,
      in <code class="function">reraise</code></h4>
  <div class="source "><pre class="line before"><span class="ws">    </span>import collections.abc as collections_abc</pre>
<pre class="line before"><span class="ws"></span> </pre>
<pre class="line before"><span class="ws">    </span>def reraise(tp, value, tb=None):</pre>
<pre class="line before"><span class="ws">        </span>if value.__traceback__ is not tb:</pre>
<pre class="line before"><span class="ws">            </span>raise value.with_traceback(tb)</pre>
<pre class="line current"><span class="ws">        </span>raise value</pre>
<pre class="line after"><span class="ws"></span> </pre>
<pre class="line after"><span class="ws">    </span>implements_to_string = _identity</pre>
<pre class="line after"><span class="ws"></span> </pre>
<pre class="line after"><span class="ws"></span>else:</pre>
<pre class="line after"><span class="ws">    </span>iterkeys = lambda d: d.iterkeys()</pre></div>
</div>

<li><div class="frame" id="frame-2439967650872">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">2447</em>,
      in <code class="function">wsgi_app</code></h4>
  <div class="source "><pre class="line before"><span class="ws">        </span>ctx = self.request_context(environ)</pre>
<pre class="line before"><span class="ws">        </span>error = None</pre>
<pre class="line before"><span class="ws">        </span>try:</pre>
<pre class="line before"><span class="ws">            </span>try:</pre>
<pre class="line before"><span class="ws">                </span>ctx.push()</pre>
<pre class="line current"><span class="ws">                </span>response = self.full_dispatch_request()</pre>
<pre class="line after"><span class="ws">            </span>except Exception as e:</pre>
<pre class="line after"><span class="ws">                </span>error = e</pre>
<pre class="line after"><span class="ws">                </span>response = self.handle_exception(e)</pre>
<pre class="line after"><span class="ws">            </span>except:  # noqa: B001</pre>
<pre class="line after"><span class="ws">                </span>error = sys.exc_info()[1]</pre></div>
</div>

<li><div class="frame" id="frame-2439967650928">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">1953</em>,
      in <code class="function">full_dispatch_request</code></h4>
  <div class="source "><pre class="line before"><span class="ws">            </span>rv = self.preprocess_request()</pre>
<pre class="line before"><span class="ws">            </span>if rv is None:</pre>
<pre class="line before"><span class="ws">                </span>rv = self.dispatch_request()</pre>
<pre class="line before"><span class="ws">        </span>except Exception as e:</pre>
<pre class="line before"><span class="ws">            </span>rv = self.handle_user_exception(e)</pre>
<pre class="line current"><span class="ws">        </span>return self.finalize_request(rv)</pre>
<pre class="line after"><span class="ws"></span> </pre>
<pre class="line after"><span class="ws">    </span>def finalize_request(self, rv, from_error_handler=False):</pre>
<pre class="line after"><span class="ws">        </span>&quot;&quot;&quot;Given the return value from a view function this finalizes</pre>
<pre class="line after"><span class="ws">        </span>the request by converting it into a response and invoking the</pre>
<pre class="line after"><span class="ws">        </span>postprocessing functions.  This is invoked for both normal</pre></div>
</div>

<li><div class="frame" id="frame-2439967650984">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">1968</em>,
      in <code class="function">finalize_request</code></h4>
  <div class="source "><pre class="line before"><span class="ws">        </span>with the `from_error_handler` flag.  If enabled, failures in</pre>
<pre class="line before"><span class="ws">        </span>response processing will be logged and otherwise ignored.</pre>
<pre class="line before"><span class="ws"></span> </pre>
<pre class="line before"><span class="ws">        </span>:internal:</pre>
<pre class="line before"><span class="ws">        </span>&quot;&quot;&quot;</pre>
<pre class="line current"><span class="ws">        </span>response = self.make_response(rv)</pre>
<pre class="line after"><span class="ws">        </span>try:</pre>
<pre class="line after"><span class="ws">            </span>response = self.process_response(response)</pre>
<pre class="line after"><span class="ws">            </span>request_finished.send(self, response=response)</pre>
<pre class="line after"><span class="ws">        </span>except Exception:</pre>
<pre class="line after"><span class="ws">            </span>if not from_error_handler:</pre></div>
</div>

<li><div class="frame" id="frame-2439967649864">
  <h4>File <cite class="filename">"C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py"</cite>,
      line <em class="line">2098</em>,
      in <code class="function">make_response</code></h4>
  <div class="source "><pre class="line before"><span class="ws">                </span>)</pre>
<pre class="line before"><span class="ws"></span> </pre>
<pre class="line before"><span class="ws">        </span># the body must not be None</pre>
<pre class="line before"><span class="ws">        </span>if rv is None:</pre>
<pre class="line before"><span class="ws">            </span>raise TypeError(</pre>
<pre class="line current"><span class="ws">                </span>&quot;The view function did not return a valid response. The&quot;</pre>
<pre class="line after"><span class="ws">                </span>&quot; function either returned None or ended without a return&quot;</pre>
<pre class="line after"><span class="ws">                </span>&quot; statement.&quot;</pre>
<pre class="line after"><span class="ws">            </span>)</pre>
<pre class="line after"><span class="ws"></span> </pre>
<pre class="line after"><span class="ws">        </span># make sure the body is an instance of the response class</pre></div>
</div>
</ul>
  <blockquote>TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.</blockquote>
</div>

<div class="plain">
  <form action="/?__debugger__=yes&amp;cmd=paste" method="post">
    <p>
      <input type="hidden" name="language" value="pytb">
      This is the Copy/Paste friendly version of the traceback.  <span
      class="pastemessage">You can also paste this traceback into
      a <a href="https://gist.github.com/">gist</a>:
      <input type="submit" value="create paste"></span>
    </p>
    <textarea cols="50" rows="10" name="code" readonly>Traceback (most recent call last):
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 2450, in wsgi_app
    response = self.handle_exception(e)
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\_compat.py&quot;, line 39, in reraise
    raise value
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 1953, in full_dispatch_request
    return self.finalize_request(rv)
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 1968, in finalize_request
    response = self.make_response(rv)
  File &quot;C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py&quot;, line 2098, in make_response
    &quot;The view function did not return a valid response. The&quot;
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.</textarea>
  </form>
</div>
<div class="explanation">
  The debugger caught an exception in your WSGI application.  You can now
  look at the traceback which led to the error.  <span class="nojavascript">
  If you enable JavaScript you can also use additional features such as code
  execution (if the evalex feature is enabled), automatic pasting of the
  exceptions and much more.</span>
</div>
      <div class="footer">
        Brought to you by <strong class="arthur">DON'T PANIC</strong>, your
        friendly Werkzeug powered traceback interpreter.
      </div>
    </div>

    <div class="pin-prompt">
      <div class="inner">
        <h3>Console Locked</h3>
        <p>
          The console is locked and needs to be unlocked by entering the PIN.
          You can find the PIN printed out on the standard output of your
          shell that runs the server.
        <form>
          <p>PIN:
            <input type=text name=pin size=14>
            <input type=submit name=btn value="Confirm Pin">
        </form>
      </div>
    </div>
  </body>
</html>

<!--

Traceback (most recent call last):
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 1953, in full_dispatch_request
    return self.finalize_request(rv)
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 1968, in finalize_request
    response = self.make_response(rv)
  File "C:\Users\iakubal\Anaconda3\envs\general_3_6\lib\site-packages\flask\app.py", line 2098, in make_response
    "The view function did not return a valid response. The"
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.

如何正确编写Flasgger?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-16 05:05:26

我从未使用过Flasgger,但就我而言,你的问题是你使用行

代码语言:javascript
复制
with server.test_request_context('/results'): 

在服务器上。

它不应该在服务器中使用,而应该在客户机中用于测试服务器。

如果删除这一行(并保留rest if request.method == 'POST': ...),那么就不会显示这个问题了。

但是,它显示了其他问题,因为您在使用pandas时出错了。requests.get_json()获得带有数据的字符串(JSON),并将其转换为字典或列表,但是pd.read_json()需要再次使用带有数据的字符串(JSON),因此必须将其转换回来。

代码语言:javascript
复制
    data = request.get_json(force=True)
    json_text = json.dumps(data)
    df = pd.read_json(json_text, orient='records') #orient='index')

或者你应该直接得到字符串而不让人垂涎三尺。

代码语言:javascript
复制
    json_text = request.get_data()
    df = upload_data(json_text)

我还遇到了其他问题。当我单击Try out时,示例显示单行的数据,它在read_json()中需要orient='index',但在行中使用list,而在read_json()中则需要orient='records'

完整的工作代码,例如带有行列表的数据

代码语言:javascript
复制
import datetime
import numpy as np
import pandas as pd
from flask import Flask, jsonify, make_response, Response, request, json
from flasgger import Swagger
import io

def upload_data(json_text):
    # `record` for list of rows, `index` for single row
    df = pd.read_json(json_text, orient='records') #orient='index')

    df['Date'] = pd.to_datetime(df['Date'], format="%Y-%d-%m %H:%M:%S")
    df['QI'] = np.nan

    return df

server = Flask(__name__)
Swagger(server)

@server.route('/results', methods=['POST', 'GET'])
def DL_results_get():
 """post endpoint
---
tags:
  - ML-KA-results
parameters:
  - name: body
    in: body
    required: true
    schema:
      id: ML-KA-results
      type: "object"
      required:
        - Rate
        - KE
        - SU
        - ML-PC 1
        - ML-PC 2
        - ML-PC 3
        - ML-PC 4
        - ML-PC 5
        - ML-PC 6
        - ML-Totals
        - LL-PC 1
        - LL-PC 2
        - LL-PC 3
        - LL-PC 4
        - LL-PC 5
        - LL-PC 6
        - LL-Totals
      properties:
        Rate:
          type: string
          default: "9/20/2020 8:50"
        KE:
          type: string
          default: "1"
        SU:
          type: string
          default: " GgG"
        ML-PC 1:
          type: string
          default: "154.11"
        ML-PC 2:
          type: string
          default: "0"
        ML-PC 3:
          type: string
          default: "0"
        ML-PC 4:
          type: string
          default: "0"
        ML-PC 5:
          type: string
          default: "0"
        ML-PC 6:
          type: string
          default: "0"
        ML-Totals:
          type: string
          default: "154.11"
        LL-PC 1:
          type: string
          default: "0"
        LL-PC 2:
          type: string
          default: "0"
        LL-PC 3:
          type: string
          default: "0"
        LL-PC 4:
          type: string
          default: "0"
        LL-PC 5:
          type: string
          default: "0"
        LL-PC 6:
          type: string
          default: "0"
        LL-Totals:
          type: string
          default: "0"
responses:
  200:
    description: The product inserted in the database
    schema:
      $ref: '#/definitions/Product'
"""

    #with server.test_request_context('/results'):
    if request.method == 'POST':
        #data = request.get_json(force=True)
        #json_text = json.dumps(data)
        json_text = request.get_data()
        df = upload_data(json_text)
        return df.to_json()
    else:
        return print('GET is not supported')

if __name__ == '__main__':
    server.run(debug=True, port=8500)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65297526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档