Python-to-JavaScript transpiler that enables Python 3 development in web browsers with full DOM integration and standard library support
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
HTTP request handling with Python-friendly interfaces for web service communication and data exchange. Brython provides a comprehensive Ajax class that wraps XMLHttpRequest with Pythonic syntax and event-driven callbacks.
Python interface to XMLHttpRequest for HTTP communications with servers and APIs.
class Ajax:
"""
HTTP request handler with event-based callbacks.
"""
def __init__(self):
"""Initialize new Ajax request object."""
def bind(self, event: str, callback: Callable) -> 'Ajax':
"""
Bind event handler to Ajax request.
Args:
event: Event type ('complete', 'error', 'timeout', 'abort')
callback: Function to call when event occurs
Returns:
Self for method chaining
Callback receives the Ajax object as parameter.
"""
def open(self, method: str, url: str, async_: bool = True) -> None:
"""
Open HTTP request.
Args:
method: HTTP method ('GET', 'POST', 'PUT', 'DELETE', etc.)
url: Target URL for request
async_: Whether request should be asynchronous
"""
def send(self, data: Any = None) -> None:
"""
Send HTTP request.
Args:
data: Data to send with request (string, dict, FormData, etc.)
"""
def set_header(self, name: str, value: str) -> None:
"""
Set HTTP request header.
Args:
name: Header name
value: Header value
"""
def set_timeout(self, timeout: int, callback: Callable = None) -> None:
"""
Set request timeout.
Args:
timeout: Timeout in milliseconds
callback: Optional timeout callback function
"""
# Response properties
text: str # Response as text
json: dict # Response parsed as JSON
status: int # HTTP status code
readyState: int # Request state (0-4)
response: Any # Raw response dataBasic Usage:
from browser.ajax import Ajax
def handle_response(req):
if req.status == 200:
print("Success:", req.text)
else:
print("Error:", req.status)
def handle_error(req):
print("Request failed")
# Create and configure request
ajax = Ajax()
ajax.bind('complete', handle_response)
ajax.bind('error', handle_error)
# Send GET request
ajax.open('GET', '/api/data')
ajax.send()Retrieve data from servers using HTTP GET method.
# GET request pattern
def get_data(url: str, callback: Callable, error_callback: Callable = None) -> Ajax:
"""
Perform GET request with callbacks.
Args:
url: URL to request
callback: Success callback function
error_callback: Error callback function
Returns:
Ajax object for further configuration
"""Usage:
from browser.ajax import Ajax
def load_user_data():
def on_success(req):
user_data = req.json
display_user(user_data)
def on_error(req):
print(f"Failed to load user: {req.status}")
ajax = Ajax()
ajax.bind('complete', on_success)
ajax.bind('error', on_error)
ajax.open('GET', '/api/user/123')
ajax.send()
# Load data with headers
def load_protected_data():
ajax = Ajax()
ajax.bind('complete', lambda req: print(req.json))
ajax.set_header('Authorization', 'Bearer token123')
ajax.open('GET', '/api/protected')
ajax.send()Send data to servers using HTTP POST method with various data formats.
# POST request patterns
def post_json(url: str, data: dict, callback: Callable) -> Ajax: ...
def post_form(url: str, form_data: dict, callback: Callable) -> Ajax: ...Usage:
from browser.ajax import Ajax
import json
def submit_form_data():
form_data = {
'name': 'John Doe',
'email': 'john@example.com',
'message': 'Hello from Brython!'
}
def on_success(req):
result = req.json
print("Form submitted:", result['id'])
ajax = Ajax()
ajax.bind('complete', on_success)
ajax.set_header('Content-Type', 'application/json')
ajax.open('POST', '/api/contact')
ajax.send(json.dumps(form_data))
def upload_file():
# File upload with FormData
from browser import document
file_input = document['file-input']
if file_input.files.length > 0:
form_data = FormData()
form_data.append('file', file_input.files[0])
form_data.append('description', 'Uploaded via Brython')
ajax = Ajax()
ajax.bind('complete', lambda req: print("Upload complete"))
ajax.open('POST', '/api/upload')
ajax.send(form_data)Advanced request configuration including headers, timeouts, and authentication.
def configure_request(ajax: Ajax) -> Ajax:
"""Configure Ajax request with common settings."""
# Headers
ajax.set_header('Content-Type', 'application/json')
ajax.set_header('Accept', 'application/json')
ajax.set_header('X-Requested-With', 'XMLHttpRequest')
# Timeout
ajax.set_timeout(5000) # 5 second timeout
return ajaxUsage:
def api_request(method, endpoint, data=None):
def on_complete(req):
if req.status >= 200 and req.status < 300:
return req.json if req.text else None
else:
print(f"API Error: {req.status}")
def on_timeout(req):
print("Request timed out")
ajax = Ajax()
ajax.bind('complete', on_complete)
ajax.bind('timeout', on_timeout)
# Set common headers
ajax.set_header('Content-Type', 'application/json')
ajax.set_header('Authorization', f'Bearer {get_auth_token()}')
# Configure timeout
ajax.set_timeout(10000) # 10 seconds
ajax.open(method, f'/api{endpoint}')
if data:
ajax.send(json.dumps(data))
else:
ajax.send()
return ajax
# Usage examples
api_request('GET', '/users')
api_request('POST', '/users', {'name': 'John', 'email': 'john@example.com'})
api_request('PUT', '/users/123', {'name': 'John Updated'})
api_request('DELETE', '/users/123')Comprehensive response processing with different data formats and error handling.
class AjaxResponse:
"""Response handling utilities."""
@staticmethod
def parse_json(req: Ajax) -> dict:
"""Parse JSON response with error handling."""
@staticmethod
def parse_xml(req: Ajax) -> Element:
"""Parse XML response."""
@staticmethod
def handle_error(req: Ajax) -> str:
"""Handle error responses with proper messaging."""Usage:
def handle_api_response(req):
"""Comprehensive response handler."""
if req.status == 200:
# Success - parse response based on content type
content_type = req.getResponseHeader('Content-Type') or ''
if 'application/json' in content_type:
try:
data = req.json
process_json_data(data)
except:
print("Invalid JSON response")
elif 'text/html' in content_type:
html_content = req.text
update_dom(html_content)
elif 'text/plain' in content_type:
text_data = req.text
display_message(text_data)
elif req.status == 400:
print("Bad Request:", req.text)
elif req.status == 401:
print("Unauthorized - please login")
redirect_to_login()
elif req.status == 404:
print("Resource not found")
elif req.status >= 500:
print("Server error:", req.status)
else:
print(f"Unexpected status: {req.status}")
def make_robust_request(url, method='GET', data=None):
"""Create request with comprehensive error handling."""
ajax = Ajax()
ajax.bind('complete', handle_api_response)
ajax.bind('error', lambda req: print("Network error occurred"))
ajax.bind('timeout', lambda req: print("Request timed out"))
ajax.bind('abort', lambda req: print("Request was aborted"))
ajax.set_timeout(15000) # 15 second timeout
ajax.open(method, url)
if data:
ajax.set_header('Content-Type', 'application/json')
ajax.send(json.dumps(data))
else:
ajax.send()
return ajaxHandle CORS (Cross-Origin Resource Sharing) requests with proper configuration.
def cors_request(url: str, method: str = 'GET',
credentials: bool = False) -> Ajax:
"""
Create CORS-enabled request.
Args:
url: Full URL including domain
method: HTTP method
credentials: Include credentials in request
Returns:
Configured Ajax object
"""Usage:
def fetch_external_api():
"""Fetch data from external API with CORS."""
def on_success(req):
api_data = req.json
print("External API data:", api_data)
def on_error(req):
if req.status == 0:
print("CORS error - check server configuration")
else:
print(f"API error: {req.status}")
ajax = Ajax()
ajax.bind('complete', on_success)
ajax.bind('error', on_error)
# CORS headers
ajax.set_header('Accept', 'application/json')
ajax.open('GET', 'https://api.external-service.com/data')
ajax.send()
def authenticated_cors_request():
"""CORS request with credentials."""
ajax = Ajax()
ajax.bind('complete', lambda req: print(req.json))
# Enable credentials for CORS
ajax.withCredentials = True
ajax.set_header('Authorization', 'Bearer token123')
ajax.open('GET', 'https://api.secure-service.com/user')
ajax.send()# Ajax event types
COMPLETE = 'complete' # Request completed (success or error)
ERROR = 'error' # Network or request error
TIMEOUT = 'timeout' # Request timed out
ABORT = 'abort' # Request was aborted
PROGRESS = 'progress' # Upload/download progress (if supported)def status_code_handler(req):
"""Handle different HTTP status codes appropriately."""
status_handlers = {
200: lambda: print("OK:", req.json),
201: lambda: print("Created:", req.json),
204: lambda: print("No Content - success"),
400: lambda: print("Bad Request:", req.text),
401: lambda: print("Unauthorized"),
403: lambda: print("Forbidden"),
404: lambda: print("Not Found"),
429: lambda: print("Rate Limited"),
500: lambda: print("Internal Server Error"),
502: lambda: print("Bad Gateway"),
503: lambda: print("Service Unavailable")
}
handler = status_handlers.get(req.status)
if handler:
handler()
else:
print(f"Unhandled status: {req.status}")This Ajax system provides comprehensive HTTP communication capabilities for Brython applications, enabling seamless integration with REST APIs, web services, and server-side endpoints using familiar Python syntax and event-driven programming patterns.
Install with Tessl CLI
npx tessl i tessl/pypi-brython