Skip to content

Commit

Permalink
chore(python): change base image (#227)
Browse files Browse the repository at this point in the history
Changed base image to AWS official
Also fixed being able to set env vars on the function
  • Loading branch information
eladcon authored May 12, 2024
1 parent 00b4f2b commit d457129
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 27 deletions.
4 changes: 2 additions & 2 deletions python/function.test.w
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ let func = new cloud.Function(new python.InflightFunction(
allow: ["get", "put"],
}
},
));
), { env: { "FOO": "bar" } });

test "invokes the function" {
let res = func.invoke("function1");
log("res: {res ?? "null"}");
expect.equal(Json.parse(res!).get("body"), "Hello!");
expect.equal(bucket.get("test.txt"), "Hello, world!function1");
expect.equal(bucket.get("test.txt"), "Hello, world!function1bar");
}
4 changes: 2 additions & 2 deletions python/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion python/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@winglibs/python",
"description": "python library for Wing",
"version": "0.0.1",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://github.com/winglang/winglibs.git",
Expand Down
13 changes: 12 additions & 1 deletion python/sim/containers.w
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ pub struct ContainerOpts {
/** Internal container port to expose */
flags: Map<str>?; // flags to pass to the docker run command
port: num?;
exposedPort: num?; // internal port to expose
env: Map<str?>?;
readiness: str?; // http get
replicas: num?; // number of replicas
public: bool?; // whether the container should have a public url (default: false)
args: Array<str>?; // container arguments
volumes: Map<str>?; // volumes to mount
network: str?; // network to connect to
entrypoint: str?; // entrypoint to run

/**
* A list of globs of local files to consider as input sources for the container.
Expand Down Expand Up @@ -170,7 +172,11 @@ pub class Container {

if let port = opts.port {
dockerRun.push("-p");
dockerRun.push("{port}");
if let exposedPort = opts.exposedPort {
dockerRun.push("{exposedPort}:{port}");
} else {
dockerRun.push("{port}");
}
}

if let env = opts.env {
Expand All @@ -196,6 +202,11 @@ pub class Container {
}
}

if let entrypoint = opts.entrypoint {
dockerRun.push("--entrypoint");
dockerRun.push(entrypoint);
}

dockerRun.push(this.imageTag);

if let runArgs = this.props.args {
Expand Down
15 changes: 15 additions & 0 deletions python/sim/function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { Function: SimFunction } = require("@winglang/sdk/lib/target-sim/function.js");

module.exports.Function = class Function extends SimFunction {
constructor(
scope,
id,
inflight,
props = {},
) {
super(scope, id, inflight, props);
for (let e in props.env) {
inflight.inner.service.addEnvironment(e, props.env[e]);
}
}
};
21 changes: 15 additions & 6 deletions python/sim/inflight.w
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,39 @@ pub class Inflight impl cloud.IFunctionHandler {
pathEnv: pathEnv,
);

let port = math.floor(math.random() * 1000 + 9000);
let runtimePort = math.floor(math.random() * 1000 + 9000);
let args = Array<str>[
"/var/runtime/bootstrap",
props.handler,
"--runtime-interface-emulator-address",
"0.0.0.0:{port}",
"--runtime-api-address",
"127.0.0.1:{runtimePort}"
];
let flags = MutMap<str>{};
let var network: str? = nil;
let platform = Inflight.os();
if platform != "darwin" && platform != "win32" {
network = "host";
}

let port = math.floor(math.random() * 1000 + 9000);
let runner = new containers.Container(
image: "lambci/lambda:python3.8",
image: "public.ecr.aws/lambda/python:3.12",
name: "python-runner",
volumes: {
"/var/task:ro,delegated": outdir,
},
env: {
DOCKER_LAMBDA_STAY_OPEN: "1",
DOCKER_LAMBDA_API_PORT: "{port}",
DOCKER_LAMBDA_RUNTIME_PORT: "{port}",
},
public: true,
port: port,
args: [props.handler],
exposedPort: port,
args: args,
flags: flags.copy(),
network: network,
entrypoint: "/usr/local/bin/aws-lambda-rie",
);

this.service = new cloud.Service(inflight () => {
Expand Down Expand Up @@ -83,7 +92,7 @@ pub class Inflight impl cloud.IFunctionHandler {
runner.start(env.copy());
});

this.url = "{runner.publicUrl!}/2015-03-31/functions/myfunction/invocations";
this.url = "{runner.publicUrl!}/2015-03-31/functions/function/invocations";

this.clients = MutMap<Json>{};
this.wingClients = MutMap<std.Resource>{};
Expand Down
4 changes: 3 additions & 1 deletion python/test-assets/main.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from wing import *
import os

def handler(event, context):
print(event)
print(context)

fooEnv = os.getenv("FOO")
payload = from_function_event(event)

client = lifted("bucket")
value = client.get("test.txt")
client.put("test.txt", value + payload)
client.put("test.txt", value + payload + fooEnv)

return {
"statusCode": 200,
Expand Down
3 changes: 2 additions & 1 deletion python/test-assets/wing.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def from_function_event(event):
if target == "tf-aws":
return str(event)
elif target == "sim":
return str(event["payload"])
payload = event["payload"]
return payload if isinstance(payload, str) else json.dumps(payload)
else:
raise Exception(f"Unsupported target: {target}")

Expand Down
1 change: 1 addition & 0 deletions python/tfaws/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module.exports.Function = class Function extends Construct {
environment: {
variables: cdktf.Lazy.anyValue({
produce: () => ({
...props.env,
...this.env,
}),
}),
Expand Down
7 changes: 7 additions & 0 deletions python/util.extern.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,14 @@ export interface IHostedLiftable extends ILiftable {
}
/** Abstract interface for `Resource`. */
export interface IResource extends IConstruct, IHostedLiftable {
/** The tree node. */
readonly node: Node;
/** A hook called by the Wing compiler once for each inflight host that needs to use this object inflight.
The list of requested inflight methods
needed by the inflight host are given by `ops`.
This method is commonly used for adding permissions, environment variables, or
other capabilities to the inflight host. */
readonly onLift: (host: IInflightHost, ops: (readonly (string)[])) => void;
}
/** Shared behavior between all Wing SDK resources. */
Expand Down
18 changes: 14 additions & 4 deletions python/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const { resolve, join } = require("node:path");
const { join } = require("node:path");
const { cpSync, existsSync, mkdtempSync } = require("node:fs");
const { execSync } = require("node:child_process");
const { tmpdir } = require("node:os");
const glob = require("glob");

exports.dirname = () => __dirname;

Expand All @@ -13,19 +15,27 @@ exports.build = (options) => {
const { entrypointDir, workDir, path, homeEnv, pathEnv } = options;

// create an output directory and copy the path to it
const outdir = mkdtempSync(join(resolve(workDir), "py-func-"));
const outdir = mkdtempSync(join(tmpdir(), "py-func-"));
const resolvedPath = join(entrypointDir, path);

const copyFiles = (src, dest) => {
const files = glob.sync(join(src, "**/*.py"));
for (let file of files) {
const newFile = file.replace(src, `${dest}/`);
cpSync(file, newFile);
}
};

// if there is a requirements.txt file, install the dependencies
const requirementsPath = join(resolvedPath, "requirements.txt");
if (existsSync(requirementsPath)) {
cpSync(requirementsPath, join(outdir, "requirements.txt"));
execSync(`python -m pip install -r ${join(outdir, "requirements.txt")} -t python`,
{ cwd: outdir, env: { HOME: homeEnv, PATH: pathEnv } });
cpSync(resolvedPath, join(outdir, "python"), { recursive: true });
copyFiles(resolvedPath, join(outdir, "python"));
return join(outdir, "python");
} else {
cpSync(resolvedPath, outdir, { recursive: true });
copyFiles(resolvedPath, outdir);
return outdir;
}
};
Expand Down
25 changes: 16 additions & 9 deletions python/wplatform.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { Function: SimFunction } = require("./sim/function.js");
const { Function: TfAwsFunction } = require("./tfaws/function.js");
const { Queue: TfAwsQueue } = require("./tfaws/queue.js");
const { Topic: TfAwsTopic } = require("./tfaws/topic.js");
Expand All @@ -8,26 +9,32 @@ const QUEUE_FQN = "@winglang/sdk.cloud.Queue";
const TOPIC_FQN = "@winglang/sdk.cloud.Topic";
const BUCKET_FQN = "@winglang/sdk.cloud.Bucket";

const createFunction = (target, scope, id, inflight, props) => {
if (inflight._inflightType === "_inflightPython") {
if (target === "tf-aws") {
return new TfAwsFunction(scope, id, inflight, props);
} else if (target === "sim") {
return new SimFunction(scope, id, inflight, props);
}
}
};

module.exports.Platform = class Platform {
newInstance(type, scope, id, props) {
newInstance(type, scope, id, ...props) {
const target = process.env["WING_TARGET"];
if (type === FUNCTION_FQN) {
if (props._inflightType === "_inflightPython") {
if (target === "tf-aws") {
return new TfAwsFunction(scope, id, props);
}
}
return createFunction(target, scope, id, ...props);
} else if (type === QUEUE_FQN) {
if (target === "tf-aws") {
return new TfAwsQueue(scope, id, props);
return new TfAwsQueue(scope, id, ...props);
}
} else if (type === TOPIC_FQN) {
if (target === "tf-aws") {
return new TfAwsTopic(scope, id, props);
return new TfAwsTopic(scope, id, ...props);
}
} else if (type === BUCKET_FQN) {
if (target === "tf-aws") {
return new TfAwsBucket(scope, id, props);
return new TfAwsBucket(scope, id, ...props);
}
}
}
Expand Down

0 comments on commit d457129

Please sign in to comment.