3

I am in the bit of a weird situation where I need a Python function to run from within a script, with the script then called from my main code.

I wanted to use the subprocess module, and know how to use it to pass arguments to a pure script, but the thing is, I need to pass the arguments to the nested Python function within, most of which are optional and have default values.

I thought arparse would help me do this somehow.

Here is an example of what I am trying:

## Some Argparse, which will hopefully help
import argparse

parser = argparse.ArgumentParser()

## All arguments, with only "follow" being required
parser.add_argument('file_name', help='Name of resulting csv file')
parser.add_argument('sub_name', help='Sub-name of resulting csv file')
parser.add_argument('follow', help='Account(s) to follow', required=True)
parser.add_argument('locations', help='Locations')
parser.add_argument('languages', help='Languages')
parser.add_argument('time_limit', help='How long to keep stream open')

args = parser.parse_args()


## Actual Function
def twitter_stream_listener(file_name=None,
                            sub_name='stream_',
                            auth = api.auth,
                            filter_track=None,
                            follow=None,
                            locations=None,
                            languages=None,
                            time_limit=20):
   ... function code ...
   ... more function code ...
   ...
   ...
   ## End of script
4
  • argparse just takes the strings in sys.argv (or some other list you pass explicitly to parse_args) and gives you the object args. What you do with args is up to you. You might treat it as a global variable, or pass it as an additional argument to twitter_stream_listener, or just pass the individual attributes as arguments where needed. Commented Feb 15, 2019 at 15:24
  • Your code seems fine, are you receiving any errors? Commented Feb 15, 2019 at 15:34
  • Are you sure you need to use subprocess to start program A and execute function A.twitter_stream_listener() inside it? A much simpler approach would be to have your code import A and call A.twitter_stream_listener() directly. Commented Feb 15, 2019 at 15:47
  • aaaakshat, I am not receiving any errors, just am not sure how to structure my code to send my parsed arguments to my function. BoarGules, I wanted to do that at first, but my function in question was written by someone else, and I do not know how to refactor it to allow me to close said function midway (without affecting any other processes in the rest of the kernel), so I am trying to give it its own sub-process, which seems easier to close on-the-fly. Commented Feb 15, 2019 at 16:29

3 Answers 3

8

If you are passing arguments to functions all you need to do is feed them into the function when you're executing them:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-o", "--output_file_name", help="Name of resulting csv file")
parser.add_argument("-s", "--sub_name", default="stream_", help="Sub-name of resulting csv file")
parser.add_argument("-f", "--follow", help="Account(s) to follow", required=True)
parser.add_argument("-loc", "--locations", default=None, help="Locations")
parser.add_argument("-lan", "--languages", default=None, help="Languages")
parser.add_argument("-t", "--time_limit", default=20, help="How long to keep stream open")

options = parser.parse_args()

# then just pass in the arguments when you run the function
twitter_stream_listener(file_name=options.output_file_name,
                        sub_name=options.sub_name, 
                        auth=api.auth,
                        filter_track=None,
                        follow=options.follow,
                        locations=options.locations,
                        languages=options.languages,
                        time_limit=options.time_limit)


# or, pass the arguments into the functions when defining your function
def twitter_stream_listener_with_args(file_name=options.output_file_name,
                                      sub_name=options.sub_name, 
                                      auth=api.auth,
                                      filter_track=None,
                                      follow=options.follow,
                                      locations=options.locations,
                                      languages=options.languages,
                                      time_limit=options.time_limit):
    # does something
    pass

# then run with default parameters
twitter_stream_listener_with_args()

Sign up to request clarification or add additional context in comments.

Comments

2

You can specify defaults in the argparse section (if that is what you are trying to achieve):

#!/usr/bin/python
import argparse
parser = argparse.ArgumentParser()

parser.add_argument('--argument', default = 'something', type = str, help = 'not helpful')
parser.add_argument('--arg2', default = None, type = str, help = 'not helpful')


args = parser.parse_args()

def foo(arg , arg2 ):
    print(arg)
    if not arg2 is  None:
        print(arg2)

foo(args.argument, args.arg2)


Then calling:

$ ./test.py
something

$ ./test.py --argument='somethingelse'
somethingelse

$ ./test.py --arg2=123
something
123

$ ./test.py --arg2='ipsum' --argument='lorem'
lorem
ipsum

Is this helpful?

Comments

1

You can do it like that:

import argparse

## Actual Function
def twitter_stream_listener(file_name=None,
                            sub_name='stream_',
                            auth=api.auth,
                            filter_track=None,
                            follow=None,
                            locations=None,
                            languages=None,
                            time_limit=20):

    # Your content here


if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    ## All arguments, with only "follow" being required
    parser.add_argument('follow', help='Account(s) to follow')
    parser.add_argument('--file_name', help='Name of resulting csv file')
    parser.add_argument('--sub_name', help='Sub-name of resulting csv file')
    parser.add_argument('--locations', help='Locations')
    parser.add_argument('--languages', help='Languages')
    parser.add_argument('--time_limit', help='How long to keep stream open')

    args = parser.parse_args()

    twitter_stream_listener(file_name=args.file_name, sub_name=args.sub_name, follow=args.follow,
                            locations=args.locations, languages=args.languages, time_limit=args.time_limit)

follow will be the only required argument and the rest optional. Optional ones have to be provided with -- at the beginning. You can easily use the module with subprocess if you need it.

Example call using command line:

python -m your_module_name follow_val --file_name sth1 --locations sth2

2 Comments

Since I am still a bit of a newbie to Python scripting, what does the if __name__ == '__main__': section achieve here? Couldn't I just use your example without that?
This stackoverflow answer will explain it much better than I could possibly do in a single comment: stackoverflow.com/a/419185/3603682

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.