CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-restnavigator

A python library for interacting with HAL+JSON APIs

Pending
Overview
Eval results
Files

authentication.mddocs/

Authentication & Sessions

Built-in authentication support for various methods including Basic Auth, OAuth2, and custom authentication schemes. RestNavigator provides flexible session management through integration with the requests library.

Capabilities

Authentication Methods

Set authentication credentials for all subsequent API requests.

class HALNavigator:
    def authenticate(self, auth) -> None:
        """
        Set authentication for API requests.
        
        Parameters:
        - auth: Authentication object compatible with requests library
               (tuple for basic auth, custom auth objects, etc.)
        """

Session Management

Access and configure the underlying requests session for advanced authentication and request customization.

class HALNavigator:
    @property
    def session(self) -> 'Session':
        """
        Requests session object used for all HTTP operations.
        
        Returns:
        Session object with authentication and configuration
        """
    
    @property
    def headers(self) -> dict:
        """
        Session headers dictionary for request customization.
        
        Returns:
        Mutable dictionary of session headers
        """

Basic Authentication

from restnavigator import Navigator

# Basic authentication with username/password
api = Navigator.hal('https://api.example.com/')
api.authenticate(('username', 'password'))

# Or set during creation
api = Navigator.hal(
    'https://api.example.com/',
    auth=('username', 'password')
)

# Access authenticated resources
user_data = api['me']()

OAuth2 Authentication

from restnavigator import Navigator
from requests_oauthlib import OAuth2Session

# Create OAuth2 session
oauth = OAuth2Session('client_id', token={
    'access_token': 'your_access_token',
    'token_type': 'Bearer'
})

# Use OAuth2 session with navigator
api = Navigator.hal('https://api.example.com/', session=oauth)

# All requests will include OAuth2 authorization
user_profile = api['profile']()

Custom Authentication

import requests
from requests.auth import AuthBase

class CustomAuth(AuthBase):
    def __init__(self, api_key):
        self.api_key = api_key
    
    def __call__(self, r):
        r.headers['Authorization'] = f'ApiKey {self.api_key}'
        return r

# Use custom authentication
api = Navigator.hal('https://api.example.com/')
api.authenticate(CustomAuth('your-api-key'))

# Or with session
session = requests.Session()
session.auth = CustomAuth('your-api-key')
api = Navigator.hal('https://api.example.com/', session=session)

Session Headers

# Set default headers for all requests
api = Navigator.hal(
    'https://api.example.com/',
    headers={
        'User-Agent': 'MyApp/1.0',
        'Accept': 'application/hal+json'
    }
)

# Modify session headers after creation
api.headers['X-Custom-Header'] = 'custom-value'

# Headers are inherited by all navigators from the same API
user = api['users', 0]
print(user.headers)  # Includes all session headers

Advanced Session Configuration

import requests

# Create custom session with advanced configuration
session = requests.Session()

# Configure retries
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry_strategy = Retry(
    total=3,
    status_forcelist=[429, 500, 502, 503, 504],
    method_whitelist=["HEAD", "GET", "OPTIONS"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)

# Configure timeout
session.timeout = 30

# Use configured session
api = Navigator.hal('https://api.example.com/', session=session)

Token Refresh and Management

from requests_oauthlib import OAuth2Session

# OAuth2 with automatic token refresh
def token_updater(token):
    # Save updated token to secure storage
    save_token_to_storage(token)

oauth = OAuth2Session(
    'client_id',
    token=current_token,
    auto_refresh_url='https://api.example.com/oauth/token',
    auto_refresh_kwargs={
        'client_id': 'client_id',
        'client_secret': 'client_secret'
    },
    token_updater=token_updater
)

api = Navigator.hal('https://api.example.com/', session=oauth)

# Tokens will be automatically refreshed when they expire
data = api['protected-resource']()

Authentication State Management

# Check if navigator is authenticated
def is_authenticated(navigator):
    return navigator.session.auth is not None

# Get current authentication type
def get_auth_type(navigator):
    auth = navigator.session.auth
    if isinstance(auth, tuple) and len(auth) == 2:
        return 'basic'
    elif hasattr(auth, '__class__'):
        return auth.__class__.__name__
    return 'none'

# Clear authentication
def clear_auth(navigator):
    navigator.session.auth = None

# Usage
print("Authenticated:", is_authenticated(api))
print("Auth type:", get_auth_type(api))

Per-Request Authentication Override

# Override authentication for specific requests
result = api['sensitive-endpoint'].create(
    data,
    headers={'Authorization': 'Bearer special-token'}
)

# Use different auth for specific operations
admin_auth = ('admin', 'admin-password')
admin_result = api['admin']['users'].create(
    user_data,
    headers={'Authorization': f'Basic {base64.b64encode(b"admin:admin-password").decode()}'}
)

Session Sharing and Identity

# All navigators from the same API root share the same session
api = Navigator.hal('https://api.example.com/')
api.authenticate(('user', 'pass'))

# These navigators share authentication
users = api['users']
posts = api['posts']

# They all use the same session
assert users.session is api.session
assert posts.session is api.session

# Authentication applies to all related navigators
user_data = users[0]()  # Uses authenticated session
post_data = posts[0]()  # Uses authenticated session

Error Handling with Authentication

from restnavigator.exc import HALNavigatorError

try:
    protected_data = api['protected']()
except HALNavigatorError as e:
    if e.status == 401:
        print("Authentication required or invalid")
        # Re-authenticate or refresh token
        api.authenticate(new_credentials)
        protected_data = api['protected']()
    elif e.status == 403:
        print("Insufficient permissions")
    else:
        raise

Install with Tessl CLI

npx tessl i tessl/pypi-restnavigator

docs

authentication.md

exceptions.md

http-operations.md

index.md

navigation.md

templated-links.md

utilities.md

tile.json