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.5.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.5-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: shadowfax_flash-1.0.5.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.5.tar.gz
Algorithm Hash digest
SHA256 a45b4ad0e761143458b0949d95264fa32d461423c3280cd9df01ec579f00ee14
MD5 8c0c25093f87bfd81e18bc1ca1656796
BLAKE2b-256 8b79c1e7cb62adbdb35ce4d9ffa947110156a77e985e353932d34b9fbfe4b664

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for shadowfax_flash-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 3db943d3c01aee06ce4da05cb2c90d7cab19434bc2f6bacb6c4c75a3d8bf46e8
MD5 c36a0334e2a75001b9f9dc2c3c6894e6
BLAKE2b-256 aea40bcd0fa558156fae0c9c6ea6d52e3abc8333849099ad63a8c13b20c8a2d7

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