InvokeAI/invokeai/frontend/cli/arg_parser.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

47 lines
1.8 KiB
Python
Raw Permalink Normal View History

feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
from argparse import ArgumentParser, Namespace, RawTextHelpFormatter
from typing import Optional
from invokeai.version import __version__
_root_help = r"""Path to the runtime root directory. If omitted, the app will search for the root directory in the following order:
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
- The `$INVOKEAI_ROOT` environment variable
- The currently active virtual environment's parent directory
- `$HOME/invokeai`"""
_config_file_help = r"""Path to the invokeai.yaml configuration file. If omitted, the app will search for the file in the root directory."""
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
_parser = ArgumentParser(description="Invoke Studio", formatter_class=RawTextHelpFormatter)
_parser.add_argument("--root", type=str, help=_root_help)
_parser.add_argument("--config", dest="config_file", type=str, help=_config_file_help)
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
_parser.add_argument("--version", action="version", version=__version__, help="Displays the version and exits.")
class InvokeAIArgs:
"""Helper class for parsing CLI args.
Args should never be parsed within the application code, only in the CLI entrypoints. Parsing args within the
application creates conflicts when running tests or when using application modules directly.
If the args are needed within the application, the consumer should access them from this class.
Example:
```
# In a CLI wrapper
from invokeai.frontend.cli.arg_parser import InvokeAIArgs
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
InvokeAIArgs.parse_args()
# In the application
from invokeai.frontend.cli.arg_parser import InvokeAIArgs
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
args = InvokeAIArgs.args
"""
args: Optional[Namespace] = None
did_parse: bool = False
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
@staticmethod
def parse_args() -> Optional[Namespace]:
"""Parse CLI args and store the result."""
InvokeAIArgs.args = _parser.parse_args()
InvokeAIArgs.did_parse = True
feat: single app entrypoint with CLI arg parsing We have two problems with how argparse is being utilized: - We parse CLI args as the `api_app.py` file is read. This causes a problem pytest, which has an incompatible set of CLI args. Some tests import the FastAPI app, which triggers the config to parse CLI args, which receives the pytest args and fails. - We've repeatedly had problems when something that uses the config is imported before the CLI args are parsed. When this happens, the root dir may not be set correctly, so we attempt to operate on incorrect paths. To resolve these issues, we need to lift CLI arg parsing outside of the application code, but still let the application access the CLI args. We can create a external app entrypoint to do this. - `InvokeAIArgs` is a simple helper class that parses CLI args and stores the result. - `run_app()` is the new entrypoint. It first parses CLI args, then runs `invoke_api` to start the app. The `invokeai-web` project script and `invokeai-web.py` dev script now call `run_app()` instead of `invoke_api()`. The first time `get_config()` is called to get the singleton config object, it retrieves the args from `InvokeAIArgs`, sets the root dir if provided, then merges settings in from `invokeai.yaml`. CLI arg parsing is now safely insulated from application code, but still accessible. And we don't need to worry about import order having an impact on anything, because by the time the app is running, we have already parsed CLI args. Whew!
2024-03-15 05:33:52 +00:00
return InvokeAIArgs.args