We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
The DB API Binary function should accept bytes.
```
(3.8) jim@ds9:~/p/g/python-bigquery-sqlalchemy$ python
Python 3.8.5 (default, Jan 27 2021, 15:41:15) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import google.cloud.bigquery.dbapi
>>> google.cloud.bigquery.dbapi.Binary(b'x')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jim/p/g/python-bigquery/google/cloud/bigquery/dbapi/types.py", line 42, in Binary
    return string.encode("utf-8")
AttributeError: 'bytes' object has no attribute 'encode'
```
Bytes are the most common way to represent binary data.  Accepting strings, as it does now seems at best to be a convenience and at worst a bug magnet.

In SQLAlchemy, if you defined a model that has a binary attribute, you'd store bytes data in it, but that would break for bigquery, di to this issue.

Sqlite's `Binary` function requires bytes data.

I propose to change the function to accept bytes.  For the sake of backward compatibility, I propose to continue to accept strings.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `google/cloud/bigquery/dbapi/types.py`
Content:
```
1 # Copyright 2017 Google LLC
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 """Types used in the Google BigQuery DB-API.
16 
17 See `PEP-249`_ for details.
18 
19 .. _PEP-249:
20     https://www.python.org/dev/peps/pep-0249/#type-objects-and-constructors
21 """
22 
23 import datetime
24 
25 
26 Date = datetime.date
27 Time = datetime.time
28 Timestamp = datetime.datetime
29 DateFromTicks = datetime.date.fromtimestamp
30 TimestampFromTicks = datetime.datetime.fromtimestamp
31 
32 
33 def Binary(string):
34     """Contruct a DB-API binary value.
35 
36     Args:
37         string (str): A string to encode as a binary value.
38 
39     Returns:
40         bytes: The UTF-8 encoded bytes representing the string.
41     """
42     return string.encode("utf-8")
43 
44 
45 def TimeFromTicks(ticks, tz=None):
46     """Construct a DB-API time value from the given ticks value.
47 
48     Args:
49         ticks (float):
50             a number of seconds since the epoch; see the documentation of the
51             standard Python time module for details.
52 
53         tz (datetime.tzinfo): (Optional) time zone to use for conversion
54 
55     Returns:
56         datetime.time: time represented by ticks.
57     """
58     dt = datetime.datetime.fromtimestamp(ticks, tz=tz)
59     return dt.timetz()
60 
61 
62 class _DBAPITypeObject(object):
63     """DB-API type object which compares equal to many different strings.
64 
65     See `PEP-249`_ for details.
66 
67     .. _PEP-249:
68         https://www.python.org/dev/peps/pep-0249/#implementation-hints-for-module-authors
69     """
70 
71     def __init__(self, *values):
72         self.values = values
73 
74     def __eq__(self, other):
75         return other in self.values
76 
77 
78 STRING = "STRING"
79 BINARY = _DBAPITypeObject("BYTES", "RECORD", "STRUCT")
80 NUMBER = _DBAPITypeObject(
81     "INTEGER", "INT64", "FLOAT", "FLOAT64", "NUMERIC", "BIGNUMERIC", "BOOLEAN", "BOOL"
82 )
83 DATETIME = _DBAPITypeObject("TIMESTAMP", "DATE", "TIME", "DATETIME")
84 ROWID = "ROWID"
85
```
--- 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/google/cloud/bigquery/dbapi/types.py b/google/cloud/bigquery/dbapi/types.py
--- a/google/cloud/bigquery/dbapi/types.py
+++ b/google/cloud/bigquery/dbapi/types.py
@@ -30,16 +30,28 @@
 TimestampFromTicks = datetime.datetime.fromtimestamp
 
 
-def Binary(string):
+def Binary(data):
     """Contruct a DB-API binary value.
 
     Args:
-        string (str): A string to encode as a binary value.
+        data (bytes-like): An object containing binary data and that
+                           can be converted to bytes with the `bytes` builtin.
 
     Returns:
-        bytes: The UTF-8 encoded bytes representing the string.
+        bytes: The binary data as a bytes object.
     """
-    return string.encode("utf-8")
+    if isinstance(data, int):
+        # This is not the conversion we're looking for, because it
+        # will simply create a bytes object of the given size.
+        raise TypeError("cannot convert `int` object to binary")
+
+    try:
+        return bytes(data)
+    except TypeError:
+        if isinstance(data, str):
+            return data.encode("utf-8")
+        else:
+            raise
 
 
 def TimeFromTicks(ticks, tz=None):

{"golden_diff": "diff --git a/google/cloud/bigquery/dbapi/types.py b/google/cloud/bigquery/dbapi/types.py\n--- a/google/cloud/bigquery/dbapi/types.py\n+++ b/google/cloud/bigquery/dbapi/types.py\n@@ -30,16 +30,28 @@\n TimestampFromTicks = datetime.datetime.fromtimestamp\n \n \n-def Binary(string):\n+def Binary(data):\n     \"\"\"Contruct a DB-API binary value.\n \n     Args:\n-        string (str): A string to encode as a binary value.\n+        data (bytes-like): An object containing binary data and that\n+                           can be converted to bytes with the `bytes` builtin.\n \n     Returns:\n-        bytes: The UTF-8 encoded bytes representing the string.\n+        bytes: The binary data as a bytes object.\n     \"\"\"\n-    return string.encode(\"utf-8\")\n+    if isinstance(data, int):\n+        # This is not the conversion we're looking for, because it\n+        # will simply create a bytes object of the given size.\n+        raise TypeError(\"cannot convert `int` object to binary\")\n+\n+    try:\n+        return bytes(data)\n+    except TypeError:\n+        if isinstance(data, str):\n+            return data.encode(\"utf-8\")\n+        else:\n+            raise\n \n \n def TimeFromTicks(ticks, tz=None):\n", "issue": "The DB API Binary function should accept bytes.\n```\r\n(3.8) jim@ds9:~/p/g/python-bigquery-sqlalchemy$ python\r\nPython 3.8.5 (default, Jan 27 2021, 15:41:15) \r\n[GCC 9.3.0] on linux\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> import google.cloud.bigquery.dbapi\r\n>>> google.cloud.bigquery.dbapi.Binary(b'x')\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/home/jim/p/g/python-bigquery/google/cloud/bigquery/dbapi/types.py\", line 42, in Binary\r\n    return string.encode(\"utf-8\")\r\nAttributeError: 'bytes' object has no attribute 'encode'\r\n```\r\nBytes are the most common way to represent binary data.  Accepting strings, as it does now seems at best to be a convenience and at worst a bug magnet.\r\n\r\nIn SQLAlchemy, if you defined a model that has a binary attribute, you'd store bytes data in it, but that would break for bigquery, di to this issue.\r\n\r\nSqlite's `Binary` function requires bytes data.\r\n\r\nI propose to change the function to accept bytes.  For the sake of backward compatibility, I propose to continue to accept strings.\r\n\n", "before_files": [{"content": "# Copyright 2017 Google LLC\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\"\"\"Types used in the Google BigQuery DB-API.\n\nSee `PEP-249`_ for details.\n\n.. _PEP-249:\n    https://www.python.org/dev/peps/pep-0249/#type-objects-and-constructors\n\"\"\"\n\nimport datetime\n\n\nDate = datetime.date\nTime = datetime.time\nTimestamp = datetime.datetime\nDateFromTicks = datetime.date.fromtimestamp\nTimestampFromTicks = datetime.datetime.fromtimestamp\n\n\ndef Binary(string):\n    \"\"\"Contruct a DB-API binary value.\n\n    Args:\n        string (str): A string to encode as a binary value.\n\n    Returns:\n        bytes: The UTF-8 encoded bytes representing the string.\n    \"\"\"\n    return string.encode(\"utf-8\")\n\n\ndef TimeFromTicks(ticks, tz=None):\n    \"\"\"Construct a DB-API time value from the given ticks value.\n\n    Args:\n        ticks (float):\n            a number of seconds since the epoch; see the documentation of the\n            standard Python time module for details.\n\n        tz (datetime.tzinfo): (Optional) time zone to use for conversion\n\n    Returns:\n        datetime.time: time represented by ticks.\n    \"\"\"\n    dt = datetime.datetime.fromtimestamp(ticks, tz=tz)\n    return dt.timetz()\n\n\nclass _DBAPITypeObject(object):\n    \"\"\"DB-API type object which compares equal to many different strings.\n\n    See `PEP-249`_ for details.\n\n    .. _PEP-249:\n        https://www.python.org/dev/peps/pep-0249/#implementation-hints-for-module-authors\n    \"\"\"\n\n    def __init__(self, *values):\n        self.values = values\n\n    def __eq__(self, other):\n        return other in self.values\n\n\nSTRING = \"STRING\"\nBINARY = _DBAPITypeObject(\"BYTES\", \"RECORD\", \"STRUCT\")\nNUMBER = _DBAPITypeObject(\n    \"INTEGER\", \"INT64\", \"FLOAT\", \"FLOAT64\", \"NUMERIC\", \"BIGNUMERIC\", \"BOOLEAN\", \"BOOL\"\n)\nDATETIME = _DBAPITypeObject(\"TIMESTAMP\", \"DATE\", \"TIME\", \"DATETIME\")\nROWID = \"ROWID\"\n", "path": "google/cloud/bigquery/dbapi/types.py"}], "after_files": [{"content": "# Copyright 2017 Google LLC\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\"\"\"Types used in the Google BigQuery DB-API.\n\nSee `PEP-249`_ for details.\n\n.. _PEP-249:\n    https://www.python.org/dev/peps/pep-0249/#type-objects-and-constructors\n\"\"\"\n\nimport datetime\n\n\nDate = datetime.date\nTime = datetime.time\nTimestamp = datetime.datetime\nDateFromTicks = datetime.date.fromtimestamp\nTimestampFromTicks = datetime.datetime.fromtimestamp\n\n\ndef Binary(data):\n    \"\"\"Contruct a DB-API binary value.\n\n    Args:\n        data (bytes-like): An object containing binary data and that\n                           can be converted to bytes with the `bytes` builtin.\n\n    Returns:\n        bytes: The binary data as a bytes object.\n    \"\"\"\n    if isinstance(data, int):\n        # This is not the conversion we're looking for, because it\n        # will simply create a bytes object of the given size.\n        raise TypeError(\"cannot convert `int` object to binary\")\n\n    try:\n        return bytes(data)\n    except TypeError:\n        if isinstance(data, str):\n            return data.encode(\"utf-8\")\n        else:\n            raise\n\n\ndef TimeFromTicks(ticks, tz=None):\n    \"\"\"Construct a DB-API time value from the given ticks value.\n\n    Args:\n        ticks (float):\n            a number of seconds since the epoch; see the documentation of the\n            standard Python time module for details.\n\n        tz (datetime.tzinfo): (Optional) time zone to use for conversion\n\n    Returns:\n        datetime.time: time represented by ticks.\n    \"\"\"\n    dt = datetime.datetime.fromtimestamp(ticks, tz=tz)\n    return dt.timetz()\n\n\nclass _DBAPITypeObject(object):\n    \"\"\"DB-API type object which compares equal to many different strings.\n\n    See `PEP-249`_ for details.\n\n    .. _PEP-249:\n        https://www.python.org/dev/peps/pep-0249/#implementation-hints-for-module-authors\n    \"\"\"\n\n    def __init__(self, *values):\n        self.values = values\n\n    def __eq__(self, other):\n        return other in self.values\n\n\nSTRING = \"STRING\"\nBINARY = _DBAPITypeObject(\"BYTES\", \"RECORD\", \"STRUCT\")\nNUMBER = _DBAPITypeObject(\n    \"INTEGER\", \"INT64\", \"FLOAT\", \"FLOAT64\", \"NUMERIC\", \"BIGNUMERIC\", \"BOOLEAN\", \"BOOL\"\n)\nDATETIME = _DBAPITypeObject(\"TIMESTAMP\", \"DATE\", \"TIME\", \"DATETIME\")\nROWID = \"ROWID\"\n", "path": "google/cloud/bigquery/dbapi/types.py"}]}