Modern Python SDK for Shopify Partners API - Comprehensive GraphQL client with type safety, automatic pagination, and dual query approaches (raw GraphQL + dynamic FieldSelector). Built for developers who want powerful functionality without complex abstractions.
- Raw GraphQL - Execute queries directly with full control
- Dynamic FieldSelector - Build queries programmatically with type safety
- Type Safety - Full type hints throughout the codebase
- Automatic Pagination - Built-in cursor-based pagination support
- Intelligent Rate Limiting - Exponential backoff with retry logic
- Comprehensive Error Handling - Detailed GraphQL and HTTP error messages
- Zero Complex Abstractions - Direct GraphQL access with minimal overhead
- Synchronous API - Simple, intuitive Python interface
- Extensible Architecture - Easy to extend with custom field selections
- Rich Documentation - Comprehensive examples and API reference
pip install shopify-partners-sdkpoetry add shopify-partners-sdk# Clone the repository
git clone https://github.com/amitray007/shopify-partners-sdk.git
cd shopify-partners-sdk
# Install with Poetry
poetry install
# Or with pip in development mode
pip install -e .Get your credentials from the Shopify Partners Dashboard:
- Settings β API credentials
- Create or select an API credential
- Copy your Organization ID and Access Token (starts with
prtapi_)
The SDK provides two ways to interact with the Shopify Partners API:
from shopify_partners_sdk import ShopifyPartnersClient, FieldSelector
# Initialize the client
client = ShopifyPartnersClient(
organization_id="your-org-id",
access_token="prtapi_your-access-token",
api_version="2025-04"
)
# Build and execute query with FieldSelector
fields = FieldSelector().add_fields('id', 'title', 'handle')
result = client.query('app', fields, id='your-app-id')
print(f"App: {result['app']['title']}")
client.close()from shopify_partners_sdk import ShopifyPartnersClient
# Initialize the client
client = ShopifyPartnersClient(
organization_id="your-org-id",
access_token="prtapi_your-access-token",
api_version="2025-04"
)
# Execute raw GraphQL
query = """
query GetApp($id: ID!) {
app(id: $id) {
id
title
handle
}
}
"""
response = client.execute_raw(query, {"id": "your-app-id"})
result = response["data"]
print(f"App: {result['app']['title']}")
client.close()You can also configure the client using environment variables:
export SHOPIFY_PARTNERS_ORGANIZATION_ID="your-org-id"
export SHOPIFY_PARTNERS_ACCESS_TOKEN="prtapi_your-access-token"
export SHOPIFY_PARTNERS_API_VERSION="2025-04"from shopify_partners_sdk import ShopifyPartnersClient
# Client will automatically use environment variables
client = ShopifyPartnersClient()from shopify_partners_sdk import FieldSelector, CommonFields
# Simple query
fields = FieldSelector().add_fields('id', 'title', 'handle', 'apiKey')
result = client.query('app', fields, id='app-id')
# Query with nested fields
app_fields = (FieldSelector()
.add_fields('id', 'title', 'handle')
.add_nested_field('shop', FieldSelector().add_fields('name', 'myshopifyDomain')))
result = client.query('app', app_fields, id='app-id')
# Paginated connection query
app_fields = CommonFields.basic_app() # Predefined common fields
result = client.connection_query('apps', app_fields, first=25)
# Complex nested query with money fields
transaction_fields = (FieldSelector()
.add_fields('id', 'createdAt', 'type')
.add_money_field('netAmount') # Automatically adds amount and currencyCode
.add_nested_field('app', CommonFields.basic_app())
.add_nested_field('shop', CommonFields.basic_shop()))
result = client.connection_query('transactions', transaction_fields, first=50)
# Complex query with nested connections
event_fields = FieldSelector().add_field('type')
app_fields = (FieldSelector()
.add_field('name')
.add_connection_field('events', event_fields, first=10)) # Connection with args
result = client.query('app', app_fields, id='app-id')# Get a single app
query = """
query GetApp($id: ID!) {
app(id: $id) {
id
title
handle
apiKey
}
}
"""
response = client.execute_raw(query, {"id": "app-id"})
app = response["data"]["app"]
# Get API versions
query = """
query GetApiVersions {
publicApiVersions {
handle
displayName
supported
}
}
"""
response = client.execute_raw(query)
versions = response["data"]["publicApiVersions"]
# Get paginated apps
query = """
query GetApps($first: Int!, $after: String) {
apps(first: $first, after: $after) {
edges {
cursor
node {
id
title
handle
}
}
pageInfo {
hasNextPage
hasPreviousPage
}
}
}
"""
response = client.execute_raw(query, {"first": 25})
apps = response["data"]["apps"]# Create an app credit with FieldSelector
result_fields = (FieldSelector()
.add_nested_field('appCredit', FieldSelector()
.add_fields('id', 'description')
.add_money_field('amount'))
.add_nested_field('userErrors', FieldSelector()
.add_fields('field', 'message')))
input_data = {
"appId": "your-app-id",
"amount": {"amount": "10.00", "currencyCode": "USD"},
"description": "Refund for billing issue"
}
result = client.mutation('appCreditCreate', result_fields, input=input_data)
if result.get("userErrors"):
print("Errors:", result["userErrors"])
else:
print("Credit created:", result["appCredit"])# Create an app credit
mutation = """
mutation CreateAppCredit($input: AppCreditCreateInput!) {
appCreditCreate(input: $input) {
appCredit {
id
description
amount {
amount
currencyCode
}
}
userErrors {
field
message
}
}
}
"""
input_data = {
"appId": "your-app-id",
"amount": {"amount": "10.00", "currencyCode": "USD"},
"description": "Refund for billing issue"
}
response = client.execute_raw(mutation, {"input": input_data})
result = response["data"]import requests
from shopify_partners_sdk import ShopifyPartnersClient
# Custom HTTP client with specific settings
session = requests.Session()
session.timeout = 60.0
client = ShopifyPartnersClient(
organization_id="your-org-id",
access_token="your-token",
http_client=session
)from shopify_partners_sdk.exceptions import (
AuthenticationError,
RateLimitError,
GraphQLError
)
try:
# FieldSelector approach
fields = FieldSelector().add_fields('id', 'title')
result = client.query('app', fields, id='invalid-id')
except AuthenticationError:
print("Invalid credentials")
except RateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after} seconds")
except GraphQLError as e:
print(f"GraphQL error: {e.message}")
try:
# Raw GraphQL approach
query = """
query GetApp($id: ID!) {
app(id: $id) { id title }
}
"""
response = client.execute_raw(query, {"id": "invalid-id"})
if response.get("errors"):
print("GraphQL errors:", response["errors"])
else:
result = response["data"]
except AuthenticationError:
print("Invalid credentials")
except RateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after} seconds")from shopify_partners_sdk.config import ShopifyPartnersSDKSettings
# Custom configuration
settings = ShopifyPartnersSDKSettings(
organization_id="your-org-id",
access_token="your-token",
api_version="2025-04",
base_url="https://partners.shopify.com",
timeout_seconds=30.0,
max_retries=3,
log_level="INFO"
)
client = ShopifyPartnersClient.from_settings(settings)- App:
id,name,apiKey,events - Shop:
id,name,myshopifyDomain,avatarUrl - Organization:
id,name,avatarUrl - Transaction:
id,createdAt(interface) - Money:
amount,currencyCode - AppEvent:
type,occurredAt,app,shop(interface)
- AppCharge:
id,amount,name,test(interface) - AppCredit:
id,amount,name,test - AppSubscription:
id,amount,name,test,billingOn - AppPurchaseOneTime:
id,amount,name,test
- Currency:
USD,EUR,GBP,CAD,AUD, etc. - AppEventTypes:
RELATIONSHIP_INSTALLED,CREDIT_APPLIED,SUBSCRIPTION_CHARGE_ACCEPTED, etc. - TransactionType:
APP_ONE_TIME_SALE,APP_SUBSCRIPTION_SALE,SERVICE_SALE, etc. - AppPricingInterval:
EVERY_30_DAYS,ANNUAL
# Clone the repository
git clone https://github.com/amitray007/shopify-partners-sdk.git
cd shopify-partners-sdk
# Install Poetry (if not already installed)
curl -sSL https://install.python-poetry.org | python3 -
# Install dependencies
poetry install
# Install pre-commit hooks
poetry run pre-commit installContributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for your changes
- Ensure all tests pass (
poetry run pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
See CHANGELOG.md for a list of changes and version history.
- π Documentation - Comprehensive guides and API reference
- π Issue Tracker - Bug reports and feature requests
- π¬ Discussions - Community Q&A and support
- π Examples - Real-world usage examples
- Built with Requests for reliable HTTP client functionality
- Uses Pydantic for data validation and settings management
- Inspired by the official Shopify GraphQL APIs and developer feedback
Made with β€οΈ for the Shopify developer community
β Star this repo β’ π Report Bug β’ π‘ Request Feature