We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
BigQuery: expose public helper method to convert a list of schema fields to/from a list of schema dictionaries (JSON)
I've received some feedback asking how to take a schema from the client library and save it to a JSON file. One reason to do this is the [`bq` command-line tool](https://cloud.google.com/bigquery/bq-command-line-tool#creatingtablefromfile) accepts a schema file, formatted like

```
[
  {"name": "name", "type": "string", "mode": "required"},
  {"name": "gender", "type": "string", "mode": "nullable"},
  {"name": "count", "type": "integer", "mode": "required"}
]
```

Note: this format is the same as the API representation.

It would be great if our client libraries could read/write in this format.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bigquery/google/cloud/bigquery/schema.py`
Content:
```
1 # Copyright 2015 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Schemas for BigQuery tables / queries."""
16 
17 
18 class SchemaField(object):
19     """Describe a single field within a table schema.
20 
21     :type name: str
22     :param name: the name of the field.
23 
24     :type field_type: str
25     :param field_type: the type of the field (one of 'STRING', 'INTEGER',
26                        'FLOAT', 'BOOLEAN', 'TIMESTAMP' or 'RECORD').
27 
28     :type mode: str
29     :param mode: the mode of the field (one of 'NULLABLE', 'REQUIRED',
30                  or 'REPEATED').
31 
32     :type description: str
33     :param description: optional description for the field.
34 
35     :type fields: tuple of :class:`SchemaField`
36     :param fields: subfields (requires ``field_type`` of 'RECORD').
37     """
38     def __init__(self, name, field_type, mode='NULLABLE',
39                  description=None, fields=()):
40         self._name = name
41         self._field_type = field_type
42         self._mode = mode
43         self._description = description
44         self._fields = tuple(fields)
45 
46     @property
47     def name(self):
48         """str: The name of the field."""
49         return self._name
50 
51     @property
52     def field_type(self):
53         """str: The type of the field.
54 
55         Will be one of 'STRING', 'INTEGER', 'FLOAT', 'BOOLEAN',
56         'TIMESTAMP' or 'RECORD'.
57         """
58         return self._field_type
59 
60     @property
61     def mode(self):
62         """str: The mode of the field.
63 
64         Will be one of 'NULLABLE', 'REQUIRED', or 'REPEATED'.
65         """
66         return self._mode
67 
68     @property
69     def is_nullable(self):
70         """Check whether 'mode' is 'nullable'."""
71         return self._mode == 'NULLABLE'
72 
73     @property
74     def description(self):
75         """Optional[str]: Description for the field."""
76         return self._description
77 
78     @property
79     def fields(self):
80         """tuple: Subfields contained in this field.
81 
82         If ``field_type`` is not 'RECORD', this property must be
83         empty / unset.
84         """
85         return self._fields
86 
87     def _key(self):
88         """A tuple key that unique-ly describes this field.
89 
90         Used to compute this instance's hashcode and evaluate equality.
91 
92         Returns:
93             tuple: The contents of this :class:`SchemaField`.
94         """
95         return (
96             self._name,
97             self._field_type.lower(),
98             self._mode,
99             self._description,
100             self._fields,
101         )
102 
103     def __eq__(self, other):
104         if not isinstance(other, SchemaField):
105             return NotImplemented
106         return self._key() == other._key()
107 
108     def __ne__(self, other):
109         return not self == other
110 
111     def __hash__(self):
112         return hash(self._key())
113 
114     def __repr__(self):
115         return 'SchemaField{}'.format(self._key())
116
```
--- 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/bigquery/google/cloud/bigquery/schema.py b/bigquery/google/cloud/bigquery/schema.py
--- a/bigquery/google/cloud/bigquery/schema.py
+++ b/bigquery/google/cloud/bigquery/schema.py
@@ -43,6 +43,25 @@
         self._description = description
         self._fields = tuple(fields)
 
+    @classmethod
+    def from_api_repr(cls, api_repr):
+        """Return a ``SchemaField`` object deserialized from a dictionary.
+
+        Args:
+            api_repr (Mapping[str, str]): The serialized representation
+                of the SchemaField, such as what is output by
+                :meth:`to_api_repr`.
+
+        Returns:
+            SchemaField: The ``SchemaField`` object.
+        """
+        return cls(
+            field_type=api_repr['type'].upper(),
+            fields=[cls.from_api_repr(f) for f in api_repr.get('fields', ())],
+            mode=api_repr['mode'].upper(),
+            name=api_repr['name'],
+        )
+
     @property
     def name(self):
         """str: The name of the field."""
@@ -84,6 +103,28 @@
         """
         return self._fields
 
+    def to_api_repr(self):
+        """Return a dictionary representing this schema field.
+
+        Returns:
+            dict: A dictionary representing the SchemaField in a serialized
+                form.
+        """
+        # Put together the basic representation. See http://bit.ly/2hOAT5u.
+        answer = {
+            'mode': self.mode.lower(),
+            'name': self.name,
+            'type': self.field_type.lower(),
+        }
+
+        # If this is a RECORD type, then sub-fields are also included,
+        # add this to the serialized representation.
+        if self.field_type.upper() == 'RECORD':
+            answer['fields'] = [f.to_api_repr() for f in self.fields]
+
+        # Done; return the serialized dictionary.
+        return answer
+
     def _key(self):
         """A tuple key that unique-ly describes this field.

{"golden_diff": "diff --git a/bigquery/google/cloud/bigquery/schema.py b/bigquery/google/cloud/bigquery/schema.py\n--- a/bigquery/google/cloud/bigquery/schema.py\n+++ b/bigquery/google/cloud/bigquery/schema.py\n@@ -43,6 +43,25 @@\n         self._description = description\n         self._fields = tuple(fields)\n \n+    @classmethod\n+    def from_api_repr(cls, api_repr):\n+        \"\"\"Return a ``SchemaField`` object deserialized from a dictionary.\n+\n+        Args:\n+            api_repr (Mapping[str, str]): The serialized representation\n+                of the SchemaField, such as what is output by\n+                :meth:`to_api_repr`.\n+\n+        Returns:\n+            SchemaField: The ``SchemaField`` object.\n+        \"\"\"\n+        return cls(\n+            field_type=api_repr['type'].upper(),\n+            fields=[cls.from_api_repr(f) for f in api_repr.get('fields', ())],\n+            mode=api_repr['mode'].upper(),\n+            name=api_repr['name'],\n+        )\n+\n     @property\n     def name(self):\n         \"\"\"str: The name of the field.\"\"\"\n@@ -84,6 +103,28 @@\n         \"\"\"\n         return self._fields\n \n+    def to_api_repr(self):\n+        \"\"\"Return a dictionary representing this schema field.\n+\n+        Returns:\n+            dict: A dictionary representing the SchemaField in a serialized\n+                form.\n+        \"\"\"\n+        # Put together the basic representation. See http://bit.ly/2hOAT5u.\n+        answer = {\n+            'mode': self.mode.lower(),\n+            'name': self.name,\n+            'type': self.field_type.lower(),\n+        }\n+\n+        # If this is a RECORD type, then sub-fields are also included,\n+        # add this to the serialized representation.\n+        if self.field_type.upper() == 'RECORD':\n+            answer['fields'] = [f.to_api_repr() for f in self.fields]\n+\n+        # Done; return the serialized dictionary.\n+        return answer\n+\n     def _key(self):\n         \"\"\"A tuple key that unique-ly describes this field.\n", "issue": "BigQuery: expose public helper method to convert a list of schema fields to/from a list of schema dictionaries (JSON)\nI've received some feedback asking how to take a schema from the client library and save it to a JSON file. One reason to do this is the [`bq` command-line tool](https://cloud.google.com/bigquery/bq-command-line-tool#creatingtablefromfile) accepts a schema file, formatted like\r\n\r\n```\r\n[\r\n  {\"name\": \"name\", \"type\": \"string\", \"mode\": \"required\"},\r\n  {\"name\": \"gender\", \"type\": \"string\", \"mode\": \"nullable\"},\r\n  {\"name\": \"count\", \"type\": \"integer\", \"mode\": \"required\"}\r\n]\r\n```\r\n\r\nNote: this format is the same as the API representation.\r\n\r\nIt would be great if our client libraries could read/write in this format.\r\n\r\n\n", "before_files": [{"content": "# Copyright 2015 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Schemas for BigQuery tables / queries.\"\"\"\n\n\nclass SchemaField(object):\n    \"\"\"Describe a single field within a table schema.\n\n    :type name: str\n    :param name: the name of the field.\n\n    :type field_type: str\n    :param field_type: the type of the field (one of 'STRING', 'INTEGER',\n                       'FLOAT', 'BOOLEAN', 'TIMESTAMP' or 'RECORD').\n\n    :type mode: str\n    :param mode: the mode of the field (one of 'NULLABLE', 'REQUIRED',\n                 or 'REPEATED').\n\n    :type description: str\n    :param description: optional description for the field.\n\n    :type fields: tuple of :class:`SchemaField`\n    :param fields: subfields (requires ``field_type`` of 'RECORD').\n    \"\"\"\n    def __init__(self, name, field_type, mode='NULLABLE',\n                 description=None, fields=()):\n        self._name = name\n        self._field_type = field_type\n        self._mode = mode\n        self._description = description\n        self._fields = tuple(fields)\n\n    @property\n    def name(self):\n        \"\"\"str: The name of the field.\"\"\"\n        return self._name\n\n    @property\n    def field_type(self):\n        \"\"\"str: The type of the field.\n\n        Will be one of 'STRING', 'INTEGER', 'FLOAT', 'BOOLEAN',\n        'TIMESTAMP' or 'RECORD'.\n        \"\"\"\n        return self._field_type\n\n    @property\n    def mode(self):\n        \"\"\"str: The mode of the field.\n\n        Will be one of 'NULLABLE', 'REQUIRED', or 'REPEATED'.\n        \"\"\"\n        return self._mode\n\n    @property\n    def is_nullable(self):\n        \"\"\"Check whether 'mode' is 'nullable'.\"\"\"\n        return self._mode == 'NULLABLE'\n\n    @property\n    def description(self):\n        \"\"\"Optional[str]: Description for the field.\"\"\"\n        return self._description\n\n    @property\n    def fields(self):\n        \"\"\"tuple: Subfields contained in this field.\n\n        If ``field_type`` is not 'RECORD', this property must be\n        empty / unset.\n        \"\"\"\n        return self._fields\n\n    def _key(self):\n        \"\"\"A tuple key that unique-ly describes this field.\n\n        Used to compute this instance's hashcode and evaluate equality.\n\n        Returns:\n            tuple: The contents of this :class:`SchemaField`.\n        \"\"\"\n        return (\n            self._name,\n            self._field_type.lower(),\n            self._mode,\n            self._description,\n            self._fields,\n        )\n\n    def __eq__(self, other):\n        if not isinstance(other, SchemaField):\n            return NotImplemented\n        return self._key() == other._key()\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __hash__(self):\n        return hash(self._key())\n\n    def __repr__(self):\n        return 'SchemaField{}'.format(self._key())\n", "path": "bigquery/google/cloud/bigquery/schema.py"}], "after_files": [{"content": "# Copyright 2015 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Schemas for BigQuery tables / queries.\"\"\"\n\n\nclass SchemaField(object):\n    \"\"\"Describe a single field within a table schema.\n\n    :type name: str\n    :param name: the name of the field.\n\n    :type field_type: str\n    :param field_type: the type of the field (one of 'STRING', 'INTEGER',\n                       'FLOAT', 'BOOLEAN', 'TIMESTAMP' or 'RECORD').\n\n    :type mode: str\n    :param mode: the mode of the field (one of 'NULLABLE', 'REQUIRED',\n                 or 'REPEATED').\n\n    :type description: str\n    :param description: optional description for the field.\n\n    :type fields: tuple of :class:`SchemaField`\n    :param fields: subfields (requires ``field_type`` of 'RECORD').\n    \"\"\"\n    def __init__(self, name, field_type, mode='NULLABLE',\n                 description=None, fields=()):\n        self._name = name\n        self._field_type = field_type\n        self._mode = mode\n        self._description = description\n        self._fields = tuple(fields)\n\n    @classmethod\n    def from_api_repr(cls, api_repr):\n        \"\"\"Return a ``SchemaField`` object deserialized from a dictionary.\n\n        Args:\n            api_repr (Mapping[str, str]): The serialized representation\n                of the SchemaField, such as what is output by\n                :meth:`to_api_repr`.\n\n        Returns:\n            SchemaField: The ``SchemaField`` object.\n        \"\"\"\n        return cls(\n            field_type=api_repr['type'].upper(),\n            fields=[cls.from_api_repr(f) for f in api_repr.get('fields', ())],\n            mode=api_repr['mode'].upper(),\n            name=api_repr['name'],\n        )\n\n    @property\n    def name(self):\n        \"\"\"str: The name of the field.\"\"\"\n        return self._name\n\n    @property\n    def field_type(self):\n        \"\"\"str: The type of the field.\n\n        Will be one of 'STRING', 'INTEGER', 'FLOAT', 'BOOLEAN',\n        'TIMESTAMP' or 'RECORD'.\n        \"\"\"\n        return self._field_type\n\n    @property\n    def mode(self):\n        \"\"\"str: The mode of the field.\n\n        Will be one of 'NULLABLE', 'REQUIRED', or 'REPEATED'.\n        \"\"\"\n        return self._mode\n\n    @property\n    def is_nullable(self):\n        \"\"\"Check whether 'mode' is 'nullable'.\"\"\"\n        return self._mode == 'NULLABLE'\n\n    @property\n    def description(self):\n        \"\"\"Optional[str]: Description for the field.\"\"\"\n        return self._description\n\n    @property\n    def fields(self):\n        \"\"\"tuple: Subfields contained in this field.\n\n        If ``field_type`` is not 'RECORD', this property must be\n        empty / unset.\n        \"\"\"\n        return self._fields\n\n    def to_api_repr(self):\n        \"\"\"Return a dictionary representing this schema field.\n\n        Returns:\n            dict: A dictionary representing the SchemaField in a serialized\n                form.\n        \"\"\"\n        # Put together the basic representation. See http://bit.ly/2hOAT5u.\n        answer = {\n            'mode': self.mode.lower(),\n            'name': self.name,\n            'type': self.field_type.lower(),\n        }\n\n        # If this is a RECORD type, then sub-fields are also included,\n        # add this to the serialized representation.\n        if self.field_type.upper() == 'RECORD':\n            answer['fields'] = [f.to_api_repr() for f in self.fields]\n\n        # Done; return the serialized dictionary.\n        return answer\n\n    def _key(self):\n        \"\"\"A tuple key that unique-ly describes this field.\n\n        Used to compute this instance's hashcode and evaluate equality.\n\n        Returns:\n            tuple: The contents of this :class:`SchemaField`.\n        \"\"\"\n        return (\n            self._name,\n            self._field_type.lower(),\n            self._mode,\n            self._description,\n            self._fields,\n        )\n\n    def __eq__(self, other):\n        if not isinstance(other, SchemaField):\n            return NotImplemented\n        return self._key() == other._key()\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __hash__(self):\n        return hash(self._key())\n\n    def __repr__(self):\n        return 'SchemaField{}'.format(self._key())\n", "path": "bigquery/google/cloud/bigquery/schema.py"}]}