【问题标题】:TypeError: 'NoneType' object is not subscriptable on GAE instance assigning JSON to python variableTypeError:“NoneType”对象在将 JSON 分配给 python 变量的 GAE 实例上不可下标
【发布时间】:2021-04-25 22:53:11
【问题描述】:

在将 JSON 分配给像 sheet_id = data["sheetID"] 这样的 python 变量时,我收到错误 TypeError: 'NoneType' object is not subscriptable。 它只发生在我的 Google App Engine 实例上。在本地运行我的 Flask 应用程序并使用 Postman 向应用程序发送 POST 请求时,我没有得到它。这是代码sn-p

@app.route('/main',methods=["POST"])
def main():
    data = request.json
    print(data)
    scope = [
    'https://www.googleapis.com/auth/spreadsheets',
    'https://www.googleapis.com/auth/gmail.send',
    'https://www.googleapis.com/auth/gmail.settings.basic',
    'https://www.googleapis.com/auth/gmail.settings.sharing'
    ]

    GCP_PROJECT = os.environ['GCP_PROJECT']
    GAE_SID_VERSION = os.environ['GAE_SID_VERSION']


    credentials1 = access_secret_version(GCP_PROJECT, <SECRET NAME>, GAE_SID_VERSION)
    credentials1 = json.loads(credentials1)
    credentials = service_account.Credentials.from_service_account_info(credentials1)
    scoped_credentials = credentials.with_scopes(scope)
    gc = gspread.authorize(scoped_credentials)

    #for sheet with categories and score
    sheet_id = data["sheetID"] #this gives me the error

    workbook = gc.open_by_key(sheet_id)
    ...

    ...
    return "OK"

奇怪的是整个程序运行完成,我收到response = OK。我可以将 json 数据从 Google 表格中的触发脚本发送到我的 GAE 实例,然后 GAE 实例稍后将数据加载到 Gcloud 存储桶中。我从this link 了解到datasheet_id 可能是None,但在这种情况下,我的整个程序将如何运行完成甚至只是打开工作簿?这是 Google Apps 脚本

function runDockerImage(sheetID , mainWorksheet , emailTo , emailList , deliverToCloud ,filterOn , labelDisplay , sandbox , deliverToSlack) {
  // The code below logs the HTML code of the Google home page.
  var dataJSON = {
    'sheetID' :sheetID,
    'mainWorksheet' : mainWorksheet,
    'emailTo' : emailTo,
    'emailList' : emailList,
    'deliverToCloud' : deliverToCloud,
    'filterOn' : filterOn,
    'labelDisplay': labelDisplay,
    'sandbox' : sandbox,
    'deliverToSlack' : deliverToSlack 
    
  };
  
  payload = JSON.stringify(dataJSON)
  
  var headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'Authorization': 'Basic _authcode_'
  };
  
  var options = {
     'method': 'post',
     'contentType': 'application/json',
     'headers': headers,
     'payload': payload
  };
  
  
  var response = UrlFetchApp.fetch('https://<project-id>.uc.r.appspot.com/main', options);
  Logger.log(response);
 
}

这是来自 App Engine 错误报告日志的追溯:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/app/app.py", line 118, in main
    sheet_id = data["sheetID"]
TypeError: 'NoneType' object is not subscriptable

最后,我想问一下,这个程序怎么可能完全运行并出现这个错误?我想如果我不解决这个问题,我以后可能会遇到一些严重的问题。

错误报告日志的屏幕截图

【问题讨论】:

    标签: python json google-app-engine flask google-cloud-platform


    【解决方案1】:

    错误表示dataNone

    $ python3
    Python 3.8.3 (v3.8.3:6f8c8320e9, May 13 2020, 16:29:34) 
    [Clang 6.0 (clang-600.0.57)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> d=None
    >>> d['3']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'NoneType' object is not subscriptable
    

    奇怪的是整个程序运行完成,我收到响应= OK。

    您确定没有错误处理程序或返回 OK 的东西,即使请求处理程序抛出异常?

    另外,你为什么要这样做?

    dataJSON = request.json
    json_string = json.dumps(dataJSON)
    data = json.loads(json_string)
    

    request.json 将 json 请求有效负载作为 python dict 提供给您,但随后您将其转换为 json 字符串,然后再次将其解析为 python dict。你应该可以做到data = request.json

    【讨论】:

    • 现在不知何故错误消失了。我还仔细检查了我的代码,只有在程序结束时我才返回“OK”。我还将这三行更正为data = request.json。感谢您的帮助。
    • 除了runDockerImage 之外可能还有别的东西打到你的端点/main。除非有一些其他代码覆盖了变量data,否则此错误似乎是由于请求处理程序在没有 json 有效负载的情况下被命中,因此request.json 返回了None。此外,python3 的堆栈驱动程序日志可能有点不稳定,并且并不总是将来自同一请求的日志组合在一起。因此,也许您正在查看交织在一起的多个请求的日志,并且看起来错误返回正常。如果您附上屏幕截图,则更容易分辨。
    • 嗨@Alex,这是有道理的。我认为这就是发生的事情,并且错误报告日志在报告时显示了错误的时间。因为当我运行它并检查日志时,我得到了那个错误,但程序运行完成了。我假设您的意思是错误报告破折号的屏幕截图,因此我已将其包含在答案中
    • 我的意思是“日志资源管理器”中的日志截图。您可以通过单击屏幕截图中的“查看日志”来到达那里,但这可能会过滤掉除堆栈跟踪之外的所有内容。我也希望看到堆栈跟踪周围的日志。
    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    相关资源
    最近更新 更多