Skip to content

Commit feda4dc

Browse files
authored
Merge pull request #163 from 1Password/sdk-core/2025-03-20-a8be62a1
Python SDK RC 0.2.1
2 parents 08bdab5 + e76b521 commit feda4dc

File tree

13 files changed

+506
-29
lines changed

13 files changed

+506
-29
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Operations:
8989
- [x] [Delete items](https://developer.1password.com/docs/sdks/manage-items#delete-an-item)
9090
- [x] [Archive items](https://developer.1password.com/docs/sdks/manage-items/#archive-an-item)
9191
- [x] [List items](https://developer.1password.com/docs/sdks/list-vaults-items/)
92-
- [x] [Share items](https://developer.1password.com/docs/sdks/share-items) (items with files cannot be shared)
92+
- [x] [Share items](https://developer.1password.com/docs/sdks/share-items)
9393
- [x] [Generate PIN, random and memorable passwords](https://developer.1password.com/docs/sdks/manage-items#generate-a-password)
9494

9595
Field types:
@@ -98,7 +98,7 @@ Field types:
9898
- [x] Concealed fields
9999
- [x] Text fields
100100
- [x] Notes
101-
- [x] SSH private keys, public keys, fingerprint and key type
101+
- [x] SSH private keys, public keys, fingerprint and key type
102102
- [x] One-time passwords
103103
- [x] URLs
104104
- [x] Websites (used to suggest and autofill logins)
@@ -107,8 +107,8 @@ Field types:
107107
- [x] Credit card numbers
108108
- [x] Emails
109109
- [x] References to other items
110-
- [ ] Address
111-
- [ ] Date
110+
- [x] Address
111+
- [x] Date
112112
- [x] MM/YY
113113
- [x] Files attachments and Document items
114114
- [x] Menu

example/example.py

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ async def main():
102102
)
103103
print(code)
104104
# [developer-docs.sdk.python.resolve-totp-code]-end
105-
105+
await resolve_all_secrets(
106+
client, created_item.vault_id, created_item.id, "username", "password"
107+
)
106108
# [developer-docs.sdk.python.get-totp-item-crud]-start
107109
# Fetch a totp code from the item
108110
for f in created_item.fields:
@@ -229,6 +231,7 @@ async def share_item(client: Client, vault_id: str, item_id: str):
229231

230232

231233
async def create_ssh_key_item(client: Client):
234+
# [developer-docs.sdk.python.create-sshkey-item]-start
232235
# Generate a 2048-bit RSA private key
233236
private_key = rsa.generate_private_key(
234237
public_exponent=65537,
@@ -242,7 +245,6 @@ async def create_ssh_key_item(client: Client):
242245
encryption_algorithm=serialization.NoEncryption(),
243246
)
244247

245-
# [developer-docs.sdk.python.create-sshkey-item]-start
246248
# Create an Item containing SSH Key and add it to your vault.
247249
to_create = ItemCreateParams(
248250
title="SSH Key Item Created With Python SDK",
@@ -382,5 +384,85 @@ async def create_attach_and_delete_file_field_item(client: Client):
382384
await client.items.delete(deleted_file_item.vault_id, deleted_file_item.id)
383385

384386

387+
async def resolve_all_secrets(
388+
client: Client, vault_id: str, item_id: str, field_id: str, field_id2: str
389+
):
390+
# [developer-docs.sdk.python.resolve-bulk-secret]-start
391+
# Retrieves multiple secret from 1Password.
392+
secrets = await client.secrets.resolve_all(
393+
[
394+
f"op://{vault_id}//{item_id}/{field_id}",
395+
f"op://{vault_id}/{item_id}/{field_id2}",
396+
]
397+
)
398+
for secret in secrets.individual_responses.values():
399+
if secret.error is not None:
400+
print(str(secret.error))
401+
else:
402+
print(secret.content.secret)
403+
# [developer-docs.sdk.python.resolve-bulk-secret]-end
404+
405+
406+
def generate_special_item_fields():
407+
fields = (
408+
[
409+
# [developer-docs.sdk.python.address-field-type]-start
410+
ItemField(
411+
id="address",
412+
title="Address",
413+
sectionId="",
414+
field_type=ItemFieldType.ADDRESS,
415+
value="",
416+
details=ItemFieldDetailsAddress(
417+
content=AddressFieldDetails(
418+
street="1234 Main St",
419+
city="San Francisco",
420+
state="CA",
421+
zip="94111",
422+
country="USA",
423+
),
424+
),
425+
),
426+
# [developer-docs.sdk.python.address-field-type]-end
427+
# [developer-docs.sdk.python.date-field-type]-start
428+
ItemField(
429+
id="date",
430+
title="Date",
431+
section_id="",
432+
field_type=ItemFieldType.DATE,
433+
value="1998-03-15",
434+
),
435+
# [developer-docs.sdk.python.date-field-type]-end
436+
# [developer-docs.sdk.python.month-year-field-type]-start
437+
ItemField(
438+
id="month_year",
439+
title="Month Year",
440+
section_id="",
441+
field_type=ItemFieldType.MONTHYEAR,
442+
value="03/1998",
443+
),
444+
# [developer-docs.sdk.python.month-year-field-type]-end
445+
# [developer-docs.sdk.python.reference-field-type]-start
446+
ItemField(
447+
id="Reference",
448+
title="Reference",
449+
sectionId="",
450+
field_type=ItemFieldType.REFERENCE,
451+
value="f43hnkatjllm5fsfsmgaqdhv7a",
452+
),
453+
# [developer-docs.sdk.python.reference-field-type]-end
454+
# [developer-docs.sdk.python.totp-field-type]-start
455+
ItemField(
456+
id="onetimepassword",
457+
title="one-time-password",
458+
section_id="",
459+
field_type=ItemFieldType.TOTP,
460+
value="otpauth://totp/my-example-otp?secret=jncrjgbdjnrncbjsr&issuer=1Password",
461+
),
462+
# [developer-docs.sdk.python.totp-field-type]-end
463+
],
464+
)
465+
466+
385467
if __name__ == "__main__":
386468
asyncio.run(main())

src/onepassword/build_number.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
SDK_BUILD_NUMBER = "0020001"
1+
SDK_BUILD_NUMBER = "0020101"

src/onepassword/core.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from onepassword.errors import raise_typed_exception
55

6-
# In empirical tests, we determined that maximum message size that can cross the FFI boundary
6+
# In empirical tests, we determined that maximum message size that can cross the FFI boundary
77
# is ~128MB. Past this limit, FFI will throw an error and the program will crash.
88
# We set the limit to 50MB to be safe and consistent with the other SDKs (where this limit is 64MB), to be reconsidered upon further testing
99
MESSAGE_LIMIT = 50 * 1024 * 1024
@@ -33,7 +33,8 @@ async def _invoke(invoke_config):
3333
serialized_config = json.dumps(invoke_config)
3434
if len(serialized_config.encode()) > MESSAGE_LIMIT:
3535
raise ValueError(
36-
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help.")
36+
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help."
37+
)
3738
try:
3839
return await core.invoke(serialized_config)
3940
except Exception as e:
@@ -45,7 +46,8 @@ def _invoke_sync(invoke_config):
4546
serialized_config = json.dumps(invoke_config)
4647
if len(serialized_config.encode()) > MESSAGE_LIMIT:
4748
raise ValueError(
48-
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help.")
49+
f"message size exceeds the limit of {MESSAGE_LIMIT} bytes, please contact 1Password at [email protected] or https://developer.1password.com/joinslack if you need help."
50+
)
4951
try:
5052
return core.invoke_sync(serialized_config)
5153
except Exception as e:
462 KB
Binary file not shown.
487 KB
Binary file not shown.
559 KB
Binary file not shown.
476 KB
Binary file not shown.
742 KB
Binary file not shown.

src/onepassword/secrets.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from .iterator import SDKIterator
55
from typing import Optional, List
66
from pydantic import TypeAdapter
7-
from .types import GeneratePasswordResponse, PasswordRecipe
7+
from .types import GeneratePasswordResponse, PasswordRecipe, ResolveAllResponse
88

99

1010
class Secrets:
@@ -35,6 +35,25 @@ async def resolve(self, secret_reference: str) -> str:
3535
response = TypeAdapter(str).validate_json(response)
3636
return response
3737

38+
async def resolve_all(self, secret_references: List[str]) -> ResolveAllResponse:
39+
"""
40+
Resolve takes in a list of secret references and returns the secrets they point to or errors if any.
41+
"""
42+
response = await _invoke(
43+
{
44+
"invocation": {
45+
"clientId": self.client_id,
46+
"parameters": {
47+
"name": "SecretsResolveAll",
48+
"parameters": {"secret_references": secret_references},
49+
},
50+
}
51+
}
52+
)
53+
54+
response = TypeAdapter(ResolveAllResponse).validate_json(response)
55+
return response
56+
3857
@staticmethod
3958
def validate_secret_reference(secret_reference: str) -> None:
4059
"""

0 commit comments

Comments
 (0)