Skip to content

Commit

Permalink
Update BigQuery remote function for vision AI to VPCSC compliant and …
Browse files Browse the repository at this point in the history
…latest version (#8883)

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Charles Engelke <engelke@google.com>
  • Loading branch information
3 people committed Feb 7, 2023
1 parent 4f0c43f commit 7dcfea2
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 21 deletions.
6 changes: 3 additions & 3 deletions bigquery/remote-function/vision/requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Flask==2.2.2
functions-framework==3.2.0
google-cloud-vision==3.1.2
pytest==7.1.3
functions-framework==3.3.0
google-cloud-vision==3.2.0
pytest==7.2.0
4 changes: 2 additions & 2 deletions bigquery/remote-function/vision/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Flask==2.2.2
functions-framework==3.2.0
google-cloud-vision==3.1.2
functions-framework==3.3.0
google-cloud-vision==3.2.0
12 changes: 7 additions & 5 deletions bigquery/remote-function/vision/vision_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
# limitations under the License.

# [START bigquery_remote_function_vision]
import urllib.request

import flask
import functions_framework
from google.cloud import vision_v1
from google.cloud import vision


@functions_framework.http
Expand All @@ -29,13 +31,13 @@ def label_detection(request: flask.Request) -> flask.Response:
https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#output_format
"""
try:
client = vision_v1.ImageAnnotatorClient()
client = vision.ImageAnnotatorClient()
calls = request.get_json()['calls']
replies = []
for call in calls:
results = client.label_detection(
{'source': {'image_uri': call[0]}})
replies.append(vision_v1.AnnotateImageResponse.to_dict(results))
content = urllib.request.urlopen(call[0]).read()
results = client.label_detection({'content': content})
replies.append(vision.AnnotateImageResponse.to_dict(results))
return flask.make_response(flask.jsonify({'replies': replies}))
except Exception as e:
return flask.make_response(flask.jsonify({'errorMessage': str(e)}), 400)
Expand Down
27 changes: 16 additions & 11 deletions bigquery/remote-function/vision/vision_function_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from unittest import mock

import flask
from google.cloud import vision_v1
from google.cloud import vision
import pytest

import vision_function
Expand All @@ -27,16 +27,19 @@ def app() -> flask.Flask:
return flask.Flask(__name__)


@mock.patch('vision_function.vision_v1')
def test_vision_function(mock_vision_v1: object, app: flask.Flask) -> None:
@mock.patch('vision_function.urllib.request')
@mock.patch('vision_function.vision')
def test_vision_function(mock_vision: object, mock_request: object,
app: flask.Flask) -> None:
mock_request.urlopen = mock.Mock(read=mock.Mock(return_value=b'filedata'))
label_detection_mock = mock.Mock(side_effect=[
vision_v1.AnnotateImageResponse(
vision.AnnotateImageResponse(
{'label_annotations': [{'description': 'apple'}]}),
vision_v1.AnnotateImageResponse(
vision.AnnotateImageResponse(
{'label_annotations': [{'description': 'banana'}]})])
mock_vision_v1.ImageAnnotatorClient = mock.Mock(
mock_vision.ImageAnnotatorClient = mock.Mock(
return_value=mock.Mock(label_detection=label_detection_mock))
mock_vision_v1.AnnotateImageResponse = vision_v1.AnnotateImageResponse
mock_vision.AnnotateImageResponse = vision.AnnotateImageResponse
with app.test_request_context(
json={'calls': [['https://storage.googleapis.com/bucket/apple'],
['https://storage.googleapis.com/bucket/banana']]}):
Expand All @@ -47,11 +50,13 @@ def test_vision_function(mock_vision_v1: object, app: flask.Flask) -> None:
assert 'banana' in str(response.get_json()['replies'][1])


@mock.patch('vision_function.vision_v1')
def test_vision_function_error(
mock_vision_v1: object, app: flask.Flask) -> None:
@mock.patch('vision_function.urllib.request')
@mock.patch('vision_function.vision')
def test_vision_function_error(mock_vision: object, mock_request: object,
app: flask.Flask) -> None:
mock_request.urlopen = mock.Mock(read=mock.Mock(return_value=b'filedata'))
label_detection_mock = mock.Mock(side_effect=Exception('API error'))
mock_vision_v1.ImageAnnotatorClient = mock.Mock(
mock_vision.ImageAnnotatorClient = mock.Mock(
return_value=mock.Mock(label_detection=label_detection_mock))
with app.test_request_context(
json={'calls': [['https://storage.googleapis.com/bucket/apple'],
Expand Down

0 comments on commit 7dcfea2

Please sign in to comment.