argparse
Python
command line interface
optional arguments
programming tutorial

Require either of two arguments using argparse

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

With argparse, "require either of two arguments" can mean two different things. Sometimes you want exactly one of the two options, and sometimes you want at least one of them while still allowing both. argparse supports the first case directly with a mutually exclusive group, while the second case needs a small custom validation step after parsing.

Case 1: Exactly One of Two Arguments

If the command should accept --file or --url, but never both, use a mutually exclusive group with required=True.

python
1import argparse
2
3parser = argparse.ArgumentParser()
4group = parser.add_mutually_exclusive_group(required=True)
5group.add_argument("--file")
6group.add_argument("--url")
7
8args = parser.parse_args()
9print(args)

This gives you the desired behavior:

  • '--file data.txt is valid'
  • '--url https://example.com is valid'
  • giving both is rejected
  • giving neither is rejected

This is the cleanest built-in solution when the options truly exclude each other.

Case 2: At Least One of Two Arguments

If the script should accept --username, --token, or both together, a mutually exclusive group is the wrong tool because it forbids both. In that case, parse normally and validate manually.

python
1import argparse
2
3parser = argparse.ArgumentParser()
4parser.add_argument("--username")
5parser.add_argument("--token")
6
7args = parser.parse_args()
8
9if not args.username and not args.token:
10    parser.error("at least one of --username or --token is required")
11
12print(args)

This keeps the CLI flexible while still enforcing the rule that one of the two inputs must be present.

Add Helpful Messages and Types

The validation logic should still work with richer arguments such as paths, integers, or constrained strings.

python
1import argparse
2from pathlib import Path
3
4parser = argparse.ArgumentParser()
5parser.add_argument("--config", type=Path)
6parser.add_argument("--profile")
7
8args = parser.parse_args()
9
10if args.config is None and args.profile is None:
11    parser.error("provide either --config or --profile")

Good CLI behavior is not only about enforcing rules. It is also about making failures readable and actionable.

Combine Groups with Other Arguments Carefully

Real CLIs often have required positional arguments, optional flags, and one either-or rule. That is fine, but keep the either-or logic isolated so the parser remains readable.

python
1import argparse
2
3parser = argparse.ArgumentParser()
4parser.add_argument("output")
5
6source_group = parser.add_mutually_exclusive_group(required=True)
7source_group.add_argument("--file")
8source_group.add_argument("--url")
9
10parser.add_argument("--verbose", action="store_true")
11
12args = parser.parse_args()
13print(args)

This is easier to maintain than scattering conditional checks across the whole script.

Prefer Built-In Behavior When It Matches the Rule

If the requirement is truly exclusive, use add_mutually_exclusive_group. It gives you consistent help text and standard error handling for free. Manual checks are best reserved for rules that argparse does not model directly, such as "at least one of these three flags, but combinations are allowed."

That keeps the command-line interface both strict and predictable.

Test the Help Output

CLI usability depends heavily on the generated help text. After building the parser, run:

bash
python script.py --help

If the help text does not make the either-or rule obvious, add clearer help messages to the arguments or refine the error text in parser.error.

Common Pitfalls

  • Using a mutually exclusive group when the rule actually allows both arguments together.
  • Writing custom validation for an exclusive rule that argparse already supports directly.
  • Forgetting required=True on the mutually exclusive group and then allowing neither option.
  • Producing vague error messages that do not tell the user what combination is valid.
  • Letting CLI validation logic spread across the script instead of keeping it near the parser.

Summary

  • Use add_mutually_exclusive_group(required=True) when exactly one of two arguments must be provided.
  • Use normal arguments plus parser.error(...) when at least one argument is required but both are allowed.
  • Keep validation close to the parser definition.
  • Test the generated help text so the rule is obvious to users.
  • The right solution depends on whether the two arguments are exclusive or simply alternative inputs.

Course illustration
Course illustration