We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Consider making `starlette.templating.Jinja2Templates.get_env` "protected"
Hi,
Thank you very much for your project! We are using it intensively through FastAPI.

While I was exploring the code base and looking how to use `Jinja2Templates`, I noticed the method `get_env`. At first I thought it was a getter for the environment, but eventually realized it is only called in the constructor of the class.

It would make much more sense to me if the method was called `_get_env`. This would signal that it should not be used outside of the class (or at least that the caller needs to know what she is doing).

For example, if I want to add filters or globals to the environment, I should write:

```
templates = Jinja2Templates(...)
templates.env.globals[...] = ...
```

instead of:

```
templates = Jinja2Templates(...)
templates.get_env().globals[...] = ...
```

As of current implementation, the second snippet has no effect.

Thank you very much for considering this request!

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `starlette/templating.py`
Content:
```
1 import typing
2 
3 from starlette.background import BackgroundTask
4 from starlette.responses import Response
5 from starlette.types import Receive, Scope, Send
6 
7 try:
8     import jinja2
9 
10     # @contextfunction renamed to @pass_context in Jinja 3.0, to be removed in 3.1
11     if hasattr(jinja2, "pass_context"):
12         pass_context = jinja2.pass_context
13     else:  # pragma: nocover
14         pass_context = jinja2.contextfunction
15 except ImportError:  # pragma: nocover
16     jinja2 = None  # type: ignore
17 
18 
19 class _TemplateResponse(Response):
20     media_type = "text/html"
21 
22     def __init__(
23         self,
24         template: typing.Any,
25         context: dict,
26         status_code: int = 200,
27         headers: dict = None,
28         media_type: str = None,
29         background: BackgroundTask = None,
30     ):
31         self.template = template
32         self.context = context
33         content = template.render(context)
34         super().__init__(content, status_code, headers, media_type, background)
35 
36     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
37         request = self.context.get("request", {})
38         extensions = request.get("extensions", {})
39         if "http.response.template" in extensions:
40             await send(
41                 {
42                     "type": "http.response.template",
43                     "template": self.template,
44                     "context": self.context,
45                 }
46             )
47         await super().__call__(scope, receive, send)
48 
49 
50 class Jinja2Templates:
51     """
52     templates = Jinja2Templates("templates")
53 
54     return templates.TemplateResponse("index.html", {"request": request})
55     """
56 
57     def __init__(self, directory: str) -> None:
58         assert jinja2 is not None, "jinja2 must be installed to use Jinja2Templates"
59         self.env = self.get_env(directory)
60 
61     def get_env(self, directory: str) -> "jinja2.Environment":
62         @pass_context
63         def url_for(context: dict, name: str, **path_params: typing.Any) -> str:
64             request = context["request"]
65             return request.url_for(name, **path_params)
66 
67         loader = jinja2.FileSystemLoader(directory)
68         env = jinja2.Environment(loader=loader, autoescape=True)
69         env.globals["url_for"] = url_for
70         return env
71 
72     def get_template(self, name: str) -> "jinja2.Template":
73         return self.env.get_template(name)
74 
75     def TemplateResponse(
76         self,
77         name: str,
78         context: dict,
79         status_code: int = 200,
80         headers: dict = None,
81         media_type: str = None,
82         background: BackgroundTask = None,
83     ) -> _TemplateResponse:
84         if "request" not in context:
85             raise ValueError('context must include a "request" key')
86         template = self.get_template(name)
87         return _TemplateResponse(
88             template,
89             context,
90             status_code=status_code,
91             headers=headers,
92             media_type=media_type,
93             background=background,
94         )
95
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/starlette/templating.py b/starlette/templating.py
--- a/starlette/templating.py
+++ b/starlette/templating.py
@@ -56,9 +56,9 @@
 
     def __init__(self, directory: str) -> None:
         assert jinja2 is not None, "jinja2 must be installed to use Jinja2Templates"
-        self.env = self.get_env(directory)
+        self.env = self._create_env(directory)
 
-    def get_env(self, directory: str) -> "jinja2.Environment":
+    def _create_env(self, directory: str) -> "jinja2.Environment":
         @pass_context
         def url_for(context: dict, name: str, **path_params: typing.Any) -> str:
             request = context["request"]

{"golden_diff": "diff --git a/starlette/templating.py b/starlette/templating.py\n--- a/starlette/templating.py\n+++ b/starlette/templating.py\n@@ -56,9 +56,9 @@\n \n     def __init__(self, directory: str) -> None:\n         assert jinja2 is not None, \"jinja2 must be installed to use Jinja2Templates\"\n-        self.env = self.get_env(directory)\n+        self.env = self._create_env(directory)\n \n-    def get_env(self, directory: str) -> \"jinja2.Environment\":\n+    def _create_env(self, directory: str) -> \"jinja2.Environment\":\n         @pass_context\n         def url_for(context: dict, name: str, **path_params: typing.Any) -> str:\n             request = context[\"request\"]\n", "issue": "Consider making `starlette.templating.Jinja2Templates.get_env` \"protected\"\nHi,\r\nThank you very much for your project! We are using it intensively through FastAPI.\r\n\r\nWhile I was exploring the code base and looking how to use `Jinja2Templates`, I noticed the method `get_env`. At first I thought it was a getter for the environment, but eventually realized it is only called in the constructor of the class.\r\n\r\nIt would make much more sense to me if the method was called `_get_env`. This would signal that it should not be used outside of the class (or at least that the caller needs to know what she is doing).\r\n\r\nFor example, if I want to add filters or globals to the environment, I should write:\r\n\r\n```\r\ntemplates = Jinja2Templates(...)\r\ntemplates.env.globals[...] = ...\r\n```\r\n\r\ninstead of:\r\n\r\n```\r\ntemplates = Jinja2Templates(...)\r\ntemplates.get_env().globals[...] = ...\r\n```\r\n\r\nAs of current implementation, the second snippet has no effect.\r\n\r\nThank you very much for considering this request!\n", "before_files": [{"content": "import typing\n\nfrom starlette.background import BackgroundTask\nfrom starlette.responses import Response\nfrom starlette.types import Receive, Scope, Send\n\ntry:\n    import jinja2\n\n    # @contextfunction renamed to @pass_context in Jinja 3.0, to be removed in 3.1\n    if hasattr(jinja2, \"pass_context\"):\n        pass_context = jinja2.pass_context\n    else:  # pragma: nocover\n        pass_context = jinja2.contextfunction\nexcept ImportError:  # pragma: nocover\n    jinja2 = None  # type: ignore\n\n\nclass _TemplateResponse(Response):\n    media_type = \"text/html\"\n\n    def __init__(\n        self,\n        template: typing.Any,\n        context: dict,\n        status_code: int = 200,\n        headers: dict = None,\n        media_type: str = None,\n        background: BackgroundTask = None,\n    ):\n        self.template = template\n        self.context = context\n        content = template.render(context)\n        super().__init__(content, status_code, headers, media_type, background)\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        request = self.context.get(\"request\", {})\n        extensions = request.get(\"extensions\", {})\n        if \"http.response.template\" in extensions:\n            await send(\n                {\n                    \"type\": \"http.response.template\",\n                    \"template\": self.template,\n                    \"context\": self.context,\n                }\n            )\n        await super().__call__(scope, receive, send)\n\n\nclass Jinja2Templates:\n    \"\"\"\n    templates = Jinja2Templates(\"templates\")\n\n    return templates.TemplateResponse(\"index.html\", {\"request\": request})\n    \"\"\"\n\n    def __init__(self, directory: str) -> None:\n        assert jinja2 is not None, \"jinja2 must be installed to use Jinja2Templates\"\n        self.env = self.get_env(directory)\n\n    def get_env(self, directory: str) -> \"jinja2.Environment\":\n        @pass_context\n        def url_for(context: dict, name: str, **path_params: typing.Any) -> str:\n            request = context[\"request\"]\n            return request.url_for(name, **path_params)\n\n        loader = jinja2.FileSystemLoader(directory)\n        env = jinja2.Environment(loader=loader, autoescape=True)\n        env.globals[\"url_for\"] = url_for\n        return env\n\n    def get_template(self, name: str) -> \"jinja2.Template\":\n        return self.env.get_template(name)\n\n    def TemplateResponse(\n        self,\n        name: str,\n        context: dict,\n        status_code: int = 200,\n        headers: dict = None,\n        media_type: str = None,\n        background: BackgroundTask = None,\n    ) -> _TemplateResponse:\n        if \"request\" not in context:\n            raise ValueError('context must include a \"request\" key')\n        template = self.get_template(name)\n        return _TemplateResponse(\n            template,\n            context,\n            status_code=status_code,\n            headers=headers,\n            media_type=media_type,\n            background=background,\n        )\n", "path": "starlette/templating.py"}], "after_files": [{"content": "import typing\n\nfrom starlette.background import BackgroundTask\nfrom starlette.responses import Response\nfrom starlette.types import Receive, Scope, Send\n\ntry:\n    import jinja2\n\n    # @contextfunction renamed to @pass_context in Jinja 3.0, to be removed in 3.1\n    if hasattr(jinja2, \"pass_context\"):\n        pass_context = jinja2.pass_context\n    else:  # pragma: nocover\n        pass_context = jinja2.contextfunction\nexcept ImportError:  # pragma: nocover\n    jinja2 = None  # type: ignore\n\n\nclass _TemplateResponse(Response):\n    media_type = \"text/html\"\n\n    def __init__(\n        self,\n        template: typing.Any,\n        context: dict,\n        status_code: int = 200,\n        headers: dict = None,\n        media_type: str = None,\n        background: BackgroundTask = None,\n    ):\n        self.template = template\n        self.context = context\n        content = template.render(context)\n        super().__init__(content, status_code, headers, media_type, background)\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        request = self.context.get(\"request\", {})\n        extensions = request.get(\"extensions\", {})\n        if \"http.response.template\" in extensions:\n            await send(\n                {\n                    \"type\": \"http.response.template\",\n                    \"template\": self.template,\n                    \"context\": self.context,\n                }\n            )\n        await super().__call__(scope, receive, send)\n\n\nclass Jinja2Templates:\n    \"\"\"\n    templates = Jinja2Templates(\"templates\")\n\n    return templates.TemplateResponse(\"index.html\", {\"request\": request})\n    \"\"\"\n\n    def __init__(self, directory: str) -> None:\n        assert jinja2 is not None, \"jinja2 must be installed to use Jinja2Templates\"\n        self.env = self._create_env(directory)\n\n    def _create_env(self, directory: str) -> \"jinja2.Environment\":\n        @pass_context\n        def url_for(context: dict, name: str, **path_params: typing.Any) -> str:\n            request = context[\"request\"]\n            return request.url_for(name, **path_params)\n\n        loader = jinja2.FileSystemLoader(directory)\n        env = jinja2.Environment(loader=loader, autoescape=True)\n        env.globals[\"url_for\"] = url_for\n        return env\n\n    def get_template(self, name: str) -> \"jinja2.Template\":\n        return self.env.get_template(name)\n\n    def TemplateResponse(\n        self,\n        name: str,\n        context: dict,\n        status_code: int = 200,\n        headers: dict = None,\n        media_type: str = None,\n        background: BackgroundTask = None,\n    ) -> _TemplateResponse:\n        if \"request\" not in context:\n            raise ValueError('context must include a \"request\" key')\n        template = self.get_template(name)\n        return _TemplateResponse(\n            template,\n            context,\n            status_code=status_code,\n            headers=headers,\n            media_type=media_type,\n            background=background,\n        )\n", "path": "starlette/templating.py"}]}