简体   繁体   中英

How can I capture STDOUT on a Python UDF in Snowflake to return as string?

Some Python libraries output the result of their functions to STDOUT - and in a Python UDF in Snowflake I need to capture that value to a String to return it.

For example the output of help() or numpy.show_config() .

You can capture stdout using contextlib.redirect_stdout .

For example, to capture the output of help(numpy) :

create or replace function help_numpy()
returns string
language python
runtime_version = '3.8'
packages = ('numpy')  
handler = 'x'
as $$
import io
from contextlib import redirect_stdout
from pydoc import help
import numpy

def x():
    f = io.StringIO()
    with redirect_stdout(f):
        help(numpy)
    return f.getvalue()
$$;

select help_numpy();

Or to capture the output of numpy.show_config() you just need to replace the functions called inside the redirect_stdout() block:

    with redirect_stdout(f):
       numpy.show_config()

Note that to use help() we also had to from pydoc import help . Otherwise you'll get the error NameError: name 'help' is not defined in function HELP with handler .

That's a great idea for all UDF languages. Open source JavaScript is often filled with with alert , window.alert , console.log etc. To capture the alert and console out functions in JavaScript:

create or replace function STDOUT()
returns array
language javascript
as
$$
//----- Start of standard out intercepts. Add to top of UDF
console.logs = [];
window = {};
console.log   = function(){ console.logs.push({"type":"log",   "timestamp":new Date().toISOString(), "out":Array.from(arguments)}) };
console.warn  = function(){ console.logs.push({"type":"warn",  "timestamp":new Date().toISOString(), "out":Array.from(arguments)}) };
console.error = function(){ console.logs.push({"type":"error", "timestamp":new Date().toISOString(), "out":Array.from(arguments)}) };
console.debug = function(){ console.logs.push({"type":"debug", "timestamp":new Date().toISOString(), "out":Array.from(arguments)}) };
alert         = function(){ console.logs.push({"type":"alert", "timestamp":new Date().toISOString(), "out":Array.from(arguments)}) };
window.alert  = function(){ console.logs.push({"type":"alert", "timestamp":new Date().toISOString(), "out":Array.from(arguments)}) };
//----- End of standard out intercepts

console.log("My log.");
console.warn("My warning");
console.error("My error");
alert("My alert");
window.alert("My window alert");

return console.logs;

$$;

select STDOUT();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM