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

Uploaded Python 3

File details

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

File metadata

  • Download URL: shadowfax_flash-1.0.6.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.6.tar.gz
Algorithm Hash digest
SHA256 954fb7e01b8c058e348cc761273d38207c408ce8f1f17ee04cec34742cc6f082
MD5 5288c03e82d8410430cbc80014fceabc
BLAKE2b-256 05330d1321a1f2edef3f3ad76254fa122fc9a54ef9bbad5deff1fbea391a0522

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for shadowfax_flash-1.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 2ce8db5021a133cee1d46868d526262bf9c53e5c04c0bec8885c33abdf279804
MD5 6b7e3955d017ff15f9ad7c0202a35aeb
BLAKE2b-256 0a4162c03d04068cf6ab88d9c1d0af587a73371bfbaf17ac2d8c8c4f03b44f1b

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