You know the drill. You need to scrape some data, automate a workflow, or test that cursed SPA that breaks every other week. You fire up Playwright, spend 2 hours configuring Docker, another hour debugging why your bot got blocked, and then realize you need to handle CAPTCHAs. What if we just... didn't? Steel's Python SDK is browser automation for people who want to ship, not spend their weekend becoming a DevOps expert.
Installation (The Easy Part)
That's it. No Docker, no browser downloads, no "works on my machine" negative energy.
Your First Steel Session
Here's how you create a cloud browser session in just a few lines:
from steel import Steel
import os
api_key = os.getenv("STEEL_API_KEY")
client = Steel(steel_api_key=api_key)
try:
session = client.sessions.create()
print(f"Session ID: {session.id}")
print(f"Watch live at: {session.session_viewer_url}")
except Exception as e:
print(f"Error creating session: {e}")
No cap - that's a full browser running in the cloud with anti-bot protection enabled. You can literally watch it live in your browser.
Connect Your Favorite Tools
Steel provides WebSocket URLs that work with browser automation tools. Here's how to get the connection details:
import asyncio
import os
from steel import Steel
async def get_browser_connection():
api_key = os.getenv("STEEL_API_KEY")
try:
client = Steel(steel_api_key=api_key)
session = client.sessions.create()
print(f"Session ID: {session.id}")
print(f"WebSocket URL: {session.websocket_url}")
print(f"\nFor Puppeteer connection:")
print(f"browserWSEndpoint: '{session.websocket_url}'")
client.sessions.release(session.id)
except Exception as e:
print(f"Error: {e}")
asyncio.run(get_browser_connection())
Same API you know, but now it's running on infrastructure that doesn't hate you.
Real-World Examples That Actually Work
Price Monitoring (Because Everything's Expensive)
import asyncio
import os
from steel import Steel
async def check_price(product_url):
api_key = os.getenv("STEEL_API_KEY")
try:
client = Steel(steel_api_key=api_key)
session = client.sessions.create(
)
print(f"Session created: {session.id}")
print(f"WebSocket URL for browser connection: {session.websocket_url}")
price_data = {
"session_id": session.id,
"product_url": product_url,
"websocket_url": session.websocket_url,
"status": "session_ready_for_browser_connection"
}
client.sessions.release(session.id)
return price_data
except Exception as e:
print(f"Error in price monitoring: {e}")
return None
async def main():
result = await check_price("https://example.com/product")
print("Price monitoring result:", result)
asyncio.run(main())
Form Automation (For When You're Too Lazy to Click)
import asyncio
import os
from steel import Steel
async def fill_application_form(form_url, user_data):
api_key = os.getenv("STEEL_API_KEY")
try:
client = Steel(steel_api_key=api_key)
session = client.sessions.create(
timeout=3600000
)
print(f"Session created: {session.id}")
print(f"WebSocket URL: {session.websocket_url}")
print(f"Form URL to automate: {form_url}")
print(f"User data: {user_data}")
form_automation_plan = {
"session_id": session.id,
"websocket_url": session.websocket_url,
"form_url": form_url,
"automation_steps": [
f"Fill firstName with: {user_data.get('first_name', 'N/A')}",
f"Fill lastName with: {user_data.get('last_name', 'N/A')}",
f"Fill email with: {user_data.get('email', 'N/A')}",
f"Select country: {user_data.get('country', 'N/A')}",
"Submit form and wait for step-2"
]
}
client.sessions.release(session.id)
return form_automation_plan
except Exception as e:
print(f"Error in form automation: {e}")
return None
async def main():
sample_user_data = {
'first_name': 'John',
'last_name': 'Doe',
'email': 'john.doe@example.com',
'country': 'US'
}
result = await fill_application_form("https://example.com/application-form", sample_user_data)
print("Form automation result:", result)
asyncio.run(main())
The Secret Sauce: Built-in Anti-Bot Protection
Here's what you get with paid plans:
Residential proxy rotation - No more IP bans
Automatic CAPTCHA solving - For common types (sorry, no magic)
Browser fingerprint randomization - Look like a different human every time
Human-like behavior simulation - Mouse movements that don't scream "I'M A BOT"
All enabled with one flag: use_proxy=True, solve_captcha=True
Note: These features require upgrading from the hobby (free) plan. The hobby plan still gives you cloud browsers with basic anti-detection.
Session Management That Makes Sense
Sessions stick around for up to 24 hours and maintain state across requests:
try:
session = client.sessions.create(
timeout=86400000
)
print(f"Session created: {session.id}")
print(f"Session URL: {session.session_viewer_url}")
print("Browser automation would happen here...")
session_details = client.sessions.retrieve(session.id)
print(f"Status: {session_details.status}")
client.sessions.release(session.id)
print("Session released successfully")
except Exception as e:
print(f"Error in session management: {e}")
Pro tip: Use the session viewer URL to watch your automation live. It's surprisingly satisfying.
Error Handling (Because Things Break)
import asyncio
import time
import random
import os
from steel import Steel
async def scrape_the_thing(session, url):
"""Placeholder function for actual scraping logic."""
print(f"Scraping {url} using session {session.id}")
if random.random() < 0.3:
raise Exception("Simulated scraping failure")
return {"url": url, "data": "scraped_data", "session_id": session.id}
async def robust_automation(url, max_retries=3):
api_key = os.getenv("STEEL_API_KEY")
if not api_key:
raise Exception("STEEL_API_KEY environment variable is not set")
client = Steel(steel_api_key=api_key)
for attempt in range(max_retries):
session = None
try:
session = client.sessions.create()
print(f"Attempt {attempt + 1}: Created session {session.id}")
result = await scrape_the_thing(session, url)
client.sessions.release(session.id)
print(f"Success on attempt {attempt + 1}")
return result
except Exception as error:
print(f"Attempt {attempt + 1} failed: {error}")
if session:
try:
client.sessions.release(session.id)
except:
pass
if attempt < max_retries - 1:
delay = (2 ** attempt) + random.uniform(0, 1)
print(f"Waiting {delay:.2f} seconds before retry...")
await asyncio.sleep(delay)
raise Exception(f"Failed after {max_retries} attempts")
async def main():
try:
result = await robust_automation("https://example.com", max_retries=3)
print("Final result:", result)
except Exception as e:
print(f"Robust automation failed: {e}")
asyncio.run(main())
File Management (Upload/Download Vibes)
Need to handle files? We got you:
file_upload = client.sessions.files.upload(
session_id=session.id,
file=open('document.pdf', 'rb'),
path='uploads/document.pdf'
)
file_data = client.sessions.files.download(
session_id=session.id,
path='downloads/result.pdf'
)
archive = client.sessions.files.download_archive(session_id=session.id)
Quick Start for the Impatient
from steel import Steel
import os
client = Steel(steel_api_key=os.getenv("STEEL_API_KEY"))
session = client.sessions.create(
use_proxy=True,
solve_captcha=True,
block_ads=True
)
print(f"✨ Session created: {session.id}")
print(f"🔗 Watch live: {session.session_viewer_url}")
print(f"🌐 WebSocket: {session.websocket_url}")
Next Steps (Ship Something Cool)
Ready to build? Check out:
Python SDK on GitHub - All the code and examples
Steel Cookbook - Real examples that work
Discord Community - Get help, share wins
Free tier gives you 100 browser hours per month - perfect for testing and small projects.
The Bottom Line
Steel's Python SDK removes the infrastructure headaches so you can focus on building cool stuff. No Docker containers to manage, no proxy services to configure, no CAPTCHAs to solve manually.
Just pip install steel-sdk
and start automating.
Questions? Hit us up in Discord or check the docs. We're here to help you ship faster.
Ready to try it? Get your free API key and let's see what you build. 🚀