We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Provider base and cluster provider to be added to reference
**Is your feature request related to a problem? Please describe.**

In the last set of doc updates where we trimmed some of the developer docs we've moved to relying more on the references to point someone to. It looks like the [provider base](https://github.com/Parsl/parsl/blob/master/parsl/providers/provider_base.py) class and [cluster provider](https://github.com/Parsl/parsl/blob/master/parsl/providers/cluster_provider.py) are missing from there. 

**Describe the solution you'd like**
Update docs to add these to the reference.

Provider base and cluster provider to be added to reference
**Is your feature request related to a problem? Please describe.**

In the last set of doc updates where we trimmed some of the developer docs we've moved to relying more on the references to point someone to. It looks like the [provider base](https://github.com/Parsl/parsl/blob/master/parsl/providers/provider_base.py) class and [cluster provider](https://github.com/Parsl/parsl/blob/master/parsl/providers/cluster_provider.py) are missing from there. 

**Describe the solution you'd like**
Update docs to add these to the reference.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `parsl/providers/cluster_provider.py`
Content:
```
1 import logging
2 from abc import abstractmethod
3 from string import Template
4 
5 from parsl.providers.error import SchedulerMissingArgs, ScriptPathError
6 from parsl.launchers.error import BadLauncher
7 from parsl.providers.provider_base import ExecutionProvider
8 
9 logger = logging.getLogger(__name__)
10 
11 
12 class ClusterProvider(ExecutionProvider):
13     """ This class defines behavior common to all cluster/supercompute-style scheduler systems.
14 
15     Parameters
16     ----------
17     label : str
18         Label for this provider.
19     channel : Channel
20         Channel for accessing this provider. Possible channels include
21         :class:`~parsl.channels.LocalChannel` (the default),
22         :class:`~parsl.channels.SSHChannel`, or
23         :class:`~parsl.channels.SSHInteractiveLoginChannel`.
24     walltime : str
25         Walltime requested per block in HH:MM:SS.
26     launcher : str
27         FIXME
28     cmd_timeout : int
29         Timeout for commands made to the scheduler in seconds
30 
31     .. code:: python
32 
33                                 +------------------
34                                 |
35           script_string ------->|  submit
36                id      <--------|---+
37                                 |
38           [ ids ]       ------->|  status
39           [statuses]   <--------|----+
40                                 |
41           [ ids ]       ------->|  cancel
42           [cancel]     <--------|----+
43                                 |
44                                 +-------------------
45     """
46 
47     def __init__(self,
48                  label,
49                  channel,
50                  nodes_per_block,
51                  init_blocks,
52                  min_blocks,
53                  max_blocks,
54                  parallelism,
55                  walltime,
56                  launcher,
57                  cmd_timeout=10):
58 
59         self._label = label
60         self.channel = channel
61         self.nodes_per_block = nodes_per_block
62         self.init_blocks = init_blocks
63         self.min_blocks = min_blocks
64         self.max_blocks = max_blocks
65         self.parallelism = parallelism
66         self.launcher = launcher
67         self.walltime = walltime
68         self.cmd_timeout = cmd_timeout
69         if not callable(self.launcher):
70             raise(BadLauncher(self.launcher,
71                               "Launcher for executor: {} is of type: {}. Expects a parsl.launcher.launcher.Launcher or callable".format(
72                                   label, type(self.launcher))))
73 
74         self.script_dir = None
75 
76         # Dictionary that keeps track of jobs, keyed on job_id
77         self.resources = {}
78 
79     def execute_wait(self, cmd, timeout=None):
80         t = self.cmd_timeout
81         if timeout is not None:
82             t = timeout
83         return self.channel.execute_wait(cmd, t)
84 
85     def _write_submit_script(self, template, script_filename, job_name, configs):
86         """Generate submit script and write it to a file.
87 
88         Args:
89               - template (string) : The template string to be used for the writing submit script
90               - script_filename (string) : Name of the submit script
91               - job_name (string) : job name
92               - configs (dict) : configs that get pushed into the template
93 
94         Returns:
95               - True: on success
96 
97         Raises:
98               SchedulerMissingArgs : If template is missing args
99               ScriptPathError : Unable to write submit script out
100         """
101 
102         try:
103             submit_script = Template(template).substitute(jobname=job_name, **configs)
104             # submit_script = Template(template).safe_substitute(jobname=job_name, **configs)
105             with open(script_filename, 'w') as f:
106                 f.write(submit_script)
107 
108         except KeyError as e:
109             logger.error("Missing keys for submit script : %s", e)
110             raise (SchedulerMissingArgs(e.args, self.label))
111 
112         except IOError as e:
113             logger.error("Failed writing to submit script: %s", script_filename)
114             raise (ScriptPathError(script_filename, e))
115         except Exception as e:
116             print("Template : ", template)
117             print("Args : ", job_name)
118             print("Kwargs : ", configs)
119             logger.error("Uncategorized error: %s", e)
120             raise (e)
121 
122         return True
123 
124     @abstractmethod
125     def _status(self):
126         pass
127 
128     def status(self, job_ids):
129         """ Get the status of a list of jobs identified by the job identifiers
130         returned from the submit request.
131 
132         Args:
133              - job_ids (list) : A list of job identifiers
134 
135         Returns:
136              - A list of JobStatus objects corresponding to each job_id in the job_ids list.
137 
138         Raises:
139              - ExecutionProviderException or its subclasses
140 
141         """
142         if job_ids:
143             self._status()
144         return [self.resources[jid]['status'] for jid in job_ids]
145 
146     @property
147     def label(self):
148         return self._label
149
```
--- 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/parsl/providers/cluster_provider.py b/parsl/providers/cluster_provider.py
--- a/parsl/providers/cluster_provider.py
+++ b/parsl/providers/cluster_provider.py
@@ -14,18 +14,18 @@
 
     Parameters
     ----------
-    label : str
+      label : str
         Label for this provider.
-    channel : Channel
+      channel : Channel
         Channel for accessing this provider. Possible channels include
         :class:`~parsl.channels.LocalChannel` (the default),
         :class:`~parsl.channels.SSHChannel`, or
         :class:`~parsl.channels.SSHInteractiveLoginChannel`.
-    walltime : str
+      walltime : str
         Walltime requested per block in HH:MM:SS.
-    launcher : str
+      launcher : str
         FIXME
-    cmd_timeout : int
+      cmd_timeout : int
         Timeout for commands made to the scheduler in seconds
 
     .. code:: python

{"golden_diff": "diff --git a/parsl/providers/cluster_provider.py b/parsl/providers/cluster_provider.py\n--- a/parsl/providers/cluster_provider.py\n+++ b/parsl/providers/cluster_provider.py\n@@ -14,18 +14,18 @@\n \n     Parameters\n     ----------\n-    label : str\n+      label : str\n         Label for this provider.\n-    channel : Channel\n+      channel : Channel\n         Channel for accessing this provider. Possible channels include\n         :class:`~parsl.channels.LocalChannel` (the default),\n         :class:`~parsl.channels.SSHChannel`, or\n         :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n-    walltime : str\n+      walltime : str\n         Walltime requested per block in HH:MM:SS.\n-    launcher : str\n+      launcher : str\n         FIXME\n-    cmd_timeout : int\n+      cmd_timeout : int\n         Timeout for commands made to the scheduler in seconds\n \n     .. code:: python\n", "issue": "Provider base and cluster provider to be added to reference\n**Is your feature request related to a problem? Please describe.**\r\n\r\nIn the last set of doc updates where we trimmed some of the developer docs we've moved to relying more on the references to point someone to. It looks like the [provider base](https://github.com/Parsl/parsl/blob/master/parsl/providers/provider_base.py) class and [cluster provider](https://github.com/Parsl/parsl/blob/master/parsl/providers/cluster_provider.py) are missing from there. \r\n\r\n**Describe the solution you'd like**\r\nUpdate docs to add these to the reference.\r\n\nProvider base and cluster provider to be added to reference\n**Is your feature request related to a problem? Please describe.**\r\n\r\nIn the last set of doc updates where we trimmed some of the developer docs we've moved to relying more on the references to point someone to. It looks like the [provider base](https://github.com/Parsl/parsl/blob/master/parsl/providers/provider_base.py) class and [cluster provider](https://github.com/Parsl/parsl/blob/master/parsl/providers/cluster_provider.py) are missing from there. \r\n\r\n**Describe the solution you'd like**\r\nUpdate docs to add these to the reference.\r\n\n", "before_files": [{"content": "import logging\nfrom abc import abstractmethod\nfrom string import Template\n\nfrom parsl.providers.error import SchedulerMissingArgs, ScriptPathError\nfrom parsl.launchers.error import BadLauncher\nfrom parsl.providers.provider_base import ExecutionProvider\n\nlogger = logging.getLogger(__name__)\n\n\nclass ClusterProvider(ExecutionProvider):\n    \"\"\" This class defines behavior common to all cluster/supercompute-style scheduler systems.\n\n    Parameters\n    ----------\n    label : str\n        Label for this provider.\n    channel : Channel\n        Channel for accessing this provider. Possible channels include\n        :class:`~parsl.channels.LocalChannel` (the default),\n        :class:`~parsl.channels.SSHChannel`, or\n        :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n    walltime : str\n        Walltime requested per block in HH:MM:SS.\n    launcher : str\n        FIXME\n    cmd_timeout : int\n        Timeout for commands made to the scheduler in seconds\n\n    .. code:: python\n\n                                +------------------\n                                |\n          script_string ------->|  submit\n               id      <--------|---+\n                                |\n          [ ids ]       ------->|  status\n          [statuses]   <--------|----+\n                                |\n          [ ids ]       ------->|  cancel\n          [cancel]     <--------|----+\n                                |\n                                +-------------------\n    \"\"\"\n\n    def __init__(self,\n                 label,\n                 channel,\n                 nodes_per_block,\n                 init_blocks,\n                 min_blocks,\n                 max_blocks,\n                 parallelism,\n                 walltime,\n                 launcher,\n                 cmd_timeout=10):\n\n        self._label = label\n        self.channel = channel\n        self.nodes_per_block = nodes_per_block\n        self.init_blocks = init_blocks\n        self.min_blocks = min_blocks\n        self.max_blocks = max_blocks\n        self.parallelism = parallelism\n        self.launcher = launcher\n        self.walltime = walltime\n        self.cmd_timeout = cmd_timeout\n        if not callable(self.launcher):\n            raise(BadLauncher(self.launcher,\n                              \"Launcher for executor: {} is of type: {}. Expects a parsl.launcher.launcher.Launcher or callable\".format(\n                                  label, type(self.launcher))))\n\n        self.script_dir = None\n\n        # Dictionary that keeps track of jobs, keyed on job_id\n        self.resources = {}\n\n    def execute_wait(self, cmd, timeout=None):\n        t = self.cmd_timeout\n        if timeout is not None:\n            t = timeout\n        return self.channel.execute_wait(cmd, t)\n\n    def _write_submit_script(self, template, script_filename, job_name, configs):\n        \"\"\"Generate submit script and write it to a file.\n\n        Args:\n              - template (string) : The template string to be used for the writing submit script\n              - script_filename (string) : Name of the submit script\n              - job_name (string) : job name\n              - configs (dict) : configs that get pushed into the template\n\n        Returns:\n              - True: on success\n\n        Raises:\n              SchedulerMissingArgs : If template is missing args\n              ScriptPathError : Unable to write submit script out\n        \"\"\"\n\n        try:\n            submit_script = Template(template).substitute(jobname=job_name, **configs)\n            # submit_script = Template(template).safe_substitute(jobname=job_name, **configs)\n            with open(script_filename, 'w') as f:\n                f.write(submit_script)\n\n        except KeyError as e:\n            logger.error(\"Missing keys for submit script : %s\", e)\n            raise (SchedulerMissingArgs(e.args, self.label))\n\n        except IOError as e:\n            logger.error(\"Failed writing to submit script: %s\", script_filename)\n            raise (ScriptPathError(script_filename, e))\n        except Exception as e:\n            print(\"Template : \", template)\n            print(\"Args : \", job_name)\n            print(\"Kwargs : \", configs)\n            logger.error(\"Uncategorized error: %s\", e)\n            raise (e)\n\n        return True\n\n    @abstractmethod\n    def _status(self):\n        pass\n\n    def status(self, job_ids):\n        \"\"\" Get the status of a list of jobs identified by the job identifiers\n        returned from the submit request.\n\n        Args:\n             - job_ids (list) : A list of job identifiers\n\n        Returns:\n             - A list of JobStatus objects corresponding to each job_id in the job_ids list.\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n\n        \"\"\"\n        if job_ids:\n            self._status()\n        return [self.resources[jid]['status'] for jid in job_ids]\n\n    @property\n    def label(self):\n        return self._label\n", "path": "parsl/providers/cluster_provider.py"}], "after_files": [{"content": "import logging\nfrom abc import abstractmethod\nfrom string import Template\n\nfrom parsl.providers.error import SchedulerMissingArgs, ScriptPathError\nfrom parsl.launchers.error import BadLauncher\nfrom parsl.providers.provider_base import ExecutionProvider\n\nlogger = logging.getLogger(__name__)\n\n\nclass ClusterProvider(ExecutionProvider):\n    \"\"\" This class defines behavior common to all cluster/supercompute-style scheduler systems.\n\n    Parameters\n    ----------\n      label : str\n        Label for this provider.\n      channel : Channel\n        Channel for accessing this provider. Possible channels include\n        :class:`~parsl.channels.LocalChannel` (the default),\n        :class:`~parsl.channels.SSHChannel`, or\n        :class:`~parsl.channels.SSHInteractiveLoginChannel`.\n      walltime : str\n        Walltime requested per block in HH:MM:SS.\n      launcher : str\n        FIXME\n      cmd_timeout : int\n        Timeout for commands made to the scheduler in seconds\n\n    .. code:: python\n\n                                +------------------\n                                |\n          script_string ------->|  submit\n               id      <--------|---+\n                                |\n          [ ids ]       ------->|  status\n          [statuses]   <--------|----+\n                                |\n          [ ids ]       ------->|  cancel\n          [cancel]     <--------|----+\n                                |\n                                +-------------------\n    \"\"\"\n\n    def __init__(self,\n                 label,\n                 channel,\n                 nodes_per_block,\n                 init_blocks,\n                 min_blocks,\n                 max_blocks,\n                 parallelism,\n                 walltime,\n                 launcher,\n                 cmd_timeout=10):\n\n        self._label = label\n        self.channel = channel\n        self.nodes_per_block = nodes_per_block\n        self.init_blocks = init_blocks\n        self.min_blocks = min_blocks\n        self.max_blocks = max_blocks\n        self.parallelism = parallelism\n        self.launcher = launcher\n        self.walltime = walltime\n        self.cmd_timeout = cmd_timeout\n        if not callable(self.launcher):\n            raise(BadLauncher(self.launcher,\n                              \"Launcher for executor: {} is of type: {}. Expects a parsl.launcher.launcher.Launcher or callable\".format(\n                                  label, type(self.launcher))))\n\n        self.script_dir = None\n\n        # Dictionary that keeps track of jobs, keyed on job_id\n        self.resources = {}\n\n    def execute_wait(self, cmd, timeout=None):\n        t = self.cmd_timeout\n        if timeout is not None:\n            t = timeout\n        return self.channel.execute_wait(cmd, t)\n\n    def _write_submit_script(self, template, script_filename, job_name, configs):\n        \"\"\"Generate submit script and write it to a file.\n\n        Args:\n              - template (string) : The template string to be used for the writing submit script\n              - script_filename (string) : Name of the submit script\n              - job_name (string) : job name\n              - configs (dict) : configs that get pushed into the template\n\n        Returns:\n              - True: on success\n\n        Raises:\n              SchedulerMissingArgs : If template is missing args\n              ScriptPathError : Unable to write submit script out\n        \"\"\"\n\n        try:\n            submit_script = Template(template).substitute(jobname=job_name, **configs)\n            # submit_script = Template(template).safe_substitute(jobname=job_name, **configs)\n            with open(script_filename, 'w') as f:\n                f.write(submit_script)\n\n        except KeyError as e:\n            logger.error(\"Missing keys for submit script : %s\", e)\n            raise (SchedulerMissingArgs(e.args, self.label))\n\n        except IOError as e:\n            logger.error(\"Failed writing to submit script: %s\", script_filename)\n            raise (ScriptPathError(script_filename, e))\n        except Exception as e:\n            print(\"Template : \", template)\n            print(\"Args : \", job_name)\n            print(\"Kwargs : \", configs)\n            logger.error(\"Uncategorized error: %s\", e)\n            raise (e)\n\n        return True\n\n    @abstractmethod\n    def _status(self):\n        pass\n\n    def status(self, job_ids):\n        \"\"\" Get the status of a list of jobs identified by the job identifiers\n        returned from the submit request.\n\n        Args:\n             - job_ids (list) : A list of job identifiers\n\n        Returns:\n             - A list of JobStatus objects corresponding to each job_id in the job_ids list.\n\n        Raises:\n             - ExecutionProviderException or its subclasses\n\n        \"\"\"\n        if job_ids:\n            self._status()\n        return [self.resources[jid]['status'] for jid in job_ids]\n\n    @property\n    def label(self):\n        return self._label\n", "path": "parsl/providers/cluster_provider.py"}]}