Local-first embedded commerce library for Python
Project description
stateset-embedded
Local-first embedded commerce library for Python, powered by Rust.
Installation
pip install stateset-embedded
Or build from source:
cd bindings/python
pip install maturin
maturin develop
Quick Start
from stateset_embedded import Commerce, CreateOrderItemInput
# Initialize with SQLite database
commerce = Commerce("./store.db")
# Or use in-memory database for testing
commerce = Commerce(":memory:")
# Create a customer
customer = commerce.customers.create(
email="alice@example.com",
first_name="Alice",
last_name="Smith"
)
print(f"Created customer: {customer.id}")
# Create a product with variant
product = commerce.products.create(
name="Premium Widget",
description="A high-quality widget"
)
# Create inventory
item = commerce.inventory.create_item(
sku="WIDGET-001",
name="Premium Widget",
initial_quantity=100
)
# Check stock
stock = commerce.inventory.get_stock("WIDGET-001")
print(f"Available: {stock.total_available}")
# Create an order
order = commerce.orders.create(
customer_id=customer.id,
items=[
CreateOrderItemInput(
sku="WIDGET-001",
name="Premium Widget",
quantity=2,
unit_price=29.99
)
]
)
print(f"Order {order.order_number}: ${order.total_amount}")
# Ship the order
commerce.orders.ship(order.id, tracking_number="1Z999AA10123456784")
# Analytics
summary = commerce.analytics.sales_summary(period="last30days")
print(f"Revenue: ${summary.total_revenue}")
# Currency conversion (set a rate, then convert)
commerce.currency.set_rate("USD", "EUR", 0.92, source="manual")
conversion = commerce.currency.convert("USD", "EUR", 100.0)
print(f"$100 USD = €{conversion.converted_amount} EUR")
Features
- Local-First: All data stored in SQLite, works offline
- Zero Dependencies: Single native extension, no external services
- Type Safe: Full type hints and IDE support
- Fast: Native Rust performance
- Analytics + Currency: Built-in reporting/forecasting and multi-currency operations
API Reference
Commerce
Main entry point for all operations.
commerce = Commerce("./store.db") # SQLite file
commerce = Commerce(":memory:") # In-memory database
Customers
# Create
customer = commerce.customers.create(
email="alice@example.com",
first_name="Alice",
last_name="Smith",
phone="+1234567890",
accepts_marketing=True
)
# Get by ID or email
customer = commerce.customers.get(customer_id)
customer = commerce.customers.get_by_email("alice@example.com")
# List all
customers = commerce.customers.list()
# Count
count = commerce.customers.count()
Orders
# Create
order = commerce.orders.create(
customer_id=customer.id,
items=[
CreateOrderItemInput(
sku="SKU-001",
name="Product Name",
quantity=2,
unit_price=29.99
)
],
currency="USD",
notes="Gift wrap please"
)
# Get
order = commerce.orders.get(order_id)
# List all
orders = commerce.orders.list()
# Update status
order = commerce.orders.update_status(order_id, "processing")
# Ship with tracking
order = commerce.orders.ship(order_id, tracking_number="1Z123...")
# Cancel
order = commerce.orders.cancel(order_id)
Products
# Create with variants
from stateset_embedded import CreateProductVariantInput
product = commerce.products.create(
name="Premium Widget",
description="High-quality widget",
variants=[
CreateProductVariantInput(
sku="WIDGET-SM",
price=19.99,
name="Small"
),
CreateProductVariantInput(
sku="WIDGET-LG",
price=29.99,
name="Large"
)
]
)
# Get by ID
product = commerce.products.get(product_id)
# Get variant by SKU
variant = commerce.products.get_variant_by_sku("WIDGET-SM")
# List all
products = commerce.products.list()
Inventory
# Create inventory item
item = commerce.inventory.create_item(
sku="WIDGET-001",
name="Premium Widget",
description="High-quality widget",
initial_quantity=100,
reorder_point=10
)
# Check stock levels
stock = commerce.inventory.get_stock("WIDGET-001")
print(f"On hand: {stock.total_on_hand}")
print(f"Allocated: {stock.total_allocated}")
print(f"Available: {stock.total_available}")
# Adjust stock
commerce.inventory.adjust("WIDGET-001", -5, "Sold 5 units")
commerce.inventory.adjust("WIDGET-001", 50, "Received shipment")
# Reserve for order
reservation = commerce.inventory.reserve(
sku="WIDGET-001",
quantity=2,
reference_type="order",
reference_id=order_id,
expires_in_seconds=3600 # 1 hour
)
# Confirm reservation (deducts from on-hand)
commerce.inventory.confirm_reservation(reservation.id)
# Or release reservation (returns to available)
commerce.inventory.release_reservation(reservation.id)
Returns
from stateset_embedded import CreateReturnItemInput
# Create return request
ret = commerce.returns.create(
order_id=order.id,
reason="defective",
items=[
CreateReturnItemInput(
order_item_id=order.items[0].id,
quantity=1
)
],
reason_details="Product arrived damaged"
)
# Get return
ret = commerce.returns.get(return_id)
# Approve return
ret = commerce.returns.approve(return_id)
# Reject return
ret = commerce.returns.reject(return_id, "Item was used")
# List all returns
returns = commerce.returns.list()
Carts / Checkout
from stateset_embedded import CartAddress, AddCartItemInput
# Create a cart (guest checkout)
cart = commerce.carts.create(customer_email="alice@example.com", currency="USD")
# Add items
commerce.carts.add_item(
cart_id=cart.id,
item=AddCartItemInput(
sku="SKU-001",
name="Widget",
quantity=2,
unit_price=29.99,
),
)
# Set shipping (address + selection)
address = CartAddress(
first_name="Alice",
last_name="Smith",
line1="123 Main St",
city="San Francisco",
postal_code="94105",
country="US",
)
cart = commerce.carts.set_shipping(
cart.id,
address,
shipping_method="standard",
shipping_carrier="ups",
shipping_amount=9.99,
)
# Reserve inventory for cart items (optional)
cart = commerce.carts.reserve_inventory(cart.id)
# Complete checkout (creates an order)
result = commerce.carts.complete(cart.id)
print(result.order_number)
Analytics
# Sales summary
summary = commerce.analytics.sales_summary(period="last30days")
print(summary.total_revenue, summary.order_count)
# Top products / customers
top_products = commerce.analytics.top_products(period="this_month", limit=10)
top_customers = commerce.analytics.top_customers(period="all_time", limit=10)
# Forecasting
forecasts = commerce.analytics.demand_forecast(days_ahead=30)
revenue = commerce.analytics.revenue_forecast(periods_ahead=3, granularity="month")
Currency
# Set an exchange rate
commerce.currency.set_rate("USD", "EUR", 0.92, source="manual")
# Convert currency
conversion = commerce.currency.convert("USD", "EUR", 100.0)
print(conversion.converted_amount)
# Store settings
settings = commerce.currency.get_settings()
settings = commerce.currency.enable_currencies(["USD", "EUR", "GBP"])
Order Statuses
pending- Order created, awaiting confirmationconfirmed- Order confirmedprocessing- Order being processedshipped- Order shippeddelivered- Order deliveredcancelled- Order cancelledrefunded- Order refunded
Return Reasons
defective- Product is defectivenot_as_described- Product not as describedwrong_item- Wrong item receivedno_longer_needed- No longer neededchanged_mind- Changed mindbetter_price_found- Found better price elsewheredamaged- Product arrived damagedother- Other reason
Development
# Install dev dependencies
pip install maturin pytest
# Build in development mode
maturin develop
# Run tests
pytest tests/
# Build release wheel
maturin build --release
License
MIT OR Apache-2.0
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
stateset_embedded-0.2.0.tar.gz
(593.9 kB
view details)
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 stateset_embedded-0.2.0.tar.gz.
File metadata
- Download URL: stateset_embedded-0.2.0.tar.gz
- Upload date:
- Size: 593.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebc83e1924844faf6af89bfae3ed41860e9f3929c44050cba57ddcd2a0a144ed
|
|
| MD5 |
42f6c2a8be62ca843102e89193c2f51f
|
|
| BLAKE2b-256 |
fdd290beed7f83ac1fb9f82765159dc2ac8d9398b782150c1121c71a14ba2825
|
File details
Details for the file stateset_embedded-0.2.0-cp310-cp310-manylinux_2_31_x86_64.whl.
File metadata
- Download URL: stateset_embedded-0.2.0-cp310-cp310-manylinux_2_31_x86_64.whl
- Upload date:
- Size: 4.7 MB
- Tags: CPython 3.10, manylinux: glibc 2.31+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7e5fb5b44ba1a618762726d5a29fdaec244f06051ebcb6f78e8c5725dc3bbfe
|
|
| MD5 |
52b87bd6bf1ff861da19b42b11022f45
|
|
| BLAKE2b-256 |
17befa720e707b8c36cc2e0c67e8318146bbaad6b7b6057a6fb6e889ae652277
|