bapp-connectors
A ports-and-adapters integration framework for connecting to external services: marketplaces, couriers, payment gateways, messaging providers, and file storage.
Architecture
┌──────────────────────────────────────────────┐
│ Django Layer (django-bapp-connectors) │
│ Models, Services, Tasks, Circuit Breaker │
├──────────────────────────────────────────────┤
│ Core Framework (bapp-connectors) │
│ Ports, DTOs, HTTP Client, Registry, Webhooks │
├──────────────────────────────────────────────┤
│ Provider Adapters │
│ Trendyol, eMAG, Sameday, Stripe, ... │
└──────────────────────────────────────────────┘
Two packages, one monorepo:
| Package | Purpose | Dependencies |
|---|---|---|
bapp-connectors |
Core framework + all provider adapters | requests, pydantic (no Django) |
django-bapp-connectors |
Multi-tenant Django integration | django, bapp-connectors, cryptography |
Providers
| Family | Providers | Count |
|---|---|---|
| Shop | Company Store (BAPP), CEL.ro, eMAG, Gomag, Magento, Okazii, PrestaShop, Shopify, Trendyol, Vendigo, WooCommerce | 11 |
| Courier | Colete Online, GLS, Sameday | 3 |
| Payment | Cardinity, EuPlatesc, LibraPay, MobilPay, Netopia, PayPal, Stripe, Utrust | 8 |
| Messaging | Discord, GoIP, Instagram DM, Matrix, Facebook Messenger, RoboSMS, Telegram, WhatsApp | 8 |
| Storage | Dropbox, FTP File Storage, Google Drive, OneDrive, S3 Storage, SFTP, WebDAV | 7 |
| LLM | Anthropic, Google Gemini, Ollama, OpenAI | 4 |
| Feed | Compari.ro, Facebook Commerce, Google Merchant Center, Okazii.ro | 4 |
| Ads | Facebook Ads, Google Ads, LinkedIn Ads, Microsoft Ads, Pinterest Ads, TikTok Ads | 6 |
| Gmail, Mailchimp Transactional, Amazon SES, SMTP Email | 4 | |
| Social | Facebook Page, Instagram, LinkedIn Page, Pinterest, Threads, TikTok, YouTube Shorts | 7 |
| Total | 62 |
Quick Start
Install
uv add bapp-connectors # core only
uv add django-bapp-connectors # with Django integration
Use a provider directly
from bapp_connectors.providers.shop.trendyol import TrendyolShopAdapter
adapter = TrendyolShopAdapter(credentials={
"username": "api_user",
"password": "api_pass",
"seller_id": "12345",
"country": "RO",
})
# Test connection
result = adapter.test_connection()
print(result.success)
# Fetch orders
orders = adapter.get_orders()
for order in orders.items:
print(order.order_id, order.status, order.total)
# Check capabilities
from bapp_connectors.core.capabilities import BulkUpdateCapability
if adapter.supports(BulkUpdateCapability):
adapter.bulk_update_products(updates)
Use the registry
from bapp_connectors.core.registry import registry
# Import providers to register them
import bapp_connectors.providers.shop.trendyol
# Create adapter via registry
adapter = registry.create_adapter(
family="shop",
provider="trendyol",
credentials={"username": "...", "password": "...", "seller_id": "..."},
)
# List all registered providers
for manifest in registry.list_providers():
print(f"{manifest.family}: {manifest.name}")
Django integration
# models.py
from django_bapp_connectors.models import AbstractConnection
class Connection(AbstractConnection):
company = models.ForeignKey("company.Company", on_delete=models.CASCADE)
# Usage
conn = Connection.objects.create(
company=company,
provider_family="shop",
provider_name="trendyol",
)
conn.credentials = {"username": "...", "password": "...", "seller_id": "..."}
conn.save()
# Get adapter and use it
adapter = conn.get_adapter()
orders = adapter.get_orders()
# Circuit breaker: auto-disables after 3 auth failures
conn.is_operational # True when is_enabled AND is_connected
Core Concepts
Ports (Interfaces)
Each provider family has a port that defines the common contract:
ShopPort— orders, products, stock/price syncCourierPort— AWB generation, tracking, shipment managementPaymentPort— checkout sessions, payment status, refundsMessagingPort— send messages (SMS, email, WhatsApp, Telegram), reply to inboundStoragePort— save, open, delete, exists, listdir, size (Django Storage API compatible)LLMPort— chat completion, model listing, tool/function calling
Capabilities (Optional Features)
Adapters can implement optional capabilities beyond their port:
BulkUpdateCapability— batch product updatesWebhookCapability— signature verification, webhook parsingOAuthCapability— OAuth2 flow (authorize, exchange, refresh)InvoiceAttachmentCapability— attach invoices to ordersProductFeedCapability— generate product feedsEmbeddingCapability— text embeddings for RAG/searchTranscriptionCapability— audio-to-text (Whisper)StreamingCapability— streaming LLM responsesImageGenerationCapability— AI image generation
Feature discovery: adapter.supports(BulkUpdateCapability)
Normalized DTOs
All providers return the same data types:
Order,OrderItem,OrderStatus,PaymentStatusProduct,ProductUpdate,ProductCategoryShipment,AWBLabel,TrackingEventCheckoutSession,PaymentResult,RefundOutboundMessage,InboundMessage,DeliveryReportChatMessage,LLMResponse,TokenUsage,ModelInfo,ToolCallEmbeddingResult,TranscriptionResult,ImageResultContact,AddressPaginatedResult[T]— cursor-based pagination
Provider-specific data lives in the extra: dict field and provider_meta.
Resilient HTTP Client
Built-in retry, rate limiting, and observability:
- Exponential backoff with configurable max retries
- Token-bucket rate limiting per provider
- Request/response middleware chain for logging
- Error classification: retryable vs permanent
Error Hierarchy
ConnectorError
├── AuthenticationError (401/403, not retryable)
├── ConfigurationError (bad config, not retryable)
├── ValidationError (bad request, not retryable)
├── RateLimitError (429, retryable, has retry_after)
├── ProviderError (5xx, retryable)
├── PermanentProviderError (4xx non-auth, not retryable)
├── UnsupportedFeatureError (capability not supported)
└── WebhookVerificationError (bad signature)
Development
# Setup
cd packages/connectors
uv sync --extra dev
# Run tests
uv run pytest tests/ src/bapp_connectors/providers/shop/trendyol/tests/ -v -p no:django
# Lint
uv run ruff check src/
uv run ruff format src/
Django workspace
cd packages/connectors/packages/django
uv sync --extra dev
uv run pytest tests/ -v
Documentation
- Provider Development Guide — How to add a new provider or create a new family
- Django Integration Guide — How to use the Django package
- Connecting Social & Ads Providers — Per-provider credential setup, targeting model, and performance reporting
Project Structure
packages/connectors/
├── src/bapp_connectors/
│ ├── core/
│ │ ├── ports/ # Port interfaces (contracts)
│ │ ├── capabilities/ # Optional capability interfaces
│ │ ├── dto/ # Normalized data transfer objects
│ │ ├── http/ # Resilient HTTP client + auth + retry + rate limit
│ │ ├── webhooks/ # Webhook dispatcher + signature verification
│ │ ├── errors.py # Error hierarchy
│ │ ├── types.py # Enums
│ │ ├── manifest.py # Provider manifest schema
│ │ └── registry.py # Provider registry
│ └── providers/
<!-- STRUCTURE:BEGIN -->
│ ├── shop/ # Company Store (BAPP), CEL.ro, eMAG, Gomag, Magento, Okazii, PrestaShop, Shopify, Trendyol, Vendigo, WooCommerce
│ ├── courier/ # Colete Online, GLS, Sameday
│ ├── payment/ # Cardinity, EuPlatesc, LibraPay, MobilPay, Netopia, PayPal, Stripe, Utrust
│ ├── messaging/ # Discord, GoIP, Instagram DM, Matrix, Facebook Messenger, RoboSMS, Telegram, WhatsApp
│ ├── storage/ # Dropbox, FTP File Storage, Google Drive, OneDrive, S3 Storage, SFTP, WebDAV
│ ├── llm/ # Anthropic, Google Gemini, Ollama, OpenAI
│ ├── feed/ # Compari.ro, Facebook Commerce, Google Merchant Center, Okazii.ro
│ ├── ads/ # Facebook Ads, Google Ads, LinkedIn Ads, Microsoft Ads, Pinterest Ads, TikTok Ads
│ ├── email/ # Gmail, Mailchimp Transactional, Amazon SES, SMTP Email
│ └── social/ # Facebook Page, Instagram, LinkedIn Page, Pinterest, Threads, TikTok, YouTube Shorts
<!-- STRUCTURE:END -->
├── packages/django/ # Django integration (separate uv workspace)
│ └── src/django_bapp_connectors/
│ ├── models/ # Abstract models (Connection, SyncState, WebhookEvent, ExecutionLog)
│ ├── services/ # Service layer (Connection, Sync, Webhook)
│ ├── webhooks/ # Django views + URL routing
│ ├── tasks.py # Celery tasks with circuit breaker
│ ├── callbacks.py # Execution logging middleware
│ ├── encryption.py # Fernet credential encryption
│ └── admin.py # Admin mixins
├── tests/ # Core framework tests
└── docs/ # Documentation
Release files for bapp-connectors 0.31.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bapp_connectors-0.31.1.tar.gz | 1.7 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bapp_connectors-0.31.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.4 MB
Release files / bapp_connectors-0.31.1.tar.gz
| Download URL | bapp_connectors-0.31.1.tar.gz |
|---|---|
| Size | 1.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a96f9e18da6558fb0f59eb7c4d28a4646b225361d5140841b10506bb5a6ff13c
|
|
BLAKE2b-256 checksum How to use checksums |
4925fe9833603dd12e02cc152d8845216279566ab8bfcc5846f238996ee0abd7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / bapp_connectors-0.31.1-py3-none-any.whl
| Download URL | bapp_connectors-0.31.1-py3-none-any.whl |
|---|---|
| Size | 781.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
37ca3d5550afb03b42c5dfa7abb7a579a389822e9221587334d033251a8cac5b
|
|
BLAKE2b-256 checksum How to use checksums |
bae31fbb630451cdd5a0efa15e67a0ec8e63e33387579914573bdad3bde3b46a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency log