Examples
WARNING: This section is a work in progres and in some places it is outdated.
Lets first look at a trivial example and explain it along and then provide more complex scenarios
Trivial Example
Consider the following folder structure
where temp.yaml
has the following contents
while main.py
has the following contents
from atro_core.args import Arg, InputArgs
input_args = InputArgs()
# Specify source
input_args.include_source("./temp.yaml")
# Add arguments
input_args.add_arg(
Arg(
name="is_atro_args_example",
arg_type=bool,
help="Just an example",
required=True,
)
)
# Create model
model = input_args.get_dict()
model
in the example above would be model = {'is_atro_args_example': True}
.
As mentioned above first the InputArgs is instantiated, we then include a source which happens to be the temp.yaml
file, this can be passed as a string or a Path
type, here I opted for string. I then instruct what argument I want to add, specifying some help, the type I want it to be and insist that it is present, if its missing an ValueError will be raised.
Types
Below one can see the use of arg_type=int
and arg_type=str
, other types like bool
and float
are also supported. In principle even more complex types such as dict
and list
are supported, but they are rarely good use-case with this package, it is usually better to use yaml
or json
files for those and load using pyyaml
or json
instead of this package.
Environment variables
For sake of the example suppose you have (somehow) passed in the environment variables ATRO_TEST_APP_NAME
and ATRO_TEST_RANDOM_NUMBER
with values test
and 10
respectively.
The prefix here is ATRO_TEST
. The remaining part of the environment variable must match the "name" argument in the Arg part.
# Setup
from atro_core.args import Arg, InputArgs
input_args = InputArgs(prefix="ATRO_TEST")
input_args.add_arg(Arg(name="random_number", arg_type=int, help="Just some random number", required=True))
input_args.add_arg(Arg(name="app_name", arg_type=str, help="App name", required=True))
# Obtain the model (of type dict[str, Any])
model = input_args.get_dict()
# Show that indeed we have the correct values
assert type(model.get("app_name")) == str
assert type(model.get("random_number")) == int
assert model.get("app_name") == "test"
assert model.get("random_number") == 10
Command line arguments
Suppose you have a file called some_file.py
with the following contents:
from atro_core.args import Arg, InputArgs
# Setup
input_args = InputArgs()
input_args.add_arg(Arg(name="random-number", arg_type=int, help="Just some random number", required=True))
# Show that indeed we have the correct values
model = input_args.get_dict()
print(model.get("random-number"))
if model.get("random-number"):
assert type(model.get("random-number")) == int
If one runs the following command:
you'd see that the output is 10
and the assertion passes.
If one runs the following command:2
you'd see a ValueError
being raised as the type is incorrect.
Environment files
For this example suposse we have a file called .env
in the same directory where the python file is with the following contents:
then the following code would work:
# Setup
env_files: list[Path] = [Path(__file__).parent / ".env"]
input_args = InputArgs(prefix="ATRO_TEST", env_files=env_files)
input_args.add_arg(Arg(name="app_env_file_name", arg_type=str, help="App name", required=False))
# Create model
model = input_args.get_dict()
assert model.get("app_env_file_name") == "test"
requesting random_env_file_number would also work, but it is not shown here for brevity.
YAML files
Consider the following yaml file (called test.yaml
) which is in the same directory as the python file:
then the following code would work:
# Setup
yaml_files = [Path(__file__).parent / "test.yaml"] if provided else []
input_args = InputArgs(prefix="ATRO_TEST", yaml_files=yaml_files)
input_args.add_arg(Arg(name="app_yaml_file_name", arg_type=str, help="App name", required=False))
# Create model
model = input_args.get_dict()
# Assert
assert model.get("app_yaml_file_name") == "test"
Populate class instance
We easily can populate a pydantic BaseModel
Populate AppSettings
To populate pydantic BaseClass with loaded parameters
class Settings(BaseModel):
NAME: str
HOST: str
PORT: int
OPTIONAL_PARAMETER: str = "DEFAULT"
NULLABLE_PARAMETER: Optional[str]
app_settings = InputArgs(prefix="MYPREFIX").populate_cls(Settings, cli_args)
Work in progress
In the future the intention is to use pyyaml
and json
to load data from yamls and jsons on users behalf along with all the other sources of input. Currently json is not supported and yaml is in its early stages of support.