Skip to content

Commit b106e34

Browse files
test(boxsdkgen): test AI confidence score (box/box-codegen#919) (#1317)
1 parent 246bac9 commit b106e34

4 files changed

Lines changed: 38 additions & 17 deletions

File tree

.codegen.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "engineHash": "f9e2519", "specHash": "ccdb456", "version": "4.3.0" }
1+
{ "engineHash": "b181eba", "specHash": "ccdb456", "version": "4.3.0" }

docs/box_sdk_gen/ai.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ See the endpoint docs at
167167
<!-- sample post_ai_extract_structured -->
168168

169169
```python
170-
client.ai.create_ai_extract_structured([AiItemBase(id=file.id)], fields=[CreateAiExtractStructuredFields(key='firstName', display_name='First name', description='Person first name', prompt='What is the your first name?', type='string'), CreateAiExtractStructuredFields(key='lastName', display_name='Last name', description='Person last name', prompt='What is the your last name?', type='string'), CreateAiExtractStructuredFields(key='dateOfBirth', display_name='Birth date', description='Person date of birth', prompt='What is the date of your birth?', type='date'), CreateAiExtractStructuredFields(key='age', display_name='Age', description='Person age', prompt='How old are you?', type='float'), CreateAiExtractStructuredFields(key='hobby', display_name='Hobby', description='Person hobby', prompt='What is your hobby?', type='multiSelect', options=[CreateAiExtractStructuredFieldsOptionsField(key='guitar'), CreateAiExtractStructuredFieldsOptionsField(key='books')])], ai_agent=ai_extract_structured_agent_basic_text_config)
170+
client.ai.create_ai_extract_structured([AiItemBase(id=file.id)], fields=[CreateAiExtractStructuredFields(key='firstName', display_name='First name', description='Person first name', prompt='What is the your first name?', type='string'), CreateAiExtractStructuredFields(key='lastName', display_name='Last name', description='Person last name', prompt='What is the your last name?', type='string'), CreateAiExtractStructuredFields(key='dateOfBirth', display_name='Birth date', description='Person date of birth', prompt='What is the date of your birth?', type='date'), CreateAiExtractStructuredFields(key='age', display_name='Age', description='Person age', prompt='How old are you?', type='float'), CreateAiExtractStructuredFields(key='hobby', display_name='Hobby', description='Person hobby', prompt='What is your hobby?', type='multiSelect', options=[CreateAiExtractStructuredFieldsOptionsField(key='guitar'), CreateAiExtractStructuredFieldsOptionsField(key='books')])], include_confidence_score=True, ai_agent=ai_extract_structured_agent_basic_text_config)
171171
```
172172

173173
### Arguments

docs/config-sharing-implementation.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ This document describes the implementation of configuration sharing between the
2626

2727
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2828

29-
3029
## Overview
3130

3231
The configuration sharing feature allows developers to seamlessly migrate from the legacy SDK to the generated SDK by automatically extracting and converting authentication and network configuration from a legacy client to a generated client.
@@ -38,11 +37,13 @@ The configuration sharing feature allows developers to seamlessly migrate from t
3837
The `LegacyTokenStorageAdapter` class bridges the gap between legacy OAuth2 token storage mechanisms (callbacks) and the generated SDK's `TokenStorage` interface.
3938

4039
**Key Features:**
40+
4141
- Converts legacy token format (access_token, refresh_token tuple) to generated SDK `AccessToken` objects
4242
- Supports both read and write operations
4343
- Handles token storage callbacks from legacy OAuth2 implementations
4444

4545
**Example:**
46+
4647
```python
4748
from boxsdk.auth.oauth2 import OAuth2
4849
from boxsdk.util.token_storage_adapter import LegacyTokenStorageAdapter
@@ -86,6 +87,7 @@ Three new methods have been added to the `Client` class in `boxsdk/client/client
8687
Creates a fully configured generated SDK client from the legacy client. This is the main convenience method that combines `get_sdk_gen_authentication()` and `get_sdk_gen_network_session()`.
8788

8889
**Parameters:**
90+
8991
- `auth_options` (optional): Dictionary with authentication options
9092
- `token_storage`: Custom `TokenStorage` instance
9193
- `network_options` (optional): Dictionary with network options
@@ -95,9 +97,11 @@ Creates a fully configured generated SDK client from the legacy client. This is
9597
- `additional_headers`: Dictionary of additional HTTP headers
9698

9799
**Returns:**
100+
98101
- `BoxClient` instance from `box_sdk_gen`, fully configured with shared settings
99102

100103
**Example:**
104+
101105
```python
102106
from boxsdk import Client
103107
from boxsdk.auth import OAuth2
@@ -122,18 +126,22 @@ legacy_user = legacy_client.user().get()
122126
Extracts authentication configuration from the legacy client and converts it to a generated SDK `Authentication` object.
123127

124128
**Supported Authentication Types:**
129+
125130
- `DeveloperTokenAuth``BoxDeveloperTokenAuth`
126131
- `OAuth2``BoxOAuth`
127132
- `JWTAuth``BoxJWTAuth`
128133
- `CCGAuth``BoxCCGAuth`
129134

130135
**Parameters:**
136+
131137
- `token_storage` (optional): Custom `TokenStorage` instance. If not provided, an adapter will be created to bridge legacy token storage.
132138

133139
**Returns:**
140+
134141
- `Authentication` object compatible with `box_sdk_gen`
135142

136143
**Example:**
144+
137145
```python
138146
from boxsdk import Client
139147
from boxsdk.auth import OAuth2
@@ -153,21 +161,25 @@ gen_client = BoxClient(auth=gen_auth)
153161
Extracts network configuration from the legacy client and converts it to a generated SDK `NetworkSession` object.
154162

155163
**Parameters:**
164+
156165
- `network_client` (optional): Custom `NetworkClient` instance
157166
- `retry_strategy` (optional): Custom `RetryStrategy` instance
158167
- `data_sanitizer` (optional): Custom `DataSanitizer` instance
159168
- `additional_headers` (optional): Dictionary of additional HTTP headers
160169

161170
**Returns:**
171+
162172
- `NetworkSession` object compatible with `box_sdk_gen`
163173

164174
**Configuration Mapping:**
175+
165176
- Base URLs: Extracted from `API` config
166177
- Proxy settings: Extracted from `Proxy` config
167178
- Retry strategy: Extracted from `API.MAX_RETRY_ATTEMPTS` and session retry settings
168179
- Custom headers: Merged from session default headers and additional headers
169180

170181
**Example:**
182+
171183
```python
172184
from boxsdk import Client
173185
from box_sdk_gen.client import BoxClient
@@ -205,10 +217,7 @@ from boxsdk import Client
205217
from boxsdk.auth import OAuth2
206218

207219
legacy_auth = OAuth2(
208-
client_id="...",
209-
client_secret="...",
210-
access_token="...",
211-
refresh_token="..."
220+
client_id="...", client_secret="...", access_token="...", refresh_token="..."
212221
)
213222
legacy_client = Client(legacy_auth)
214223

@@ -230,7 +239,7 @@ legacy_auth = JWTAuth(
230239
client_secret="...",
231240
enterprise_id="...",
232241
jwt_key_id="...",
233-
rsa_private_key_file_sys_path="path/to/key.pem"
242+
rsa_private_key_file_sys_path="path/to/key.pem",
234243
)
235244
legacy_client = Client(legacy_auth)
236245

@@ -241,7 +250,9 @@ gen_client = legacy_client.get_sdk_gen_client()
241250
if user_id:
242251
gen_auth = legacy_client.get_authentication()
243252
gen_auth = gen_auth.with_user_subject(user_id)
244-
gen_client = BoxClient(auth=gen_auth, network_session=legacy_client.get_network_session())
253+
gen_client = BoxClient(
254+
auth=gen_auth, network_session=legacy_client.get_network_session()
255+
)
245256
```
246257

247258
### CCG Authentication
@@ -250,11 +261,7 @@ if user_id:
250261
from boxsdk import Client
251262
from boxsdk.auth import CCGAuth
252263

253-
legacy_auth = CCGAuth(
254-
client_id="...",
255-
client_secret="...",
256-
enterprise_id="..."
257-
)
264+
legacy_auth = CCGAuth(client_id="...", client_secret="...", enterprise_id="...")
258265
legacy_client = Client(legacy_auth)
259266

260267
# Get generated client
@@ -273,7 +280,7 @@ legacy_client = Client(OAuth2(...))
273280
gen_client = legacy_client.get_sdk_gen_client(
274281
network_options={
275282
"additional_headers": {"X-Custom-Header": "value"},
276-
"retry_strategy": custom_retry_strategy
283+
"retry_strategy": custom_retry_strategy,
277284
}
278285
)
279286
```
@@ -289,6 +296,7 @@ The `LegacyTokenStorageAdapter` implements the `TokenStorage` interface from `bo
289296
- `clear()`: Clears stored tokens
290297

291298
The adapter converts between:
299+
292300
- Legacy format: `(access_token: str, refresh_token: Optional[str])`
293301
- Generated format: `AccessToken(access_token, refresh_token, expires_in, token_type)`
294302

@@ -304,6 +312,7 @@ Each authentication type is handled specifically:
304312
### Network Configuration Conversion
305313

306314
Network settings are extracted from:
315+
307316
- `Session.api_config`: Base URLs, OAuth URLs
308317
- `Session.proxy_config`: Proxy settings
309318
- `Session._default_headers`: Custom headers

test/box_sdk_gen/test/ai.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,12 @@ def testAIExtractStructuredWithFields():
252252
parent=UploadFileAttributesParentField(id='0'),
253253
),
254254
string_to_byte_stream(
255-
'My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar.'
255+
''.join(
256+
[
257+
'My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar. My UUID is ',
258+
get_uuid(),
259+
]
260+
)
256261
),
257262
)
258263
file: FileFull = uploaded_files.entries[0]
@@ -300,8 +305,10 @@ def testAIExtractStructuredWithFields():
300305
],
301306
),
302307
],
308+
include_confidence_score=True,
303309
ai_agent=ai_extract_structured_agent_basic_text_config,
304310
)
311+
assert not response.confidence_score == None
305312
assert to_string(response.answer.get('hobby')) == to_string(['guitar'])
306313
assert to_string(response.answer.get('firstName')) == 'John'
307314
assert to_string(response.answer.get('lastName')) == 'Doe'
@@ -318,7 +325,12 @@ def testAIExtractStructuredWithMetadataTemplate():
318325
parent=UploadFileAttributesParentField(id='0'),
319326
),
320327
string_to_byte_stream(
321-
'My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar.'
328+
''.join(
329+
[
330+
'My name is John Doe. I was born in 4th July 1990. I am 34 years old. My hobby is guitar. My UUID is ',
331+
get_uuid(),
332+
]
333+
)
322334
),
323335
)
324336
file: FileFull = uploaded_files.entries[0]

0 commit comments

Comments
 (0)