Repository: nautobot/nautobot

Issue:
Include "rich" installation in getting started
### Environment
* Nautobot version (Docker tag too if applicable): develop
* Python version: 3.8
* Database platform, version: postgresql
* Middleware(s):

### Steps to Reproduce
1. Don't install rich on docker host
2. Run `invoke build`

<!-- What did you expect to happen? -->
### Expected Behavior

To build without error.

Should just need to document in the `getting-started.md` document that you must install rich for the development environment.

<!-- What happened instead? -->
### Observed Behavior

```
kennethcelenza@Kenneths-MBP ~/github/nautobot % invoke build
Traceback (most recent call last):
  File "/System/Volumes/Data/Users/kennethcelenza/Library/Python/3.8/bin/invoke", line 8, in <module>
    sys.exit(program.run())
  File "/Users/kennethcelenza/Library/Python/3.8/lib/python/site-packages/invoke/program.py", line 373, in run
    self.parse_collection()
  File "/Users/kennethcelenza/Library/Python/3.8/lib/python/site-packages/invoke/program.py", line 465, in parse_collection
    self.load_collection()
  File "/Users/kennethcelenza/Library/Python/3.8/lib/python/site-packages/invoke/program.py", line 696, in load_collection
    module, parent = loader.load(coll_name)
  File "/Users/kennethcelenza/Library/Python/3.8/lib/python/site-packages/invoke/loader.py", line 76, in load
    module = imp.load_module(name, fd, path, desc)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/imp.py", line 234, in load_module
    return load_source(name, filename, file)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/imp.py", line 171, in load_source
    module = _load(spec)
  File "<frozen importlib._bootstrap>", line 702, in _load
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/kennethcelenza/github/nautobot/tasks.py", line 23, in <module>
    from rich import print  # pylint: disable=redefined-builtin
ModuleNotFoundError: No module named 'rich'
kennethcelenza@Kenneths-MBP ~/github/nautobot %
```

### TODO
- Update tasks to not require `rich`, catch `ImportError` and allow to proceed.


Discussion:
A few quick thoughts:

- In the virtualenv development workflow, `poetry install` will auto-install `rich`, but we document the Docker development workflow as requiring only `invoke` and nothing else.
- `rich` should not be a hard requirement, we should catch the ImportError and allow the invoke tasks to proceed.


Resolving patch:
diff --git a/tasks.py b/tasks.py
--- a/tasks.py
+++ b/tasks.py
@@ -19,8 +19,13 @@
 from invoke import Collection, task as invoke_task
 from invoke.exceptions import Exit
 
-# Override built-in print function with rich's pretty-printer function
-from rich import print  # pylint: disable=redefined-builtin
+try:
+    # Override built-in print function with rich's pretty-printer function, if available
+    from rich import print  # pylint: disable=redefined-builtin
+
+    HAS_RICH = True
+except ModuleNotFoundError:
+    HAS_RICH = False
 
 
 def is_truthy(arg):
@@ -117,7 +122,10 @@ def docker_compose(context, command, **kwargs):
     env.update({"PYTHON_VER": context.nautobot.python_ver})
     if "hide" not in kwargs:
         env_str = " \\\n    ".join(f"{var}={value}" for var, value in env.items())
-        print(f"[dim]{env_str} \\\n    {compose_command}[/dim]")
+        if HAS_RICH:
+            print(f"[dim]{env_str} \\\n    {compose_command}[/dim]")
+        else:
+            print(f"{env_str} \\\n    {compose_command}")
     return context.run(compose_command, env=env, **kwargs)
 
 


Test patch: