質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

460閲覧

Python APIの結果をdataframeを使ってget_request()にすべての結果を入れることができない

msy47

総合スコア26

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2023/02/06 08:33

編集2023/02/10 18:43

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 1つめのAPI(dataservice/device)でデバイス一覧が出力され
  • デバイス一覧をもとに2つ目のAPI(dataservice/statistics/approute/fec/aggregation)を実行し
  • デバイスx紐付くTunnelの結果をすべて表示したい

前提

デバイス一覧

devicelist

11.1.1.1 21.1.1.2 31.1.1.3 41.1.1.4

例として、2つ目のAPI結果では、1デバイスに複数のTunnel結果が出力される。
1.1.1.1以下に存在する複数のトンネル(abc, edf, ghi, jki...)

example

1deviceId debice loss latency 21.1.1.1 abc 999 999 31.1.1.1 edf 999 999 41.1.1.1 ghi 999 999 51.1.1.1 jkl 999 999

指摘により、1デバイスxn個のトンネルが、デバイス一覧すべてをprintすることで
Logでは取得できていることを確認できたが、
以下の箇所のロジックにて、csvで出力することができない

Tunnel_level_quality_analysis_df = get_request(vmanage_info_df)
以上の一文でget_request(vmanage_info_df)をcsvに入れると認識している。

しかし、csvの結果が、デバイス一覧のみしか出力されていない。
df = df[["deviceId", "system-ip", "host-name", "device-model", "bfdSessionsUp", "bfdSessions"]]
の結果しか入っていない状況です。

想定結果のcsv

Result_from_csv

1System_ip loss_percentage ・・・・ vqoe_score dt 21.1.1.1 99.99・・・・5 2023/01/01 01:01:01 31.1.1.1 99.98・・・・5 2023/01/01 01:01:01 41.1.1.1 99.97・・・・5 2023/01/01 01:01:01 51.1.1.1 99.96・・・・5 2023/01/01 01:01:01 6System_ip loss_percentage ・・・・ vqoe_score dt 71.1.1.2 99.99・・・・5 2023/01/01 01:01:01 81.1.1.2 99.98・・・・5 2023/01/01 01:01:01 91.1.1.2 99.97・・・・5 2023/01/01 01:01:01 101.1.1.2 99.96・・・・5 2023/01/01 01:01:01 11System_ip loss_percentage ・・・・ vqoe_score dt 121.1.1.3 99.99・・・・5 2023/01/01 01:01:01 131.1.1.3 99.98・・・・5 2023/01/01 01:01:01 141.1.1.3 99.97・・・・5 2023/01/01 01:01:01 151.1.1.3 99.96・・・・5 2023/01/01 01:01:01 16System_ip loss_percentage ・・・・ vqoe_score dt 171.1.1.4 99.99・・・・5 2023/01/01 01:01:01 181.1.1.4 99.98・・・・5 2023/01/01 01:01:01 191.1.1.4 99.97・・・・5 2023/01/01 01:01:01 201.1.1.4 99.96・・・・5 2023/01/01 01:01:01

発生している問題・エラーメッセージ

log

1debug1 2debug2 3debug3 4device_url 5https://vmanage_ABC/dataservice/device 6filter_df 7deviceId system_ip・・・bdfSessionsUp bfdSessions 81.1.1.1 1.1.1.1 ・・・ 8 8 91.1.1.2 1.1.1.2 ・・・ 8 8 101.1.1.3 1.1.1.3 ・・・ 8 8 111.1.1.4 1.1.1.4 ・・・ 8 8 12 13query_data 14{'query':(略),{'value':['1.1.1.1'],(略). 'type':'sum'}]}} 15device_list 16<Response [200]> 17200 18df2 19System_ip loss_percentage ・・・・ vqoe_score dt 201.1.1.1 99.99・・・・5 2023/01/01 01:01:01 211.1.1.1 99.98・・・・5 2023/01/01 01:01:01 221.1.1.1 99.97・・・・5 2023/01/01 01:01:01 231.1.1.1 99.96・・・・5 2023/01/01 01:01:01 24df_itertuples 25deviceId system_ip・・・bdfSessionsUp bfdSessions 261.1.1.1 1.1.1.1 ・・・ 8 8 271.1.1.2 1.1.1.2 ・・・ 8 8 281.1.1.3 1.1.1.3 ・・・ 8 8 291.1.1.4 1.1.1.4 ・・・ 8 8 30 31query_data 32{'query':(略),{'value':['1.1.1.1'],(略). 'type':'sum'}]}} 33device_list 34<Response [200]> 35200 36df2 37System_ip loss_percentage ・・・・ vqoe_score dt 381.1.1.2 99.99・・・・5 2023/01/01 01:01:01 391.1.1.2 99.98・・・・5 2023/01/01 01:01:01 401.1.1.2 99.97・・・・5 2023/01/01 01:01:01 411.1.1.2 99.96・・・・5 2023/01/01 01:01:01 42df_itertuples 43deviceId system_ip・・・bdfSessionsUp bfdSessions 441.1.1.1 1.1.1.1 ・・・ 8 8 451.1.1.2 1.1.1.2 ・・・ 8 8 461.1.1.3 1.1.1.3 ・・・ 8 8 471.1.1.4 1.1.1.4 ・・・ 8 8 48 49query_data 50{'query':(略),{'value':['1.1.1.1'],(略). 'type':'sum'}]}} 51device_list 52<Response [200]> 53200 54df2 55System_ip loss_percentage ・・・・ vqoe_score dt 561.1.1.3 99.99・・・・5 2023/01/01 01:01:01 571.1.1.3 99.98・・・・5 2023/01/01 01:01:01 581.1.1.3 99.97・・・・5 2023/01/01 01:01:01 591.1.1.3 99.96・・・・5 2023/01/01 01:01:01 60df_itertuples 61deviceId system_ip・・・bdfSessionsUp bfdSessions 621.1.1.1 1.1.1.1 ・・・ 8 8 631.1.1.2 1.1.1.2 ・・・ 8 8 641.1.1.3 1.1.1.3 ・・・ 8 8 651.1.1.4 1.1.1.4 ・・・ 8 8 66 67query_data 68{'query':(略),{'value':['1.1.1.1'],(略). 'type':'sum'}]}} 69device_list 70<Response [200]> 71200 72df2 73System_ip loss_percentage ・・・・ vqoe_score dt 741.1.1.4 99.99・・・・5 2023/01/01 01:01:01 751.1.1.4 99.98・・・・5 2023/01/01 01:01:01 761.1.1.4 99.97・・・・5 2023/01/01 01:01:01 771.1.1.4 99.96・・・・5 2023/01/01 01:01:01 78df_itertuples 79deviceId system_ip・・・bdfSessionsUp bfdSessions 801.1.1.1 1.1.1.1 ・・・ 8 8 811.1.1.2 1.1.1.2 ・・・ 8 8 821.1.1.3 1.1.1.3 ・・・ 8 8 831.1.1.4 1.1.1.4 ・・・ 8 8

該当のソースコード(df2はprintで確認_回答反映

Python

1import json 2import boto3 3import csv 4import numpy as np 5import pandas as pd 6import requests 7import os 8import urllib3 9urllib3.disable_warnings(urlib3.exceptions.InsecureRequests.InsecureRequestWarning) 10from io import StringIO 11from datetime import datetime 12 13headers_post = ["accept": "application/json", "Content-Type": "application/json"] 14 15print("debug1") 16 17def lambda_handler(event, context): 18 s3 = boto3.resource(`s3`) 19 bucket_name = os.environ.get(`S3_BUCKET`) 20 21 vmanage_info = "tmp/vmanage_info.csv" 22 bucket.download_file(os.environ.get(`CSV_VMANAGE_INFO`), vmanage_info) 23 vmanage_info_df = pd.read.csv(vmanage_info) 24 25 device_info = "/tmp/device_info.csv" 26 bucket.download_file(os.environ.get(`CSV_DEVICE_INFO`), device_info) 27 device_info_df = pd.read.csv(device_info) 28 29 Tunnel_level_quality_analysis_df = get_request(vmanage_info_df) 30 31 tmp_csv = "/tmp/Tunnel_level_quality_analysis.csv" 32 Tunnel_level_quality_analysis_df.to_csv(tmp_csv, encoding='utf-8', index=False) 33 34 s3 = boto3.resource('s3') 35 s3.meta.client.upload_file(tmp_csvm 'utlink-vmanage-bucket', 'csv/Tunnel_level_quality_analysis.csv') 36 37 print("debug2") 38 39def get_request(vmanage_info_df): 40 #api_datalist = [] 41 for row in vmanage_info_df.itertuples(): 42 vmanage_host = row[1] 43 vmanage_port = row[2] 44 vmanage_username = row[3] 45 vmanage_password = row[4] 46 47 base_url = `https://%s:%s`%(vmanage_host, vmanage_port) 48 49 login_action = `/j_security_check` 50 51 login_data = {`j_username` : vmanage_username, `j_password` : vmanage_password} 52 53 login_url = base_url + login_action 54 55 session = requests.session() 56 57 pring("debug3") 58 59 login_response = session.post(url=login_url, data=login_data, verify=False) 60 if b`<html>` in login_response.content: 61 print("Login token Failed") 62 exit(1) 63 64 xsrf_token_url = base_url + '/dataservice/client/token' 65 66 login_token = session.get(url=xsrf_token_url, verify=False) 67 if login_token.status_code == 200: 68 if b`<html>` in login_token.content: 69 print("Login token Failed") 70 exit(1) 71 72 session.headers[`X-XSRF-TOKEN`] = login_token.content 73 74 75 device_url = base_url + `/dataservice/device` 76 print("device_url") 77 print(device_url) 78 79 device_list = session.get(url=device_url, verify=False) 80 if device_list.status_code = 200: 81 json_data = device_list.json() 82 else: 83 print (device_list.status_code) 84 85 df = pd.json_normalize(json_data["data"] 86 df = df[(df["device-type"] == "vedge") & (df["reachability"] == "reachable")] 87 88 print("filter_df") 89 print(df) 90 91 df = df[["deviceId", "system-ip", "host-name", "device-model", "bfdSessionsUp", "bfdSessions"]] 92 93 for data in df.itertuples(): 94 System_ip = data[1] 95 query_data = ["query":(),["value":[System_ip],()"type":"sum"}]}} 96 print("query_data") 97 print(query_data) 98 99 device_url = base_url + '/dataservice/statistics/approute/fec/aggregation' 100 #print("device_url") 101 #print(device_url) 102 103 device_list = session.post(url=device_url, json=query_data, headers=headers_post, verify=False) 104 print("device_list") 105 print(device_list) 106 107 if device_list.status_code == 200: 108 print (device_list.status_code) 109 json_data = device_list.json() 110 111 df2 = pd.json_normalize(json_data["data"]) 112 113 #先頭にsystemip 114 df2.insert(0, 'System_ip', data[1]) 115 #末尾にdatetime 116 df2['dt'] = datetime.now(),strftime('%Y%m%d% %H:%M:%S') 117 c = df2.pop('dt') 118 df2.insert(df2.shape[1], c.name, c) 119 120 print("df2") 121 print(df2) 122 123 else: 124 print(device_list.status_code) 125 126 127 return df

試したこと

forやdfなどの位置を組み替えてデバッグ中なのですが、
いずれも末尾のデバイス結果しか出力されず

理想 以下のdf結果において、デバイス分出力したい

DeviceList

1deviceId system_ip・・・bdfSessionsUp bfdSessions 21.1.1.1 1.1.1.1 ・・・ 8 8 31.1.1.2 1.1.1.2 ・・・ 8 8 41.1.1.3 1.1.1.3 ・・・ 8 8 51.1.1.4 1.1.1.4 ・・・ 8 8

想定結果

Result

1System_ip loss_percentage ・・・・ vqoe_score dt 21.1.1.1 99.99・・・・5 2023/01/01 01:01:01 31.1.1.1 99.98・・・・5 2023/01/01 01:01:01 41.1.1.1 99.97・・・・5 2023/01/01 01:01:01 51.1.1.1 99.96・・・・5 2023/01/01 01:01:01 6System_ip loss_percentage ・・・・ vqoe_score dt 71.1.1.2 99.99・・・・5 2023/01/01 01:01:01 81.1.1.2 99.98・・・・5 2023/01/01 01:01:01 91.1.1.2 99.97・・・・5 2023/01/01 01:01:01 101.1.1.2 99.96・・・・5 2023/01/01 01:01:01 11System_ip loss_percentage ・・・・ vqoe_score dt 121.1.1.3 99.99・・・・5 2023/01/01 01:01:01 131.1.1.3 99.98・・・・5 2023/01/01 01:01:01 141.1.1.3 99.97・・・・5 2023/01/01 01:01:01 151.1.1.3 99.96・・・・5 2023/01/01 01:01:01 16System_ip loss_percentage ・・・・ vqoe_score dt 171.1.1.4 99.99・・・・5 2023/01/01 01:01:01 181.1.1.4 99.98・・・・5 2023/01/01 01:01:01 191.1.1.4 99.97・・・・5 2023/01/01 01:01:01 201.1.1.4 99.96・・・・5 2023/01/01 01:01:01

補足情報(FW/ツールのバージョンなど)

Python3.9
ここにより詳細な情報を記載してください。

回答動作確認コード

文字数制限のため追記箇所のみ記載

・・・・(略)・・・・ dfs = [] def lambda_handler(event, context): ・・・・(略)・・・・ print("df2") print(df2) dfs.append(df2) ・・・・(略)・・・・ df_con = pd.concat(dfs).reset_index(drop=True) print(df_con) return df_con

Result

1System_ip loss_percentage ・・・・ vqoe_score dt 21.1.1.1 99.99・・・・5 2023/01/01 01:01:01 31.1.1.1 99.98・・・・5 2023/01/01 01:01:01 41.1.1.1 99.97・・・・5 2023/01/01 01:01:01 51.1.1.1 99.96・・・・5 2023/01/01 01:01:01 6・・・・(略)・・・・ 71.1.1.4 99.99・・・・5 2023/01/01 01:01:01 81.1.1.4 99.98・・・・5 2023/01/01 01:01:01 91.1.1.4 99.97・・・・5 2023/01/01 01:01:01 101.1.1.4 99.96・・・・5 2023/01/01 01:01:01

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2023/02/06 08:59

「for data in df.itertuples():」でのdfと、そのループ中で 「df = pd.json_normalize(json_data["data"])」と代入しているのは 意図通りでしょうか? 同じdfという変数を使っているあたりに混乱があるような気がします。
msy47

2023/02/06 09:26

can110さん ご指摘ありがとうございます。 これ、まずいのでしょうかそこが理解できておらず。 その後のdf.insertを使用するためにまずはjsonをdfにデータとして入れて上げる必要があるのかなと言う認識でした。 取得した結果に、時間(datetime)と、dviceid(デバイスIP)をデバイスごとにつけたいためです。
msy47

2023/02/06 10:17

>「for data in df.itertuples():」でのdf →deviceidを取得するためのdfです deviceId system_ip・・・bdfSessionsUp bfdSessions 1.1.1.1 1.1.1.1 ・・・ 8 8 1.1.1.2 1.1.1.2 ・・・ 8 8 1.1.1.3 1.1.1.3 ・・・ 8 8 1.1.1.4 1.1.1.4 ・・・ 8 8 >そのループ中で >「df = pd.json_normalize(json_data["data"])」 →device_list = session.post(~ を受けて、json_data = device_list.json()を入れ込むためなので 全然別物でした!? なんかできそうな気がします。。。
can110

2023/02/06 12:45

別物は別の変数で扱わないと混乱するので、一度そのあたりを整理すると解決へ進めるかと思います。
msy47

2023/02/09 03:38

can110さん ご助言ありがとうございます! 以下で、printではデバイスごとのトンネルステータスを確認できたのですが、その結果をcsvへ入れることができずにいます。再度、ご助言いただきたく。 修正した箇所 ```107 if device_list.status_code == 200: if分にいかを追加 ``` ```120-123 df.insert(0, 'System_ip', data[1]) df['df'] = datetime.now(),strftime('%Y%m%d% %H:%M:%S') c = df.pop('dt') df.insert(df.shape[1], c.name, c) ``` ```fix_107 if device_list.status_code == 200: json_data = device_list.json() df2 = pd.json_normalize(json_data["data"]) #先頭にsystemip df2.insert(0, 'System_ip', data[1]) #末尾にdatetime df2['df'] = datetime.now(),strftime('%Y%m%d% %H:%M:%S') c = df2.pop('dt') df.insert(df2.shape[1], c.name, c) print("df2") print(df2) else: print(device_list.status_code) ``` 問題 29行目の Tunnel_level_quality_analysis_df = get_request(vmanage_info_df) 以上の一文でget_request(vmanage_info_df)をcsvに入れると認識しているのですが、 csvの結果が 91行目のdf = df[["deviceId", "system-ip", "host-name", "device-model", "bfdSessionsUp", "bfdSessions"]] の結果しか入っていない状況です。
can110

2023/02/09 04:15

とりあえずこの欄は修正依頼のやり取り用の欄であり、 コードも正しく表示されないので質問本文に反映させたほうがよいです。
msy47

2023/02/09 05:13

can110さん ご指摘ありがとうございます。 修正後の結果と、現時点の問題を修正・追記いたしました。
guest

回答1

0

ベストアンサー

全体的な処理の流れを完全に把握できていませんが、提示コードでのdf2を行方向に1つにまとめたいということであれば、以下のような感じで各df2をリストに貯めておき、最後にconcatで結合してやればよいです。
なお、提示された想定結果では見出し行が複数行存在しますが、提示コードでは最後にto_csvを1回しか読んでいないので、見出し行も先頭1行だけとなります。

Python

1import pandas as pd 2 3def get_request(): 4 5 dfs = [] 6 for i in range(3): 7 # 何らかの処理でdf2を作成 8 df2 = pd.DataFrame({'v1':[i,i*10]}) 9 dfs.append(df2) 10 11 df_ret = pd.concat(dfs).reset_index(drop=True) 12 return df_ret 13 14df_ret = get_request() 15print(df_ret) 16""" 17 v1 180 0 191 0 202 1 213 10 224 2 235 20 24"""

投稿2023/02/09 07:40

can110

総合スコア38233

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msy47

2023/02/09 10:11

can110さん ご回答ありがとうございます!現在、試行錯誤して組み込んでおります。 質問なのですが、 組み込み箇所としては def get_request(): は def get_request(vmanage_info_df): の位置 という認識で間違いないでしょうか。 ># 何らかの処理でdf2を作成 というのか for row in vmanage_info_df.itertuples(): からなのか for data in df.itertuples(): からなのか 1つ目の認識ですが、間違いないでしょうか。
can110

2023/02/09 10:15

> 組み込み箇所としては~ はい。 > ~からなのか~ dfs = []は関数呼び出しの先頭 dfs.append(df2)は質問コードでのprint(df2)してるところ 最後のconcatは関数末尾 という想定での回答となります。
msy47

2023/02/10 01:54

can110さん 回答いただいたソースを反映したのですが →該当のソースコード(回答を反映 print(df_ret)も表示されず 反映方法が間違っているのでしょうか
can110

2023/02/10 02:07

「if device_list.status_code = 200:」などあきらかにおかしい部分があります。 まずはしっかりとデバッグして、既存の動作(各df2が作成できる)までができたあとに 回答分を反映させてください。
msy47

2023/02/10 08:09 編集

can110さん ソースの間違い、見づらさ申し訳ありません。当方事情により目視で手移ししている次第です。 現在の「該当のソースコード(df2はprintで確認_回答反映」については df2でlog上では「発生している問題・エラーメッセージ」が出力されている状態です。 しかし 137,138行目の以下を、コメントアウトを外した場合エラーとなります。 #df_ret = get_request(vmanage_info_df) #print(df_ret) エラー NameError: name 'vmanage_info_df' is not defined となりました。 追記となります。 124行目のdf2 = pd.dataFrame({'v1' :[i, i*10]})をいれるとエラーが発生します。 コメントアウトすると動作します。 エラー "module 'pandas' hs no attribute 'dataFrame'" →こちらスペルミスでした。 pd.dataFrame→ pd.DataFrame
can110

2023/02/10 08:15

> 当方事情により目視で手移ししている次第です。 まずはローカルで実行でき、動作をデバッグできるテスト的な環境を用意しましょう。 API呼出などテスト環境で動かせない部分は、テストデータを返す関数なりを呼ぶように差し替えればよいです。 そのテスト環境で 「Web上の既存のものと同じ動作ができて(意図とは異なるが)同じ結果データができる」 といったところまで実現できたあとに回答分を反映するようにしないと 現状のトライアンドエラーを繰り返す状況では解決は困難かと思います。
msy47

2023/02/10 08:50

can110さん 言い訳失礼しました。 ご回答頂いた件について補足いただきたく思います。 ==== # 何らかの処理でdf2を作成 df2 = pd.DataFrame({'v1':[i,i*10]}) ==== 以下の部分がdf2に入る結果とロジックと認識しております。間違いないでしょうか。 print(df2)のdf2が必要な結果、追加していく結果。 ==== if device_list.status_code == 200: json_data = device_list.json() df2 = pd.json_normalize(json_data["data"]) #先頭にsystemip df2.insert(0, 'System_ip', data[1]) #末尾にdatetime df2['df'] = datetime.now(),strftime('%Y%m%d% %H:%M:%S') c = df2.pop('dt') df.insert(df2.shape[1], c.name, c) print("df2") print(df2) ==== 以下のような認識は間違いでしょうか。そうなるとfor i in range(3):の意味がなくなってしまいますね。・・・ ==== df2 = pd.DataFrame(df2) ====
can110

2023/02/10 09:05

回答コードは動作の流れを説明するためのものなので forループの回数やdf2の中身など、具体的な意味はないです。 質問コードでdf2が複数個できあがるなら、回答コードのように連結すればよいということです。
msy47

2023/02/10 09:43

can110さん 思考停止しておりました。必要な結果を出力することができました!ありがとうございます! ~~~ >回答コードは動作の流れを説明するためのものなので >forループの回数やdf2の中身など、具体的な意味はないです。 >質問コードでdf2が複数個できあがるなら、回答コードのように連結すればよいということです。 ~~~
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問