'Python call to Apple Reporter JAR File answering runtime questions to retrieve token

Apple's Reporter API requires getting a token as of August 10, 2017. I'm trying to automate this by calling the JAR file in Python, with parameters so I'm using subprocess, and I need to handle the stdout at runtime. The work in progress below gives me an attribute EXIT error from using WITH. I'm open to other approaches as so far I can't answer the runtime questions so I'm not getting the token returned.

import subprocess
from subprocess import Popen, PIPE

with subprocess.call(['java -jar Reporter.jar p=Reporter.properties sales.generateToken'], shell=True, stdin=PIPE, stdout=PIPE, universal_newlines=True) as p:
    for line in p.stdout: 
        if line.startswith("Please enter your username"):
            answer = 'username'
        elif line.startswith("Please enter your password"):
            answer = 'password'
        else:
            continue # skip it
        print(answer, p.stdin) # provide answer
        p.stdin.flush()


Solution 1:[1]

You can use a magical package called expect!

This is what the expect.script should look like:

$ cat expect.script
#!/usr/bin/expect -f
spawn java -jar Reporter.jar p=Reporter.properties Sales.generateToken
expect -exact "Please enter your username: "
send -- "{username}\r"
expect -exact "\r
Please enter your password: "
send -- "{password}\r"
expect -exact "\r
If you generate a new access token, your existing token will be deleted. You will need to save your new access token within your properties file. Do you still want to continue? (y/n): "
send -- "y\r"
expect eof

You can use python to dynamically create the script file and use it to interact with the Reporter.jar

Here is an example:

import tempfile
import os
from subprocess import check_output

script_exp = """
#!/usr/bin/expect -f
spawn java -jar {reporter_jar_path} p={properties_file} Sales.generateToken
expect -exact "Please enter your username: "
send -- "{username}\\r"
expect -exact "\\r
Please enter your password: "
send -- "{password}\\r"
expect -exact "\\r
If you generate a new access token, your existing token will be deleted. You will need to save your new access token within your properties file. Do you still want to continue? (y/n): "
send -- "y\\r"
expect eof
"""
output_folder = "/tmp/"
with tempfile.NamedTemporaryFile(suffix=".script", dir=output_folder) as script_file_obj:
    script_file = os.path.basename(script_file_obj.name)
    with open(os.path.join(output_folder, script_file), "wt") as out_file:
        content = script_exp.format(
            reporter_jar_path="Reports.jar",
            properties_file="Reporter.properties",
            username="username",
            password="password"
        )
        out_file.write(content)
    print(script_file)
    args = ['/usr/bin/expect', script_file]
    output = check_output(args, cwd=output_folder)
    xml_response = b'<?xml' + output.split(b'<?xml')[-1]

Alternatively you can user pure python to interact with Apple's HTTP endpoints. Here are some examples of that:

https://github.com/fedoco/itc-reporter

https://github.com/chason/pytunes-reporter

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dcjesusfreak05