diff --git a/package.json b/package.json index b779814c00f6..eaef8d99f5be 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "build:publish": "tsc --build tsconfig.publish.json && npm run copyfiles", "build:watch": "npm run build && tsc --watch", "clean": "rimraf lib dev", - "copyfiles": "node -e \"const fs = require('fs'); fs.mkdirSync('./lib', {recursive:true}); fs.copyFileSync('./src/dynamicImport.js', './lib/dynamicImport.js')\"", + "copyfiles": "npm run copyDynamicImportModule && npm run copyEmulatorFiles", + "copyDynamicImportModule": "node -e \"const fs = require('fs'); fs.mkdirSync('./lib', {recursive:true}); fs.copyFileSync('./src/dynamicImport.js', './lib/dynamicImport.js')\"", + "copyEmulatorFiles": "cp ./src/emulator/functionsEmulatorRuntime.py ./lib/emulator/functionsEmulatorRuntime.py", "format": "npm run format:ts && npm run format:other", "format:other": "npm run lint:other -- --write", "format:ts": "npm run lint:ts -- --fix --quiet", diff --git a/src/emulator/functionsEmulator.ts b/src/emulator/functionsEmulator.ts index bc01ba445e47..ce9178079096 100644 --- a/src/emulator/functionsEmulator.ts +++ b/src/emulator/functionsEmulator.ts @@ -1304,7 +1304,7 @@ export class FunctionsEmulator implements EmulatorInstance { backend: EmulatableBackend, envs: Record ): Promise { - const args = [path.join(__dirname, "functionsEmulatorRuntime")]; + const args = [path.join(__dirname, "functionsEmulatorRuntime.py")]; if (this.args.debugPort) { this.logger.log( @@ -1329,6 +1329,7 @@ export class FunctionsEmulator implements EmulatorInstance { const childProcess = runWithVirtualEnv([bin, ...args], backend.functionsDir, { ...process.env, ...envs, + HOST: "localhost", PORT: port.toString(), }); diff --git a/src/emulator/functionsEmulatorRuntime.py b/src/emulator/functionsEmulatorRuntime.py new file mode 100644 index 000000000000..b42f35ed413d --- /dev/null +++ b/src/emulator/functionsEmulatorRuntime.py @@ -0,0 +1,30 @@ +# Copyright 2023 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""A light wrapper around the Functions Framework for the purpose of emulator support.""" + +import os +from functions_framework import create_app +from functions_framework._http.flask import FlaskApplication + +def create_server(host, port): + app = create_app() + FlaskApplication(app, host, port, False).run() + + +def main(): + create_server(os.environ["HOST"], os.environ["PORT"]) + + +if __name__ == "__main__": + main() diff --git a/src/functions/python.ts b/src/functions/python.ts index 48afcfd37a5b..ad054c8aa99c 100644 --- a/src/functions/python.ts +++ b/src/functions/python.ts @@ -20,11 +20,14 @@ export function runWithVirtualEnv( const command = process.platform === "win32" ? venvActivate : "source"; const args = [process.platform === "win32" ? "" : venvActivate, "&&", ...commandAndArgs]; logger.debug(`Running command with virtualenv: command=${command}, args=${JSON.stringify(args)}`); + logger.debug(JSON.stringify(envs)); return spawn(command, args, { shell: true, cwd, stdio: [/* stdin= */ "ignore", /* stdout= */ "pipe", /* stderr= */ "inherit"], - ...envs, + // Linting disabled since internal types expect NODE_ENV which does not apply to Python runtimes. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any + env: envs as any, }); }