2

I am returning a variable from a function in python.

When I try to retrieve the variable in another function, it prints out the print statements of the original function for a second time.

Here is my code:

user_name = 'my_user'
kms_cleint = 'client_info'
aws_account = 'company-account'
def create_kms_key(user_name, kms_client):   
    print("****************************************************************")
    print("         Create KMS Key for %s                                   " % user_name)
    print("****************************************************************")
    kms_key_id = 5
    return kms_key_id

def store_secret(user_name, kms_client, secrets_client, aws_account):
    print("****************************************************************")
    print("         Store Secret for %s for AWS account: %s                " % (user_name, aws_account))
    print("****************************************************************")
    f = open(os.devnull,"w")
    kms_key_id = create_kms_key(user_name, kms_client).set_log_stream(f)

My output:

****************************************************************
         Create KMS Key for user35
****************************************************************
****************************************************************
         Store Secret for user35 for AWS account: company-account
****************************************************************
****************************************************************
         Create KMS Key for user35
****************************************************************

I am trying to avoid printing out the create_kms_key function output a second time.

I am getting this error when I try to redirect the output to /dev/null when I call the create_kms_key function:

AttributeError: 'int' object has no attribute 'set_log_stream'

How can I keep the create_kms_key function from printing it's output a second time?

bluethundr
  • 1,005
  • 17
  • 68
  • 141
  • Looks like this may have been answered elsewhere: https://stackoverflow.com/questions/6735917/redirecting-stdout-to-nothing-in-python – Jon Betts Apr 03 '19 at 16:06
  • Thank you. I try the accepted solution from that exact stack overflow link and that didn't work. That is in the code above. However I did find another solution in that same thread. That uses contextlib. I used ` with contextlib.redirect_stdout(None): kms_key_id = create_kms_key(user_name, kms_client)` That worked. Thanks! – bluethundr Apr 03 '19 at 16:14
  • My fault, not reading your question carefully enough... sorry! – Jon Betts Apr 03 '19 at 16:16
  • haha! That's ok man. Thanks anyway. :) – bluethundr Apr 03 '19 at 16:20

2 Answers2

2

The error has to do with this line:

create_kms_key(user_name, kms_client).set_log_stream(f)

The function create_kms_key returns an int, which then you immediately call .set_log_stream(f), which is not a method of int. Not only that, but create_kms_key runs completely before .set_log_stream(f) gets invoked.

Instead of these lines:

f = open(os.devnull,"w")
kms_key_id = create_kms_key(user_name, kms_client).set_log_stream(f)

try these instead:

with open(os.devnull, 'w') as devnull:
    saved_stdout = sys.stdout  # save off the real stdout
    sys.stdout = devnull       # temporarily suppress stdout
    kms_key_id = create_kms_key(user_name, kms_client)
    sys.stdout = saved_stdout  # restore stdout

This way you'll temporarily suppress the text normally written to sys.stdout. You'll have to be careful about any exceptions thrown in create_kms_key, as they could skip over the restoration line of code, preventing sys.stdout from being properly restored.

J-L
  • 1,786
  • 10
  • 13
  • 1
    That looks like a nice solution! I will give that a try. I've already solved this with contextlib, as I mention above. But it's good to have that as an option. Thanks! – bluethundr Apr 03 '19 at 16:24
  • Ah, good! To be honest, the `contextlib` solution you found probably handles the exception issue I was talking about, so it's probably the safer solution. (It's also a little shorter, too.) – J-L Apr 03 '19 at 16:53
  • 1
    Yup! That's what I like about it. It's harmless, succinct and works great! What's not to love? – bluethundr Apr 03 '19 at 17:58
2

I solved the problem by doing this:

import contextlib
    with contextlib.redirect_stdout(None):
        kms_key_id = create_kms_key(user_name, kms_client)

That prevents the function from printing out a second time.

bluethundr
  • 1,005
  • 17
  • 68
  • 141