Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
57 changes: 57 additions & 0 deletions python/council-events/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Stagehand + Browserbase: Philadelphia Council Events Scraper

## AT A GLANCE
- Goal: automate extraction of Philadelphia Council events for 2025 from the official calendar.
- Flow: navigate to phila.legistar.com → click calendar → select 2025 → extract event data (name, date, time).
- Benefits: quickly gather upcoming council events without manual browsing, structured data ready for analysis or notifications.
Docs → https://docs.browserbase.com/stagehand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link


## GLOSSARY
- act: perform UI actions from a prompt (click, select, navigate).
Docs → https://docs.stagehand.dev/basics/act
- extract: pull structured data from a page using AI and Pydantic schemas.
Docs → https://docs.stagehand.dev/basics/extract
- Pydantic schema: type-safe data models that validate extracted content.

## QUICKSTART
1) cd council-events
2) python -m venv venv
3) source venv/bin/activate # On Windows: venv\Scripts\activate
4) pip install stagehand python-dotenv pydantic
5) cp .env.example .env
6) Add your Browserbase API key, Project ID, and OpenAI API key to .env
7) python main.py

## EXPECTED OUTPUT
- Initializes Stagehand session with Browserbase
- Navigates to Philadelphia Council calendar
- Selects 2025 events from dropdown
- Extracts event names, dates, and times
- Displays structured JSON output with all events
- Provides live session URL for monitoring
- Closes session cleanly

## COMMON PITFALLS
- "ModuleNotFoundError": ensure all dependencies are installed via pip
- Missing credentials: verify .env contains BROWSERBASE_PROJECT_ID, BROWSERBASE_API_KEY, and OPENAI_API_KEY
- No events found: check if the website structure has changed or if 2025 calendar is available
- Network issues: ensure internet access and phila.legistar.com is accessible
- Import errors: activate your virtual environment if you created one

## USE CASES
• Civic monitoring: Track upcoming council meetings, hearings, and votes for advocacy or journalism.
• Event aggregation: Pull council calendars into dashboards, newsletters, or community notification systems.
• Research & analysis: Collect historical event data to analyze meeting frequency, topics, or scheduling patterns.

## NEXT STEPS
• Multi-year extraction: Loop through multiple years to build historical event database.
• Event details: Click into individual events to extract agendas, attendees, and documents.
• Notifications: Set up scheduled runs to detect new events and send alerts via email/Slack.

## HELPFUL RESOURCES
📚 Stagehand Docs: https://docs.browserbase.com/stagehand
🎮 Browserbase: https://www.browserbase.com
💡 Try it out: https://www.browserbase.com/playground
🔧 Templates: https://github.com/browserbase/stagehand/tree/main/examples
📧 Need help? [email protected]

113 changes: 113 additions & 0 deletions python/council-events/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Stagehand + Browserbase: Philadelphia Council Events Scraper - See README.md for full documentation

import os
import asyncio
from dotenv import load_dotenv
from stagehand import Stagehand, StagehandConfig
from pydantic import BaseModel, Field
from typing import List

# Load environment variables
load_dotenv()


class Event(BaseModel):
"""Single event with name, date, and time"""
name: str = Field(..., description="the name of the event")
date: str = Field(..., description="the date of the event")
time: str = Field(..., description="the time of the event")


class EventResults(BaseModel):
"""Collection of events extracted from the calendar"""
results: List[Event] = Field(..., description="array of events")


async def main():
"""
Searches Philadelphia Council Events for 2025 and extracts event information.
Uses AI-powered browser automation to navigate and interact with the site.
"""
print("Starting Philadelphia Council Events automation...")

# Initialize Stagehand with Browserbase for cloud-based browser automation
config = StagehandConfig(
env="BROWSERBASE",
api_key=os.environ.get("BROWSERBASE_API_KEY"),
project_id=os.environ.get("BROWSERBASE_PROJECT_ID"),
model_name="openai/gpt-4.1",
model_api_key=os.environ.get("OPENAI_API_KEY"),
verbose=1,
# 0 = errors only, 1 = info, 2 = debug
# (When handling sensitive data like passwords or API keys, set verbose: 0 to prevent secrets from appearing in logs.)
# https://docs.stagehand.dev/configuration/logging
)

try:
# Use async context manager for automatic resource management
async with Stagehand(config) as stagehand:
print("Initializing browser session...")
print("Stagehand session started successfully")

# Provide live session URL for debugging and monitoring
session_id = None
if hasattr(stagehand, 'session_id'):
session_id = stagehand.session_id
elif hasattr(stagehand, 'browserbase_session_id'):
session_id = stagehand.browserbase_session_id

if session_id:
print(f"Watch live: https://browserbase.com/sessions/{session_id}")

page = stagehand.page

# Navigate to Philadelphia Council
print("Navigating to: https://phila.legistar.com/")
await page.goto("https://phila.legistar.com/")
print("Page loaded successfully")

# Click calendar from the navigation menu
print("Clicking calendar from the navigation menu")
await page.act("click calendar from the navigation menu")

# Select 2025 from the month dropdown
print("Selecting 2025 from the month dropdown")
await page.act("select 2025 from the month dropdown")

# Extract event data using AI to parse the structured information
print("Extracting event information...")
results = await page.extract(
"Extract the table with the name, date and time of the events",
schema=EventResults
)

print(f"Found {len(results.results)} events")
print("Event data extracted successfully:")

# Display results in formatted JSON
import json
print(json.dumps(results.model_dump(), indent=2))

print("Session closed successfully")

except Exception as error:
print(f"Error during event extraction: {error}")

# Provide helpful troubleshooting information
print("\nCommon issues:")
print("1. Check .env file has BROWSERBASE_PROJECT_ID and BROWSERBASE_API_KEY")
print("2. Verify OPENAI_API_KEY is set in environment")
print("3. Ensure internet access and https://phila.legistar.com is accessible")
print("4. Verify Browserbase account has sufficient credits")
print("5. Check if the calendar page structure has changed")

raise


if __name__ == "__main__":
try:
asyncio.run(main())
except Exception as err:
print(f"Application error: {err}")
exit(1)

58 changes: 58 additions & 0 deletions python/polymarket-research/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Stagehand + Browserbase: Polymarket Prediction Market Research

## AT A GLANCE
- Goal: automate research of prediction markets on Polymarket to extract current odds, pricing, and volume data.
- Flow: navigate to polymarket.com → search for market → select result → extract market data (odds, prices, volume, changes).
- Benefits: quickly gather market intelligence on prediction markets without manual browsing, structured data ready for analysis or trading decisions.
Docs → https://docs.browserbase.com/stagehand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a valid url

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


## GLOSSARY
- act: perform UI actions from a prompt (click, type, search).
Docs → https://docs.stagehand.dev/basics/act
- extract: pull structured data from a page using AI and Pydantic schemas.
Docs → https://docs.stagehand.dev/basics/extract
- prediction market: a market where participants trade contracts based on the outcome of future events.

## QUICKSTART
1) cd polymarket-research
2) python -m venv venv
3) source venv/bin/activate # On Windows: venv\Scripts\activate
4) pip install stagehand python-dotenv pydantic
5) cp .env.example .env
6) Add your Browserbase API key, Project ID, and OpenAI API key to .env
7) python main.py

## EXPECTED OUTPUT
- Initializes Stagehand session with Browserbase
- Navigates to Polymarket website
- Searches for "Elon Musk unfollow Trump" prediction market
- Selects first market result from search dropdown
- Extracts market data: title, odds, yes/no prices, volume, price changes
- Displays structured JSON output with market information
- Provides live session URL for monitoring
- Closes session cleanly

## COMMON PITFALLS
- "ModuleNotFoundError": ensure all dependencies are installed via pip
- Missing credentials: verify .env contains BROWSERBASE_PROJECT_ID, BROWSERBASE_API_KEY, and OPENAI_API_KEY
- No search results: check if the search query returns valid markets or try different search terms
- Network issues: ensure internet access and polymarket.com is accessible
- Import errors: activate your virtual environment if you created one

## USE CASES
• Market research: Track odds and sentiment on political events, sports outcomes, or business predictions.
• Trading analysis: Monitor price movements, volume trends, and market efficiency for investment decisions.
• News aggregation: Collect prediction market data to supplement traditional news sources with crowd-sourced forecasts.

## NEXT STEPS
• Multi-market tracking: Loop through multiple markets to build comprehensive prediction database.
• Historical analysis: Track price changes over time to identify trends and patterns.
• Automated alerts: Set up scheduled runs to detect significant market movements and send notifications.

## HELPFUL RESOURCES
📚 Stagehand Docs: https://docs.browserbase.com/stagehand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

🎮 Browserbase: https://www.browserbase.com
💡 Try it out: https://www.browserbase.com/playground
🔧 Templates: https://github.com/browserbase/stagehand/tree/main/examples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python linking to TS repo + this is also a dead link

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

📧 Need help? [email protected]

116 changes: 116 additions & 0 deletions python/polymarket-research/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Stagehand + Browserbase: Polymarket prediction market research - See README.md for full documentation

import os
import asyncio
from dotenv import load_dotenv
from stagehand import Stagehand, StagehandConfig
from pydantic import BaseModel, Field
from typing import Optional

# Load environment variables
load_dotenv()


class MarketData(BaseModel):
"""Market data extracted from Polymarket prediction market"""
marketTitle: Optional[str] = Field(None, description="the title of the market")
currentOdds: Optional[str] = Field(None, description="the current odds or probability")
yesPrice: Optional[str] = Field(None, description="the yes price")
noPrice: Optional[str] = Field(None, description="the no price")
totalVolume: Optional[str] = Field(None, description="the total trading volume")
priceChange: Optional[str] = Field(None, description="the recent price change")


async def main():
"""
Searches Polymarket for a prediction market and extracts current odds, pricing, and volume data.
Uses AI-powered browser automation to navigate and interact with the site.
"""
print("Starting Polymarket research automation...")

# Initialize Stagehand with Browserbase for cloud-based browser automation
# Using BROWSERBASE environment to run in cloud rather than locally
config = StagehandConfig(
env="BROWSERBASE",
api_key=os.environ.get("BROWSERBASE_API_KEY"),
project_id=os.environ.get("BROWSERBASE_PROJECT_ID"),
model_name="openai/gpt-4.1",
model_api_key=os.environ.get("OPENAI_API_KEY"),
verbose=1,
# 0 = errors only, 1 = info, 2 = debug
# (When handling sensitive data like passwords or API keys, set verbose: 0 to prevent secrets from appearing in logs.)
# https://docs.stagehand.dev/configuration/logging
)

try:
# Use async context manager for automatic resource management
async with Stagehand(config) as stagehand:
print("Initializing browser session...")
print("Stagehand session started successfully")

# Provide live session URL for debugging and monitoring
session_id = None
if hasattr(stagehand, 'session_id'):
session_id = stagehand.session_id
elif hasattr(stagehand, 'browserbase_session_id'):
session_id = stagehand.browserbase_session_id

if session_id:
print(f"Watch live: https://browserbase.com/sessions/{session_id}")

page = stagehand.page

# Navigate to Polymarket
print("Navigating to: https://polymarket.com/")
await page.goto("https://polymarket.com/")
print("Page loaded successfully")

# Click the search box to trigger search dropdown
print("Clicking the search box at the top of the page")
await page.act("click the search box at the top of the page")

# Type search query
searchQuery = "Elon Musk unfollow Trump"
print(f"Typing '{searchQuery}' into the search box")
await page.act(f"type '{searchQuery}' into the search box")

# Click the first market result from the search dropdown
print("Selecting first market result from search dropdown")
await page.act("click the first market result from the search dropdown")
print("Market page loaded")

# Extract market data using AI to parse the structured information
print("Extracting market information...")
marketData = await page.extract(
"Extract the current odds and market information for the prediction market",
schema=MarketData
)

print("Market data extracted successfully:")

# Display results in formatted JSON
import json
print(json.dumps(marketData.model_dump(), indent=2))

print("Session closed successfully")

except Exception as error:
print(f"Error during market research: {error}")

# Provide helpful troubleshooting information
print("\nCommon issues:")
print("1. Check .env file has BROWSERBASE_PROJECT_ID and BROWSERBASE_API_KEY")
print("2. Verify OPENAI_API_KEY is set in environment")
print("3. Ensure internet access and https://polymarket.com is accessible")
print("4. Verify Browserbase account has sufficient credits")

raise


if __name__ == "__main__":
try:
asyncio.run(main())
except Exception as err:
print(f"Application error: {err}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some of the other python templates have a bunch of error logs to help user, can keep consistent

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

exit(1)

Loading