In this lesson, you’ll extend the basic parser so users can provide optional settings. The bruteforcer will still require a domain, but now it can also accept a wordlist path.
Back in the original command-centre recipe, this was the point where the tool needed two things: an option to provide a domain name and an option to provide a wordlist. We already have the domain, so now we add the wordlist without making the person running the tool type it every single time.
Concepts Covered
Optional command-line arguments
Short and long flags
Default values
Generated help output
Why This Matters
Good defaults make a tool quick to run. Good options make it flexible when the default isn’t enough. The trick is giving the user control without making every run feel like filling out paperwork.
Objective
Add a -w / --wordlist option with a sensible default and readable help text.
Optional Arguments
Optional arguments are usually introduced with a dash. A short flag such as -w is quick to type, while a long flag such as --wordlist is easier to read in notes and scripts.
Optional arguments will show up again later in a programming context, and they don’t map one-to-one to the way we use them in argument parsers. A small digression, then: as the name suggests, optional arguments are optional, which makes them perfect for things like verbosity, timeout values, wordlist paths, and other knobs that let the user decide how much control they need.
import argparseparser = argparse.ArgumentParser(prog="bernauer")parser.add_argument("domain", help="domain to test, e.g. example.test")parser.add_argument("-w", "--wordlist", default="data/wordlist.txt",help="path to a wordlist file",)args = parser.parse_args(["example.test", "--wordlist", "data/one_hundered_subdomains.txt"])print(args.domain)print(args.wordlist)
1
Give the option both a short name and a long name.
2
Use the course wordlist when the user doesn’t provide a path.
3
Write help text for the person running the tool, not for the person reading the source.
example.test
data/one_hundered_subdomains.txt
Here’s what’s happening: if the user provides --wordlist, argparse stores that value. If they don’t, argparse stores the default. Either way, the rest of your program can read args.wordlist without caring which path the user took to get there.
Defaults
If the user doesn’t provide --wordlist, argparse stores the default value for you. For a tool like ours, that means we can include a small built-in wordlist for practice and still let the user bring their own list later.
Defaults are one of those tiny pieces of polish that make a command-line tool feel less fussy. The user can run the common case quickly, and the uncommon case is still available when they need it.
A parser can generate its own help screen. Setting prog="bernauer" keeps the notebook output stable and makes the command name look like a real script.
Running the script with the -h or --help flag demonstrates how useful argparse can be. We’ve done very little to configure the parser, but it has already generated a handler for us. Keep in mind this is the only option you get for free; the others need help text from you.
If you’re the decorating and/or customisation type, you can also add a sweet description to your argument parser so the help output starts with a tiny banner or a sentence about what the tool does.
print(parser.format_help())
usage: bernauer [-h] [-w WORDLIST] domainpositional arguments:domain domain to test, e.g. example.test
options:-h, --help show this help message and exit
-w, --wordlistWORDLIST
path to a wordlist file
Checkpoint
Update your parser so it accepts:
a required domain
an optional -w / --wordlist
a default wordlist path of data/wordlist.txt
Test both forms: one command with --wordlist, and one command that relies on the default. Then print build_argument_parser().format_help() and read it like a user would. Is it clear what the tool expects, or does it leave Future You guessing?
import argparsedef build_argument_parser(): parser = argparse.ArgumentParser(prog="bernauer") parser.add_argument("domain", help="domain to test, e.g. example.test")# Add the wordlist option here.return parser# args = build_argument_parser().parse_args(["example.test"])# print(args.wordlist)
Extension Activity
Add a parser description so the help output explains what the tool does before listing the arguments. A little ASCII-art flourish is welcome if you’re feeling fancy, but clarity wins over decoration.