
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Revolutionary Full-Stack Python Web Framework - Write React-like components in pure Python
A modern, reactive web framework that allows developers to write both frontend and backend entirely in Python, with automatic compilation to efficient JavaScript for the browser.
PyFrame revolutionizes web development by eliminating the traditional frontend/backend divide. Write your entire application in Python - from reactive UI components to database models - and PyFrame handles the rest.
from pyframe import PyFrameApp, Component, Model, Field, FieldType
# Define your data model
class User(Model):
name: str = Field(FieldType.STRING, max_length=100)
email: str = Field(FieldType.EMAIL, unique=True)
# ↳ Automatically generates database tables, migrations, and REST APIs!
# Create reactive UI components in Python
class UserProfile(Component):
def render(self):
user = self.props.get("user")
return f"""
<div class="profile">
<h1>Welcome, {user.name}!</h1>
<p>Email: {user.email}</p>
</div>
"""
# ↳ Automatically compiles to JavaScript for the browser!
# Set up your app
app = PyFrameApp()
@app.component_route("/profile/<user_id>")
class ProfilePage(UserProfile):
pass
app.run() # 🎉 Full-stack app running!
PyFrame uses a layered architecture where each component can be used independently:
┌─────────────────────────────────────────────────────────────┐
│ 🎨 Frontend (Python → JavaScript) │
│ • Reactive components written in Python │
│ • Automatic compilation to efficient JavaScript │
│ • Client-side hydration and state management │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ ⚙️ Core Runtime │
│ • Component lifecycle management │
│ • Routing and navigation │
│ • Server-side rendering (SSR) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 🗄️ Data Layer │
│ • Model definitions with automatic migrations │
│ • Auto-generated REST/GraphQL APIs │
│ • Built-in validation and relationships │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 🔌 Plugin System │
│ • Authentication and authorization │
│ • Caching and performance optimization │
│ • Analytics and monitoring │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 🌐 Server & Deployment │
│ • Context-aware adaptive rendering │
│ • Multiple deployment targets (serverless, edge, VPS) │
│ • Development server with hot reload │
└─────────────────────────────────────────────────────────────┘
pip install pyframe-web
PyFrame includes a command-line tool to help you get started quickly:
# Create a new project
pyframe-web create my-awesome-app
cd my-awesome-app
# Install dependencies
pip install -r requirements.txt
# Run the development server
python main.py
# or
pyframe-web run
Your app will be available at http://localhost:3000
with hot reload enabled!
# app.py
from pyframe import PyFrameApp, Component, StatefulComponent
class Counter(StatefulComponent):
def __init__(self, props=None, children=None):
super().__init__(props, children)
self.set_state("count", 0)
def increment(self):
count = self.get_state("count", 0)
self.set_state("count", count + 1)
def render(self):
count = self.get_state("count", 0)
return f"""
<div>
<h1>Count: {count}</h1>
<button onclick="this.component.increment()">
Click me!
</button>
</div>
"""
app = PyFrameApp()
@app.component_route("/")
class HomePage(Counter):
pass
if __name__ == "__main__":
app.run()
python app.py
Visit http://localhost:3000
to see your reactive counter in action! 🎉
class TodoList(StatefulComponent):
def __init__(self, props=None, children=None):
super().__init__(props, children)
self.set_state("todos", [])
self.set_state("input_value", "")
def add_todo(self):
input_value = self.get_state("input_value", "")
if input_value.strip():
todos = self.get_state("todos", [])
todos.append({"id": len(todos), "text": input_value, "done": False})
self.set_state("todos", todos)
self.set_state("input_value", "")
def toggle_todo(self, todo_id):
todos = self.get_state("todos", [])
for todo in todos:
if todo["id"] == todo_id:
todo["done"] = not todo["done"]
self.set_state("todos", todos)
def render(self):
todos = self.get_state("todos", [])
input_value = self.get_state("input_value", "")
todo_items = ""
for todo in todos:
checked = "checked" if todo["done"] else ""
todo_items += f"""
<li>
<input type="checkbox" {checked}
onchange="this.component.toggle_todo({todo['id']})">
<span class="{'done' if todo['done'] else ''}">{todo['text']}</span>
</li>
"""
return f"""
<div class="todo-app">
<h1>Todo List</h1>
<div class="add-todo">
<input type="text" value="{input_value}"
placeholder="Add a todo..."
onchange="this.component.set_state('input_value', this.value)">
<button onclick="this.component.add_todo()">Add</button>
</div>
<ul class="todo-list">{todo_items}</ul>
</div>
"""
from pyframe.data.models import Model, Field, FieldType
from datetime import datetime
class User(Model):
username: str = Field(FieldType.STRING, unique=True, max_length=50)
email: str = Field(FieldType.EMAIL, unique=True)
first_name: str = Field(FieldType.STRING, max_length=50, required=False)
last_name: str = Field(FieldType.STRING, max_length=50, required=False)
is_active: bool = Field(FieldType.BOOLEAN, default=True)
created_at: datetime = Field(FieldType.DATETIME, auto_now_add=True)
class Post(Model):
title: str = Field(FieldType.STRING, max_length=200)
content: str = Field(FieldType.TEXT)
author_id: str = Field(FieldType.UUID, foreign_key="User")
published: bool = Field(FieldType.BOOLEAN, default=False)
tags: list = Field(FieldType.JSON, default=list)
# Automatically generates:
# GET /api/users - List users
# POST /api/users - Create user
# GET /api/users/:id - Get user
# PUT /api/users/:id - Update user
# DELETE /api/users/:id - Delete user
# (Same for posts)
# Use in Python:
user = User.create(username="john", email="john@example.com")
post = Post.create(title="Hello World", content="...", author_id=user.id)
class ChatRoom(StatefulComponent):
def __init__(self, props=None, children=None):
super().__init__(props, children)
self.set_state("messages", [])
self.set_state("input_value", "")
# Subscribe to real-time updates
room_id = props.get("room_id", "general")
live_sync_manager.subscribe_to_channel(f"chat:{room_id}")
def send_message(self):
input_value = self.get_state("input_value", "")
if input_value.strip():
message = ChatMessage.create(
content=input_value,
room_id=self.props.get("room_id"),
user_id=self.props.get("user_id")
)
# ↳ Automatically broadcasts to all connected clients!
self.set_state("input_value", "")
def render(self):
messages = self.get_state("messages", [])
input_value = self.get_state("input_value", "")
message_list = ""
for msg in messages:
message_list += f"""
<div class="message">
<strong>{msg['username']}:</strong> {msg['content']}
</div>
"""
return f"""
<div class="chat-room">
<div class="messages">{message_list}</div>
<div class="input-area">
<input type="text" value="{input_value}"
onchange="this.component.set_state('input_value', this.value)"
onkeypress="if(event.key==='Enter') this.component.send_message()">
<button onclick="this.component.send_message()">Send</button>
</div>
</div>
"""
from pyframe.plugins.auth_plugin import AuthPlugin, require_auth
# Configure authentication
app.register_plugin(AuthPlugin({
"jwt_secret": "your-secret-key",
"password_min_length": 8
}))
# Protected routes
@app.component_route("/dashboard")
@require_auth
class Dashboard(Component):
def render(self):
user = self.props.get("user")
return f"""
<div class="dashboard">
<h1>Welcome, {user.username}!</h1>
<p>This is your private dashboard.</p>
</div>
"""
# Login component
class LoginForm(StatefulComponent):
def __init__(self, props=None, children=None):
super().__init__(props, children)
self.set_state("username", "")
self.set_state("password", "")
self.set_state("loading", False)
async def handle_login(self):
self.set_state("loading", True)
username = self.get_state("username", "")
password = self.get_state("password", "")
# Make API call to login endpoint
response = await fetch("/auth/login", {
"method": "POST",
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"username": username, "password": password})
})
if response.ok:
# Redirect to dashboard
window.location.href = "/dashboard"
else:
self.set_state("loading", False)
# Show error message
def render(self):
username = self.get_state("username", "")
password = self.get_state("password", "")
loading = self.get_state("loading", False)
return f"""
<form class="login-form" onsubmit="this.component.handle_login(); return false;">
<h2>Login</h2>
<input type="text" placeholder="Username" value="{username}"
onchange="this.component.set_state('username', this.value)">
<input type="password" placeholder="Password" value="{password}"
onchange="this.component.set_state('password', this.value)">
<button type="submit" {'disabled' if loading else ''}>
{'Logging in...' if loading else 'Login'}
</button>
</form>
"""
Explore a complete blog application built with PyFrame:
git clone https://github.com/pyframe/pyframe.git
cd pyframe/examples/blog_app
pip install -r requirements.txt
python main.py
Visit http://localhost:3000
to see:
asyncio
- Asynchronous programmingwebsockets
- Real-time communicationwatchdog
- File system monitoringPyJWT
- JSON Web Tokens# Clone the repository
git clone https://github.com/pyframe/pyframe.git
cd pyframe
# Install dependencies
pip install -r requirements.txt
# Run tests
python -m pytest
# Run the example app
cd examples/blog_app
python main.py
PyFrame applications can be deployed anywhere Python runs:
from pyframe.deployment.wsgi import create_wsgi_app
# WSGI for Apache, Gunicorn, uWSGI
application = create_wsgi_app(app)
from pyframe.deployment.asgi import create_asgi_app
# ASGI for Uvicorn, Daphne, Hypercorn
application = create_asgi_app(app)
# AWS Lambda, Vercel, Netlify Functions
def lambda_handler(event, context):
return app.handle_serverless_request(event, context)
# Cloudflare Workers, Deno Deploy
app.configure_for_edge_deployment()
We welcome contributions! Please see our Contributing Guide for details.
MIT License - see the LICENSE file for details.
PyFrame is inspired by:
Ready to build the future of web development with Python? 🐍✨
pip install pyframe-web
FAQs
Revolutionary Full-Stack Python Web Framework - Write React-like components in pure Python
We found that pyframe-web demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.