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

Uploaded Python 3

File details

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

File metadata

  • Download URL: shadowfax_flash-1.0.0.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.0.tar.gz
Algorithm Hash digest
SHA256 292c80834410eb0872924f8021be0644eb364103118777ed398c7f46fcf93074
MD5 44e78248da987f567c40f9c5344faa74
BLAKE2b-256 633ecd94c5fdcd78330ef5065644a1b91a2bafbd8a4776e92393ae3d88dca208

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for shadowfax_flash-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 86f3cd9900f9fd9342093eace0f46f5f86388589190b361213ecda45f9e250db
MD5 3a79f47c801071e3350bda3cee0ba8e5
BLAKE2b-256 0eb429349a8b2a3a988ef55c42d2dcbfa8e3821b93587fc46c84217ea6af7973

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