generated from axioma-ai-labs/python-template
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #78 from axioma-ai-labs/feature/56-shopify_support
Shopify integration to Nevron
- Loading branch information
Showing
8 changed files
with
385 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Shopify Integration | ||
|
||
## Setup | ||
|
||
1. Create a Shopify Private App | ||
- Go to your Shopify admin panel | ||
- Navigate to Apps > Develop apps | ||
- Click "Create an app" | ||
- Configure the app permissions (products, orders, inventory) | ||
- Generate API credentials | ||
|
||
2. Get API Credentials | ||
- Note down the API key | ||
- Note down the API password (access token) | ||
- Note your store name | ||
- Or: create a test store beforehead, Go To Apps & sales channels > install your app > give neccessary permisions > Go To API Credentials and note down API key/password/store name | ||
|
||
3. Configure Environment Variables | ||
Add these to your `.env` file: | ||
```bash | ||
SHOPIFY_API_KEY=your_api_key_here | ||
SHOPIFY_PASSWORD=your_password_here | ||
SHOPIFY_STORE_NAME=your-store-name | ||
``` | ||
|
||
### Basic Setup | ||
```python | ||
from src.tools.shopify import initialize_shopify_client, get_products, get_orders, update_inventory | ||
|
||
# Initialize Shopify client | ||
client = initialize_shopify_client() | ||
|
||
# Get all products | ||
products = get_products(client) | ||
|
||
# Get all orders | ||
orders = get_orders(client) | ||
|
||
# Update inventory for a product | ||
update_inventory( | ||
client=client, | ||
product_id="product_id_here", | ||
inventory_level=100 | ||
) | ||
``` | ||
|
||
## Features | ||
- Secure authentication with Shopify API | ||
- Retrieve product listings and details | ||
- Access order information | ||
- Manage inventory levels | ||
- Error handling and logging | ||
- SSL verification handling | ||
- Session management | ||
|
||
## TODOs for Future Enhancements: | ||
- Add support for creating and updating products | ||
- Implement customer management | ||
- Add support for discount codes | ||
- Add support for handling Shopify webhooks for real-time updates | ||
- Enable advanced features like creating new products or orders | ||
- Enhance error handling and retry mechanisms for API interactions | ||
- Add support for fulfillment operations | ||
- Implement multi-location inventory management | ||
- Add support for collection management | ||
- Implement order processing workflows | ||
|
||
## Reference | ||
For implementation details, see: `src/tools/shopify.py` | ||
|
||
The implementation uses the official Shopify Python API. For more information, refer to: | ||
- [Shopify Admin API Documentation](https://shopify.dev/api/admin-rest) | ||
- [Shopify Python API Library](https://github.com/Shopify/shopify_python_api) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
"""Shopify integration tool.""" | ||
|
||
import ssl | ||
from typing import Dict, List | ||
|
||
import shopify | ||
import urllib3 | ||
from loguru import logger | ||
|
||
from src.core.config import settings | ||
from src.core.exceptions import ShopifyError | ||
|
||
# Disable SSL verification warnings and disable SSL globally | ||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) | ||
ssl._create_default_https_context = ssl._create_unverified_context | ||
|
||
|
||
def initialize_shopify_client( | ||
api_key: str = settings.SHOPIFY_API_KEY, | ||
password: str = settings.SHOPIFY_PASSWORD, | ||
store_name: str = settings.SHOPIFY_STORE_NAME, | ||
) -> shopify.Session: | ||
""" | ||
Authenticate and return a Shopify client instance. | ||
Args: | ||
api_key (str): API key for the Shopify store. | ||
password (str): API password for the Shopify store. | ||
store_name (str): The Shopify store name. | ||
Returns: | ||
shopify.Session: Authenticated Shopify session. | ||
""" | ||
try: | ||
api_version = "2024-01" | ||
shop_url = f"https://{store_name}" | ||
|
||
# Initialize and activate session | ||
session = shopify.Session(shop_url, api_version, password) | ||
shopify.ShopifyResource.activate_session(session) | ||
|
||
return session | ||
except Exception as e: | ||
logger.error(f"Failed to initialize Shopify client: {e}") | ||
raise ShopifyError(f"Authentication failed: {e}") | ||
|
||
|
||
def get_products(client: shopify.Session) -> List[Dict]: | ||
""" | ||
Retrieve a list of products from the Shopify store. | ||
Args: | ||
client (shopify.Session): Authenticated Shopify session. | ||
Returns: | ||
List[Dict]: List of product details. | ||
""" | ||
try: | ||
products = shopify.Product.find() | ||
return [product.to_dict() for product in products] | ||
except Exception as e: | ||
logger.error(f"Error retrieving products: {e}") | ||
shopify.ShopifyResource.clear_session() | ||
raise ShopifyError(f"Failed to retrieve products: {e}") | ||
|
||
|
||
def get_orders(client: shopify.Session) -> List[Dict]: | ||
""" | ||
Retrieve a list of orders from the Shopify store. | ||
Args: | ||
client (shopify.Session): Authenticated Shopify session. | ||
Returns: | ||
List[Dict]: List of order details. | ||
""" | ||
try: | ||
orders = shopify.Order.find() | ||
return [order.to_dict() for order in orders] | ||
except Exception as e: | ||
logger.error(f"Error retrieving orders: {e}") | ||
shopify.ShopifyResource.clear_session() | ||
raise ShopifyError(f"Failed to retrieve orders: {e}") | ||
|
||
|
||
def update_inventory(client: shopify.Session, product_id: str, inventory_level: int) -> None: | ||
""" | ||
Update inventory for a specified product. | ||
Args: | ||
client (shopify.Session): Authenticated Shopify session. | ||
product_id (str): The ID of the product to update. | ||
inventory_level (int): New inventory level. | ||
""" | ||
try: | ||
# Get the product and its first variant | ||
product = shopify.Product.find(product_id) | ||
variant = product.variants[0] | ||
|
||
# Get the inventory item ID | ||
inventory_item_id = variant.inventory_item_id | ||
|
||
# Get the location ID (usually the first/default location) | ||
locations = shopify.Location.find() | ||
location_id = locations[0].id | ||
|
||
# Update the inventory level | ||
shopify.InventoryLevel.set( | ||
location_id=location_id, inventory_item_id=inventory_item_id, available=inventory_level | ||
) | ||
|
||
logger.info( | ||
f"Updated inventory for product {product_id} to {inventory_level} at location {location_id}" | ||
) | ||
except Exception as e: | ||
logger.error(f"Error updating inventory: {e}") | ||
shopify.ShopifyResource.clear_session() | ||
raise ShopifyError(f"Failed to update inventory: {e}") |
Oops, something went wrong.