简体   繁体   English

如何在 URL 中正确调用带有 * 的 REST-API

[英]how to properly call a REST-API with an * in the URL

i searched the internet (and stackoverflow:D) to find an answer for the following question - and found none that i understood .我搜索了互联网(和stackoverflow:D)以找到以下问题的答案 - 并没有找到我理解的答案。

background:背景:
we want to use a python script to connect our companies CMDB with our AWX/Ansible infrastructure.我们想使用 python 脚本将我们公司的 CMDB 与我们的 AWX/Ansible 基础设施连接起来。
the CMDB has a REST API which supports a (halfway) proper export. CMDB 有一个REST API支持(中途)正确导出。
i'm currently stuck with the implementation of the correct API call.我目前坚持执行正确的 API 调用。
i can call the API itself and authenticate, but i can't call the proper filter to get the results i need.我可以调用 API 本身并进行身份验证,但我无法调用适当的过滤器来获得我需要的结果。
the filter is realized by having the following string within the URL (more in the attached code example)过滤器是通过在 URL 中包含以下字符串来实现的(更多在附加的代码示例中)

Label LIKE "host*"

it seems that python has a problem with the *.似乎 python 的 *.
error message:错误信息:

InvalidURL(f"URL can't contain control characters. {url!r} "


I found some bug reports that there is an issue within some python versions, but i'm way to new to properly understand if this affects me here:D我发现了一些错误报告,表明某些 python 版本中存在问题,但我很容易正确理解这是否会影响到我:D

used python version 3.7.4使用 python 版本 3.7.4

PS: let's see if i can get the markup right:D PS:让我们看看我是否可以正确标记:D


i switched the called URL to determine where exactly the problem occurs.我切换了调用的 URL 以确定问题的确切位置。
it only occurs when i use the SQL like filter part.它仅在我使用 SQL 之类的过滤器部件时发生。
this part is essential since i just want our "hosts" to be returned and not the whole CMDB itself.这部分是必不可少的,因为我只想返回我们的“主机”而不是整个 CMDB 本身。


#import the required classes and such
from http.client import HTTPConnection
import json
#create a HTTP connection client
client = HTTPConnection("cmdb.example.company")
#basic auth and some header details
headers = {'Content-Type': 'application/json',
           'Authorization' : 'Basic my-auth-token'}
#working API call
client.request('GET', '/cmdb/rest/hosts?attributes=Label,Keywords,Tag,Description&limit=10', headers=headers)

#broken API call returns - InvalidURL(f"URL can't contain control characters. {url!r} "
client.request('GET', '/cmdb/rest/hosts?filter=Label LIKE "host*"&attributes=Label,Keywords,Tag,Description&limit=10', headers=headers)
#check and convert the response into a readable (JSON) format
response = client.getresponse()
data = response.read()

#debugging print - show that the returned data is bytes?!
print(data)

#convert the returned data into json
my_json = data.decode('utf8').replace("'", '"')
data = json.loads(my_json)

#only return the data part from the JSON and ignore the meta-overhead
text = json.dumps(data["data"], sort_keys=True, indent=4)
print(text)

so, i want to know how to properly call the API with the described filter and resolve the displayed error.所以,我想知道如何使用描述的过滤器正确调用 API 并解决显示的错误。
can you give me an example i can try or pin-point a beginners mistake i made?你能给我一个例子,我可以尝试或指出我犯的初学者错误吗?
am i affected by the mentioned python bug regarding the URL call with * in it?我是否受到提到的关于 URL 调用中带有 * 的 python 错误的影响?

thanks for helping me out:)谢谢你的协助:)

soooo i found my beginners mistake myself:太棒了,我发现我的初学者自己弄错了:

i used the URL from my browser - and my browser automaticly encodes the special characters within the URL.我在浏览器中使用了 URL - 我的浏览器自动对 URL 中的特殊字符进行编码。
i found the following piece of code within Python3 URL encoding guide and modified the string to fit my needs:)我在 Python3 URL 编码指南中找到了以下代码,并修改了字符串以满足我的需要:)

import urllib.parse
query = ' "host*"'
urllib.parse.quote(query)
'%20%22host%2A%22'


Result: '%20%22host%2A%22'结果:“%20%22host%2A%22”
%20 = " " %20 = " "
%22 = " " " %22 = " " "
%2A = "*" %2A = "*"

so the final code looks somewhat like this:所以最终的代码看起来有点像这样:

#broken API call returns - InvalidURL(f"URL can't contain control characters. {url!r} "
client.request('GET', '/cmdb/rest/hosts?filter=Label LIKE "host*"&attributes=Label,Keywords,Tag,Description&limit=10', headers=headers)

filter=Label LIKE "host*"过滤器=标签喜欢“主机*”

#fixed API call
client.request('GET', '/cmdb/rest/hosts?filter=Label%20LIKE%20%22host%2A%22&attributes=Label,Keywords,Tag,Description&limit=10', headers=headers)

filter=Label%20LIKE%20%22host%2A%22过滤器=标签%20LIKE%20%22host%2A%22

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM