From 69d3ec7b0185bd400f501773dfa485fa1409f1ec Mon Sep 17 00:00:00 2001
From: Andrew Chen Wang <acwangpython@gmail.com>
Date: Sun, 3 Mar 2024 16:12:57 -0500
Subject: [PATCH 1/9] Add watchfile reload options * Includes reload path
 option and filter options

---
 README.md         | 21 ++++++++++++++++++++-
 granian/cli.py    | 33 ++++++++++++++++++++++++++++++++-
 granian/server.py | 22 ++++++++++++++++++++--
 3 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 0bc9da6c..e3b57e4f 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ A Rust HTTP server for Python applications.
 The main reasons behind Granian design are:
 
 - Have a single, correct HTTP implementation, supporting versions 1, 2 (and eventually 3)
-- Provide a single package for several platforms 
+- Provide a single package for several platforms
 - Avoid the usual Gunicorn + uvicorn + http-tools dependency composition on unix systems
 - Provide stable [performance](https://github.com/emmett-framework/granian/blob/master/benchmarks/README.md) when compared to existing alternatives
 
@@ -181,6 +181,25 @@ Options:
                                   changes (requires granian[reload] extra)
                                   [env var: GRANIAN_RELOAD; default:
                                   (disabled)]
+  --reload-paths TEXT             WatchFile paths to watch for changes
+                                  (requires granian[reload] extra)  [env var:
+                                  GRANIAN_RELOAD_PATHS; default:
+                                  /path/to/cwd]
+  --reload-ignore-paths TEXT      WatchFile paths to ignore changes for
+                                  (requires granian[reload] extra)  [env var:
+                                  GRANIAN_RELOAD_IGNORE_PATHS]
+  --reload-ignore-dirs TEXT       WatchFile directories to ignore changes for
+                                  (requires granian[reload] extra). Replaces
+                                  the default list of directories to ignore in
+                                  watchfiles.filters.DefaultFilter.  [env var:
+                                  GRANIAN_RELOAD_IGNORE_DIRS]
+  --reload-ignore-entity-patterns TEXT
+                                  WatchFile entity patterns to ignore changes
+                                  for (requires granian[reload] extra).
+                                  Replaces the default list of patterns to
+                                  ignore in watchfiles.filters.DefaultFilter.
+                                  [env var:
+                                  GRANIAN_RELOAD_IGNORE_ENTITY_PATTERNS]
   --process-name TEXT             Set a custom name for processes (requires
                                   granian[pname] extra)  [env var:
                                   GRANIAN_PROCESS_NAME]
diff --git a/granian/cli.py b/granian/cli.py
index db5bbadd..8a3ccc1d 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -1,6 +1,6 @@
 import json
 from pathlib import Path
-from typing import Optional
+from typing import List, Optional
 
 import typer
 
@@ -109,6 +109,33 @@ def main(
         help="Enable auto reload on application's files changes (requires granian[reload] extra)",
         show_default='disabled',
     ),
+    reload_paths: List[str] = typer.Option(
+        [Path.cwd()],
+        '--reload-paths',
+        help='WatchFile paths to watch for changes (requires granian[reload] extra)',
+    ),
+    reload_ignore_paths: List[str] = typer.Option(
+        [],
+        '--reload-ignore-paths',
+        help='WatchFile paths to ignore changes for (requires granian[reload] extra)',
+    ),
+    reload_ignore_dirs: List[str] = typer.Option(
+        [],
+        '--reload-ignore-dirs',
+        help=(
+            'WatchFile directories to ignore changes for (requires granian[reload] extra). '
+            'Replaces  the default list of directories to ignore in '
+            'watchfiles.filters.DefaultFilter.'
+        ),
+    ),
+    reload_ignore_entity_patterns: List[str] = typer.Option(
+        [],
+        '--reload-ignore-entity-patterns',
+        help=(
+            'WatchFile entity patterns to ignore changes for (requires granian[reload] extra). '
+            'Replaces the default list of patterns to ignore in watchfiles.filters.DefaultFilter.'
+        ),
+    ),
     process_name: Optional[str] = typer.Option(
         None,
         help='Set a custom name for processes (requires granian[pname] extra)',
@@ -167,5 +194,9 @@ def main(
         url_path_prefix=url_path_prefix,
         respawn_failed_workers=respawn_failed_workers,
         reload=reload,
+        reload_paths=reload_paths,
+        reload_ignore_paths=reload_ignore_paths,
+        reload_ignore_dirs=reload_ignore_dirs,
+        reload_ignore_entity_patterns=reload_ignore_entity_patterns,
         process_name=process_name,
     ).serve()
diff --git a/granian/server.py b/granian/server.py
index 1e009b04..82d14b48 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -88,6 +88,10 @@ def __init__(
         url_path_prefix: Optional[str] = None,
         respawn_failed_workers: bool = False,
         reload: bool = False,
+        reload_paths: Optional[List[str]] = None,
+        reload_ignore_paths: Optional[List[str]] = None,
+        reload_ignore_dirs: Optional[List[str]] = None,
+        reload_ignore_entity_patterns: Optional[List[str]] = None,
         process_name: Optional[str] = None,
     ):
         self.target = target
@@ -111,6 +115,10 @@ def __init__(
         self.url_path_prefix = url_path_prefix
         self.respawn_failed_workers = respawn_failed_workers
         self.reload_on_changes = reload
+        self.reload_paths = reload_paths
+        self.reload_ignore_paths = reload_ignore_paths
+        self.reload_ignore_dirs = reload_ignore_dirs
+        self.reload_ignore_entity_patterns = reload_ignore_entity_patterns
         self.process_name = process_name
 
         configure_logging(self.log_level, self.log_config, self.log_enabled)
@@ -416,11 +424,21 @@ def _serve_with_reloader(self, spawn_target, target_loader):
             logger.error('Using --reload requires the granian[reload] extra')
             sys.exit(1)
 
-        reload_path = Path.cwd()
+        reload_paths = self.reload_paths or [Path.cwd()]
+        reload_filter = watchfiles.filters.DefaultFilter(
+            ignore_dirs=self.reload_ignore_dirs,
+            ignore_entity_patterns=self.reload_ignore_entity_patterns,
+            ignore_paths=self.reload_ignore_paths,
+        )
+
         sock = self.startup(spawn_target, target_loader)
 
         try:
-            for _ in watchfiles.watch(reload_path, stop_event=self.main_loop_interrupt):
+            for _ in watchfiles.watch(
+                *reload_paths,
+                watch_filter=reload_filter,
+                stop_event=self.main_loop_interrupt,
+            ):
                 logger.info('Changes detected, reloading workers..')
                 self._stop_workers()
                 self._spawn_workers(sock, spawn_target, target_loader)

From b7d8581a0da5e7151c28029cd27c91d0d56f3877 Mon Sep 17 00:00:00 2001
From: Amon Khavari <amon.khavari@veeva.com>
Date: Wed, 31 Jul 2024 18:10:05 +0200
Subject: [PATCH 2/9] feat: adjust reload feature

---
 granian/_imports.py |  2 ++
 granian/cli.py      | 41 +++++++++++++++++++++++------------------
 granian/server.py   | 32 +++++++++++++++++++++-----------
 3 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/granian/_imports.py b/granian/_imports.py
index b07ce1b3..531de25a 100644
--- a/granian/_imports.py
+++ b/granian/_imports.py
@@ -5,5 +5,7 @@
 
 try:
     import watchfiles
+    from watchfiles import BaseFilter
 except ImportError:
     watchfiles = None
+    BaseFilter = None
diff --git a/granian/cli.py b/granian/cli.py
index c854cee4..309e462b 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -196,30 +196,35 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 )
 @option(
     '--reload-paths',
-    default=pathlib.Path.cwd(),
-    help='WatchFile paths to watch for changes (requires granian[reload] extra)',
-)
-@option(
-    '--reload-ignore-paths',
-    default=[],
-    help='WatchFile paths to ignore changes for (requires granian[reload] extra)',
+    type=click.Path(exists=True, file_okay=True, dir_okay=True, readable=True, path_type=pathlib.Path),
+    default=(pathlib.Path.cwd(),),
+    help='Paths to watch for changes',
+    multiple=True,
 )
 @option(
     '--reload-ignore-dirs',
-    default=[],
+    default=(),
     help=(
-        'WatchFile directories to ignore changes for (requires granian[reload] extra). '
-        'Replaces  the default list of directories to ignore in '
-        'watchfiles.filters.DefaultFilter.'
+        'Names of directories to ignore (i.e. should not trigger reload). '
+        'Extends the default list of directories to ignore in watchfiles.filters.DefaultFilter.'
     ),
+    multiple=True,
 )
 @option(
     '--reload-ignore-entity-patterns',
-    default=[],
+    default=(),
     help=(
-        'WatchFile entity patterns to ignore changes for (requires granian[reload] extra). '
-        'Replaces the default list of patterns to ignore in watchfiles.filters.DefaultFilter.'
+        'Regex patterns to ignore changes for. '
+        'Extends the default list of patterns to ignore in watchfiles.filters.DefaultFilter.'
     ),
+    multiple=True,
+)
+@option(
+    '--reload-ignore-paths',
+    type=click.Path(exists=False, path_type=pathlib.Path),
+    default=(),
+    help='Absolute paths to ignore changes for',
+    multiple=True,
 )
 @option(
     '--process-name',
@@ -269,10 +274,10 @@ def cli(
     respawn_failed_workers: bool,
     respawn_interval: float,
     reload: bool,
-    reload_paths: List[str],
-    reload_ignore_paths: List[str],
-    reload_ignore_dirs: List[str],
-    reload_ignore_entity_patterns: List[str],
+    reload_paths: List[pathlib.Path],
+    reload_ignore_dirs: Optional[List[str]],
+    reload_ignore_entity_patterns: Optional[List[str]],
+    reload_ignore_paths: Optional[List[pathlib.Path]],
     process_name: Optional[str],
     pid_file: Optional[pathlib.Path],
 ) -> None:
diff --git a/granian/server.py b/granian/server.py
index 0988230d..0363d3a7 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -4,6 +4,7 @@
 import errno
 import multiprocessing
 import os
+import pathlib
 import signal
 import socket
 import ssl
@@ -12,11 +13,11 @@
 import time
 from functools import partial
 from pathlib import Path
-from typing import Any, Callable, Dict, List, Optional, Tuple
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple
 
 from ._futures import future_watcher_wrapper
 from ._granian import ASGIWorker, RSGIWorker, WSGIWorker
-from ._imports import setproctitle, watchfiles
+from ._imports import BaseFilter, setproctitle, watchfiles
 from ._internal import load_target
 from .asgi import LifespanProtocol, _callback_wrapper as _asgi_call_wrap
 from .constants import HTTPModes, Interfaces, Loops, ThreadModes
@@ -95,10 +96,11 @@ def __init__(
         respawn_failed_workers: bool = False,
         respawn_interval: float = 3.5,
         reload: bool = False,
-        reload_paths: Optional[List[str]] = None,
-        reload_ignore_paths: Optional[List[str]] = None,
-        reload_ignore_dirs: Optional[List[str]] = None,
-        reload_ignore_entity_patterns: Optional[List[str]] = None,
+        reload_paths: Sequence[pathlib.Path] = (pathlib.Path.cwd(),),
+        reload_ignore_dirs: Optional[Sequence[str]] = (),
+        reload_ignore_entity_patterns: Optional[Sequence[str]] = (),
+        reload_ignore_paths: Optional[Sequence[pathlib.Path]] = (),
+        reload_filter: Optional[BaseFilter] = None,
         process_name: Optional[str] = None,
         pid_file: Optional[Path] = None,
     ):
@@ -137,6 +139,7 @@ def __init__(
         self.reload_ignore_paths = reload_ignore_paths
         self.reload_ignore_dirs = reload_ignore_dirs
         self.reload_ignore_entity_patterns = reload_ignore_entity_patterns
+        self.reload_filter = reload_filter
         self.process_name = process_name
         self.pid_file = pid_file
 
@@ -585,18 +588,25 @@ def _serve_with_reloader(self, spawn_target, target_loader):
             logger.error('Using --reload requires the granian[reload] extra')
             sys.exit(1)
 
-        reload_paths = self.reload_paths or [Path.cwd()]
+        # Use given or default filter rules
+        reload_filter = self.reload_filter or watchfiles.filters.DefaultFilter
+        # Extend `reload_filter` with explicit args
+        ignore_dirs = (*reload_filter.ignore_dirs, *self.reload_ignore_dirs)
+        ignore_entity_patterns = (
+            *reload_filter.ignore_entity_patterns,
+            *self.reload_ignore_entity_patterns,
+        )
+        ignore_paths = (*reload_filter.ignore_paths, *self.reload_ignore_paths)
+        # Construct new filter
         reload_filter = watchfiles.filters.DefaultFilter(
-            ignore_dirs=self.reload_ignore_dirs,
-            ignore_entity_patterns=self.reload_ignore_entity_patterns,
-            ignore_paths=self.reload_ignore_paths,
+            ignore_dirs=ignore_dirs, ignore_entity_patterns=ignore_entity_patterns, ignore_paths=ignore_paths
         )
 
         sock = self.startup(spawn_target, target_loader)
 
         try:
             for _ in watchfiles.watch(
-                *reload_paths,
+                *self.reload_paths,
                 watch_filter=reload_filter,
                 stop_event=self.main_loop_interrupt,
             ):

From ccdef03839686dbb416a6c8f618708c11b650a58 Mon Sep 17 00:00:00 2001
From: Amon Khavari <44270110+iamkhav@users.noreply.github.com>
Date: Thu, 1 Aug 2024 17:00:19 +0200
Subject: [PATCH 3/9] Update granian/server.py

---
 granian/server.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/granian/server.py b/granian/server.py
index 0363d3a7..38c40827 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -13,7 +13,7 @@
 import time
 from functools import partial
 from pathlib import Path
-from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type
 
 from ._futures import future_watcher_wrapper
 from ._granian import ASGIWorker, RSGIWorker, WSGIWorker
@@ -100,7 +100,7 @@ def __init__(
         reload_ignore_dirs: Optional[Sequence[str]] = (),
         reload_ignore_entity_patterns: Optional[Sequence[str]] = (),
         reload_ignore_paths: Optional[Sequence[pathlib.Path]] = (),
-        reload_filter: Optional[BaseFilter] = None,
+        reload_filter: Optional[Type[BaseFilter]] = None,
         process_name: Optional[str] = None,
         pid_file: Optional[Path] = None,
     ):

From f9da2c692699b584de66e875a8c5df593f43d0cf Mon Sep 17 00:00:00 2001
From: Amon Khavari <amon.khavari@veeva.com>
Date: Fri, 2 Aug 2024 18:28:54 +0200
Subject: [PATCH 4/9] gh comments: remove pathlib import and better naming
 ignore-patterns

---
 granian/cli.py    |  6 +++---
 granian/server.py | 11 +++++------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/granian/cli.py b/granian/cli.py
index 309e462b..c031a0d8 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -211,7 +211,7 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
     multiple=True,
 )
 @option(
-    '--reload-ignore-entity-patterns',
+    '--reload-ignore-patterns',
     default=(),
     help=(
         'Regex patterns to ignore changes for. '
@@ -276,7 +276,7 @@ def cli(
     reload: bool,
     reload_paths: List[pathlib.Path],
     reload_ignore_dirs: Optional[List[str]],
-    reload_ignore_entity_patterns: Optional[List[str]],
+    reload_ignore_patterns: Optional[List[str]],
     reload_ignore_paths: Optional[List[pathlib.Path]],
     process_name: Optional[str],
     pid_file: Optional[pathlib.Path],
@@ -333,7 +333,7 @@ def cli(
         reload_paths=reload_paths,
         reload_ignore_paths=reload_ignore_paths,
         reload_ignore_dirs=reload_ignore_dirs,
-        reload_ignore_entity_patterns=reload_ignore_entity_patterns,
+        reload_ignore_patterns=reload_ignore_patterns,
         process_name=process_name,
         pid_file=pid_file,
     )
diff --git a/granian/server.py b/granian/server.py
index 38c40827..22c98423 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -4,7 +4,6 @@
 import errno
 import multiprocessing
 import os
-import pathlib
 import signal
 import socket
 import ssl
@@ -96,10 +95,10 @@ def __init__(
         respawn_failed_workers: bool = False,
         respawn_interval: float = 3.5,
         reload: bool = False,
-        reload_paths: Sequence[pathlib.Path] = (pathlib.Path.cwd(),),
+        reload_paths: Sequence[Path] = (Path.cwd(),),
         reload_ignore_dirs: Optional[Sequence[str]] = (),
-        reload_ignore_entity_patterns: Optional[Sequence[str]] = (),
-        reload_ignore_paths: Optional[Sequence[pathlib.Path]] = (),
+        reload_ignore_patterns: Optional[Sequence[str]] = (),
+        reload_ignore_paths: Optional[Sequence[Path]] = (),
         reload_filter: Optional[Type[BaseFilter]] = None,
         process_name: Optional[str] = None,
         pid_file: Optional[Path] = None,
@@ -138,7 +137,7 @@ def __init__(
         self.reload_paths = reload_paths
         self.reload_ignore_paths = reload_ignore_paths
         self.reload_ignore_dirs = reload_ignore_dirs
-        self.reload_ignore_entity_patterns = reload_ignore_entity_patterns
+        self.reload_ignore_patterns = reload_ignore_patterns
         self.reload_filter = reload_filter
         self.process_name = process_name
         self.pid_file = pid_file
@@ -594,7 +593,7 @@ def _serve_with_reloader(self, spawn_target, target_loader):
         ignore_dirs = (*reload_filter.ignore_dirs, *self.reload_ignore_dirs)
         ignore_entity_patterns = (
             *reload_filter.ignore_entity_patterns,
-            *self.reload_ignore_entity_patterns,
+            *self.reload_ignore_patterns,
         )
         ignore_paths = (*reload_filter.ignore_paths, *self.reload_ignore_paths)
         # Construct new filter

From 5e11d9157dbf913acfc83a1a6fe3c107450d5df5 Mon Sep 17 00:00:00 2001
From: Amon Khavari <amon.khavari@veeva.com>
Date: Fri, 2 Aug 2024 19:11:52 +0200
Subject: [PATCH 5/9] gh comments: default args

---
 granian/cli.py    |  5 +----
 granian/server.py | 16 ++++++++--------
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/granian/cli.py b/granian/cli.py
index c031a0d8..3af91dba 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -197,13 +197,12 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 @option(
     '--reload-paths',
     type=click.Path(exists=True, file_okay=True, dir_okay=True, readable=True, path_type=pathlib.Path),
-    default=(pathlib.Path.cwd(),),
     help='Paths to watch for changes',
+    show_default='pathlib.Path.cwd()',
     multiple=True,
 )
 @option(
     '--reload-ignore-dirs',
-    default=(),
     help=(
         'Names of directories to ignore (i.e. should not trigger reload). '
         'Extends the default list of directories to ignore in watchfiles.filters.DefaultFilter.'
@@ -212,7 +211,6 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 )
 @option(
     '--reload-ignore-patterns',
-    default=(),
     help=(
         'Regex patterns to ignore changes for. '
         'Extends the default list of patterns to ignore in watchfiles.filters.DefaultFilter.'
@@ -222,7 +220,6 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 @option(
     '--reload-ignore-paths',
     type=click.Path(exists=False, path_type=pathlib.Path),
-    default=(),
     help='Absolute paths to ignore changes for',
     multiple=True,
 )
diff --git a/granian/server.py b/granian/server.py
index 22c98423..efbce2fc 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -95,10 +95,10 @@ def __init__(
         respawn_failed_workers: bool = False,
         respawn_interval: float = 3.5,
         reload: bool = False,
-        reload_paths: Sequence[Path] = (Path.cwd(),),
-        reload_ignore_dirs: Optional[Sequence[str]] = (),
-        reload_ignore_patterns: Optional[Sequence[str]] = (),
-        reload_ignore_paths: Optional[Sequence[Path]] = (),
+        reload_paths: Optional[Sequence[Path]] = None,
+        reload_ignore_dirs: Optional[Sequence[str]] = None,
+        reload_ignore_patterns: Optional[Sequence[str]] = None,
+        reload_ignore_paths: Optional[Sequence[Path]] = None,
         reload_filter: Optional[Type[BaseFilter]] = None,
         process_name: Optional[str] = None,
         pid_file: Optional[Path] = None,
@@ -134,10 +134,10 @@ def __init__(
         self.respawn_failed_workers = respawn_failed_workers
         self.reload_on_changes = reload
         self.respawn_interval = respawn_interval
-        self.reload_paths = reload_paths
-        self.reload_ignore_paths = reload_ignore_paths
-        self.reload_ignore_dirs = reload_ignore_dirs
-        self.reload_ignore_patterns = reload_ignore_patterns
+        self.reload_paths = reload_paths or Path.cwd()
+        self.reload_ignore_paths = reload_ignore_paths or ()
+        self.reload_ignore_dirs = reload_ignore_dirs or ()
+        self.reload_ignore_patterns = reload_ignore_patterns or ()
         self.reload_filter = reload_filter
         self.process_name = process_name
         self.pid_file = pid_file

From 3ecd76a25654e6be4e9316c696b0c543473e1385 Mon Sep 17 00:00:00 2001
From: Amon Khavari <amon.khavari@veeva.com>
Date: Thu, 15 Aug 2024 17:17:44 +0200
Subject: [PATCH 6/9] gh comments

---
 README.md         | 10 +++++-----
 granian/cli.py    |  4 ++--
 granian/server.py |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 62ae5441..83b838be 100644
--- a/README.md
+++ b/README.md
@@ -195,19 +195,19 @@ Options:
   --reload-paths TEXT             WatchFile paths to watch for changes
                                   (requires granian[reload] extra)  [env var:
                                   GRANIAN_RELOAD_PATHS; default:
-                                  /path/to/cwd]
+                                  Working directory]
   --reload-ignore-paths TEXT      WatchFile paths to ignore changes for
                                   (requires granian[reload] extra)  [env var:
                                   GRANIAN_RELOAD_IGNORE_PATHS]
   --reload-ignore-dirs TEXT       WatchFile directories to ignore changes for
-                                  (requires granian[reload] extra). Replaces
+                                  (requires granian[reload] extra). Extends
                                   the default list of directories to ignore in
                                   watchfiles.filters.DefaultFilter.  [env var:
                                   GRANIAN_RELOAD_IGNORE_DIRS]
-  --reload-ignore-entity-patterns TEXT
-                                  WatchFile entity patterns to ignore changes
+  --reload-ignore-patterns TEXT
+                                  WatchFile entity patterns (regex) to ignore changes
                                   for (requires granian[reload] extra).
-                                  Replaces the default list of patterns to
+                                  Extends the default list of patterns to
                                   ignore in watchfiles.filters.DefaultFilter.
                                   [env var:
                                   GRANIAN_RELOAD_IGNORE_ENTITY_PATTERNS]
diff --git a/granian/cli.py b/granian/cli.py
index 3af91dba..85f8eba9 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -198,7 +198,7 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
     '--reload-paths',
     type=click.Path(exists=True, file_okay=True, dir_okay=True, readable=True, path_type=pathlib.Path),
     help='Paths to watch for changes',
-    show_default='pathlib.Path.cwd()',
+    show_default='Working directory',
     multiple=True,
 )
 @option(
@@ -271,7 +271,7 @@ def cli(
     respawn_failed_workers: bool,
     respawn_interval: float,
     reload: bool,
-    reload_paths: List[pathlib.Path],
+    reload_paths: Optional[List[pathlib.Path]],
     reload_ignore_dirs: Optional[List[str]],
     reload_ignore_patterns: Optional[List[str]],
     reload_ignore_paths: Optional[List[pathlib.Path]],
diff --git a/granian/server.py b/granian/server.py
index e7f5364c..2b552f1c 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -134,7 +134,7 @@ def __init__(
         self.respawn_failed_workers = respawn_failed_workers
         self.reload_on_changes = reload
         self.respawn_interval = respawn_interval
-        self.reload_paths = reload_paths or Path.cwd()
+        self.reload_paths = reload_paths or [Path.cwd()]
         self.reload_ignore_paths = reload_ignore_paths or ()
         self.reload_ignore_dirs = reload_ignore_dirs or ()
         self.reload_ignore_patterns = reload_ignore_patterns or ()

From a83a0320e3bd231536c1bf1db2155efc37a80c2b Mon Sep 17 00:00:00 2001
From: Amon Khavari <amon.khavari@veeva.com>
Date: Thu, 15 Aug 2024 17:20:13 +0200
Subject: [PATCH 7/9] improve type hint to

---
 granian/_imports.py | 2 --
 granian/server.py   | 4 ++--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/granian/_imports.py b/granian/_imports.py
index 531de25a..b07ce1b3 100644
--- a/granian/_imports.py
+++ b/granian/_imports.py
@@ -5,7 +5,5 @@
 
 try:
     import watchfiles
-    from watchfiles import BaseFilter
 except ImportError:
     watchfiles = None
-    BaseFilter = None
diff --git a/granian/server.py b/granian/server.py
index 2b552f1c..69cf030b 100644
--- a/granian/server.py
+++ b/granian/server.py
@@ -16,7 +16,7 @@
 
 from ._futures import future_watcher_wrapper
 from ._granian import ASGIWorker, RSGIWorker, WSGIWorker
-from ._imports import BaseFilter, setproctitle, watchfiles
+from ._imports import setproctitle, watchfiles
 from ._internal import load_target
 from .asgi import LifespanProtocol, _callback_wrapper as _asgi_call_wrap
 from .constants import HTTPModes, Interfaces, Loops, ThreadModes
@@ -99,7 +99,7 @@ def __init__(
         reload_ignore_dirs: Optional[Sequence[str]] = None,
         reload_ignore_patterns: Optional[Sequence[str]] = None,
         reload_ignore_paths: Optional[Sequence[Path]] = None,
-        reload_filter: Optional[Type[BaseFilter]] = None,
+        reload_filter: Optional[Type[watchfiles.BaseFilter]] = None,
         process_name: Optional[str] = None,
         pid_file: Optional[Path] = None,
     ):

From c45e9a9179d3d31b1b3543d9325c2e0c6bcbbaca Mon Sep 17 00:00:00 2001
From: Amon Khavari <amon.khavari@veeva.com>
Date: Thu, 15 Aug 2024 17:41:34 +0200
Subject: [PATCH 8/9] improvements to documentation

---
 README.md      | 26 ++++++++++----------------
 granian/cli.py |  4 ++--
 2 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index 83b838be..7e62f724 100644
--- a/README.md
+++ b/README.md
@@ -192,25 +192,19 @@ Options:
                                   changes (requires granian[reload] extra)
                                   [env var: GRANIAN_RELOAD; default:
                                   (disabled)]
-  --reload-paths TEXT             WatchFile paths to watch for changes
-                                  (requires granian[reload] extra)  [env var:
-                                  GRANIAN_RELOAD_PATHS; default:
-                                  Working directory]
-  --reload-ignore-paths TEXT      WatchFile paths to ignore changes for
-                                  (requires granian[reload] extra)  [env var:
-                                  GRANIAN_RELOAD_IGNORE_PATHS]
-  --reload-ignore-dirs TEXT       WatchFile directories to ignore changes for
-                                  (requires granian[reload] extra). Extends
+  --reload-paths TEXT             Paths to watch for changes [env var:
+                                  GRANIAN_RELOAD_PATHS; default: Working directory]
+  --reload-ignore-dirs TEXT       Names of directories to ignore changes for 
+                                  (i.e. should not trigger reload). Extends
                                   the default list of directories to ignore in
-                                  watchfiles.filters.DefaultFilter.  [env var:
-                                  GRANIAN_RELOAD_IGNORE_DIRS]
-  --reload-ignore-patterns TEXT
-                                  WatchFile entity patterns (regex) to ignore changes
-                                  for (requires granian[reload] extra).
+                                  watchfiles.filters.DefaultFilter.  
+                                  [env var: GRANIAN_RELOAD_IGNORE_DIRS]
+  --reload-ignore-patterns TEXT   Entity patterns (regex) to ignore changes for.
                                   Extends the default list of patterns to
                                   ignore in watchfiles.filters.DefaultFilter.
-                                  [env var:
-                                  GRANIAN_RELOAD_IGNORE_ENTITY_PATTERNS]
+                                  [env var: GRANIAN_RELOAD_IGNORE_ENTITY_PATTERNS]
+  --reload-ignore-paths TEXT      Absolute paths to ignore changes for 
+                                  [env var: GRANIAN_RELOAD_IGNORE_PATHS]
   --process-name TEXT             Set a custom name for processes (requires
                                   granian[pname] extra)  [env var:
                                   GRANIAN_PROCESS_NAME]
diff --git a/granian/cli.py b/granian/cli.py
index 85f8eba9..a9c2e7ae 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -204,7 +204,7 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 @option(
     '--reload-ignore-dirs',
     help=(
-        'Names of directories to ignore (i.e. should not trigger reload). '
+        'Names of directories to ignore changes for (i.e. should not trigger reload). '
         'Extends the default list of directories to ignore in watchfiles.filters.DefaultFilter.'
     ),
     multiple=True,
@@ -212,7 +212,7 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 @option(
     '--reload-ignore-patterns',
     help=(
-        'Regex patterns to ignore changes for. '
+        'Entity patterns (regex) to ignore changes for. '
         'Extends the default list of patterns to ignore in watchfiles.filters.DefaultFilter.'
     ),
     multiple=True,

From fa414232a094afa674d91ac8ee802d16a2c62fad Mon Sep 17 00:00:00 2001
From: Giovanni Barillari <giovanni.barillari@sentry.io>
Date: Thu, 22 Aug 2024 13:01:39 +0200
Subject: [PATCH 9/9] Minor CLI help change

---
 README.md      | 24 ++++++++++++------------
 granian/cli.py |  8 ++++----
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md
index 7e62f724..80997563 100644
--- a/README.md
+++ b/README.md
@@ -192,19 +192,19 @@ Options:
                                   changes (requires granian[reload] extra)
                                   [env var: GRANIAN_RELOAD; default:
                                   (disabled)]
-  --reload-paths TEXT             Paths to watch for changes [env var:
-                                  GRANIAN_RELOAD_PATHS; default: Working directory]
-  --reload-ignore-dirs TEXT       Names of directories to ignore changes for 
-                                  (i.e. should not trigger reload). Extends
-                                  the default list of directories to ignore in
-                                  watchfiles.filters.DefaultFilter.  
-                                  [env var: GRANIAN_RELOAD_IGNORE_DIRS]
-  --reload-ignore-patterns TEXT   Entity patterns (regex) to ignore changes for.
+  --reload-paths PATH             Paths to watch for changes  [env var:
+                                  GRANIAN_RELOAD_PATHS; default: (Working
+                                  directory)]
+  --reload-ignore-dirs TEXT       Names of directories to ignore changes for.
+                                  Extends the default list of directories to
+                                  ignore in watchfiles' default filter  [env
+                                  var: GRANIAN_RELOAD_IGNORE_DIRS]
+  --reload-ignore-patterns TEXT   Path patterns (regex) to ignore changes for.
                                   Extends the default list of patterns to
-                                  ignore in watchfiles.filters.DefaultFilter.
-                                  [env var: GRANIAN_RELOAD_IGNORE_ENTITY_PATTERNS]
-  --reload-ignore-paths TEXT      Absolute paths to ignore changes for 
-                                  [env var: GRANIAN_RELOAD_IGNORE_PATHS]
+                                  ignore in watchfiles' default filter  [env
+                                  var: GRANIAN_RELOAD_IGNORE_PATTERNS]
+  --reload-ignore-paths PATH      Absolute paths to ignore changes for  [env
+                                  var: GRANIAN_RELOAD_IGNORE_PATHS]
   --process-name TEXT             Set a custom name for processes (requires
                                   granian[pname] extra)  [env var:
                                   GRANIAN_PROCESS_NAME]
diff --git a/granian/cli.py b/granian/cli.py
index a9c2e7ae..fb131f66 100644
--- a/granian/cli.py
+++ b/granian/cli.py
@@ -204,16 +204,16 @@ def option(*param_decls: str, cls: Optional[Type[click.Option]] = None, **attrs:
 @option(
     '--reload-ignore-dirs',
     help=(
-        'Names of directories to ignore changes for (i.e. should not trigger reload). '
-        'Extends the default list of directories to ignore in watchfiles.filters.DefaultFilter.'
+        'Names of directories to ignore changes for. '
+        "Extends the default list of directories to ignore in watchfiles' default filter"
     ),
     multiple=True,
 )
 @option(
     '--reload-ignore-patterns',
     help=(
-        'Entity patterns (regex) to ignore changes for. '
-        'Extends the default list of patterns to ignore in watchfiles.filters.DefaultFilter.'
+        'Path patterns (regex) to ignore changes for. '
+        "Extends the default list of patterns to ignore in watchfiles' default filter"
     ),
     multiple=True,
 )