Python client for Gravi-Vision BOL scanning API
Project description
Gravi-Vision Python Client
A Python client library for the Gravi-Vision API, which extracts structured data from BOL (Bill of Lading) and delivery receipt images using computer vision.
Features
- Synchronous scanning - Upload files and wait for results
- Asynchronous scanning - Upload files with callback for background processing
- Stateless callback handling - Kubernetes-friendly architecture
- Type-safe - Full type hints and Pydantic models
- Easy integration - Works with FastAPI for callback endpoints
Installation
pip install gravi-vision
Quick Start
Synchronous Scanning
from gravi_vision import GraviVisionClient
client = GraviVisionClient(api_key="your-api-key")
# Scan a BOL image
result = client.scan_bol(
image_path="path/to/bol.jpg",
reference_id="order-123"
)
print(result.items) # List of line items
print(result.reference_id) # "order-123"
Asynchronous Scanning with Callbacks
For long-running scans, use asynchronous mode where the server processes the image in the background and sends results to your callback endpoint.
Step 1: Set up a FastAPI callback handler
from fastapi import FastAPI
from gravi_vision import GraviVisionClient, EBolRequest
app = FastAPI()
client = GraviVisionClient(
api_key="your-api-key",
base_url="http://api.example.com",
callback_url="https://your-app.example.com/callbacks",
callback_auth_token="secret-token"
)
# Define your callback handler
def handle_bol_result(request: EBolRequest) -> None:
"""Process the scanned BOL data when it comes back from the server."""
print(f"Received scan result for request_id: {request.request_id}")
print(f"Reference ID: {request.reference_id}")
print(f"Items: {request.items}")
# Store result in database, update order status, etc.
# use reference_id to correlate with your business data
order_id = request.reference_id
# ... your logic here
# Mount the callback router at your desired path
callback_router = client.get_callback_router(
handler=handle_bol_result,
path_prefix="/api/v1"
)
app.include_router(callback_router)
Step 2: Upload image for processing
# Initiate async scan - returns immediately with request_id
response = client.scan_bol_async(
image_path="path/to/bol.jpg",
reference_id="order-123" # Use your business identifier for correlation
)
print(response["request_id"]) # Unique scan request ID
print(response["reference_id"]) # "order-123"
# The server processes the image in the background
# When done, it POSTs the result to your callback endpoint
# Your handle_bol_result function will be called automatically
Architecture
Callback Design
The callback system is stateless and Kubernetes-friendly:
- Client generates a
request_idfor each scan - Client calls
scan_bol_async()which returns immediately - Server processes image in background
- Server POSTs result to
{callback_url}/gravi-vision-callbacks/{request_id} - Your app's
CallbackRoutervalidates the request and calls your handler - Handler uses
reference_idto correlate result with your business data
Key benefit: No state stored on the client. Works seamlessly with:
- Serverless deployments
- Kubernetes auto-scaling
- Multiple app replicas
- Load balancers
API Reference
GraviVisionClient
Main client class for interacting with the Gravi-Vision API.
Initialization
client = GraviVisionClient(
api_key: str, # API key for authentication
base_url: str = "https://vision.gravitate.energy", # API server URL
callback_url: str | None = None, # Your app's callback URL
callback_auth_token: str | None = None, # Bearer token for callback auth
default_callback_handler: Callable | None = None # Default handler function
)
Methods
health_check() -> dict
Check if the API is healthy.
health = client.health_check()
print(health["status"]) # "ok"
scan_bol(image_path: str, reference_id: str | None = None) -> EBolRequest
Synchronously scan a BOL image and return results immediately.
result = client.scan_bol(
image_path="path/to/bol.jpg",
reference_id="order-123"
)
print(result.items) # List of scanned line items
scan_bol_async(image_path: str, reference_id: str | None = None) -> dict
Asynchronously scan a BOL image. Returns immediately with request_id.
response = client.scan_bol_async(
image_path="path/to/bol.jpg",
reference_id="order-123"
)
# Server will process in background and POST result to your callback
get_callback_router(handler: Callable, path_prefix: str = "") -> APIRouter
Get a FastAPI router for receiving callbacks.
async def my_handler(data: EBolRequest):
print(f"Got result for {data.reference_id}")
router = client.get_callback_router(
handler=my_handler,
path_prefix="/api/v1"
)
app.include_router(router)
Models
EBolRequest
Scanned BOL data with line items.
class EBolRequest(BaseModel):
request_id: str | None = None # Unique scan request ID
reference_id: str | None = None # Your business identifier (e.g., order_id)
items: list[EBolDetailRequest] # Line items scanned from the document
EBolDetailRequest
A single line item from a BOL.
class EBolDetailRequest(BaseModel):
item_code: str | None = None
description: str | None = None
quantity: int | None = None
unit: str | None = None
weight: float | None = None
# ... other fields
VisionResponse
Generic API response wrapper.
class VisionResponse(BaseModel):
success: bool
data: EBolRequest | None = None
error: str | None = None
Context Manager Usage
Use the client as a context manager for automatic resource cleanup:
async with GraviVisionClient(api_key="key") as client:
result = await client.scan_bol("image.jpg")
Error Handling
from httpx import HTTPError
try:
result = client.scan_bol("bol.jpg")
except HTTPError as e:
print(f"API error: {e}")
Configuration
Configure via environment variables or parameters:
import os
from gravi_vision import GraviVisionClient
client = GraviVisionClient(
api_key=os.getenv("GRAVI_API_KEY"),
base_url=os.getenv("GRAVI_API_URL", "http://localhost:8000"),
callback_url=os.getenv("GRAVI_CALLBACK_URL"),
callback_auth_token=os.getenv("GRAVI_CALLBACK_TOKEN")
)
Development
Running Tests
pytest
Type Checking
mypy .
Formatting and Linting
ruff check --fix .
ruff format .
License
MIT
Support
For issues and feature requests, visit the GitHub issues page.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gravi_vision-0.1.1.tar.gz.
File metadata
- Download URL: gravi_vision-0.1.1.tar.gz
- Upload date:
- Size: 6.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e783569fb14c06c7bd88646b6dd76530ef30cfb1627dd789e6eba40252bc573
|
|
| MD5 |
556f1279dd4c7b9d20c35d07fe9832e4
|
|
| BLAKE2b-256 |
71b26b85d538be615a7806fa9c9485646d9987d2f25f034c6020d759897a4a6b
|
Provenance
The following attestation bundles were made for gravi_vision-0.1.1.tar.gz:
Publisher:
publish-client.yml on gravitate-energy/gravi-vision
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gravi_vision-0.1.1.tar.gz -
Subject digest:
5e783569fb14c06c7bd88646b6dd76530ef30cfb1627dd789e6eba40252bc573 - Sigstore transparency entry: 714058731
- Sigstore integration time:
-
Permalink:
gravitate-energy/gravi-vision@633365c06903a280a5962b5730fbb4305fb66ea2 -
Branch / Tag:
refs/tags/patch - Owner: https://github.com/gravitate-energy
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-client.yml@633365c06903a280a5962b5730fbb4305fb66ea2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file gravi_vision-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gravi_vision-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4761979481318ccae6170e1560940f3975a7195fca5913af8a7bac8e8df9bf0e
|
|
| MD5 |
0d989fb1f6ec228c2bfd3d50b21536db
|
|
| BLAKE2b-256 |
3959a29785b2b9d2632e6f01c34346b78e6b5b8c794f15a38648baf9c1317073
|
Provenance
The following attestation bundles were made for gravi_vision-0.1.1-py3-none-any.whl:
Publisher:
publish-client.yml on gravitate-energy/gravi-vision
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gravi_vision-0.1.1-py3-none-any.whl -
Subject digest:
4761979481318ccae6170e1560940f3975a7195fca5913af8a7bac8e8df9bf0e - Sigstore transparency entry: 714058735
- Sigstore integration time:
-
Permalink:
gravitate-energy/gravi-vision@633365c06903a280a5962b5730fbb4305fb66ea2 -
Branch / Tag:
refs/tags/patch - Owner: https://github.com/gravitate-energy
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-client.yml@633365c06903a280a5962b5730fbb4305fb66ea2 -
Trigger Event:
push
-
Statement type: