Open tchanxx opened 11 months ago
Hello,
I actually got this to work on lambda without using a lambda layer
Here is my python build function to build the package in pulumi but it can be inspiration for someone to create a guide
const buildPython = async (folderPath: string, prismaSchemaDirectory: string, requirementsPath: string): Promise<pulumi.asset.FileArchive> => {
const tempFolder = await mkdtemp(path.join(tmpdir(), "temp-"));
const commands: string[] = [
`cd ${tempFolder}`,
`mkdir -p ${tempFolder}/out/`,
`mkdir -p ${tempFolder}/dist/`,
`cd ${folderPath}`,
`pip install -U -r ${requirementsPath} --target ${tempFolder}/out/`,
// `sed -i '27,55d' ${tempFolder}/out/generated_python/__init__.py`, // Removes some init code for debugging
`rsync -avu -r ${folderPath}/ ${tempFolder}/out/ --ignore-existing --exclude=out/ --exclude=dist/`,
`cd ${prismaSchemaDirectory}`,
"prisma generate",
`rsync -av -r ${prismaSchemaDirectory}/.generated_python/node_modules/prisma/ ${tempFolder}/out/ --exclude=out/ --exclude=dist/`,
`cd ${tempFolder}/out/`,
'for f in query-engine* ; do mv -- "$f" "prisma-$f" ; done',
`zip -r ${tempFolder}/dist/out.zip .`,
`cd ${tempFolder}/`
];
const {stdout, stderr} = await execAsync(commands.join('; '), {
shell: "/bin/bash"
});
const zipFile = `${tempFolder}/dist/out.zip`;
console.log("Built Prisma Package: ", zipFile);
return new pulumi.asset.FileArchive(zipFile);
}
also added the following lambda layer for ssl
arn:aws:lambda:us-east-1:034541671702:layer:openssl-lambda:1
following environment variables:
variables: {
DATABASE_URL_SECRET_ARN: props.connectionString.arn,
PRISMA_CLI_BINARY_TARGETS: "native,rhel-openssl-1.0.x",
PRISMA_HOME_DIR: "/var/task"
}
following pyproject.toml
[tool.prisma]
# cache engine binaries in a directory relative to your project
binary_cache_dir = '.generated_python'
and client/generator in schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["postgresqlExtensions"] // Enable the postgresqlExtensions. Currently in preview
output = "./generated"
binaryTargets = ["native", "rhel-openssl-1.0.x"]
}
// generator
generator pythonClient {
provider = "prisma-client-py"
output = "./PrismaPy"
recursive_type_depth = 5
binaryTargets = ["native", "rhel-openssl-1.0.x"]
}
When I naively deploy this to AWS Lambda using sls deploy, I get ModuleNotFoundError: No module named 'prisma.models' which I think indicates that the client wasn't generated. Is there a trick or any suggestions to get this to generate correctly to be used with the Serverless Framework? I was also looking for ways to run commands after the pip installation so that I could put python3 -m prisma generate there but I couldn't find any.
You can use serverless-scriptable-plugin
. Here is roughly how I have managed to work with Prisma Python client on AWS Lambda with Serverless Framework.
Some notes:
pyproject.toml
and client/generator in schema.prisma
as per sarwaan001's previous commentserverless.yml
plugins:
- serverless-scriptable-plugin
custom:
scriptable:
hooks:
before:package:createDeploymentArtifacts: ./package-with-prisma-client.sh
package:
artifact: .serverless/package.zip
./package-with-prisma-client.sh
#!/bin/bash
PACKAGE_FILE=.serverless/package.zip
rm -f $PACKAGE_FILE && rm -rf output && mkdir -p output
# Get non-Prisma dependencies
pip install -r requirements.txt --target output/libs
# Install Prisma and generate client
pip install prisma
prisma generate --schema ../prisma/schema.prisma --generator pythonClient
# Copy generated models
cp -R /opt/hostedtoolcache/Python/3.11.6/x64/lib/python3.11/site-packages/prisma* output/libs
# Add Prisma engine binaries to zip with `prisma-` prefix
mkdir output/prisma
cp -R .generated_python/node_modules/prisma/query-engine* output/prisma/
(
cd output/prisma/
for f in query-engine*; do
mv -- "$f" "prisma-$f"
done
zip -r ../../$PACKAGE_FILE .
)
# Add dependencies to zip
(cd output/libs && zip -r ../../$PACKAGE_FILE . -x '*__pycache__*')
# Add app to zip
zip -r $PACKAGE_FILE your-src-folder -x '*__pycache__*'
Problem
I searched through the issues and docs and I couldn't find anything mentioning support for running this on serverless functions.
I am trying to use the Serverless Framework to deploy this on AWS Lambda, but I cannot figure out how to package the generated client. I am using the serverless-python-requirements plugin and I am using the
dockerizePip: true
option to compile the Python requirements for Arm64 because my local is Macbook.When I naively deploy this to AWS Lambda using
sls deploy
, I getModuleNotFoundError: No module named 'prisma.models'
which I think indicates that the client wasn't generated.Is there a trick or any suggestions to get this to generate correctly to be used with the Serverless Framework? I was also looking for ways to run commands after the pip installation so that I could put
python3 -m prisma generate
there but I couldn't find any.Suggested solution
Documentation on how to do this.
I am also cross-posting this in the
serverless-python-requirements
repo to ask there as well.