Repository: encode/starlette

Issue:
Check directory exists when instantiating `StaticFiles`
The `StaticFiles` application should ensure that the directory exists at the point it is instantiated.

(With an optional switch to turn this behavior off)

Discussion:
tomchristie: Perfect!

Patch:
diff --git a/docs/staticfiles.md b/docs/staticfiles.md
index 448cc3b..cc8db5e 100644
--- a/docs/staticfiles.md
+++ b/docs/staticfiles.md
@@ -1,7 +1,12 @@
 
-Starlette also includes a `StaticFiles` class for serving a specific directory:
+Starlette also includes a `StaticFiles` class for serving files in a given directory:
 
-* `StaticFiles(directory)` - Serve any files in the given `directory`.
+### StaticFiles
+
+Signature: `StaticFiles(directory, check_dir=True)`
+
+* `directory` - A string denoting the directory path
+* `check_dir` - Ensure that the directory exists upon instantiation. Defaults to `True`
 
 You can combine this ASGI application with Starlette's routing to provide
 comprehensive static file serving.
diff --git a/starlette/staticfiles.py b/starlette/staticfiles.py
index 8a7527a..ec2418e 100644
--- a/starlette/staticfiles.py
+++ b/starlette/staticfiles.py
@@ -8,7 +8,9 @@ from starlette.types import ASGIInstance, Receive, Scope, Send
 
 
 class StaticFiles:
-    def __init__(self, *, directory: str) -> None:
+    def __init__(self, *, directory: str, check_dir: bool = True) -> None:
+        if check_dir and not os.path.isdir(directory):
+            raise RuntimeError("Directory '%s' does not exist" % directory)
         self.directory = directory
         self.config_checked = False
 


Test patch:
diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py
index 9d12de8..84f3368 100644
--- a/tests/test_staticfiles.py
+++ b/tests/test_staticfiles.py
@@ -54,9 +54,16 @@ def test_staticfiles_with_missing_file_returns_404(tmpdir):
     assert response.text == "Not Found"
 
 
+def test_staticfiles_instantiated_with_missing_directory(tmpdir):
+    with pytest.raises(RuntimeError) as exc:
+        path = os.path.join(tmpdir, "no_such_directory")
+        app = StaticFiles(directory=path)
+    assert "does not exist" in str(exc)
+
+
 def test_staticfiles_configured_with_missing_directory(tmpdir):
     path = os.path.join(tmpdir, "no_such_directory")
-    app = StaticFiles(directory=path)
+    app = StaticFiles(directory=path, check_dir=False)
     client = TestClient(app)
     with pytest.raises(RuntimeError) as exc:
         client.get("/example.txt")
@@ -68,7 +75,7 @@ def test_staticfiles_configured_with_file_instead_of_directory(tmpdir):
     with open(path, "w") as file:
         file.write("<file content>")
 
-    app = StaticFiles(directory=path)
+    app = StaticFiles(directory=path, check_dir=False)
     client = TestClient(app)
     with pytest.raises(RuntimeError) as exc:
         client.get("/example.txt")