Skip to content

Commit 7a710d1

Browse files
Merge pull request #2 from mattjacksoncello/configclass
Configclass
2 parents 52c721f + 7a761b9 commit 7a710d1

6 files changed

Lines changed: 268 additions & 113 deletions

File tree

USAGE.md

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,69 @@ async_client: AsyncClient = new_async_client(
5656
proxies={"http://": "http://proxy.example.com"}) # Proxy configuration
5757
```
5858

59-
Both client types support all [httpx client options](https://www.python-httpx.org/api/#client) through their respective configuration classes.
59+
## Client Configuration
60+
61+
The SDK provides a `ClientConfig` class that allows you to configure the underlying httpx client. This includes SSL certificate verification and all other httpx client options.
62+
63+
### SSL Certificate Verification
64+
65+
When connecting to a 1Password Connect server using HTTPS, you may need to configure SSL certificate verification:
66+
67+
```python
68+
from onepasswordconnectsdk.config import ClientConfig
69+
70+
# Verify SSL using a custom CA certificate
71+
config = ClientConfig(cafile="path/to/ca.pem")
72+
client = new_client("https://connect.example.com", "your-token", config=config)
73+
74+
# Disable SSL verification (not recommended for production)
75+
config = ClientConfig(verify=False)
76+
client = new_client("https://connect.example.com", "your-token", config=config)
77+
```
78+
79+
### Additional Configuration Options
80+
81+
The ClientConfig class accepts all httpx client options as keyword arguments. These options are passed directly to the underlying httpx client:
82+
83+
```python
84+
# Configure timeouts and redirects
85+
config = ClientConfig(
86+
cafile="path/to/ca.pem",
87+
timeout=30.0, # 30 second timeout
88+
follow_redirects=True, # Follow HTTP redirects
89+
max_redirects=5 # Maximum number of redirects to follow
90+
)
91+
92+
# Configure proxy settings
93+
config = ClientConfig(
94+
proxies={
95+
"http://": "http://proxy.example.com",
96+
"https://": "https://proxy.example.com"
97+
}
98+
)
99+
100+
# Configure custom headers
101+
config = ClientConfig(
102+
headers={
103+
"User-Agent": "CustomApp/1.0",
104+
"X-Custom-Header": "value"
105+
}
106+
)
107+
```
108+
109+
### Async Client Configuration
110+
111+
The same configuration options work for both synchronous and asynchronous clients:
112+
113+
```python
114+
config = ClientConfig(
115+
cafile="path/to/ca.pem",
116+
timeout=30.0
117+
)
118+
async_client = new_client("https://connect.example.com", "your-token", is_async=True, config=config)
119+
```
120+
121+
For a complete list of available configuration options, see the [httpx client documentation](https://www.python-httpx.org/api/#client).
60122

61123
## Environment Variables
62124

@@ -199,6 +261,4 @@ async def main():
199261
await async_client.session.aclose()
200262

201263
asyncio.run(main())
202-
```
203-
204-
All the examples shown above for the sync client work the same way with the async client, just with async/await syntax.
264+
```
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Example script demonstrating how to connect to a 1Password Connect server
4+
using CA certificate verification and list all secrets in a vault.
5+
6+
Shows both synchronous and asynchronous usage.
7+
Update the configuration variables below with your values.
8+
"""
9+
10+
import asyncio
11+
from onepasswordconnectsdk.client import new_client
12+
from onepasswordconnectsdk.config import ClientConfig
13+
14+
# Configuration
15+
CONNECT_URL = "https://connect.example.com" # Your 1Password Connect server URL
16+
TOKEN = "eyJhbGc..." # Your 1Password Connect token
17+
VAULT_ID = "vaults_abc123" # ID of the vault to list secrets from
18+
CA_FILE = "path/to/ca.pem" # Path to your CA certificate file
19+
20+
def list_vault_secrets():
21+
"""
22+
Connect to 1Password Connect server and list all secrets in the specified vault.
23+
Uses CA certificate verification for secure connection.
24+
"""
25+
try:
26+
# Configure client with CA certificate verification
27+
config = ClientConfig(
28+
cafile=CA_FILE,
29+
timeout=30.0 # 30 second timeout
30+
)
31+
32+
# Initialize client with configuration
33+
client = new_client(CONNECT_URL, TOKEN, config=config)
34+
35+
# Get all items in the vault
36+
items = client.get_items(VAULT_ID)
37+
38+
# Print items
39+
print(f"\nSecrets in vault {VAULT_ID}:")
40+
print("-" * 40)
41+
for item in items:
42+
print(f"- {item.title} ({item.category})")
43+
44+
except Exception as e:
45+
print(f"Error: {str(e)}")
46+
47+
48+
async def list_vault_secrets_async():
49+
"""
50+
Async version: Connect to 1Password Connect server and list all secrets in the specified vault.
51+
Uses CA certificate verification for secure connection.
52+
"""
53+
try:
54+
# Configure client with CA certificate verification
55+
config = ClientConfig(
56+
cafile=CA_FILE,
57+
timeout=30.0 # 30 second timeout
58+
)
59+
60+
# Initialize async client with configuration
61+
client = new_client(CONNECT_URL, TOKEN, is_async=True, config=config)
62+
63+
# Get all items in the vault
64+
items = await client.get_items(VAULT_ID)
65+
66+
# Print items
67+
print(f"\nSecrets in vault {VAULT_ID} (async):")
68+
print("-" * 40)
69+
for item in items:
70+
print(f"- {item.title} ({item.category})")
71+
72+
# Close the client gracefully
73+
await client.session.aclose()
74+
75+
except Exception as e:
76+
print(f"Error: {str(e)}")
77+
78+
if __name__ == "__main__":
79+
# Run sync version
80+
print("Running synchronous example...")
81+
list_vault_secrets()
82+
83+
# Run async version
84+
print("\nRunning asynchronous example...")
85+
asyncio.run(list_vault_secrets_async())

src/onepasswordconnectsdk/async_client.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
"""Python AsyncClient for connecting to 1Password Connect"""
22
import httpx
33
from httpx import HTTPError
4-
from typing import Dict, List, Union
4+
from typing import Dict, List, Union, Optional
55
import os
66

77
from onepasswordconnectsdk.client import ENV_SERVICE_ACCOUNT_JWT_VARIABLE
88
from onepasswordconnectsdk.models.constants import CONNECT_HOST_ENV_VARIABLE
99

1010
from onepasswordconnectsdk.serializer import Serializer
11+
from onepasswordconnectsdk.config import ClientConfig
1112
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder, get_timeout
1213
from onepasswordconnectsdk.errors import (
1314
EnvironmentHostNotSetException,
@@ -21,24 +22,22 @@
2122
class AsyncClient:
2223
"""Python Async Client Class"""
2324

24-
def __init__(self, config: 'AsyncClientConfig') -> None:
25+
def __init__(self, url: str, token: str, config: Optional[ClientConfig] = None) -> None:
2526
"""Initialize async client
2627
2728
Args:
28-
config: AsyncClientConfig instance containing all client configuration
29+
url (str): The url of the 1Password Connect API
30+
token (str): The 1Password Service Account token
31+
config (Optional[ClientConfig]): Optional configuration for httpx client
2932
"""
30-
self.url = config.url
31-
self.token = config.token
32-
self.session = self.create_session(config)
33+
self.url = url
34+
self.token = token
35+
self.config = config
36+
self.session = self.create_session(url, token)
3337
self.serializer = Serializer()
3438

35-
def create_session(self, config: 'AsyncClientConfig') -> httpx.AsyncClient:
36-
"""Create an HTTP session using the provided configuration"""
37-
# Update headers in the existing config
38-
headers = config.headers or {}
39-
headers.update(self.build_headers(config.token))
40-
config.headers = headers
41-
return config
39+
def create_session(self, url: str, token: str) -> httpx.AsyncClient:
40+
return httpx.AsyncClient(base_url=url, headers=self.build_headers(token), timeout=get_timeout())
4241

4342
def build_headers(self, token: str) -> Dict[str, str]:
4443
return build_headers(token)

src/onepasswordconnectsdk/client.py

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
import httpx
33
from httpx import HTTPError, USE_CLIENT_DEFAULT
44
import json
5-
from typing import Dict, List, Union
5+
from typing import Dict, List, Union, Optional
66
import os
77

8+
from onepasswordconnectsdk.async_client import AsyncClient
9+
from onepasswordconnectsdk.config import ClientConfig
810
from onepasswordconnectsdk.serializer import Serializer
911
from onepasswordconnectsdk.utils import build_headers, is_valid_uuid, PathBuilder, get_timeout
1012
from onepasswordconnectsdk.errors import (
@@ -22,24 +24,15 @@
2224
class Client:
2325
"""Python Client Class"""
2426

25-
def __init__(self, config: 'ClientConfig') -> None:
26-
"""Initialize client
27-
28-
Args:
29-
config: ClientConfig instance containing all client configuration
30-
"""
31-
self.url = config.url
32-
self.token = config.token
33-
self.session = self.create_session(config)
27+
def __init__(self, url: str, token: str) -> None:
28+
"""Initialize client"""
29+
self.url = url
30+
self.token = token
31+
self.session = self.create_session(url, token)
3432
self.serializer = Serializer()
3533

36-
def create_session(self, config: 'ClientConfig') -> httpx.Client:
37-
"""Create an HTTP session using the provided configuration"""
38-
# Update headers in the existing config
39-
headers = config.headers or {}
40-
headers.update(self.build_headers(config.token))
41-
config.headers = headers
42-
return config
34+
def create_session(self, url: str, token: str) -> httpx.Client:
35+
return httpx.Client(base_url=url, headers=self.build_headers(token), timeout=get_timeout())
4336

4437
def build_headers(self, token: str) -> Dict[str, str]:
4538
return build_headers(token)
@@ -388,20 +381,19 @@ def sanitize_for_serialization(self, obj):
388381
return self.serializer.sanitize_for_serialization(obj)
389382

390383

391-
def new_client(url: str, token: str, **kwargs) -> Client:
384+
def new_client(url: str, token: str, is_async: bool = False) -> Union[AsyncClient, Client]:
392385
"""Builds a new client for interacting with 1Password Connect
393-
394-
Args:
395-
url: The url of the 1Password Connect API
396-
token: The 1Password Service Account token
397-
**kwargs: Additional httpx.Client configuration options
386+
Parameters:
387+
url: The url of the 1Password Connect API
388+
token: The 1Password Service Account token
389+
is_async: Initialize async or sync client
398390
399391
Returns:
400-
Client: The 1Password Connect client
392+
Client: The 1Password Connect client
401393
"""
402-
from onepasswordconnectsdk.config import ClientConfig
403-
config = ClientConfig(url=url, token=token, **kwargs)
404-
return Client(config)
394+
if is_async:
395+
return AsyncClient(url, token)
396+
return Client(url, token)
405397

406398

407399
def new_client_from_environment(url: str = None, **kwargs) -> Client:

0 commit comments

Comments
 (0)