workos-python icon indicating copy to clipboard operation
workos-python copied to clipboard

Expose api key validation

Open denizs opened this issue 2 months ago • 3 comments

Description

Documentation

Once a new version is released, one could update the code examples that are currently limited to authkit-nextjs and express.

[x] Yes

If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.

denizs avatar Nov 05 '25 15:11 denizs

@mattgd - I'd like to get this contribution in, but I'm unsure of the next steps. The PR template tells me link a PR to corresponding docs, however, searching for docs in your org's repos didn't yield any result. Could please point me into the right direction?

denizs avatar Nov 06 '25 08:11 denizs

Hey @nholden sorry for that very unpleasant review. I should've mentioned the PR is by far not ready for review and that I'm primarily wondering what to do about the following sentence in the PR template:

If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.

It sounded like I had to first create another PR somewhere else before getting this one reviewed.

I've cleaned up the AI slop and can confirm it's working on my machine ™️. I've used the API key widget to issue an API key for our application and then successfully validated it:

In [1]: from workos import WorkOSClient

In [2]: workos_client = WorkOSClient(
   ...:     client_id="client_[..]",
   ...:     api_key="sk_test_[..]"
   ...: )

In [3]: workos_client.api_keys.validate_api_key(value="sk_[..]")
Out[3]: ApiKey(object='api_key', id='api_key_[..]', owner=ApiKeyOwner(type='organization', id='org_[..]'), name='test', obfuscated_value='...', last_used_at='2025-11-13T08:38:26.462Z', permissions=[], created_at='2025-11-13T08:00:17.478Z', updated_at='2025-11-13T08:15:11.604Z')

denizs avatar Nov 13 '25 08:11 denizs

Greptile Overview

Greptile Summary

This PR adds API key validation functionality to the workos-python SDK, allowing developers to programmatically validate API keys.

Key Changes:

  • Added new ApiKeys and AsyncApiKeys modules with validate_api_key() method
  • Created ApiKey and ApiKeyOwner Pydantic models for type safety
  • Integrated modules into both sync (SyncClient) and async (AsyncClient) clients
  • Implemented comprehensive test coverage using the sync_and_async test pattern
  • Followed established SDK patterns for module structure, HTTP client usage, and error handling

Implementation Quality:

  • Properly handles authentication errors by raising AuthenticationException on 401 responses
  • Uses Protocol classes for type hints and maintains dual sync/async support
  • Follows the SDK's established patterns (lazy initialization, module structure, test patterns)
  • API key path extracted as constant API_KEY_VALIDATION_PATH for maintainability

Confidence Score: 5/5

  • This PR is safe to merge with no issues found
  • The implementation follows all established SDK patterns perfectly, includes comprehensive tests, properly handles errors, and introduces no security concerns. All custom rules were checked (no sensitive data logging, no SQL injection, proper error handling).
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
workos/api_keys.py 5/5 Added new API keys module with validate_api_key method following established patterns with sync/async support
workos/types/api_keys/api_keys.py 5/5 Defined ApiKey and ApiKeyOwner Pydantic models matching API response structure
tests/test_api_keys.py 5/5 Comprehensive tests for both sync/async variants with valid and invalid key scenarios

Sequence Diagram

sequenceDiagram
    participant Client as SDK Client
    participant ApiKeys as ApiKeys Module
    participant HTTP as HTTP Client
    participant API as WorkOS API

    Client->>ApiKeys: validate_api_key(value="sk_...")
    ApiKeys->>HTTP: request(path="api_keys/validations", method=POST, json={value: "sk_..."})
    HTTP->>API: POST /api_keys/validations
    
    alt Valid API Key
        API-->>HTTP: 200 OK {api_key: {...}}
        HTTP-->>ApiKeys: response_json
        ApiKeys->>ApiKeys: ApiKey.model_validate(response["api_key"])
        ApiKeys-->>Client: ApiKey object
    else Invalid API Key
        API-->>HTTP: 401 Unauthorized
        HTTP->>HTTP: raise AuthenticationException
        HTTP-->>ApiKeys: AuthenticationException
        ApiKeys-->>Client: AuthenticationException
    end

greptile-apps[bot] avatar Nov 13 '25 08:11 greptile-apps[bot]