Lombax
Lombax

Reputation: 871

Using subprocess to run a command via Flask throws KeyError: 'PWD'

I am attempting to use Flask to run a command using subprocess. At a high level what I am trying to do is create a way that a user can hit a URL and pass in a 'test_name' [for PoC I am using smoke]. That test name then gets passed along to flask_test_runner(). In flask_test_runner I am attempting to run the following pytest command

pytest -m test_name -html=report.html --self-contained-html 

using subprocess

command = subprocess.Popen(["pytest", "-m", test_name, "-html=report.html", "--self-contained-html"],
                                   stdout=subprocess.PIPE, stderr=subprocess.PIPE)

All of this is running inside a docker container. I have done my best to validate that docker is not the root cause. At one point I included a RUN pytest at the end of the dockerfile and it kicked off the tests.

My server starts up as expected:

 * Serving Flask app "webserver" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 282-250-075

When I hit the URL http://localhost:5000/apitesting/smoke I get the following back in the Response:

Content-Type: text/html; charset=utf-8
Content-Length: 0
Server: Werkzeug/0.14.1 Python/3.6.4
Date: Wed, 30 May 2018 20:20:39 GMT

and this error in my console:

  File "/usr/local/lib/python3.6/site-packages/pytest_cloud/plugin.py", line 77, in pytest_addoption
    os.path.basename(os.environ['PWD'])
  File "/usr/local/lib/python3.6/os.py", line 669, in __getitem__
    raise KeyError(key) from None
KeyError: 'PWD'

I do not understand why this is happening, so any help is appreciated. Thank you for your time.

For reference my app route is as follows:

@app.route('/apitesting/<test_name>', methods=['GET', 'POST'])
def runsmoketests(test_name):
    '''
    :param test_name: test type passed in by the user 
    '''
    flask_app_cmd = api_flask_test_runner.flask_test_runner(test_name)
    print(flask_app_cmd[0])
    print(flask_app_cmd[1])
    return flask_app_cmd

The flask_test_runner that I call is:

import subprocess

def flask_test_runner(test_name):
    '''
    :param test_name: is passed along from the route /apitesting/<test_name>
    :return: 
    '''

    command = subprocess.Popen(["pytest", "-m", test_name, "-html=report.html", "--self-contained-html"],
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    (out, err) = command.communicate()

    return (out, err)

Upvotes: 1

Views: 699

Answers (1)

Lombax
Lombax

Reputation: 871

Your suggestion was spot on

Since the PWD key is missing you could probably try os.environ['PWD'] = os.getcwd(). Hopefully that will set the variable and your script can continue.

I updated the method to:

def flask_test_runner(test_name):

    # force PWD
    os.environ['PWD'] = os.getcwd()

    command = subprocess.Popen(["pytest", "-m", test_name, "-html=report.html", "--self-contained-html"],
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    return command.communicate()

I can now hit the endpount without error!

$ docker run -p 5000:5000 command_test_cont-1

 * Serving Flask app "webserver" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 282-250-075
172.17.0.1 - - [31/May/2018 13:46:57] "GET /apitesting/smoke HTTP/1.1" 0 -
172.17.0.1 - - [31/May/2018 13:46:59] "GET /favicon.ico HTTP/1.1" 200 -

Upvotes: 1

Related Questions