jeff0000 jeff0000 - 2 months ago 10
Python Question

How to "increment" variable outside of for loop block in Python?

I have the following code:

#!/usr/bin/python

import time
import uuid
import hmac
import hashlib
import base64
import json
import urllib3
import certifi
import datetime
import requests
import re
from datetime import datetime

http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED') # Force certificatecheck.ca_certs = certifi.where(), #Path to the Certifi bundle.

# Get the status response from pritunl api

BASE_URL = 'https://<REDACTED>'
API_TOKEN = '<REDACTED>'
API_SECRET = '<REDACTED>'
LOG_PATH = '/var/log/logfiles/'


def auth_request(
method,
path,
headers=None,
data=None,
):
auth_timestamp = str(int(time.time()))


auth_nonce = uuid.uuid4().hex
auth_string = '&'.join([API_TOKEN, auth_timestamp, auth_nonce,
method.upper(), path]
+ (([data] if data else [])))
auth_signature = base64.b64encode(hmac.new(API_SECRET, auth_string,
hashlib.sha256).digest())
auth_headers = {
'Auth-Token': API_TOKEN,
'Auth-Timestamp': auth_timestamp,
'Auth-Nonce': auth_nonce,
'Auth-Signature': auth_signature,
}
if headers:
auth_headers.update(headers)
return http.request(method, BASE_URL + path, headers=auth_headers,
body=data)

response1 = auth_request('GET', '/server')
if response1.status == 200:
pritunlServResponse = json.loads(response1.data) # print pritunlServResponse# print response1.data

Name = [y['name'] for y in pritunlServResponse]
Server_id = [x['id'] for x in pritunlServResponse]

for srv_name in Name:
for srv_id in Server_id:
response2 = auth_request('GET', '/server/' + srv_id
+ '/output')
pritunlServResponse2 = json.loads(response2.data)
py_pritunlServResponse2 = pritunlServResponse2['output']

print ('value of srv_id: ', srv_id, '\n')
print ('value of srv_name: ', srv_name, '\n')

logfile = open(LOG_PATH + srv_name + '_vpn_out.log', 'w')
for log in py_pritunlServResponse2:
if re.search(r'(?!52\.39\.62\.8)', log):
logfile.write('%s\n' % log)

logfile.close()
else:

raise SystemExit


This code visits a website using authentication (the address has been redacted), grabs some text formatted in JSON, and parses two values from the output: "srv_name" and "srv_id". This code then uses the "srv_id" to construct additional HTTP requests to get log files from the server. It then grabs the log files - one for each "srv_id" and names them with the values obtained from "srv_name".

The code as written is syntactically correct, but it's not what I need. As it's written, there is a nested for loop (for srv_id in Server_id:) inside another for loop (for srv_name in Name:).

What I need is to keep the for loop (for srv_id in Server_id:), but "increment" the server name variable (move it to the next value) after each pass though the for loop for srv_id (for srv_id in Server_id:) so that I can have a separate log file with the appropriate server name.

The "fixed" code could look something like:

#!/usr/bin/python

import time
import uuid
import hmac
import hashlib
import base64
import json
import urllib3
import certifi
import datetime
import requests
import re
from datetime import datetime

http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED') # Force certificate check.ca_certs = certifi.where(), #Path to the Certifi bundle.

# Get the status response from pritunl api

BASE_URL = 'https://<REDACTED>'
API_TOKEN = '<REDACTED>'
API_SECRET = '<REDACTED>'
LOG_PATH = '/var/log/logfiles/'


def auth_request(
method,
path,
headers=None,
data=None,
):
auth_timestamp = str(int(time.time()))


auth_nonce = uuid.uuid4().hex
auth_string = '&'.join([API_TOKEN, auth_timestamp, auth_nonce,
method.upper(), path]
+ (([data] if data else [])))
auth_signature = base64.b64encode(hmac.new(API_SECRET, auth_string,
hashlib.sha256).digest())
auth_headers = {
'Auth-Token': API_TOKEN,
'Auth-Timestamp': auth_timestamp,
'Auth-Nonce': auth_nonce,
'Auth-Signature': auth_signature,
}
if headers:
auth_headers.update(headers)
return http.request(method, BASE_URL + path, headers=auth_headers,
body=data)

response1 = auth_request('GET', '/server')
if response1.status == 200:
pritunlServResponse = json.loads(response1.data) # print pritunlServResponse# print response1.data

Name = [y['name'] for y in pritunlServResponse]
Server_id = [x['id'] for x in pritunlServResponse]


for srv_id in Server_id:
response2 = auth_request('GET', '/server/' + srv_id
+ '/output')
pritunlServResponse2 = json.loads(response2.data)
py_pritunlServResponse2 = pritunlServResponse2['output']

print ('value of srv_id: ', srv_id, '\n')
print ('value of Name: ', Name, '\n')

logfile = open(LOG_PATH + srv_name + '_vpn_out.log', 'w')
for log in py_pritunlServResponse2:
if re.search(r'(?!52\.39\.62\.8)', log):
logfile.write('%s\n' % log)

logfile.close()

<CODE TO ADVANCE "Name">
else:

raise SystemExit

Answer

Use:

for srv_name, srv_id in zip(Name, Server_id):
    ...

Better yet, replace:

pritunlServResponse = json.loads(response1.data)

Name = [y['name'] for y in pritunlServResponse]
Server_id = [x['id'] for x in pritunlServResponse]

for srv_name in Name:
    for srv_id in Server_id:
        ...

with:

for srv_name, srv_id in [(resp['name'], resp['id']) for resp in json.loads(response1.data)]:
    ...