Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/pipedream/pipedream.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,28 @@ def __init__(
@property
def raw_access_token(self) -> Optional[str]:
"""
Returns an access token that can be used to authenticate API requests
Returns an access token that can be used to authenticate API requests.

Note: When using OAuth authentication (`client_id`/`client_secret`),
this property may perform blocking network operations. For async
applications, prefer using the async property `async_raw_access_token`
instead.
"""
return self._client_wrapper._get_token()

@property
async def async_raw_access_token(self) -> Optional[str]:
"""
Asynchronously returns an access token that can be used to authenticate
API requests.

This method is non-blocking and safe to use in async contexts such as
FastAPI, Django ASGI, or any other asyncio-based application.
"""
if self._client_wrapper._async_token is not None:
return await self._client_wrapper._async_token()
return self.raw_access_token


def _get_base_url(environment: PipedreamEnvironment) -> str:
"""
Expand Down
42 changes: 42 additions & 0 deletions tests/custom/test_client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,49 @@
from unittest.mock import AsyncMock

import pytest

from pipedream import AsyncPipedream, Pipedream


# Get started with writing tests with pytest at https://docs.pytest.org
@pytest.mark.skip(reason="Unimplemented")
def test_client() -> None:
assert True


def test_sync_pipedream_raw_access_token() -> None:
"""Test synchronous Pipedream client raw_access_token property."""
client = Pipedream(access_token="test-token", project_id="test-project")
assert client.raw_access_token == "test-token"


def test_async_pipedream_raw_access_token() -> None:
"""Test AsyncPipedream client raw_access_token property with access_token."""
client = AsyncPipedream(access_token="test-token", project_id="test-project")
assert client.raw_access_token == "test-token"


async def test_async_pipedream_async_raw_access_token() -> None:
"""Test AsyncPipedream async method async_raw_access_token() with access_token."""
client = AsyncPipedream(access_token="test-token", project_id="test-project")
token = await client.async_raw_access_token
assert token == "test-token"


async def test_async_pipedream_async_raw_access_token_with_oauth() -> None:
"""Test AsyncPipedream async method with OAuth flow."""
client = AsyncPipedream(
client_id="test-client-id",
client_secret="test-client-secret",
project_id="test-project",
)

# The client should have _async_token set when using OAuth
assert client._client_wrapper._async_token is not None

# Mock the async token provider
client._client_wrapper._async_token = AsyncMock(return_value="mocked-oauth-token")

# Test the async method
token = await client.async_raw_access_token
assert token == "mocked-oauth-token"
Comment on lines 33 to 46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Search for _async_token initialization and usage
echo "=== Searching for _async_token initialization ==="
rg -nP --type=py '_async_token\s*=' 

echo -e "\n=== Searching for _async_token references ==="
rg -nP --type=py '_async_token' -C3

echo -e "\n=== Locating AsyncClientWrapper class ==="
ast-grep --pattern 'class AsyncClientWrapper { $$$ }'

echo -e "\n=== Searching for AsyncClientWrapper in Python files ==="
rg -nP --type=py 'class AsyncClientWrapper'

Repository: PipedreamHQ/pipedream-sdk-python

Length of output: 2919


🏁 Script executed:

#!/bin/bash

echo "=== Checking AsyncPipedream constructor ==="
rg -nP --type=py 'class AsyncPipedream' -A 30

echo -e "\n=== Checking how _async_token is set during initialization ==="
rg -nP --type=py 'async_token' -B2 -A2 | head -60

Repository: PipedreamHQ/pipedream-sdk-python

Length of output: 4973


Remove the assertion on line 42 to avoid testing private implementation details.

The assertion assert client._client_wrapper._async_token is not None directly accesses a private attribute (_async_token), creating tight coupling to implementation details. Since the test verifies the actual behavior through the public API at line 48 (token = await client.async_raw_access_token), the assertion is redundant. If OAuth initialization fails, the behavioral test will catch it when attempting to retrieve the token. Removing line 42 makes the test cleaner and less dependent on internal state.

Note: Line 45 (mocking _async_token) is acceptable since there is no public setter and mocking is necessary to test the async token provider behavior.

🧰 Tools
🪛 Ruff (0.14.8)

37-37: Possible hardcoded password assigned to argument: "client_secret"

(S106)


49-49: Possible hardcoded password assigned to: "token"

(S105)

🤖 Prompt for AI Agents
In tests/custom/test_client.py around lines 33 to 49, remove the assertion that
accesses the private attribute (the line asserting
client._client_wrapper._async_token is not None) to avoid testing private
implementation details; simply delete that assert line and keep the mock of
_async_token and the behavioral await/verify of client.async_raw_access_token
as-is.