Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 2efc89e

Browse files
fix some more stuff
1 parent a66c4db commit 2efc89e

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

bigframes/functions/_function_client.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,12 @@ def get_remote_function_specs(
694694
for routine in routines:
695695
routine = cast(bigquery.Routine, routine)
696696
if routine.reference.routine_id == remote_function_name:
697-
return udf_def.RemoteFunctionConfig.from_bq_routine(routine)
697+
try:
698+
return udf_def.RemoteFunctionConfig.from_bq_routine(routine)
699+
except udf_def.ReturnTypeMissingError:
700+
# The remote function exists, but it's missing a return type.
701+
# Something is wrong with the function, so we should replace it.
702+
return None
698703
except google.api_core.exceptions.NotFound:
699704
# The dataset might not exist, in which case the remote function doesn't, either.
700705
# Note: list_routines doesn't make an API request until we iterate on the response object.

bigframes/functions/function.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,10 @@ def __init__(
160160
*,
161161
local_func: Optional[Callable] = None,
162162
cloud_function_ref: Optional[str] = None,
163-
post_routine: Optional[
164-
Callable[[bigframes.series.Series], bigframes.series.Series]
165-
] = None,
166163
is_managed: bool = False,
167164
):
168165
self._udf_def = udf_def
169166
self._session = session
170-
self._post_routine = post_routine
171167
self._local_fun = local_func
172168
self._cloud_function = cloud_function_ref
173169
self._is_managed = is_managed

bigframes/functions/function_template.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828

2929

3030
# Placeholder variables for testing.
31-
input_sql_types = ("STRING",)
32-
output_sql_type = "STRING"
31+
input_types = ("STRING",)
32+
output_type = "STRING"
3333

3434

3535
# Convert inputs to BigQuery JSON. See:
@@ -152,7 +152,7 @@ def udf(*args):
152152
# }
153153
# https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#input_format
154154
def udf_http(request):
155-
global input_sql_types, output_sql_type
155+
global input_types, output_type
156156
import json
157157
import traceback
158158

@@ -164,7 +164,7 @@ def udf_http(request):
164164
replies = []
165165
for call in calls:
166166
reply = convert_to_bq_json(
167-
output_sql_type, udf(*convert_call(input_sql_types, call))
167+
output_type, udf(*convert_call(input_types, call))
168168
)
169169
if type(reply) is list:
170170
# Since the BQ remote function does not support array yet,
@@ -178,7 +178,7 @@ def udf_http(request):
178178

179179

180180
def udf_http_row_processor(request):
181-
global output_sql_type
181+
global output_type
182182
import json
183183
import math
184184
import traceback
@@ -192,7 +192,7 @@ def udf_http_row_processor(request):
192192
replies = []
193193
for call in calls:
194194
reply = convert_to_bq_json(
195-
output_sql_type, udf(get_pd_series(call[0]), *call[1:])
195+
output_type, udf(get_pd_series(call[0]), *call[1:])
196196
)
197197
if type(reply) is list:
198198
# Since the BQ remote function does not support array yet,
@@ -254,6 +254,9 @@ def generate_cloud_function_main_code(
254254
# Pickle the udf with all its dependencies
255255
udf_code_file, udf_pickle_file = generate_udf_code(code_def, directory)
256256

257+
input_types = tuple(arg.sql_type for arg in udf_signature.inputs)
258+
output_type = udf_signature.output.sql_type
259+
257260
code_blocks = [
258261
f"""\
259262
import cloudpickle
@@ -263,8 +266,8 @@ def generate_cloud_function_main_code(
263266
with open("{udf_pickle_file}", "rb") as f:
264267
udf = cloudpickle.load(f)
265268
266-
input_types = {repr(input_sql_types)}
267-
output_type = {repr(output_sql_type)}
269+
input_types = {repr(input_types)}
270+
output_type = {repr(output_type)}
268271
"""
269272
]
270273

bigframes/functions/udf_def.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ def bf_type(self) -> bigframes.dtypes.Dtype:
106106

107107
@property
108108
def sql_type(self) -> str:
109-
type_kind = function_typing.sdk_type_from_python_type(self._py_type)
110-
assert type_kind is not None
111-
return type_kind.name
109+
sdk_type = function_typing.sdk_type_from_python_type(self._py_type)
110+
assert sdk_type.type_kind is not None
111+
return sdk_type.type_kind.name
112112

113113
def stable_hash(self) -> bytes:
114114
hash_val = hashlib.md5()
@@ -233,7 +233,9 @@ def from_routine(cls, routine: bigquery.Routine) -> UdfSignature:
233233

234234
## Handle return type
235235
if routine.return_type is None:
236-
raise ReturnTypeMissingError
236+
raise ReturnTypeMissingError(
237+
f"Routine {routine} has no return type. Routine properties: {routine._properties}"
238+
)
237239

238240
bq_return_type = cast(bigquery.StandardSqlDataType, routine.return_type)
239241

0 commit comments

Comments
 (0)