What specifically needs to be changed in the below in order for a program running on an Ubuntu-latest
GitHub runner to successfully connect to a Twisted web server running on localhost
of the same GitHub runner?
The same code works on a Windows laptop, with only minor changes like using where twistd
on Windows versus which twistd
on Ubuntu as shown below.
SOME RELEVANT CODE:
The code to start the Twisted web server on localhost is in a script called twistdStartup.py
that reads as follows:
import subprocess
import re
import os
escape_chars = re.compile(r'\x1B[[0-?][ -/][@-~]')
def runShellCommand(commandToRun, numLines=999):
proc = subprocess.Popen( commandToRun,cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
while True:
line = proc.stdout.readline()
if line:
if numLines == 1:
return escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n'))
else:
print(escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
else:
break
print("About to create venv.")
runShellCommand("python3 -m venv venv")
print("About to activate venv.")
runShellCommand("source venv/bin/activate")
print("About to install flask.")
runShellCommand("pip install Flask")
print("About to install requests.")
runShellCommand("pip install requests")
print("About to install twisted.")
runShellCommand("pip install Twisted")
##Set environ variable for the API
os.environ['PYTHONPATH'] = '.'
print("Done updating PYTHONPATH. About to start server.")
twistdLocation = runShellCommand("which twistd", 1)
startTwistdCommand = twistdLocation+" web --wsgi myAPI.app &>/dev/null & "
print("startTwistdCommand is: ", startTwistdCommand)
subprocess.call(startTwistdCommand, shell=True)
print("startTwistdCommand should be running in the background now.")
The code in a calling program named startTheAPI.py
that invokes the above twistdStartup.py
is:
myScript = 'twistdStartup.py'
print("About to start Twisted.")
subprocess.Popen(["python", myScript], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print("Just finished starting Twisted.")
The logs produced by that step in the GitHub Action job are as follows:
About to start Twisted.
Just finished starting Twisted.
The results of running the curl command on the same Ubuntu-latest GitHub runner in the next step of the same job after waiting 30 seconds for startup are as follows:
$ curl http://localhost:1234/api/endpoint/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 1234 after 1 ms: Connection refused
The contents of a callTheAPI.py
program that runs the curl
command would look like:
import subprocess
import re
import os
escape_chars = re.compile(r'\x1B[[0-?][ -/][@-~]')
def runShellCommand(commandToRun, numLines=999):
proc = subprocess.Popen( commandToRun,cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
while True:
line = proc.stdout.readline()
if line:
if numLines == 1:
return escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n'))
else:
print(escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
else:
break
print("About to call API.")
runShellCommand("curl http://localhost:1234/api/endpoint/")
print("Done calling API.")
SUMMARY:
The twistdStartup.py
script is running, but is failing to provide any output to the logs despite all the print()
commands. The curl command fails to connect to the correctly-stated http://localhost:1234/api/endpoint/
runShellCommand
. In the linesubprocess.Popen(["python", myScript])
assign the output to a variableproc = subprocess.Popen(["python", myScript])
and read its content (maybe you have to add again the parameters:stdout=subprocess.PIPE, stderr=subprocess.STDOUT
) – Edgar Magallon Feb 05 '23 at 18:37GitHub Actions
but I don't think I have to learn it (but if it's necessary at all then I would try to learn it). I'll try your code and check if the API does run correctly. I'm not sure why you don't get the any output by using the code I provided, in my case it does work. But, by the way, the suggestion about wrap all commands of such methodrunShellCommand("command")
must be considered , since you are using avirtualenv
andsourcing
a script then running severalrunShellCommand
will never work. – Edgar Magallon Feb 06 '23 at 05:45show a link to a minimal GitHub repository that uses a modified/corrected version of the above code to resolve this problem.
I think it'd be hard to found a repository which has that solution. Or do you want the solution provided to your question points to a GitHub repository (in my github repository in case I provide a solution)? – Edgar Magallon Feb 06 '23 at 21:57