Skip to content

Commit 969bf4b

Browse files
authored
docs: rewrite README for clarity and accuracy (#111)
- Replace marketing "Features" bullets with a concise tagline and description - Remove empty "Getting started" heading and verbose Python compatibility table - Convert REPL-style examples to clean script-style code blocks - Add missing `ttl` parameter to configuration table - Document `port=0` auto-selection behavior (443 TLS / 80 plain) - Expand Development section with actual commands instead of a dead link
1 parent 1370767 commit 969bf4b

1 file changed

Lines changed: 94 additions & 146 deletions

File tree

README.md

Lines changed: 94 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -6,212 +6,160 @@
66
[![Tests](https://github.com/itential/ipsdk/workflows/Run%20pre%20merge%20pipeline/badge.svg)](https://github.com/itential/ipsdk/actions)
77
[![Coverage](https://img.shields.io/badge/coverage-100%25-green)](https://github.com/itential/ipsdk)
88

9-
The Itential Python SDK provides a robust client implementation in Python for writing
10-
scripts and applications that can make API calls to Itential Platform or Itential
11-
Automation Gateway 4.x.
9+
> Python SDK for making API calls to Itential Platform and Itential Automation Gateway 4.x.
1210
13-
**Status**: Beta - Active development with comprehensive test coverage (100%)
14-
15-
## Features
16-
17-
- **Easy API Requests**: Automatic authentication on first API call with session management
18-
- **Multiple Authentication Methods**:
19-
- OAuth (client credentials) for Itential Platform
20-
- Basic authentication (username/password) for both Platform and Gateway
21-
- **Sync and Async Support**: Both synchronous and asynchronous HTTP clients via `want_async` parameter
22-
- **Comprehensive Logging**: Custom logging system with multiple levels (including TRACE and FATAL) and httpx integration control
23-
- **Flexible Configuration**: Customizable connection settings including TLS, certificate verification, and timeouts
24-
- **Type Safety**: Full type hints for enhanced development experience
25-
- **HTTP Methods**: Support for GET, POST, PUT, DELETE, and PATCH operations with automatic JSON handling
26-
27-
## Getting started
28-
29-
## Requirements
30-
31-
- Python 3.10 or higher
32-
- httpx >= 0.28.1
33-
34-
### Tested Python Versions
35-
36-
| Python Version | Status | Notes |
37-
|----------------|--------|-------|
38-
| 3.10 | ✅ Tested | Minimum recommended version |
39-
| 3.11 | ✅ Tested | Full support |
40-
| 3.12 | ✅ Tested | Full support |
41-
| 3.13 | ✅ Tested | Latest stable release |
42-
| 3.14 | 🔄 Beta | Development/preview testing |
43-
44-
The SDK is automatically tested against Python 3.10-3.13 in our CI pipeline to ensure compatibility across all supported versions.
11+
Provides sync and async HTTP clients with automatic authentication, session management, and sensitive data filtering. Single runtime dependency: [httpx](https://www.python-httpx.org/).
4512

4613
## Installation
4714

48-
Install `ipsdk` using pip:
49-
5015
```bash
51-
$ pip install ipsdk
16+
pip install ipsdk
5217
```
5318

54-
Or using uv (recommended for development):
19+
Or with uv:
5520

5621
```bash
57-
$ uv add ipsdk
22+
uv add ipsdk
5823
```
5924

60-
The `ipsdk` package provides factory functions for connecting to either
61-
Itential Platform or Itential Automation Gateway.
25+
Requires Python 3.10+.
6226

63-
The `platform_factory(...)` function creates a connection to Itential Platform
64-
The `gateway_factory(...)` function creates a connection to Itential Automation Gateway
27+
## Usage
6528

66-
### Basic Authentication
67-
68-
Use basic authentication with username and password:
29+
### Platform — basic auth
6930

7031
```python
71-
>>> import ipsdk
72-
>>> platform = ipsdk.platform_factory(
73-
... host="platform.itential.dev",
74-
... user="admin@pronghorn",
75-
... password="your-password"
76-
... )
77-
>>> res = platform.get("/health/server")
78-
>>> res
79-
<Response [200 OK]>
80-
>>> res.text
81-
'{"version":"15.8.10-2023.2.44","release":"2023.2.9"...`
82-
```
32+
import ipsdk
33+
34+
platform = ipsdk.platform_factory(
35+
host="platform.itential.dev",
36+
user="admin@pronghorn",
37+
password="your-password"
38+
)
8339

84-
### OAuth Authentication
40+
res = platform.get("/health/server")
41+
print(res.json())
42+
```
8543

86-
For Itential Platform, you can use OAuth with client credentials:
44+
### PlatformOAuth (client credentials)
8745

8846
```python
89-
>>> import ipsdk
90-
>>> platform = ipsdk.platform_factory(
91-
... host="platform.itential.dev",
92-
... client_id="your-client-id",
93-
... client_secret="your-client-secret"
94-
... )
95-
>>> res = platform.get("/adapters")
96-
```
47+
import ipsdk
9748

98-
### Gateway Connection
49+
platform = ipsdk.platform_factory(
50+
host="platform.itential.dev",
51+
client_id="your-client-id",
52+
client_secret="your-client-secret"
53+
)
9954

100-
Connecting to Itential Automation Gateway uses the same pattern:
55+
res = platform.get("/adapters")
56+
```
57+
58+
### Gateway
10159

10260
```python
103-
>>> import ipsdk
104-
>>> gateway = ipsdk.gateway_factory(
105-
... host="gateway.itential.dev",
106-
... user="admin@itential",
107-
... password="your-password"
108-
... )
109-
>>> res = gateway.get("/devices")
61+
import ipsdk
62+
63+
gateway = ipsdk.gateway_factory(
64+
host="gateway.itential.dev",
65+
user="admin@itential",
66+
password="your-password"
67+
)
68+
69+
res = gateway.get("/devices")
11070
```
11171

112-
### Async Support
72+
### Async
11373

114-
The SDK fully supports `asyncio` for asynchronous operations. Set `want_async=True`
115-
when creating the connection:
74+
Pass `want_async=True` to get an async client:
11675

11776
```python
11877
import asyncio
11978
import ipsdk
12079

12180
async def main():
122-
p = ipsdk.platform_factory(
81+
platform = ipsdk.platform_factory(
12382
host="platform.itential.dev",
124-
user="admin@pronghorn",
83+
client_id="your-client-id",
84+
client_secret="your-client-secret",
12585
want_async=True
12686
)
87+
res = await platform.get("/adapters")
88+
print(res.json())
12789

128-
res = await p.get("/adapters")
129-
130-
if __name__ == "__main__":
131-
asyncio.run(main())
90+
asyncio.run(main())
13291
```
13392

13493
## HTTP Methods
13594

136-
The connection object supports the following HTTP methods:
137-
138-
- `GET` - Sends a HTTP GET request to the server and returns the results
139-
- `POST` - Sends a HTTP POST request to the server and returns the results
140-
- `PUT` - Sends a HTTP PUT request to the server and returns the results
141-
- `DELETE` - Sends a HTTP DELETE request to the server and returns the results
142-
- `PATCH` - Sends a HTTP PATCH request to the server and returns the results
143-
144-
The following table shows the keyword arguments for each HTTP method:
145-
146-
| Keyword | `GET` | `POST` | `PUT` | `DELETE` | `PATCH` |
147-
|----------|---------------|----------|----------|---------------|----------|
148-
| `path` | Required | Required | Required | Required | Required |
149-
| `params` | Optional | Optional | Optional | Optional | Optional |
150-
| `json` | Not Supported | Optional | Optional | Not Supported | Optional |
95+
All clients support `get`, `post`, `put`, `delete`, and `patch`.
15196

152-
The `path` argument specifies the relative path of the URI. This value is
153-
prepended to the base URL. The base URL for Itential Platform is `<host>` and
154-
the base URL for Itential Automation Gateway is `<host>/api/v2.0`.
97+
| Argument | `get` | `post` | `put` | `delete` | `patch` |
98+
|----------|----------|----------|----------|----------|----------|
99+
| `path` | required | required | required | required | required |
100+
| `params` | optional | optional | optional | optional | optional |
101+
| `json` || optional | optional || optional |
155102

156-
The `params` argument accepts a `dict` object that is transformed into the URL
157-
query string. For example, if `params={"foo": "bar"}` the resulting query
158-
string would be `?foo=bar`
103+
`path` is the relative URI appended to the base URL. `params` is a `dict` serialized to a query string. `json` accepts a `list` or `dict`; when provided, sets `Content-Type: application/json` automatically.
159104

160-
The `json` argument accepts the payload to send in the request as JSON. This
161-
argument accepts either a `list` or `dict` object. When specified, the data
162-
will automatically be converted to a JSON string and the `Content-Type` and
163-
`Accept` headers will be set to `application/json`.
105+
**Base URLs:**
106+
- Platform: `https://host:port`
107+
- Gateway: `https://host:port/api/v2.0`
164108

165109
## Configuration
166110

167-
Both the `platform_factory` and `gateway_factory` functions support
168-
configuration using keyword arguments. The table below shows the keyword
169-
arguments for each function along with their default value.
170-
171-
| Keyword | `platform_factory` | `gateway_factory` |
172-
|-----------------|--------------------|-------------------|
173-
| `host` | `localhost` | `localhost` |
174-
| `port` | `0` | `0` |
175-
| `use_tls` | `True` | `True` |
176-
| `verify` | `True` | `True` |
177-
| `user` | `admin` | `admin@itential` |
178-
| `password` | `admin` | `admin` |
179-
| `client_id` | `None` | Not Supported |
180-
| `client_secret` | `None` | Not Supported |
181-
| `timeout` | `30` | `30` |
182-
| `want_async` | `False` | `False` |
111+
| Parameter | `platform_factory` | `gateway_factory` | Description |
112+
|-----------------|--------------------|-------------------|--------------------------------------------------|
113+
| `host` | `"localhost"` | `"localhost"` | Hostname or IP |
114+
| `port` | `0` | `0` | Port; `0` = auto (443 for TLS, 80 for plain HTTP)|
115+
| `use_tls` | `True` | `True` | Use HTTPS |
116+
| `verify` | `True` | `True` | Verify TLS certificates |
117+
| `user` | `"admin"` | `"admin@itential"`| Username for basic auth |
118+
| `password` | `"admin"` | `"admin"` | Password for basic auth |
119+
| `client_id` | `None` || OAuth client ID (Platform only) |
120+
| `client_secret` | `None` || OAuth client secret (Platform only) |
121+
| `timeout` | `30` | `30` | Request timeout in seconds |
122+
| `ttl` | `0` | `0` | Re-authenticate after N seconds; `0` = disabled |
123+
| `want_async` | `False` | `False` | Return an async client |
183124

184125
## Logging
185126

186-
The SDK includes a comprehensive logging system accessible via `ipsdk.logging`:
187-
188127
```python
189128
import ipsdk
190129

191-
# Configure logging level
192130
ipsdk.logging.set_level(ipsdk.logging.DEBUG)
193-
194-
# Use convenience functions
195131
ipsdk.logging.info("Connected to platform")
196-
ipsdk.logging.debug("Request details: %s", request_data)
197-
ipsdk.logging.error("API call failed")
198132
```
199133

200-
**Logging Features**:
201-
- **Multiple Log Levels**: TRACE (5), DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL (90), and NONE (100)
202-
- **Convenience Functions**: `debug()`, `info()`, `warning()`, `error()`, `critical()`, `fatal()`, `exception()`
203-
- **Function Tracing**: `@trace` decorator for automatic entry/exit logging with timing
204-
- **Sensitive Data Filtering**: Automatic redaction of PII, API keys, passwords, and tokens
205-
- **httpx Integration**: Optional control of httpx/httpcore logging via `propagate` parameter
134+
Available levels: `TRACE` (5), `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`, `FATAL` (90), `NONE` (100).
206135

207-
For detailed logging documentation, see the logging module docstrings.
136+
The `@ipsdk.logging.trace` decorator logs function entry/exit with timing. Sensitive data filtering (PII, passwords, tokens) is enabled by default and can be extended:
208137

209-
## Development
138+
```python
139+
ipsdk.logging.add_sensitive_data_pattern("ssn", r"\d{3}-\d{2}-\d{4}")
140+
```
210141

211-
For development setup, testing, and contribution guidelines, see the [Development Guide](docs/development.md).
142+
## Development
212143

144+
```bash
145+
# Install dependencies
146+
uv sync
147+
148+
# Run checks (lint, format, security, tests, license headers)
149+
make premerge
150+
151+
# Individual targets
152+
make test # pytest
153+
make coverage # pytest --cov (100% required)
154+
make lint # ruff check
155+
make format # ruff format
156+
make security # bandit scan
157+
make license # check GPL headers
158+
159+
# Test across Python 3.10–3.13
160+
uv run tox -p auto
161+
```
213162

214163
## License
215164

216-
This project is licensed under the GPLv3 open source license. See
217-
[license](LICENSE)
165+
GPL-3.0-or-later. See [LICENSE](LICENSE).

0 commit comments

Comments
 (0)