需要帮助将API PUT方法添加到Python脚本

我正在使用以下脚本从服务器收集库存信息并将其发送到名为Device42的产品。 该脚本目前正常工作,但我尝试添加的API之一使用PUT而不是POST。 我不是程序员,只是开始在这个脚本中使用python。 这个脚本使用铁蟒。 该脚本中可以使用PUT方法吗?

"""
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
##################################################
# a sample script to show how to use
#   /api/ip/add-or-update
#   /api/device/add-or-update
#
# requires ironPython (http://ironpython.codeplex.com/) and
# powershell (http://support.microsoft.com/kb/968929)
##################################################

import clr

clr.AddReference('System.Management.Automation')

from System.Management.Automation import (
PSMethod, RunspaceInvoke
)
RUNSPACE = RunspaceInvoke()

import urllib
import urllib2
import traceback
import base64
import math
import ssl
import functools
BASE_URL='https://device42_URL'

API_DEVICE_URL=BASE_URL+'/api/1.0/devices/'
API_IP_URL    =BASE_URL+'/api/1.0/ips/'
API_PART_URL=BASE_URL+'/api/1.0/parts/'
API_MOUNTPOINT_URL=BASE_URL+'/api/1.0/device/mountpoints/'
API_CUSTOMFIELD_URL=BASE_URL+'/api/1.0/device/custom_field/'

USER     ='usernme'
PASSWORD ='password'

old_init = ssl.SSLSocket.__init__
@functools.wraps(old_init)
def init_with_tls1(self, *args, **kwargs):
kwargs['ssl_version'] = ssl.PROTOCOL_TLSv1
old_init(self, *args, **kwargs)
ssl.SSLSocket.__init__ = init_with_tls1

def post(url, params):
"""
http post with basic-auth
params is dict like object
"""
try:
    data= urllib.urlencode(params) # convert to ascii chars
    headers = {
        'Authorization' : 'Basic '+ base64.b64encode(USER + ':' + PASSWORD),
        'Content-Type'  : 'application/x-www-form-urlencoded'
    }

    req = urllib2.Request(url, data, headers)

    print '---REQUEST---',req.get_full_url()
    print req.headers
    print req.data

    reponse = urllib2.urlopen(req)

    print '---RESPONSE---'
    print reponse.getcode()
    print reponse.info()
    print reponse.read()
except urllib2.HTTPError as err:
    print '---RESPONSE---'
    print err.getcode()
    print err.info()
    print err.read()
except urllib2.URLError as err:
    print '---RESPONSE---'
    print err

def to_ascii(s):
    # ignore non-ascii chars
    return s.encode('ascii','ignore')

def wmi(query):
    return [dict([(prop.Name, prop.Value) for prop in psobj.Properties]) for psobj in RUNSPACE.Invoke(query)]
def closest_memory_assumption(v):
    return int(256 * math.ceil(v / 256.0))

def add_or_update_device():
    computer_system  = wmi('Get-WmiObject Win32_ComputerSystem -Namespace "rootCIMV2"')[0] # take first
    bios             = wmi('Get-WmiObject Win32_BIOS -Namespace "rootCIMV2"')[0]
    operating_system = wmi('Get-WmiObject Win32_OperatingSystem -Namespace "rootCIMV2"')[0]
    environment      = wmi('Get-WmiObject Win32Reg_ESFFarmNode -Namespace "rootCIMV2"')[0]
    mem              = closest_memory_assumption(int(computer_system.get('TotalPhysicalMemory')) / 1047552)
    dev_name         = to_ascii(computer_system.get('Name')).upper()
    fqdn_name        = to_ascii(computer_system.get('Name')).upper() + '.' + to_ascii(computer_system.get('Domain')).lower()
device = {
    'memory'        : mem,
    'os'            : to_ascii(operating_system.get('Caption')),
    'osver'         : operating_system.get('OSArchitecture'),
    'osmanufacturer': to_ascii(operating_system.get('Manufacturer')),
    'osserial'      : operating_system.get('SerialNumber'),
    'osverno'       : operating_system.get('Version'),
    'service_level' : environment.get('Environment'),
    'notes'         : 'Test w/ Change to Device name collection'
}
devicedmn = ''
for dmn in ['Domain1', 'Domain2', 'Domain3', 'Domain4', 'Domain5']:
    if dmn == to_ascii(computer_system.get('Domain')).strip():
        devicedmn = 'Domain'
        device.update({ 'name' : fqdn_name, })
        break    
if devicedmn != 'Domain':
    device.update({
        'name': dev_name,
        })
manufacturer = ''
for mftr in ['VMware, Inc.', 'Bochs', 'KVM', 'QEMU', 'Microsoft Corporation', 'Xen']:
    if mftr == to_ascii(computer_system.get('Manufacturer')).strip():
        manufacturer = 'virtual'
        device.update({ 'manufacturer' : 'vmware', })
        break    
if manufacturer != 'virtual':
    device.update({
        'manufacturer': to_ascii(computer_system.get('Manufacturer')).strip(),
        'hardware': to_ascii(computer_system.get('Model')).strip(),
        'serial_no': to_ascii(bios.get('SerialNumber')).strip(),
        'type': 'Physical',
        })    
cpucount = 0
for cpu in wmi('Get-WmiObject Win32_Processor  -Namespace "rootCIMV2"'):
    cpucount += 1
    cpuspeed = cpu.get('MaxClockSpeed')
    cpucores = cpu.get('NumberOfCores')
if cpucount > 0:

    device.update({
        'cpucount': cpucount,
        'cpupower': cpuspeed,
        'cpucore':  cpucores,
        })
hddcount = 0
hddsize = 0
for hdd in wmi('Get-WmiObject Win32_LogicalDisk  -Namespace "rootCIMV2" | where{$_.Size -gt 1}'):
    hddcount += 1
    hddsize += hdd.get('Size') / 1073741742
if hddcount > 0:

    device.update({
        'hddcount': hddcount,
        'hddsize': hddsize,
        })
post(API_DEVICE_URL, device)

for hdd in wmi('Get-WmiObject Win32_LogicalDisk  -Namespace "rootCIMV2" | where{$_.Size -gt 1}'):
    mountpoint = {
          'mountpoint' : hdd.get('Name'),
          'label' : hdd.get('Caption'),
          'fstype' : hdd.get('FileSystem'),
          'capacity' : hdd.get('Size') / 1024 / 1024,
          'free_capacity' : hdd.get('FreeSpace') / 1024 / 1024,
          'device' : dev_name,
          'assignment' : 'Device',
    }
    post(API_MOUNTPOINT_URL, mountpoint)

network_adapter_configuration = wmi('Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "rootCIMV2" | where{$_.IPEnabled -eq "True"}')

for ntwk in network_adapter_configuration:
    for ipaddr in ntwk.get('IPAddress'):
        ip = {
            'ipaddress'  : ipaddr,
            'macaddress' : ntwk.get('MACAddress'),
            'label'      : ntwk.get('Description'),
            'device'     : dev_name,
        }
        post(API_IP_URL, ip)

def main():
    try:
        add_or_update_device()
    except:
        traceback.print_exc()

if __name__ == "__main__":
    main()

首先确定你需要了解PUT和POST之间的区别。 我会写出来,但社区的另一位成员在这里对这两者进行了非常好的描述。

现在,是的,您可以使用该脚本的请求。 这里是python使用请求库的一个例子,为了安装请求,如果你已经安装了pip,像这样安装它:

pip install requests

为了避免使用Requests库的一些例子,可以在这里找到文档。

HTTP获取请求。 因此,对于此示例,您可以从请求库中调用get函数,将url作为参数,然后可以从返回的touple中打印出文本。 由于GET会返回一些东西,它通常会在文本部分的touple中让你打印它。

r = requests.get('http://urlhere.com/apistuffhere')
print(r.text)

HTTP POST:发布到一个url,这取决于API的设置如何返回,它通常用于错误处理,但你也必须传入参数。 以下是向新用户条目发送POST请求的示例。 再次,您可以打印来自touple的文本以检查API的响应

payload = {'username': 'myloginname', 'password': 'passwordhere'}
r = requests.post('https://testlogin.com/newuserEntry', params=payload)
print(r.text)

或者,您可以打印只需r,它应该返回您的响应200应该是成功的。

对于PUT:您必须记住,响应不能缓存,因此您可以将数据发布到PUT网址,但您不会知道是否存在错误,但使用与POST相同的语法。 我没有尝试在使用请求库的PUT请求中打印出文本响应,因为我没有在我编写的任何API中使用PUT。

requests.put('http://urlhere.com/putextension')

现在为了在你的代码中实现这个功能,你已经拥有了url的基础,在你登录的文章中只需要做:

payload = {'username': USERNAME, 'passwd':PASSWORD}
r = requests.post('https://loginurlhere.com/', params=payload)
#check response by printing text
print (r.text)

至于把数据放到你的api的扩展中,让我们假设你已经有了一个有效负载变量,可以随时准备你需要的信息,例如API设备扩展:

requests.put(API_DEVICE, params=payload)

这应该放在网址上。 如果您在下面有任何问题评论,如果您愿意,我可以回答他们。


我的标准答案是用Requests包替换urllib2。 它使得HTTP的工作更容易。

但看看这个答案为'黑客'让PUT工作。

链接地址: http://www.djcxy.com/p/41043.html

上一篇: Need help adding API PUT method to Python script

下一篇: Laravel 5.2 different routing types