如何将python变量编码为URL和Web服务器响应?

时间:2014-10-10 15:16:50

标签: python xml json api url

假设我有一个Python函数,它将多个参数作为输入并返回一个输出。

现在我希望有一个"网络服务" (API)基于此功能。这意味着应该有一个可以使用一些参数调用的URL,这个参数应该传递给函数,函数接受它们并计算相应的结果(输出)并将其传递回Web服务器,在其中转,向用户显示结果(可能是另一个程序)。

如果一个简单的函数接受两个实值参数(例如xy)并返回一个实值结果,则可以组织函数的调用throw get参数。例如:

www.my_web_site.org/my_func_name?x=1.234&y=3.456

因此,我希望网页只包含一个实数。

然而,对于我来说,对于更复杂的输入我应该怎么做才不是那么明显。假设作为一些参数的值,我们可以有列表和字典。我应该如何在URL中对它们进行编码。我可以想象这样的事情:

www.my_web_site.org/my_func_name?x=[1,2,3,4]&y={1:'a',2:'b'}

但是,我不确定这是一个优雅的解决方案。有没有标准怎么做?也许我应该使用XML或JSON来编码输入。

同样的问题适用于输出。假设我们可以将字典或列表或甚至集合作为输出。我应该如何表达它。我应该只使用str(output)还是有另一个"标准"溶液

3 个答案:

答案 0 :(得分:6)

  

我应该使用str(output)吗?

没有!首先,您需要repr(),因为它返回许多内置Python类型的有效Python代码。但是,要解析它的输出,您需要以某种方式执行它。虽然Python有ast.literal_eval()可以安全地运行不受信任的输入(它只处理字符串,数字,元组,列表,字符串,布尔值和None),但它仍然不是很便携,有点难看传递Python代码以获取数据。


最佳解决方案是使用JSON对其进行编码。您可以使用json.dumps进行序列化并json.loads进行反序列化。

  • 它可以在几乎所有语言中解析,因此即使您想从其他工具发送请求,您也可以轻松创建参数
  • 这是一种标准化的格式,也很容易被人类阅读。
  • 对不受信任的数据进行反序列化是安全的(在反序列化时不能编写成为大量内存的JSON,并且不能像pickle那样执行任意代码)
  • 它不会像XML那样增加大量膨胀/无意中听到的。

但是,在发送JSON有效负载时,我会使用POST而不是GET(即使对url编码JSON数据是安全的 - 但在URL中有一长串JSON并不那么漂亮)。这样您就可以简单地将整个JSON结构转储到请求正文中,使用application/json内容类型,在后端甚至可以轻松访问它,例如request.get_json()如果您使用的是Flask。

如果您需要支持JSON中不是natively supported的变量类型,您可以简单地将JSON编码器/解码器子类化,并将这些类型转换为您喜欢的任何符号,例如:日期时间对象的ISO日期字符串。

答案 1 :(得分:0)

RESTful风格

GET /rectangle/1.34553/7.3439
GET /rectangle?x=1.5478;y=7.4535

黑客

GET /rectangle?args=%5B1.5467%2C+7.543%5D  # urlencoded json
GET /rectangle?_=WzEuNTY3NCwgNy4zNTQ2Mjdd  # url-safe base64 encoded json
GET /rectangle?_=eJzTyCkw4PI05EocxYMH6wEAXqha4Q  # left as exercise for the reader

答案 2 :(得分:0)

我们有类似的场景(数据库中间人)。我们从GET开始,然后切换到POST以提供输入,因为不同浏览器中的URL长度有不同的限制。参数的urlencoding也很昂贵,难以吸引眼球。

我们首选的发送输入方式是JSON,但有几个约定。与XML相比,JSON易于阅读,并且可以通过** kwargs方法轻松地为Python函数提供参数。但是,调用者知道参数的名称是依赖的。这比你想象的要难,因为它使得名称的任何变化(例如,参数名称中的拼写错误)难以修复并且引入了一定程度的脆弱性。 (我没有想到明显的解决方案!)单独的列表提供了参数的位置排序。这对我们来说很重要,因为Web服务的另一端是DB PROC,并且SQL在过去的几千年中仍然存在严格的位置参数。对于纯Python服务器端,这对您来说可能不是问题,但也要考虑C ++等。

在输出端,我们在直接JSON和CSV变体之间切换,因为我们不想承担将大量行作为JSON哈希对象处理的成本。因此,我们还使用CSV字符串数组(1行= 1字符串)对行进行编码,使用标题行对象,并将其解析为接收端的行对象数组。

HTH。我怀疑是否有“正确”的答案。