Spaces:
Sleeping
Sleeping
File size: 7,406 Bytes
39485d9 c92f9e6 39485d9 c92f9e6 39485d9 92cbbe3 c92f9e6 92cbbe3 c92f9e6 92cbbe3 c92f9e6 39485d9 c92f9e6 39485d9 92cbbe3 c92f9e6 39485d9 c92f9e6 39485d9 92cbbe3 39485d9 c92f9e6 39485d9 c92f9e6 39485d9 92cbbe3 c92f9e6 92cbbe3 39485d9 92cbbe3 c92f9e6 92cbbe3 c92f9e6 39485d9 92cbbe3 c92f9e6 92cbbe3 c92f9e6 39485d9 92cbbe3 c92f9e6 92cbbe3 39485d9 c92f9e6 92cbbe3 39485d9 92cbbe3 c92f9e6 39485d9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
import os
import logging
import requests
import json
from typing import Dict, Any, List
from dataclasses import dataclass
from dotenv import load_dotenv
import streamlit as st
import pandas as pd
from transformers import AutoTokenizer, AutoModelForCausalLM
@dataclass
class GraphQLSchemaType:
"""Store GraphQL type information including fields and relationships"""
name: str
fields: List[Dict[str, Any]]
relationships: List[Dict[str, str]]
class ShopifyGraphQLConverter:
def __init__(self, shop_url: str, access_token: str, api_key: str, model_name: str):
"""
Initialize Shopify GraphQL converter
:param shop_url: Shopify store URL
:param access_token: Shopify Admin API access token
:param api_key: LLM service API key
:param model_name: Model name for Hugging Face
"""
load_dotenv()
# Ensure shop URL has https:// scheme
if not shop_url.startswith(('http://', 'https://')):
shop_url = f'https://{shop_url}'
# Shopify GraphQL endpoint configuration
self.shop_url = shop_url
self.graphql_endpoint = f"{shop_url}/admin/api/2024-04/graphql.json"
self.access_token = access_token
# LLM API configuration
self.api_key = api_key
self.llm_api_url = "https://api.groq.com/openai/v1/chat/completions"
self.llm_headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# Load model directly for natural language processing
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
self.model = AutoModelForCausalLM.from_pretrained(model_name)
# Predefined schema for Shopify resources
self.schema = {
"Product": GraphQLSchemaType(
name="Product",
fields=[
{"name": "id", "type": "ID", "required": False},
{"name": "title", "type": "String", "required": False},
{"name": "description", "type": "String", "required": False},
{"name": "productType", "type": "String", "required": False},
{"name": "vendor", "type": "String", "required": False},
{"name": "priceRangeV2", "type": "ProductPriceRangeV2", "required": False}
],
relationships=[
{"from_field": "variants", "to_type": "ProductVariant"},
{"from_field": "collections", "to_type": "Collection"}
]
),
}
# Setup logging
logging.basicConfig(level=logging.INFO)
self.logger = logging.getLogger(__name__)
def generate_graphql_query(self, natural_query: str) -> str:
"""
Generate GraphQL query from natural language using Llama model
:param natural_query: The query in natural language
:return: GraphQL query as a string
"""
inputs = self.tokenizer(natural_query, return_tensors="pt")
outputs = self.model.generate(**inputs, max_length=500)
query = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
return query
def convert_to_graphql_query(self, natural_query: str) -> Dict[str, Any]:
"""
Convert natural language to Shopify GraphQL query
:param natural_query: Natural language query string
:return: Dictionary containing GraphQL query or error
"""
try:
query = self.generate_graphql_query(natural_query)
# Basic query validation
if query.startswith("query") and "products" in query:
return {"success": True, "query": query}
return {"success": False, "error": "Failed to generate valid GraphQL query"}
except Exception as e:
self.logger.error(f"Query generation error: {str(e)}")
return {"success": False, "error": str(e)}
def execute_query(self, graphql_query: str) -> Dict[str, Any]:
"""
Execute the GraphQL query against Shopify Admin API
:param graphql_query: GraphQL query to execute
:return: Dictionary containing query results or error
"""
try:
payload = {"query": graphql_query}
response = requests.post(
self.graphql_endpoint,
headers={
"Content-Type": "application/json",
"X-Shopify-Access-Token": self.access_token
},
json=payload
)
response.raise_for_status()
result = response.json()
return {"success": True, "data": result.get('data', {}), "errors": result.get('errors', [])}
except requests.exceptions.RequestException as e:
self.logger.error(f"Shopify GraphQL query execution error: {str(e)}")
return {"success": False, "error": str(e)}
def main():
st.title("Shopify GraphQL Natural Language Query Converter")
load_dotenv()
shop_url = os.getenv("SHOPIFY_STORE_URL", "https://agkd0n-fa.myshopify.com")
access_token = os.getenv("SHOPIFY_ACCESS_TOKEN")
groq_api_key = os.getenv("GROQ_API_KEY")
model_name = "Qwen/Qwen2.5-72B-Instruct" # Modify this for Llama3 if needed
if not all([shop_url, access_token, groq_api_key]):
st.error("Missing environment variables. Please set SHOPIFY_STORE_URL, SHOPIFY_ACCESS_TOKEN, and GROQ_API_KEY")
return
try:
graphql_converter = ShopifyGraphQLConverter(shop_url, access_token, groq_api_key, model_name)
except Exception as e:
st.error(f"Error initializing service: {str(e)}")
return
natural_query = st.text_area("Enter your Shopify query in natural language", "Find shirt with red color", height=100)
if st.button("Generate and Execute GraphQL Query"):
if not natural_query.strip():
st.warning("Please enter a valid query.")
return
with st.spinner("Generating GraphQL query..."):
graphql_result = graphql_converter.convert_to_graphql_query(natural_query)
if not graphql_result["success"]:
st.error(f"Error generating GraphQL query: {graphql_result['error']}")
return
st.subheader("Generated GraphQL Query:")
st.code(graphql_result["query"], language="graphql")
with st.spinner("Executing query..."):
query_result = graphql_converter.execute_query(graphql_result["query"])
if not query_result["success"]:
st.error(f"Error executing query: {query_result['error']}")
return
st.subheader("Query Results:")
if query_result["errors"]:
st.error(f"GraphQL Errors: {query_result['errors']}")
if query_result["data"]:
products = query_result["data"].get("products", {}).get("edges", [])
if products:
product_list = [{"Title": p["node"]["title"], "Vendor": p["node"]["vendor"]} for p in products]
st.dataframe(pd.DataFrame(product_list))
else:
st.info("No products found.")
else:
st.info("No results found.")
if __name__ == "__main__":
main()
|