port-sdk 0.1.0

Rust SDK for Port APIs.
Documentation
# Usage Guide

This walkthrough shows how to bootstrap the SDK, configure authentication, and call common APIs.

## 1. Configure Credentials

Create a `.env` file or export environment variables:

```env
PORT_CLIENT_ID=your-client-id
PORT_CLIENT_SECRET=your-client-secret
# Optional overrides:
# PORT_TOKEN_URL=https://api.getport.io/oauth/token
# PORT_BASE_URL=https://api.getport.io
# PORT_REGION=us
# PORT_PROXY_URL=http://localhost:8080
```

If you already manage access tokens elsewhere, set `PORT_ACCESS_TOKEN` instead of client credentials.

## 2. Initialize the Client

Use `PortClient::from_env` for the simplest setup:

```rust,no_run
use port_sdk::PortClient;

# #[tokio::main]
# async fn main() -> Result<(), port_sdk::error::PortError> {
dotenvy::dotenv().ok();
let client = PortClient::from_env()?;
# Ok(())
# }
```

For custom wiring, build a config manually:

```rust,no_run
use port_sdk::{PortClient, PortConfig, PortRegion};
use port_sdk::auth::{AuthStrategy, ClientCredentialsOptions};
use url::Url;

let options = ClientCredentialsOptions {
    client_id: "client-id".into(),
    client_secret: "client-secret".into(),
    token_url: Url::parse("https://api.getport.io/oauth/token")?,
    scope: None,
    audience: None,
    minimum_ttl: std::time::Duration::from_secs(30),
};

let config = PortConfig::builder()
    .region(PortRegion::Us)
    .auth(AuthStrategy::ClientCredentials(options))
    .build()?;
let client = PortClient::from_config(config)?;
```

### Using `.env` During Local Testing

1. Duplicate the template file and add your credentials:
   ```bash
   cp .env.example .env
   $EDITOR .env
   ```
2. Add either `PORT_CLIENT_ID`/`PORT_CLIENT_SECRET` (recommended) or `PORT_ACCESS_TOKEN`.
3. Run `cargo test` or `cargo run --example authentication-and-listing` to confirm the SDK can authenticate.
4. Toggle optional settings (timeouts, retries, tracing) in `.env` and rerun the commands to observe behaviour differences.

## 3. Call API Helpers

High-level helpers live in `port_sdk::apis` and accept typed payloads.

```rust,no_run
use port_sdk::apis::blueprints;
use port_sdk::client::Pagination;
use port_sdk::PortClient;

# #[tokio::main]
# async fn main() -> Result<(), port_sdk::error::PortError> {
let client = PortClient::from_env()?;
let page = Pagination::builder().per_page(20).build();
let results: serde_json::Value = blueprints::list(&client, Some(&page)).await?;
println!("blueprints: {results}");
# Ok(())
# }
```

You can also work with typed structs:

```rust,no_run
use port_sdk::apis::entities;
use port_sdk::types::entities::EntityRequest;

# #[tokio::main]
# async fn main() -> Result<(), port_sdk::error::PortError> {
let client = PortClient::from_env()?;
let request = EntityRequest::new("entity-1", "blueprint-1", None);
let response = entities::create(&client, "blueprint-1", &request).await?;
println!("created entity {}", response.identifier);
# Ok(())
# }
```

## 4. Handle Errors & Retries

All fallible operations return `Result<T, PortError>`. Match on the error to distinguish HTTP, API, or configuration issues.

```rust,no_run
match client.get::<serde_json::Value>("/blueprints").await {
    Ok(data) => println!("blueprints: {data}"),
    Err(port_sdk::error::PortError::Api { status, message, .. }) => {
        eprintln!("API error {status}: {message}");
    }
    Err(other) => eprintln!("request failed: {other:?}"),
}
```

Enable the `retry` feature (default) to automatically retry `429`/`5xx` responses. Customize policies via `PortConfig::builder().retry(...)`.

## 5. Useful Tips

- Inject a custom `reqwest::Client` via `PortClientBuilder::http_client` when you need bespoke TLS or connection pooling.
- Feature flags:
  - `retry` (default) for backoff/retry support.
  - `telemetry` to instrument requests with `tracing`.
  - `blocking` to expose `reqwest::blocking` variants (add as needed).
- The resource tracker (`PortClient::tracker`) helps clean up entities created during tests.

Refer back to this guide whenever you onboard a new service or script with the SDK.