2016-09-23 11 views
0

私は以下のスクリプトを使用してサーバーからインベントリ情報を収集し、それをDevice42という製品に送信しています。このスクリプトは現在動作していますが、追加しようとしているAPIの1つがPOSTではなくPUTを使用しています。私はプログラマーではなく、このスクリプトでPythonを使い始めました。このスクリプトは鉄のpythonを使用しています。このスクリプトでPUTメソッドを使用できますか?PythonスクリプトにAPI 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 "root\CIMV2"')[0] # take first 
    bios    = wmi('Get-WmiObject Win32_BIOS -Namespace "root\CIMV2"')[0] 
    operating_system = wmi('Get-WmiObject Win32_OperatingSystem -Namespace "root\CIMV2"')[0] 
    environment  = wmi('Get-WmiObject Win32Reg_ESFFarmNode -Namespace "root\CIMV2"')[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 "root\CIMV2"'): 
    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 "root\CIMV2" | 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 "root\CIMV2" | 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 "root\CIMV2" | 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() 
+0

はい、「PUT」メソッドを使用できますが、最初にそれを書き込む必要があります。 –

+0

基本的に "def post"セクションをコピーしてputを使用するように変更して、PUTを追加しようとしました。その後、私はAPIに「置く」ことを望むデータを含むセクションを追加しましたが、APIがPUTのみを許可するというメッセージが表示され続けています。これは、スクリプトがまだPOSTを実行しようとしていることを意味します。 – user3783772

答えて

0

私の標準的な答えは、urllib2をRequestsパッケージに置き換えることです。それはHTTP作業をもっと簡単にします。

しかし、PUTを動作させるための 'ハック'については、this SO answerをご覧ください。

1

まず最初に、PUTとPOSTの違いを理解する必要があります。私はそれを書くだろうが、コミュニティの別のメンバーは、2つの非常に良い説明を与えたhere

さて、はい、そのスクリプトでリクエストを使用できます。

pip install requests 

さて、ドキュメントができ、要求のライブラリを使用してのいくつかの例を経るといけない:ここでは、このようにそれをインストールピップをインストールした場合の要求をインストールするために、Pythonが要求ライブラリを使用した例であります見つけられるhere

HTTP Get Request。この例では、リクエストライブラリからget関数を呼び出し、urlをパラメータとして渡し、次に返されたタプルからテキストを出力することができます。 GETは何かを返すので、それは一般にタプルのテキスト部分にあり、あなたはそれを印刷することができます。

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

HTTP POST:APIを設定した方法に応じて、URLに投稿する何かを返しますが、それは一般的なエラー処理のために行いますが、あなたはまた、パラメータに渡す必要があります。次に、新しいユーザーエントリへのPOST要求の例を示します。そして再び、あなたはまた、あなただけのRを印刷することができますAPI

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

からの応答を確認するためにtoupleからテキストを印刷することができますし、それはあなたに成功する必要がある応答200を返す必要があります。

PUTの場合:レスポンスをキャッシュすることはできませんので、PUT URLにデータを投稿できますが、エラーがあるかどうかはわかりませんが、POSTと同じ構文を使用することはできません。私は書いたAPIでPUTを使わないので、リクエストライブラリでテキストレスポンスをプリントアウトしようとはしませんでした。

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

は今、あなたのコードにこれを実現するために、あなたはすでにログインのためのあなたのポストに、URLのベースを持っているだけで実行します。あなたのAPIの拡張にデータを置くことについては

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

例えば、APIデバイスの拡張機能、私たちはあなたが既にあなたが必要とする情報と、ペイロード変数の準備ができていると仮定しましょう:

requests.put(API_DEVICE, params=payload) 

そして、それは、URLに置いてください。ご質問がありましたら下記のコメントをお聞かせください。

+0

私はこの情報を見つけましたが、それ以上の研究は、要求モジュールが鉄のpythonで動作しないか、少なくとも仕事をするのは難しいように見えました。 – user3783772

+0

あなたはurllib2で同じタイプのリクエストを行うことができます。リクエストライブラリを使用するよりもずっと面倒です。 –

関連する問題