BookmarkSubscribeRSS Feed

A Practical Guide to httpx.Client for the SAS Viya REST APIs

Started 4 hours ago by
Modified 4 hours ago by
Views 38

When you interact with SAS Viya’s REST services regularly, the difference between ad‑hoc one‑off requests and a proper HTTP client is night and day. Python’s httpx.Client gives you connection pooling , strict timeouts , optional HTTP/2 , and a clean way to share configuration across calls—all of which translate into faster, safer, and more maintainable integrations with the Viya Folders API.

 

This post explains why httpx.Client is a great fit and then walks through a compact, production‑lean setup for the following examples:

 

  • authenticating to SASLogon ,
  • building a reusable client
  • resolving a folder by path
  • listing members
  • creating and deleting a subfolder

 

All endpoint behaviors are based on the official Folders API .

 

Why choose httpx.Client ?

 

  1. Real performance via pooling
    A Client instance reuses TCP connections to the same host, cutting handshake overhead and reducing latency/CPU across repeated API calls. In contrast, top‑level calls ( httpx.get(...) ) create new connections each time.
  2. Predictable reliability with strict timeouts
    httpx enforces timeouts everywhere and lets you tune connect , read , write , and pool timeouts separately, so you don’t end up with hanging processes during slow network or large payloads.
  3. Modern transport, future‑proofed
    Enable HTTP/2 for multiplexing and header compression; the client will automatically fall back to HTTP/1.1 if the server doesn’t support it. This can improve throughput when you make many calls, especially in async scenarios.
  4. Centralized configuration
    With a client you can set a base URL , shared headers (e.g., your OAuth Bearer token, Accept ), proxies and TLS once, instead of duplicating them for every request.
  5. Enterprise TLS made easy
    Pass your corporate CA bundle or an ssl.SSLContext to verify= ; httpx also honors SSL_CERT_FILE and SSL_CERT_DIR environment variables for certificate stores.

 

The Folders API in a nutshell

 

The Folders service, a SAS provided REST API endpoint, organizes SAS and external content in a hierarchical structure. Key operations we’ll use are:

 

  • Resolve by path GET /folders/@item?path=/Public/... (must match exactly one folder).
  • List members GET /folders/{id}/members (standard paging/filtering/sorting).
  • Create POST /folders (provide parentFolderUri to create a subfolder; name uniqueness is enforced at each level— 409 Conflict on duplicates).
  • Delete DELETE /folders/{id} (use ?recursive=true if the folder is not empty).

 

For permissions, predefined folders (like /Public ), and broader concepts, see the SAS Viya Help Center “Folders” guide.

 

Example 1 — Authenticate to SASLogon and build a client

 

We’ll use a client‑credentials OAuth2 flow to obtain an access token from SASLogon ( /SASLogon/oauth/token ).

 

Replace BASE_URL , CLIENT_ID , and CLIENT_SECRET with your environment settings. Ideally, they should be stored in .env file.
# auth.py

import httpx

BASE_URL = "https://viya.example.com"
TOKEN_URL = f"{BASE_URL}/SASLogon/oauth/token"
CLIENT_ID = "myclient"
CLIENT_SECRET = "mysecret"
CERT_LOC = "certificate.crt"


def get_access_token(username: str, password:str) -> str:
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
    }

    data = {"grant_type": "password", "username": username, "password": password}
    ctx = ssl.create_default_context(cafile=CERT_LOC)
    with httpx.Client(timeout=15.0, verify=ctx) as s:
        r = s.post(TOKEN_URL, auth=(CLIENT_ID, CLIENT_SECRET), headers=headers, data=data)
        r.raise_for_status()
        return r.json()["access_token"]

 

Now that we have the token, let's build a pooled httpx.Client that shares headers, base URL, timeouts, and optional HTTP/2.

 

Replace BASE_URL, and CERT_LOC with your environment settings.
# client.py

import httpx

BASE_URL = "https://viya.example.com"
CERT_LOC = "certificate.cert"

def build_client(access_token: str) -> httpx.Client:
    timeout = httpx.Timeout(connect=5.0, read=30.0, write=15.0, pool=5.0)  # strict timeouts
    ctx = ssl.create_default_context(cafile=CERT_LOC)
    return httpx.Client(
        base_url=BASE_URL,
        headers={
            "Authorization": f"Bearer {access_token}",
            "Accept": "application/json",
        },
        timeout=timeout,
        verify=ctx

    )

 

Example 2 — Resolve a folder by path and list members

 

This pattern is perfect when you only know a human‑friendly path like /Public/Examples. We first resolve the folder, then list its first 10 members with paging parameters.

 

# resolve_and_list.py

from auth import get_access_token
from client import build_client

token = get_access_token()

with build_client(token) as s:
    # Resolve by path (must match exactly one folder)
    r = s.get("/folders/folders/@item", params={"path": "/Products"})
    r.raise_for_status()
    folder = r.json()
    print("Resolved:", folder["name"], folder["id"])


    # List first 10 members (paging supported on members endpoints)
    m = s.get(f"/folders/folders/{folder['id']}/members", params={"start": 0, "limit": 10}) 
    m.raise_for_status()
    names = [it["name"] for it in m.json().get("items", [])]
    print("Members:", names)

 

Example 3 — Create and (optionally) delete a subfolder

 

POST /folders creates a folder; specify parentFolderUri to create a subfolder. The service enforces unique names at a given level , returning 409 Conflict if the name is already taken. DELETE /folders/{id} supports ?recursive=true when the target isn’t empty.

 

# create_and_delete.py

from auth import get_access_token
from client import build_client


token = get_access_token()

with build_client(token) as s:
    parent = s.get("/folders/@item", params={"path": "/Public/Examples"})
    parent.raise_for_status()
    parent_uri = parent.json()["links"]["self"]["href"]

    # Create subfolder

    payload = {"name": "Demo", "type": "folder"}
    params = {"parentFolderUri": parent_uri}
    demo = s.post("/folders", json=payload, params=params, timeout=60)
    demo.raise_for_status()
    demo_obj = demo.json()
    print("Created:", demo_obj["id"], demo_obj["name"])

    # Clean-up (recursive delete if needed)

    delete = s.delete(f"/folders/{demo_obj['id']}", params={"recursive": "true"})
    delete.raise_for_status()
    print("Deleted:", demo_obj["id"], demo_obj["name"])

 

Troubleshooting and tips

 

  • 401/403 → Recheck your SASLogon token and the folder permissions for the target path (the Help Center explains permissions and predefined folders).
  • 409 on create → Name collision is expected when a sibling already exists. Add a check in the code to validate if the name already exists.
  • TLS errors → Provide a proper CA bundle/SSL context to verify= (or set SSL_CERT_FILE / SSL_CERT_DIR).
  • Slow, large listings → Increase read timeout or page with start / limit parameters on listing endpoints.

 

Conclusion

 

Using httpx.Client with the SAS Viya REST APIs offers a powerful combination of performance, reliability, and developer ergonomics. Thanks to connection pooling and shared configuration, a single client instance reduces latency and eliminates repetitive boilerplate calls when compared to ad‑hoc calls, aligning with httpx’s documented benefits of efficient network usage and centralized settings. Fine‑grained timeout controls help prevent stalled processes and ensure predictable behavior even when interacting with large folder hierarchies or under variable network conditions, reflecting httpx’s strict enforcement of connect/read/write/pool timeouts.
For SAS developers and architects, this translates into integrations that are faster, safer, and easier to maintain —whether you’re resolving paths, listing members, provisioning folder structures, or building idempotent automation routines. Combined with the SAS Viya REST API’s predictable behaviors—clear uniqueness rules, structured paths, and rich metadata— httpx.Client becomes a natural fit for building robust tooling around Viya.
In short, if you work regularly with SAS REST endpoints, adopting httpx.Client is not just a convenience—it’s a foundational step toward writing production‑grade, resilient, and scalable API integrations.

 

Find more articles from SAS Global Enablement and Learning here.

Contributors
Version history
Last update:
4 hours ago
Updated by:

SAS AI and Machine Learning Courses

The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.

Get started

Article Tags