Skip to content

Commit 5f3ccf2

Browse files
committed
feat: add generate schema
1 parent 787df8f commit 5f3ccf2

File tree

7 files changed

+832
-0
lines changed

7 files changed

+832
-0
lines changed
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Async example script demonstrating the Generate Schema API endpoint using ScrapeGraph Python SDK.
4+
5+
This script shows how to:
6+
1. Generate a new JSON schema from a search query asynchronously
7+
2. Modify an existing schema
8+
3. Handle different types of search queries
9+
4. Check the status of schema generation requests
10+
5. Run multiple concurrent schema generations
11+
12+
Requirements:
13+
- Python 3.7+
14+
- scrapegraph-py package
15+
- aiohttp
16+
- python-dotenv
17+
- A .env file with your SGAI_API_KEY
18+
19+
Example .env file:
20+
SGAI_API_KEY=your_api_key_here
21+
22+
Usage:
23+
python async_generate_schema_example.py
24+
"""
25+
26+
import asyncio
27+
import json
28+
import os
29+
from typing import Any, Dict, Optional
30+
31+
from dotenv import load_dotenv
32+
33+
from scrapegraph_py import AsyncClient
34+
35+
# Load environment variables from .env file
36+
load_dotenv()
37+
38+
39+
class AsyncGenerateSchemaExample:
40+
"""Async example class for demonstrating the Generate Schema API using ScrapeGraph SDK"""
41+
42+
def __init__(self, base_url: str = None, api_key: str = None):
43+
# Get API key from environment if not provided
44+
self.api_key = api_key or os.getenv("SGAI_API_KEY")
45+
if not self.api_key:
46+
raise ValueError(
47+
"API key must be provided or set in .env file as SGAI_API_KEY. "
48+
"Create a .env file with: SGAI_API_KEY=your_api_key_here"
49+
)
50+
51+
# Initialize the ScrapeGraph async client
52+
if base_url:
53+
# If base_url is provided, we'll need to modify the client to use it
54+
# For now, we'll use the default client and note the limitation
55+
print(f"⚠️ Note: Custom base_url {base_url} not yet supported in this example")
56+
57+
self.client = AsyncClient(api_key=self.api_key)
58+
59+
def print_schema_response(
60+
self, response: Dict[str, Any], title: str = "Schema Generation Response"
61+
):
62+
"""Pretty print the schema generation response"""
63+
print(f"\n{'='*60}")
64+
print(f" {title}")
65+
print(f"{'='*60}")
66+
67+
if "error" in response and response["error"]:
68+
print(f"❌ Error: {response['error']}")
69+
return
70+
71+
print(f"✅ Request ID: {response.get('request_id', 'N/A')}")
72+
print(f"📊 Status: {response.get('status', 'N/A')}")
73+
print(f"🔍 User Prompt: {response.get('user_prompt', 'N/A')}")
74+
print(f"✨ Refined Prompt: {response.get('refined_prompt', 'N/A')}")
75+
76+
if "generated_schema" in response:
77+
print(f"\n📋 Generated Schema:")
78+
print(json.dumps(response["generated_schema"], indent=2))
79+
80+
async def run_examples(self):
81+
"""Run all the example scenarios asynchronously"""
82+
print("🚀 Async Generate Schema API Examples using ScrapeGraph Python SDK")
83+
print("=" * 60)
84+
85+
# Example 1: Generate schema for e-commerce products
86+
print("\n1️⃣ Example: E-commerce Product Search")
87+
ecommerce_prompt = "Find laptops with specifications like brand, processor, RAM, storage, and price"
88+
try:
89+
response = await self.client.generate_schema(ecommerce_prompt)
90+
self.print_schema_response(response, "E-commerce Products Schema")
91+
except Exception as e:
92+
print(f"❌ Error in e-commerce example: {e}")
93+
94+
# Example 2: Generate schema for job listings
95+
print("\n2️⃣ Example: Job Listings Search")
96+
job_prompt = "Search for software engineering jobs with company name, position, location, salary range, and requirements"
97+
try:
98+
response = await self.client.generate_schema(job_prompt)
99+
self.print_schema_response(response, "Job Listings Schema")
100+
except Exception as e:
101+
print(f"❌ Error in job listings example: {e}")
102+
103+
# Example 3: Generate schema for news articles
104+
print("\n3️⃣ Example: News Articles Search")
105+
news_prompt = "Find technology news articles with headline, author, publication date, category, and summary"
106+
try:
107+
response = await self.client.generate_schema(news_prompt)
108+
self.print_schema_response(response, "News Articles Schema")
109+
except Exception as e:
110+
print(f"❌ Error in news articles example: {e}")
111+
112+
# Example 4: Modify existing schema
113+
print("\n4️⃣ Example: Modify Existing Schema")
114+
existing_schema = {
115+
"$defs": {
116+
"ProductSchema": {
117+
"title": "ProductSchema",
118+
"type": "object",
119+
"properties": {
120+
"name": {"title": "Name", "type": "string"},
121+
"price": {"title": "Price", "type": "number"},
122+
},
123+
"required": ["name", "price"],
124+
}
125+
},
126+
"title": "ProductList",
127+
"type": "object",
128+
"properties": {
129+
"products": {
130+
"title": "Products",
131+
"type": "array",
132+
"items": {"$ref": "#/$defs/ProductSchema"},
133+
}
134+
},
135+
"required": ["products"],
136+
}
137+
138+
modification_prompt = (
139+
"Add brand, category, and rating fields to the existing product schema"
140+
)
141+
try:
142+
response = await self.client.generate_schema(modification_prompt, existing_schema)
143+
self.print_schema_response(response, "Modified Product Schema")
144+
except Exception as e:
145+
print(f"❌ Error in schema modification example: {e}")
146+
147+
# Example 5: Complex nested schema
148+
print("\n5️⃣ Example: Complex Nested Schema")
149+
complex_prompt = "Create a schema for a company directory with departments, each containing employees with contact info and projects"
150+
try:
151+
response = await self.client.generate_schema(complex_prompt)
152+
self.print_schema_response(response, "Company Directory Schema")
153+
except Exception as e:
154+
print(f"❌ Error in complex schema example: {e}")
155+
156+
async def run_concurrent_examples(self):
157+
"""Run multiple schema generations concurrently"""
158+
print("\n🔄 Running Concurrent Examples...")
159+
160+
# Example: Multiple concurrent schema generations
161+
prompts = [
162+
"Find restaurants with name, cuisine, rating, and address",
163+
"Search for books with title, author, genre, and publication year",
164+
"Find movies with title, director, cast, rating, and release date",
165+
]
166+
167+
try:
168+
tasks = [self.client.generate_schema(prompt) for prompt in prompts]
169+
results = await asyncio.gather(*tasks)
170+
171+
for i, (prompt, result) in enumerate(zip(prompts, results), 1):
172+
self.print_schema_response(result, f"Concurrent Example {i}: {prompt[:30]}...")
173+
174+
except Exception as e:
175+
print(f"❌ Error in concurrent examples: {e}")
176+
177+
async def demonstrate_status_checking(self):
178+
"""Demonstrate how to check the status of schema generation requests"""
179+
print("\n🔄 Demonstrating Status Checking...")
180+
181+
# Generate a simple schema first
182+
prompt = "Find restaurants with name, cuisine, rating, and address"
183+
try:
184+
response = await self.client.generate_schema(prompt)
185+
request_id = response.get('request_id')
186+
187+
if request_id:
188+
print(f"📝 Generated schema request with ID: {request_id}")
189+
190+
# Check the status
191+
print("🔍 Checking status...")
192+
status_response = await self.client.get_schema_status(request_id)
193+
self.print_schema_response(status_response, f"Status Check for {request_id}")
194+
else:
195+
print("⚠️ No request ID returned from schema generation")
196+
197+
except Exception as e:
198+
print(f"❌ Error in status checking demonstration: {e}")
199+
200+
async def close(self):
201+
"""Close the client to free up resources"""
202+
if hasattr(self, 'client'):
203+
await self.client.close()
204+
205+
206+
async def main():
207+
"""Main function to run the async examples"""
208+
# Check if API key is available
209+
if not os.getenv("SGAI_API_KEY"):
210+
print("Error: SGAI_API_KEY not found in .env file")
211+
print("Please create a .env file with your API key:")
212+
print("SGAI_API_KEY=your_api_key_here")
213+
return
214+
215+
# Initialize the example class
216+
example = AsyncGenerateSchemaExample()
217+
218+
try:
219+
# Run synchronous examples
220+
await example.run_examples()
221+
222+
# Run concurrent examples
223+
await example.run_concurrent_examples()
224+
225+
# Demonstrate status checking
226+
await example.demonstrate_status_checking()
227+
228+
except Exception as e:
229+
print(f"❌ Unexpected Error: {e}")
230+
finally:
231+
# Always close the client
232+
await example.close()
233+
234+
235+
if __name__ == "__main__":
236+
asyncio.run(main())

0 commit comments

Comments
 (0)