Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Shopify integration to Nevron #78

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,54 @@ MEMORY_VECTOR_SIZE=1536

# === Agent Personality settings ===

AGENT_PERSONALITY=You are a financial analyst. You are given a news article and some context. You need to analyze the news and provide insights. You are very naive and trustful. You are very optimistic and believe in the future of humanity.
AGENT_PERSONALITY=You are a Nevron, a financial analyst in crypto space. You are excellent in crypto and blockchain technology and your goal is to help people understand the crypto space better and avoid scams. You are very friendly, approachable and helpful. You are very optimistic and believe in the future of humanity.
AGENT_GOAL=Your goal is to analyze the news and provide insights.
AGENT_REST_TIME=300

# === LLMs settings ===

LLM_PROVIDER=openai
PERPLEXITY_NEWS_PROMPT=Search for the latest cryptocurrency news: Neurobro

OPENAI_API_KEY=
OPENAI_MODEL=gpt-4o-mini
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
OPENAI_API_KEY=

XAI_MODEL=grok-2-latest
XAI_API_KEY=

ANTHROPIC_API_KEY=
ANTHROPIC_MODEL=claude-3-5-sonnet-20240620
# === Third-party services settings ===

PERPLEXITY_API_KEY=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
# Perplexity
PERPLEXITY_API_KEY=
PERPLEXITY_ENDPOINT=https://api.perplexity.ai/chat/completions
PERPLEXITY_NEWS_PROMPT=Search for the latest cryptocurrency news: Nevron

# Coinstats
COINSTATS_API_KEY=

# Telegram
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
TELEGRAM_ADMIN_CHAT_ID=
TELEGRAM_REVIEWER_CHAT_IDS=

# Twitter
TWITTER_BEARER_TOKEN=
TWITTER_API_KEY=
TWITTER_API_SECRET_KEY=
TWITTER_ACCESS_TOKEN=
TWITTER_ACCESS_TOKEN_SECRET=

# Discord

# Discord settings
DISCORD_BOT_TOKEN=
DISCORD_CHANNEL_ID=0


#: YouTube
# YouTube settings
YOUTUBE_API_KEY=
YOUTUBE_PLAYLIST_ID=

#: WhatsApp
WHATSAPP_ID_INSTANCE=
WHATSAPP_API_TOKEN=
# WhatsApp settings
WHATSAPP_API_KEY=
WHATSAPP_PHONE_NUMBER=

# Shopify settings
SHOPIFY_API_KEY=
SHOPIFY_PASSWORD=
SHOPIFY_STORE_NAME=
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ google-auth-oauthlib = "*"
google-auth = "*"
google-api-python-client = "*"
whatsapp_api_client_python = "*"
ShopifyAPI = "*"
aiohttp = "*"
pillow = "*"
types-requests = "*"
Expand Down
23 changes: 22 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 73 additions & 0 deletions docs/agent/shopify.md
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)
6 changes: 6 additions & 0 deletions src/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ class Settings(BaseSettings):
#: WhatsApp API token
WHATSAPP_API_TOKEN: str = ""

# --- Shopify settings ---

SHOPIFY_API_KEY: str = ""
SHOPIFY_PASSWORD: str = ""
SHOPIFY_STORE_NAME: str = ""

# ==========================
# Validators
# ==========================
Expand Down
6 changes: 6 additions & 0 deletions src/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ class CoinstatsError(AgentBaseError):
"""Exception raised when Coinstats API request fails."""

pass


class ShopifyError(Exception):
"""Raised when Shopify API operations fail."""

pass
118 changes: 118 additions & 0 deletions src/tools/shopify.py
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}")
Loading
Loading