Skip to content

Commit

Permalink
Project import generated by Copybara. (#13)
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 705604014

Co-authored-by: Googler <[email protected]>
  • Loading branch information
jscud and Googler authored Dec 12, 2024
1 parent a22fb2a commit cf3c476
Show file tree
Hide file tree
Showing 11 changed files with 514 additions and 51 deletions.
64 changes: 62 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ response = client.models.generate_content(
response.text
```

#### Manually declare and invoke a function for function calling

If you don't want to use the automatic function support, you can manually
declare the function and invoke it.

The following example shows how to declare a function and pass it as a tool.
Then you will receive a function call part in the response.

``` python
function = dict(
name="get_current_weather",
Expand Down Expand Up @@ -159,15 +167,24 @@ response = client.models.generate_content(
response.candidates[0].content.parts[0].function_call
```

After you receive the function call part from model, you can invoke the function
and get the function response. And then you can pass the function response to
the model.
The following example shows how to do it for a simple function invocation.

``` python
function_call_part = response.candidates[0].content.parts[0]

function_response = get_current_weather(**function_call_part.function_call.args)
try:
function_result = get_current_weather(**function_call_part.function_call.args)
function_response = {'result': function_result}
except Exception as e: # instead of raising the exception, you can let the model handle it
function_response = {'error': str(e)}


function_response_part = types.Part.from_function_response(
name=function_call_part.function_call.name,
response={'result': function_response}
response=function_response,
)

response = client.models.generate_content(
Expand Down Expand Up @@ -245,13 +262,56 @@ print(response.text)

### Streaming

#### Streaming for text content

``` python
for chunk in client.models.generate_content_stream(
model='gemini-2.0-flash-exp', contents='Tell me a story in 300 words.'
):
print(chunk.text)
```

#### Streaming for image content

If your image is stored in Google Cloud Storage, you can use the `from_uri`
class method to create a Part object.

``` python
for chunk in client.models.generate_content_stream(
model='gemini-1.5-flash',
contents=[
'What is this image about?',
types.Part.from_uri(
file_uri='gs://generativeai-downloads/images/scones.jpg',
mime_type='image/jpeg'
)
],
):
print(chunk.text)
```

If your image is stored in your local file system, you can read it in as bytes
data and use the `from_bytes` class method to create a Part object.

``` python
YOUR_IMAGE_PATH = 'your_image_path'
YOUR_IMAGE_MIME_TYPE = 'your_image_mime_type'
with open(YOUR_IMAGE_PATH, 'rb') as f:
image_bytes = f.read()

for chunk in client.models.generate_content_stream(
model='gemini-1.5-flash',
contents=[
'What is this image about?',
types.Part.from_bytes(
data=image_bytes,
mime_type=YOUR_IMAGE_MIME_TYPE
)
],
):
print(chunk.text)
```

### Async

`client.aio` exposes all the analogous `async` methods that are
Expand Down
2 changes: 1 addition & 1 deletion google/genai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@

from .client import Client

__version__ = '0.2.1'
__version__ = '0.2.2'

__all__ = ['Client']
2 changes: 1 addition & 1 deletion google/genai/_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class HttpOptions(TypedDict):
def _append_library_version_headers(headers: dict[str, str]) -> None:
"""Appends the telemetry header to the headers dict."""
# TODO: Automate revisions to the SDK library version.
library_label = f'google-genai-sdk/0.2.1'
library_label = f'google-genai-sdk/0.2.2'
language_label = 'gl-python/' + sys.version.split()[0]
version_header_value = f'{library_label} {language_label}'
if (
Expand Down
42 changes: 31 additions & 11 deletions google/genai/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,49 @@ class APIError(Exception):
code: int
response: requests.Response

message: str = ''
status: str = 'UNKNOWN'
details: Optional[Any] = None
status: Optional[str] = None
message: Optional[str] = None
response: Optional[Any] = None

def __init__(
self, code: int, response: Union[requests.Response, 'ReplayResponse']
):
self.code = code
self.response = response

if isinstance(response, requests.Response):
try:
raw_error = response.json().get('error', {})
# do not do any extra muanipulation on the response.
# return the raw response json as is.
response_json = response.json()
except requests.exceptions.JSONDecodeError:
raw_error = {'message': response.text, 'status': response.reason}
response_json = {
'message': response.text,
'status': response.reason,
}
else:
raw_error = response.body_segments[0].get('error', {})
response_json = response.body_segments[0].get('error', {})

self.details = response_json
self.message = self._get_message(response_json)
self.status = self._get_status(response_json)
self.code = code if code else self._get_code(response_json)

super().__init__(f'{self.code} {self.status}. {self.details}')

def _get_status(self, response_json):
return response_json.get(
'status', response_json.get('error', {}).get('status', None)
)

self.message = raw_error.get('message', '')
self.status = raw_error.get('status', 'UNKNOWN')
self.details = raw_error.get('details', None)
def _get_message(self, response_json):
return response_json.get(
'message', response_json.get('error', {}).get('message', None)
)

super().__init__(f'{self.code} {self.status}. {self.message}')
def _get_code(self, response_json):
return response_json.get(
'code', response_json.get('error', {}).get('code', None)
)

def _to_replay_record(self):
"""Returns a dictionary representation of the error for replay recording.
Expand Down
1 change: 1 addition & 0 deletions google/genai/tests/errors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Unit Tests for the error modules."""
Loading

0 comments on commit cf3c476

Please sign in to comment.