【问题标题】:Extending the Twilio Weather By Phone app to create python TwiML server扩展 Twilio Weather By Phone 应用程序以创建 python TwiML 服务器
【发布时间】:2013-11-18 21:49:40
【问题描述】:

我正在尝试创建一个演示网络服务器,它根据 URL 提供的参数返回一个 TwiML Say 块,其中包含自定义文本(是的,POST 会更好,但我不太确定如何执行此操作)。它的工作原理很像 https://www.twilio.com/labs/twimlets/message,只是我想编写自己的代码,以便添加更多自定义。

我从 Weather by Phone 演示开始构建,因为它在 xml 中包含自定义文本。

我创建了我自己的名为 gracklevoice 的谷歌应用引擎,并且我得到了 weatherbyphone 示例。现在,当我尝试简化它时遇到了麻烦。我的代码如下所示:

import os
import wsgiref.handlers

from google.appengine.ext.webapp import template
from google.appengine.ext import webapp

BASE_URL = "http://gracklevoice.appspot.com/"


def xml_response(handler, page, templatevalues=None):
    """                                                                                          
    Renders an XML response using a provided template page and values                            
    """
    path = os.path.join(os.path.dirname(__file__), page)
    handler.response.headers["Content-Type"] = "text/xml"
    handler.response.out.write(template.render(path, templatevalues))

class GracklePage(webapp.RequestHandler):

    def get(self):
        self.post()

    def post(self):
        xml_response(self, 'notification.xml')

def main():
    application = webapp.WSGIApplication([ \
        ('/', GracklePage)],
        debug=True)
    wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
    main()

还有yaml文件:

application: gracklevoice
version: 1
runtime: python27
api_version: 1
threadsafe: no

handlers:
- url: /.*
  script: gracklevoice.py

还有notification.xml

<?xml version="1.0" encoding="UTF-8"?>
<Response>
     <Say voice="alice" language="en-US">                                                             
     This is a message from Grackle.                                                                  
     </Say>
</Response>

这看起来应该很简单,但是当我的客户端应用程序将呼叫 url 设置为 http://gracklevoice.appspot.com/ 时,我收到一个错误而不是语音消息:“我们很抱歉。发生了应用程序错误。再见。”我错过了什么?

查看 appEngine 日志(长度有限,welp),我看到:

2013-11-18 14:45:09.781
Traceback (most recent call last):
E 2013-11-18 14:45:09.781
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/wsgiref/handlers.py", line 86, in run
E 2013-11-18 14:45:09.781
    self.finish_response()
E 2013-11-18 14:45:09.781
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/wsgiref/handlers.py", line 128, in finish_response
E 2013-11-18 14:45:09.781
    self.write(data)
E 2013-11-18 14:45:09.781
  File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/wsgiref/handlers.py", line 204, in write
E 2013-11-18 14:45:09.781
    assert type(data) is StringType,"write() argument must be string"
E 2013-11-18 14:45:09.781
AssertionError: write() argument must be string

【问题讨论】:

  • 如果我将运行时更改为“python”,它可以工作,但 appEngine 中不推荐使用 python2.5。这不是我想要解决的方法。
  • 你检查过 twilio 的日志吗?它们不受长度限制
  • twilio 日志显示以下内容:Status: 500 Internal Server Error Content-Type: text/plain Content-Length: 59 A server error occurred. Please contact the administrator.
  • 这似乎是您的服务器正在返回的响应......您可能可以模拟 twilio 使用 fiddler 所做的请求并在服务器上进行调试。但这就是 twilio 向您提供该消息的原因,因为它从您的应用程序接收响应
  • 对,只是令人沮丧 appEngine 没有给出完整的跟踪。我会看看 fiddler 在我的 mac 上是如何工作的......

标签: python google-app-engine webserver twilio twilio-twiml


【解决方案1】:

这里是 Twilio 开发人员宣传员。使用 unicode() 函数转换 template.render(path, templatevalues) 的输出。您的新代码行将结束为

handler.response.out.write(unicode(template.render(path, templatevalues)))

template.render 函数的输出是 StringType,而不是 str 类型,这是 write 函数需要的。使用 unicode 函数进行转换会将输出转换为您需要的输入格式。

this question about issues with StringType and unicode 中有更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 2011-02-08
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多