Ubuntu-latest
GitHub Runner에서 실행되는 프로그램이 동일한 GitHub Runner에서 실행되는 Twisted 웹 서버 에 성공적으로 연결하려면 다음에서 정확히 무엇을 변경해야 합니까?localhost
아래와 같이 Ubuntu에서 사용하는 것과 비교하여 where twistd
Windows에서 사용하는 것과 같은 약간의 변경을 통해 동일한 코드를 Windows 노트북에서 실행할 수 있습니다 .which twistd
일부 관련 코드:
localhost에서 Twisted 웹 서버를 시작하는 코드는 스크립트에 있으며 twistdStartup.py
다음 내용을 포함합니다:
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.")
startTheAPI.py
위 코드를 호출하는 호출 프로그램의 코드는 다음 twistdStartup.py
과 같습니다.
myScript = 'twistdStartup.py'
print("About to start Twisted.")
subprocess.Popen(["python", myScript], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print("Just finished starting Twisted.")
GitHub Action 작업의 이 단계에서 생성된 로그는 다음과 같습니다.
About to start Twisted.
Just finished starting Twisted.
시작하기 위해 30초를 기다린 후 동일한 작업의 다음 단계에서 동일한 Ubuntu 최신 GitHub 실행기에서 컬 명령을 실행한 결과는 다음과 같습니다.
$ 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
callTheAPI.py
명령을 실행하는 프로그램의 내용은 curl
다음과 같습니다.
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.")
요약:
스크립트 twistdStartup.py
가 실행 중이지만 모든 명령을 실행했음에도 불구하고 로그에 출력을 제공하지 못합니다 print()
. 컬 명령이 올바르게 지정된 항목에 연결할 수 없습니다.http://localhost:1234/api/endpoint/
답변1
에 대한:
컬 명령이 올바르게 선언된 http://localhost:1234/api/endpoint/에 연결할 수 없습니다.
여기서 가장 큰 문제는 실행하는 모든 명령이 runShellCommand("somecommand")
새 셸에서 실행되므로 명령이 실행된 후에 모든 변경 사항(예: 함수, 변수, 환경 변수 등)이 사라진다는 것입니다.
예를 들어 다음을 시도해 보세요 twistdStartup.py
.
print("Running echo $PATH")
runShellCommand("echo $PATH")
print("Running PATH=/")
runShellCommand("PATH=/")
print("Running echo $PATH")
runShellCommand("echo $PATH")
출력(내 경우에는):
Running echo $PATH
/home/edgar/.local/bin:/home/edgar/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/go/bin
Running PATH=/
Running echo $PATH
/home/edgar/.local/bin:/home/edgar/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/go/bin
위에서 볼 수 있듯이 과제 Running PATH=/
는 다음과 같습니다 .무시당하다다시 달릴 때 runShellCommand("echo $PATH")
.
이것가능한해결책(모든 명령으로 테스트되지는 않음)은 runShellCommand
다음과 같이 모든 메서드 호출을 단일 메서드 호출로 래핑하거나 코드를 셸 스크립트로 변환하는 것입니다.
TwistdStartup.py의 일부:
runShellCommand(
"""
set -e
echo About to create venv.
python3 -m venv venv
echo About to activate venv.
. venv/bin/activate
echo About to install flask.
pip install Flask
echo About to install requests.
pip install requests
echo About to install twisted.
pip install Twisted
export PYTHONPATH='.'
echo Done updating PYTHONPATH. About to start server.
twistdLocation=$(which twistd)
echo "Running ${twistdLocation} web --wsgi customControllerAPI.app &>/dev/null &"
(
$twistdLocation web --wsgi myAPI.py >/dev/null 2>&1
)&
echo startTwistdCommand should be running in the background now.
""")
source venv/bin/activate
GitHub Actions에서 테스트하는 동안 이것이 유효하지 않기 때문에 오류가 발생한다는 것을 발견했습니다 source
(아마도 GitHub의 Ubuntu 기본 셸은 dash
). 반대를
사용하는 대신 source
다음을 사용해야 합니다 .
(훨씬 더 좋습니다): . venv/bin/activate
.
위 명령으로 인해 오류가 발생했습니다. which twistd
제대로 작동하지 않습니다.위니프출처가 없습니다. 따라서 다음 명령은
$twistdLocation web --wsgi customControllerAPI.app &>/dev/null
실패하고 Flask API는 실행되지 않습니다(따라서 다음 메시지가 표시됩니다 Failed to connect to localhost port 1234 after 1 ms: Connection refused
).
에 대한:
그러나 모든 print() 명령을 사용해도 여전히 로그에 출력을 제공할 수 없습니다.
귀하의문서api_server.py
Python 스크립트를 호출하고 계시네요 setup.py
.
apiServer = subprocess.Popen(["python", "setup.py"], stdout=subprocess.DEVNULL, cwd=str(path))
여기서는 명령의 출력을 얻을 수 없으므로 python setup.py
해당 줄을 제거하고 다음을 추가하는 것이 좋습니다.
apiServer = subprocess.Popen(["python", "setup.py"], cwd=str(path),stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
line = apiServer.stdout.readline()
if line:
print(self.escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
else:
break
twistdLocation=$(which twistd)
해당 줄을 다음으로 변경하고 싶을 수도 있습니다twistdLocation=$(command -v twistd)
." which "를 사용하지 않는 이유는 무엇입니까? 그러면 무엇을 사용해야 합니까?set -e
또한 이 줄을 스크립트의 첫 번째 줄에 추가하는 것이 좋습니다. 이 명령은 일부 오류가 발생한 경우 다음 명령의 실행을 중단하는 데 사용됩니다(따라서 일부 종속성이 자체적으로 설치되지 않으면 스크립트가 중지됩니다).- 나는
($twistdLocation web --wsgi myAPI.py >/dev/null 2>&1 )&
Python이 이 명령의 출력을 읽기 위해 기다리는 것을 방지하기 위해 이를 사용합니다subprocess
. 이로 인해 서버가 "무한히" 멈추게 됩니다. stdout
명령의 로그(및)에 관심이 있는 경우 출력을 다음과 같은 파일로 리디렉션해야 합니다.stderr
$twistdLocation ...
(
$twistdLocationn web --wsgi myAPI.py >/tmp/twistd.logs 2>&1
)&
또한 다음과 같이 cat
명령 내용을 포함하도록 github 작업을 편집해야 합니다 ./tmp/twistd.logs
steps:
- uses: actions/checkout@v3
- shell: bash
name: Start the localhost Server
run: |
echo "Current working directory is: "
echo "$PWD"
python code/commandStartServer.py
echo "Checking twistd logs"
cat /tmp/twistd.logs
따라서 이 파일에는 다음 코드가 있어야 합니다.
api_server.py
import os
import re
class api_server:
def __init__(self):
pass
escape_chars = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
def startServer(self):
path = os.getcwd()+"/api/"
print(path)
print("About to start .")
import subprocess
#The version of command on next line runs the server in the background. Comment it out and replace with the one below it if you want to see output.
apiServer = subprocess.Popen(["python", "setup.py"], cwd=str(path),stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
line = apiServer.stdout.readline()
if line:
print(self.escape_chars.sub('', line.decode('utf-8').rstrip('\r|\n')))
else:
break
#The second version of the command below will print output to the console, but will also halt your program because it runs the server in the foreground.
#apiServer = subprocess.Popen(["python", "setup.py"], cwd=str(path))
print("Just finished starting .")
def destroyServer(self):
... # your current code
installer.py
import subprocess
import re
import os
escape_chars = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
def runShellCommand(commandToRun, numLines=999):
proc = subprocess.Popen( commandToRun,cwd=None, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
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
runShellCommand(
"""
set -e
echo About to create venv.
python3 -m venv venv
echo About to activate venv.
. venv/bin/activate
echo About to install flask.
pip install Flask
echo About to install requests.
pip install requests
echo About to install twisted.
pip install Twisted
export PYTHONPATH='.'
echo Done updating PYTHONPATH: $PYTHONPATH. About to start server.
twistdLocation=$(which twistd)
echo "Running ${twistdLocation} web --wsgi customControllerAPI.app &>/dev/null &"
(
$twistdLocation web --wsgi myAPI.py >/dev/null 2>&1
)&
echo startTwistdCommand should be running in the background now.
""")
localhost-api.yml
name: localhost-api
on:
push:
branches:
- main
jobs:
start-and-then-call-localhost-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- shell: bash
name: Start the localhost Server
run: |
echo "Current working directory is: "
echo "$PWD"
python code/commandStartServer.py
echo "Checking twistd logs"
cat /tmp/twistd.logs
- shell: bash
name: Call the localhost API
run: |
echo "Current working directory is: "
echo "$PWD"
python code/commandCallAPI.py
- shell: bash
name: Destroy the localhost Server
run: |
echo "Current working directory is: "
echo "$PWD"
python code/commandDestroyServer.py