Skip to main content

Async Python client for Shadowfax Flash Integration API

Project description

Shadowfax Flash Integration API Client

An async Python client for the Shadowfax Flash Integration API, providing a simple and type-safe way to interact with Shadowfax's delivery services.

Features

  • Full support for all Shadowfax Flash API endpoints
  • Async/await support using aiohttp
  • Type hints and data validation using Pydantic
  • Support for both production and staging environments
  • Comprehensive error handling

Installation

pip install shadowfax-flash

Usage

Basic Setup

import asyncio
from shadowfax_flash import ShadowfaxFlashClient, Environment
from shadowfax_flash.models import LocationDetails, DropLocationDetails, OrderDetails, UserDetails

async def main():
    # Initialize the client
    async with ShadowfaxFlashClient(
        api_key="your_api_key_here",
        environment=Environment.PRODUCTION  # or Environment.STAGING
    ) as client:
        # Example: Validate credits key
        validation = await client.validate_credits_key(
            credits_key="your_credits_key",
            store_brand_id="your_store_brand_id"
        )
        print("Credits validation:", validation)

        # Example: Check serviceability
        serviceability = await client.check_serviceability(
            pickup_details={
                "address": "123 Main St, Bangalore, Karnataka 560001",
                "latitude": 12.9716,
                "longitude": 77.5946
            },
            drop_details={
                "address": "456 MG Road, Bangalore, Karnataka 560001",
                "latitude": 12.9758,
                "longitude": 77.6050
            }
        )
        print("Serviceability:", serviceability)

        # Example: Create an order
        order_response = await client.create_order(
            pickup_details=LocationDetails(
                name="John Doe",
                contact_number="9876543210",
                address="123 Main St, Bangalore, Karnataka 560001",
                latitude=12.9716,
                longitude=77.5946
            ),
            drop_details=DropLocationDetails(
                name="Jane Smith",
                contact_number="9876543211",
                address="456 MG Road, Bangalore, Karnataka 560001",
                latitude=12.9758,
                longitude=77.6050
            ),
            order_details=OrderDetails(
                order_id="ORDER123",
                is_prepaid=False,
                cash_to_be_collected=150.0
            ),
            user_details=UserDetails(
                contact_number="9876543210",
                credits_key="your_credits_key"
            )
        )
        print("Order created:", order_response)

        # Example: Track an order
        tracking = await client.track_order(order_id="ORDER123")
        print("Order status:", tracking.status)

        # Example: Cancel an order
        cancel_response = await client.cancel_order(order_id="ORDER123")
        print("Cancel response:", cancel_response)

# Run the async function
if __name__ == "__main__":
    asyncio.run(main())

Handling Webhook Callbacks

from fastapi import FastAPI, Request
from shadowfax_flash.models import OrderCallbackRequest

app = FastAPI()

@app.post("/webhook/order-status")
async def handle_webhook(request: Request):
    # Parse the incoming webhook data
    data = await request.json()
    
    # Process the callback
    try:
        callback = OrderCallbackRequest(**data)
        print(f"Order {callback.coid} status changed to {callback.status}")
        
        # Handle different statuses
        if callback.status == "DELIVERED":
            print(f"Order {callback.coid} has been delivered!")
        elif callback.status == "CANCELLED":
            print(f"Order {callback.coid} was cancelled. Reason: {callback.cancel_reason}")
        
        return {"status": "success"}
    except Exception as e:
        print(f"Error processing webhook: {str(e)}")
        return {"status": "error", "message": str(e)}

Available Methods

  • validate_credits_key(credits_key: str, store_brand_id: str): Validate a credits key
  • check_serviceability(pickup_details, drop_details): Check if a location is serviceable
  • create_order(pickup_details, drop_details, order_details, user_details, validations=None, communications=None): Create a new order
  • cancel_order(order_id: str): Cancel an existing order
  • track_order(order_id: str): Track the status of an order
  • process_order_callback(callback_data): Process an order status callback

Models

The package includes Pydantic models for all request and response types, providing type hints and validation:

  • LocationDetails: Pickup location details
  • DropLocationDetails: Drop location details (extends LocationDetails)
  • ServiceabilityLocation: Location for serviceability check
  • UserDetails: User information
  • OrderDetails: Order information
  • Validations: Validation settings
  • Communications: Communication preferences
  • OrderStatus: Enum of possible order statuses
  • OrderCallbackRequest: Model for webhook callbacks
  • OrderTrackResponse: Model for order tracking responses

Error Handling

The client raises appropriate exceptions for different types of errors:

  • aiohttp.ClientError: For network-related errors
  • ValueError: For API errors (e.g., validation errors, invalid requests)
  • pydantic.ValidationError: For input validation errors

Testing

To run the tests, you'll need to install the development dependencies:

pip install -e ".[dev]"
pytest

License

MIT

Author

Goutham Soratoor (grsoratoor@gmail.com)

Deployment

To deploy a new version to PyPI:

  1. Update the version in pyproject.toml following Semantic Versioning
  2. Run the deployment script:
# Using Python script (recommended)
python scripts/deploy.py

# Or using bash script
./scripts/deploy.sh

The script will:

  1. Clean up previous builds
  2. Install build dependencies
  3. Build the package
  4. Verify the package
  5. Prompt for confirmation before uploading to PyPI

Prerequisites

  • Python 3.11+
  • build and twine packages (will be installed automatically)
  • PyPI account with access to upload the package
  • Configured ~/.pypirc with your PyPI credentials or use environment variables:
    export TWINE_USERNAME=your_username
    export TWINE_PASSWORD=your_password
    

Contributing

Contributions are welcome! Please read our contributing guidelines for more information.

Support

For support, please contact Shadowfax Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shadowfax_flash-1.0.2.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shadowfax_flash-1.0.2-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

File details

Details for the file shadowfax_flash-1.0.2.tar.gz.

File metadata

  • Download URL: shadowfax_flash-1.0.2.tar.gz
  • Upload date:
  • Size: 12.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.12

File hashes

Hashes for shadowfax_flash-1.0.2.tar.gz
Algorithm Hash digest
SHA256 de76f19393527aad1f3a1943d4f6d5bf006d07dfa762e802586914e0b3fb1bb0
MD5 3137b806fcc3bc370ed733e8342668e3
BLAKE2b-256 e67cc0b8a65fdfb5105d8a890b594f25165e36841c0626db111f9914a0d8b125

See more details on using hashes here.

File details

Details for the file shadowfax_flash-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for shadowfax_flash-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ac8be7521c0aa8725aae74587b1d2bcc8b87b2bbca5e2df0c3372b7883b9bf27
MD5 ae6d8dc116812173bce6011626fd66ee
BLAKE2b-256 ccea6550ca7fd76ad48891a2efea7067402d12d69aca74f23a1e130aaa0765b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page