Skip to content

Add async/await support to ottu-py SDK#22

Merged
jerinpetergeorge merged 6 commits intomainfrom
feature/async-support
Jun 23, 2025
Merged

Add async/await support to ottu-py SDK#22
jerinpetergeorge merged 6 commits intomainfrom
feature/async-support

Conversation

@jab3z
Copy link
Contributor

@jab3z jab3z commented Jun 21, 2025

Summary

This PR adds comprehensive asynchronous support to the ottu-py SDK while maintaining full backward compatibility with the existing synchronous API.

Key Features

  • OttuAsync class: Full async/await support with identical API to the sync version
  • Async context manager: Proper resource cleanup with async with pattern
  • AsyncSession & AsyncCard: Async versions of session and card management
  • Consistent API: All async methods have identical signatures to sync counterparts
  • Comprehensive documentation: Updated README with detailed async examples

Implementation Details

  • Minimal code duplication through inheritance from base classes
  • Shared business logic between sync and async implementations
  • AsyncRequestResponseHandler for HTTP operations using httpx.AsyncClient
  • All operations support the same features (autoflow, payment methods, etc.)

Testing

  • Added comprehensive async test suite with pytest-asyncio
  • All existing tests continue to pass
  • Code coverage maintained at 86%+
  • Type checking with mypy passes

Documentation

  • Added detailed async section to README with examples
  • Context manager usage patterns
  • Error handling examples
  • Design principles explanation

Test plan

  • All existing tests pass
  • New async test suite passes
  • Code coverage above 80%
  • Type checking passes
  • Pre-commit hooks pass
  • Manual testing of async functionality

🤖 Generated with Claude Code

- Add OttuAsync class with full async/await support
- Add AsyncSession and AsyncCard classes for async operations
- Add AsyncRequestResponseHandler for async HTTP operations
- Support async context manager pattern with proper cleanup
- Maintain identical API signatures between sync and async versions
- Add comprehensive documentation and examples in README
- All async operations support the same features as sync versions
- Add pytest-asyncio dependency for async testing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jab3z jab3z requested a review from Copilot June 21, 2025 08:54

This comment was marked as outdated.

## Major Improvements

### Clean Architecture with sync_to_async
- Replaced duplicate async implementation with Django's sync_to_async wrapper
- Ensures 100% behavioral consistency between sync and async versions
- Zero code duplication - single source of truth for all logic
- Uses proven, battle-tested approach from Django ecosystem

### Dependencies and Installation
- Added asgiref as optional async dependency: `pip install 'ottu-py[async]'`
- Works with FastAPI, Django async views, aiohttp, and any async framework
- Graceful import error handling with helpful installation message

### Simplified Test Suite
- Completely rewritten tests using httpx_mock (no more unittest.mock.patch)
- Tests follow same patterns as sync tests for consistency
- Comprehensive coverage of all async functionality
- 193 tests passing with 97.91% coverage

### Enhanced Documentation
- Updated README with sync_to_async approach explanation
- Clear installation instructions for async support
- Framework integration examples (FastAPI, Django, aiohttp)
- Emphasis on 100% API consistency between sync and async

### Code Quality Fixes
- Fixed all GitHub PR review comments
- Removed complex async request handlers - not needed with sync_to_async
- Clean async context manager support
- Proper error handling maintaining sync behavior

### Benefits
- **Zero Maintenance Overhead**: No separate async code to maintain
- **Perfect Consistency**: Identical behavior guaranteed
- **Framework Agnostic**: Works with any async Python framework
- **Battle Tested**: Uses Django's proven sync_to_async approach
- **Type Safety**: All type hints and signatures preserved

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jab3z jab3z requested a review from Copilot June 21, 2025 09:20

This comment was marked as outdated.

jab3z and others added 2 commits June 21, 2025 12:34
- Integrate async support with Django and FastAPI dependencies
- Remove separate async installation requirement
- Update pyproject.toml to include asgiref with Django/FastAPI extras
- Fix f-string parsing error in example_async.py
- Remove unused typing import from async_ottu.py
- Fix long lines in test files to comply with flake8
- Add proper file endings and formatting
- Update README to reflect integrated async approach

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove FastAPI-specific installation method
- Restore async extra in pyproject.toml for clean separation
- Update import error message to guide users to [async] extra
- Simplify README to focus on 2 installation methods:
  - ottu-py[async] for async support with any framework
  - ottu-py[django] for Django integration (includes async)
- Remove FastAPI references since async works universally

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jab3z jab3z requested a review from Copilot June 21, 2025 10:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces full async/await support to the ottu-py SDK via a new OttuAsync wrapper while preserving the existing synchronous API.

  • Add OttuAsync, AsyncSessionWrapper, and AsyncCardWrapper using sync_to_async for seamless async compatibility
  • Refactor RequestResponseHandler into a shared BaseRequestResponseHandler and enhance logging
  • Provide comprehensive async test suite, update installation extras, examples, and documentation

Reviewed Changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/test_ottu/test_async_ottu.py New async tests covering auto debit, checkout, core, cards, sessions
src/ottu/request.py Split handler into BaseRequestResponseHandler, add logging methods
src/ottu/async_ottu.py Implement OttuAsync, session and card async wrappers
src/ottu/init.py Export OttuAsync in __all__
pyproject.toml Define async extra, add asgiref dependency
example_async.py Add demo script for async usage
README.md Document async support, install extras, and usage examples
CLAUDE.md Update project guidance including async section
.flake8 Exclude example_async.py from lint
Comments suppressed due to low confidence (5)

README.md:509

  • [nitpick] sync_to_async is provided by asgiref, not Django. Consider updating the description to reference asgiref.sync_to_async for clarity.
The SDK provides full asynchronous support through the `OttuAsync` class using Django's `sync_to_async` wrapper. This ensures 100% identical behavior between sync and async versions while providing proper async/await support.

CLAUDE.md:79

  • The documentation refers to a non-existent src/ottu/async_session.py. Async session functionality is implemented within src/ottu/async_ottu.py as AsyncSessionWrapper. Update the path and class name accordingly.
   - **RequestResponseHandler**: Synchronous HTTP requests using httpx.Client

tests/test_ottu/test_async_ottu.py:294

  • [nitpick] test_session_operations only covers capture. Other session methods (refund, void, cancel, expire, delete, update, refresh) added in AsyncSessionWrapper are not tested. Consider expanding this test or adding new ones to cover all session operations.
    async def test_session_operations(self, httpx_mock, auth_api_key):

src/ottu/request.py:25

  • BaseRequestResponseHandler.init accepts **kwargs but never assigns self.kwargs, causing AttributeError in _log_request and _log_response. Add self.kwargs = kwargs in the initializer.
        **kwargs,

src/ottu/request.py:2

  • httpx is referenced in type hints (httpx.Client, httpx.AsyncClient) and used in RequestResponseHandler, but there is no import httpx at the top of the file. Add import httpx.
import typing

jab3z and others added 2 commits June 21, 2025 14:39
- Remove duplicate files with weird \!21xxx\! names
- Fix README reference to use asgiref.sync.sync_to_async instead of Django's
- Update CLAUDE.md to reference correct async wrapper classes and paths
- Expand async session test coverage to include all operations:
  refund, void, cancel, expire (in addition to existing capture test)
- All async tests passing (21 passed, 2 skipped)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jerinpetergeorge jerinpetergeorge merged commit 7f07599 into main Jun 23, 2025
3 checks passed
@jab3z jab3z deleted the feature/async-support branch June 23, 2025 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants