我正在尝试创建一个Alexa技能,告诉我下一班火车时间何时在我的火车站。我想使用一个名为pygtfs的软件包,它是一个模拟以谷歌通用公共交换Feed规范(GTFS)格式存储的信息的库。我有处理从alexa发送的json对象的文件,它们工作正常。我无法将zip部署包上传到aws lambda。我有一个python脚本,创建一个部署包,但我收到一个错误。该错误不会将正确的文件添加到部署包中。
def _copy_deployment_files(deployment_dir):
for deployment_file in deployment_files:
if os.path.exists(deployment_file):
cmd = "cp{0}{1}".format(deployment_file, deployment_dir).split()
--->return_code = subprocess.call(cmd, shell=False)<----
else:
raise NameError("Deployment file not found [{0}]".format(deployment_file))
在_copy_deployment_files函数中尝试使子进程方法shell参数为true
return_code = subprocess.call(cmd, shell=True)
但它不包含AlexaBaseHandler.py,AlexaDeploymentHandler.py和main.py.
我的问题是如何让create_development将AlexaBaseHandler.py,AlexaDeploymentHandler.py和main.py添加到部署包中,以及如何确保pygtfs包也安装到部署包中?< /强>
以下是return_code = subprocess.call(cmd,shell = True)
时的结果 C:\ProgramData\Anaconda3\python.exe C:/Users/Owner/PycharmProjects/PatcoSchedule/create_deployment.py
Collecting requests==2.8.1
Using cached requests-2.8.1-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.8.1
Collecting sseclient==0.0.11
Collecting requests>=2.0.0 (from sseclient==0.0.11)
Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting six (from sseclient==0.0.11)
Using cached six-1.11.0-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.0.0->sseclient==0.0.11)
Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests>=2.0.0->sseclient==0.0.11)
Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=2.0.0->sseclient==0.0.11)
Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests>=2.0.0->sseclient==0.0.11)
Using cached idna-2.6-py2.py3-none-any.whl
Installing collected packages: chardet, urllib3, certifi, idna, requests, six, sseclient
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 six-1.11.0 sseclient-0.0.11 urllib3-1.22
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\requests already exists. Specify --upgrade to force replacement.
Collecting hammock==0.2.4
Collecting requests>=1.1.0 (from hammock==0.2.4)
Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests>=1.1.0->hammock==0.2.4)
Using cached idna-2.6-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests>=1.1.0->hammock==0.2.4)
Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=1.1.0->hammock==0.2.4)
Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=1.1.0->hammock==0.2.4)
Using cached chardet-3.0.4-py2.py3-none-any.whl
Installing collected packages: idna, urllib3, certifi, chardet, requests, hammock
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 hammock-0.2.4 idna-2.6 requests-2.18.4 urllib3-1.22
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\certifi already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\certifi-2017.7.27.1.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\chardet already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\chardet-3.0.4.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\idna already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\idna-2.6.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\requests already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\requests-2.18.4.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\urllib3 already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\urllib3-1.22.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\__pycache__ already exists. Specify --upgrade to force replacement.
Collecting pygtfs==0.1.3
Using cached pygtfs-0.1.3-py2.py3-none-any.whl
Collecting sqlalchemy>=0.7.8 (from pygtfs==0.1.3)
Using cached SQLAlchemy-1.1.14.tar.gz
Collecting six (from pygtfs==0.1.3)
Using cached six-1.11.0-py2.py3-none-any.whl
Collecting pytz>=2012d (from pygtfs==0.1.3)
Using cached pytz-2017.2-py2.py3-none-any.whl
Collecting docopt (from pygtfs==0.1.3)
Installing collected packages: sqlalchemy, six, pytz, docopt, pygtfs
Running setup.py install for sqlalchemy: started
Running setup.py install for sqlalchemy: finished with status 'done'
Successfully installed docopt-0.6.2 pygtfs-0.1.3 pytz-2017.2 six-1.11.0 sqlalchemy-1.1.14
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\six-1.11.0.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\six.py already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\__pycache__ already exists. Specify --upgrade to force replacement.
Process finished with exit code 0
C:\ProgramData\Anaconda3\python.exe C:/Users/Owner/PycharmProjects/PatcoSchedule/create_deployment.py
Collecting requests==2.8.1
Using cached requests-2.8.1-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.8.1
Collecting sseclient==0.0.11
Collecting requests>=2.0.0 (from sseclient==0.0.11)
Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting six (from sseclient==0.0.11)
Using cached six-1.11.0-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.0.0->sseclient==0.0.11)
Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests>=2.0.0->sseclient==0.0.11)
Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=2.0.0->sseclient==0.0.11)
Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests>=2.0.0->sseclient==0.0.11)
Using cached idna-2.6-py2.py3-none-any.whl
Installing collected packages: chardet, urllib3, certifi, idna, requests, six, sseclient
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 six-1.11.0 sseclient-0.0.11 urllib3-1.22
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\requests already exists. Specify --upgrade to force replacement.
Collecting hammock==0.2.4
Collecting requests>=1.1.0 (from hammock==0.2.4)
Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests>=1.1.0->hammock==0.2.4)
Using cached idna-2.6-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests>=1.1.0->hammock==0.2.4)
Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests>=1.1.0->hammock==0.2.4)
Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests>=1.1.0->hammock==0.2.4)
Using cached chardet-3.0.4-py2.py3-none-any.whl
Installing collected packages: idna, urllib3, certifi, chardet, requests, hammock
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 hammock-0.2.4 idna-2.6 requests-2.18.4 urllib3-1.22
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\certifi already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\certifi-2017.7.27.1.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\chardet already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\chardet-3.0.4.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\idna already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\idna-2.6.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\requests already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\requests-2.18.4.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\urllib3 already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\urllib3-1.22.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\__pycache__ already exists. Specify --upgrade to force replacement.
Collecting pygtfs==0.1.3
Using cached pygtfs-0.1.3-py2.py3-none-any.whl
Collecting sqlalchemy>=0.7.8 (from pygtfs==0.1.3)
Using cached SQLAlchemy-1.1.14.tar.gz
Collecting six (from pygtfs==0.1.3)
Using cached six-1.11.0-py2.py3-none-any.whl
Collecting pytz>=2012d (from pygtfs==0.1.3)
Using cached pytz-2017.2-py2.py3-none-any.whl
Collecting docopt (from pygtfs==0.1.3)
Installing collected packages: sqlalchemy, six, pytz, docopt, pygtfs
Running setup.py install for sqlalchemy: started
Running setup.py install for sqlalchemy: finished with status 'done'
Successfully installed docopt-0.6.2 pygtfs-0.1.3 pytz-2017.2 six-1.11.0 sqlalchemy-1.1.14
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\six-1.11.0.dist-info already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\six.py already exists. Specify --upgrade to force replacement.
Target directory C:\Users\Owner\PycharmProjects\PatcoSchedule\deployments\deployment_15\__pycache__ already exists. Specify --upgrade to force replacement.
处理完成,退出代码为0
这是create_deployment文件,代码是从https://github.com/youngsoul/AlexaDeploymentSample
复制的import os
import subprocess
import zipfile
"""
Script will create an AWS Lambda function deployment.
It expects there to be a deployments directory and it will create a
deployment of the form:
deployment_n
where n is incremented for each deployment based on the existing deployment
directories
"""
root_deployments_dir = "./deployments"
# List of files that should be included in the deployment
# Only the files listed here, and the libraries in the requirements.txt
# file will be included in the deployment.
deployment_files = ['AlexaBaseHandler.py', 'AlexaDeploymentHandler.py', 'main.py']
def _read_requirements():
with open("./requirements.txt", 'r') as f:
install_requirements = f.readlines()
return install_requirements
def _get_immediate_subdirectories(a_dir):
return [name for name in os.listdir(a_dir)
if os.path.isdir(os.path.join(a_dir, name))]
def _make_deployment_dir():
all_deployment_directories = _get_immediate_subdirectories(root_deployments_dir)
max_deployment_number = -1
for deployment_dir in all_deployment_directories:
dir_name_elements = deployment_dir.split("_")
if( len(dir_name_elements) == 2):
if int(dir_name_elements[1]) > max_deployment_number:
max_deployment_number = int(dir_name_elements[1])
if max_deployment_number == -1:
max_deployment_number = 0
deployment_name = "deployment_{0}".format(max_deployment_number+1)
new_deployment_dir_path = "{0}/{1}".format(root_deployments_dir, deployment_name)
if not os.path.exists(new_deployment_dir_path):
os.mkdir(new_deployment_dir_path)
return (new_deployment_dir_path, deployment_name)
def _install_requirements(deployment_requirements, deployment_dir):
"""
pip install <requirements line> -t <deployment_dir>
:param deployment_requirements
:param deployment_dir:
:return:
"""
if os.path.exists(deployment_dir):
for requirement in deployment_requirements:
cmd = "pip install {0} -t {1}".format(requirement, deployment_dir).split()
return_code = subprocess.call(cmd, shell=False)
def _copy_deployment_files(deployment_dir):
for deployment_file in deployment_files:
if os.path.exists(deployment_file):
cmd = "{0} {1}".format(deployment_file, deployment_dir).split()
return_code = subprocess.call(cmd, shell=False)
else:
raise NameError("Deployment file not found [{0}]".format(deployment_file))
def zipdir(dirPath=None, zipFilePath=None, includeDirInZip=False):
"""
Attribution: I wish I could remember where I found this on the
web. To the unknown sharer of knowledge - thank you.
Create a zip archive from a directory.
Note that this function is designed to put files in the zip archive with
either no parent directory or just one parent directory, so it will trim any
leading directories in the filesystem paths and not include them inside the
zip archive paths. This is generally the case when you want to just take a
directory and make it into a zip file that can be extracted in different
locations.
Keyword arguments:
dirPath -- string path to the directory to archive. This is the only
required argument. It can be absolute or relative, but only one or zero
leading directories will be included in the zip archive.
zipFilePath -- string path to the output zip file. This can be an absolute
or relative path. If the zip file already exists, it will be updated. If
not, it will be created. If you want to replace it from scratch, delete it
prior to calling this function. (default is computed as dirPath + ".zip")
includeDirInZip -- boolean indicating whether the top level directory should
be included in the archive or omitted. (default True)
"""
if not zipFilePath:
zipFilePath = dirPath + ".zip"
if not os.path.isdir(dirPath):
raise OSError("dirPath argument must point to a directory. "
"'%s' does not." % dirPath)
parentDir, dirToZip = os.path.split(dirPath)
#Little nested function to prepare the proper archive path
def trimPath(path):
archivePath = path.replace(parentDir, "", 1)
if parentDir:
archivePath = archivePath.replace(os.path.sep, "", 1)
if not includeDirInZip:
archivePath = archivePath.replace(dirToZip + os.path.sep, "", 1)
return os.path.normcase(archivePath)
outFile = zipfile.ZipFile(zipFilePath, "w",
compression=zipfile.ZIP_DEFLATED)
for (archiveDirPath, dirNames, fileNames) in os.walk(dirPath):
for fileName in fileNames:
filePath = os.path.join(archiveDirPath, fileName)
outFile.write(filePath, trimPath(filePath))
#Make sure we get empty directories as well
if not fileNames and not dirNames:
#or
#zipInfo.external_attr = 48
#Here to allow for inserting an empty directory. Still TBD/TODO.
outFile.writestr(zipInfo, "")
outFile.close()
if __name__ == "__main__":
(deployment_dir, deployment_name) = _make_deployment_dir()
_copy_deployment_files(deployment_dir)
install_requirements = _read_requirements()
_install_requirements(install_requirements, deployment_dir)
zipdir(deployment_dir, "{0}/{1}.zip".format(root_deployments_dir, deployment_name))
更新
NVM我想通了。我复制的代码是使用cp作为子进程的复制命令。我查找了操作系统的命令(Windows 10),它是COPY而不是cp。这是对子进程的新调用cmd = "COPY {0}
{1}".format(deployment_file,os.path.abspath(deployment_dir)).split()
答案 0 :(得分:0)