### Installing and Initializing FastApps Project (Bash) Source: https://github.com/dooilabs/fastapps_docs/blob/main/quickstart/index.mdx These commands install FastApps using uv, initialize a new project, navigate to it, and start the development server. Requires uv tool manager; outputs a running widget at a temporary public URL via cloudflared. Limitations: URL is temporary and public access is needed for testing. ```bash # 0. Install using uv uv tool install fastapps uv tool install --upgrade fastapps # Update to the latest version # 1. Create project fastapps init my-app # 2. Run cd my-app fastapps dev ``` ```bash fastapps create another-widget ``` -------------------------------- ### Install FastApps CLI and Initialize Project Source: https://context7.com/dooilabs/fastapps_docs/llms.txt Installs the FastApps command‑line tool, updates it to the latest version, creates a new FastApps project, and starts the development server with an automatic Cloudflare tunnel. These commands set up the environment required for building widgets. No additional dependencies are needed beyond uv. ```bash # Install FastApps CLI uv tool install fastapps # Update to latest version uv tool install --upgrade fastapps # Create new project fastapps init my-app # Navigate to project cd my-app # Start development server with automatic cloudflare tunnel fastapps dev ``` -------------------------------- ### Demonstrate Code Syntax Highlighting Source: https://github.com/dooilabs/fastapps_docs/blob/main/README_BLOG.md Examples of properly formatted code blocks for JavaScript and Python languages, demonstrating syntax highlighting capabilities within blog posts. Shows inline comments and function definitions for reference. ```javascript // JavaScript example const example = "Code examples use syntax highlighting"; ``` ```python # Python example def example_function(): return "Python code is also supported" ``` -------------------------------- ### Configure Navigation for Blog Posts Source: https://github.com/dooilabs/fastapps_docs/blob/main/README_BLOG.md Example configuration for adding new blog posts to the docs.json navigation file. Shows proper structure for including blog posts in the documentation navigation with groups and pages array. Must always add new posts to the end of the pages array. ```JSON { "tab": "Blog", "groups": [ { "group": "Blog", "pages": [ "blog/index", "blog/what-are-apps-in-chatgpt-and-why-they-are-the-future-of-software", "blog/inside-the-chatgpt-apps-sdk-how-it-actually-works", "blog/your-new-post" ] } ] } ``` -------------------------------- ### Complete authenticated server example Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/server-configuration/index.mdx Complete example of an authenticated FastApps server with OAuth configuration. Includes widget building, environment variable loading, and server startup. Uses uvicorn for running the application server. ```python # server/main.py import os from pathlib import Path from fastapps import WidgetBuilder, WidgetMCPServer from fastapps.cli.loader import auto_load_tools PROJECT_ROOT = Path(__file__).parent # Build all widgets builder = WidgetBuilder(PROJECT_ROOT) build_results = builder.build_all() tools = auto_load_tools(build_results) # Create authenticated server server = WidgetMCPServer( name="my-secure-widgets", widgets=tools, # OAuth Configuration auth_issuer_url=os.getenv("AUTH_ISSUER_URL"), auth_resource_server_url=os.getenv("AUTH_RESOURCE_SERVER_URL"), auth_audience=os.getenv("AUTH_AUDIENCE"), auth_required_scopes=["user"], ) app = server.get_app() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8001) ``` -------------------------------- ### Start Server with Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Runs the FastMCP server locally for testing authentication. ```bash python server/main.py ``` -------------------------------- ### Install Authentication Dependencies Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Installs required PyJWT and cryptography packages and upgrades fastmcp to ensure authentication support. ```bash pip install "PyJWT>=2.8.0" "cryptography>=41.0.0" pip install --upgrade fastmcp ``` -------------------------------- ### Premium Content Access Widget (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Creates an analytics dashboard with a freemium model. It provides different levels of access and data based on user authentication status and 'premium' scope. ```python from fastapps import BaseWidget, optional_auth, UserContext from pydantic import BaseModel class AnalyticsInput(BaseModel): pass @optional_auth(scopes=["user"]) class AnalyticsWidget(BaseWidget): identifier = "analytics" title = "Analytics Dashboard" input_schema = AnalyticsInput async def execute(self, input_data, context, user: UserContext): # Base analytics available to everyone base_analytics = await get_public_analytics() if not user.is_authenticated: # Free tier - public data only return { "tier": "free", "analytics": base_analytics, "features": ["basic_charts"], "message": "Sign in for more features" } # Standard tier - authenticated users user_analytics = await get_user_analytics(user.subject) if user.has_scope("premium"): # Premium tier - full features advanced_analytics = await get_advanced_analytics(user.subject) custom_reports = await get_custom_reports(user.subject) return { "tier": "premium", "analytics": { "base": base_analytics, "user": user_analytics, "advanced": advanced_analytics }, "custom_reports": custom_reports, "features": ["basic_charts", "advanced_charts", "export", "api_access"], "user_id": user.subject } # Standard tier return { "tier": "standard", "analytics": { "base": base_analytics, "user": user_analytics }, "features": ["basic_charts", "user_charts"], "upgrade_message": "Upgrade to premium for advanced analytics", "user_id": user.subject } ``` -------------------------------- ### Custom Deployment Widget - Configurable Search Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/mcp-integration/index.mdx Advanced widget example showing how to customize Metorial integration with specific deployment IDs and model selection. The example demonstrates parameter override capabilities and conditional model selection based on input configuration. ```python from fastapps import BaseWidget from pydantic import BaseModel, Field from server.api.metorial_mcp import call_metorial class CustomSearchInput(BaseModel): query: str = Field(..., description="Search query") use_mini: bool = Field(default=False, description="Use mini model") class CustomSearchWidget(BaseWidget): identifier = "custom-search" title = "Custom Search" input_schema = CustomSearchInput async def execute(self, input_data: CustomSearchInput, ctx): # Customize deployment and model result = await call_metorial( message=f"Find latest: {input_data.query}", deployment_id="custom_deployment_id", # Optional: override default model="gpt-4o-mini" if input_data.use_mini else "gpt-4o", max_steps=10 ) return { "query": input_data.query, "results": result } ``` -------------------------------- ### Sample OpenID Configuration JSON Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/providers/index.mdx Example of the JSON document returned by the OpenID configuration endpoint, showing issuer, authorization, token, JWKS, and registration URLs. ```json { "issuer": "https://your-oauth-provider.com", "authorization_endpoint": "...", "token_endpoint": "...", "jwks_uri": "...", "registration_endpoint": "...", ... } ``` -------------------------------- ### Basic Widget Integration - News Search Example Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/mcp-integration/index.mdx Demonstrates basic integration of Metorial MCP in a FastApps widget. The example shows how to create a simple news search widget using Pydantic models for input validation and the BaseWidget framework. Uses default deployment configuration from environment variables. ```python from fastapps import BaseWidget from pydantic import BaseModel, Field from server.api.metorial_mcp import call_metorial class NewsSearchInput(BaseModel): query: str = Field(..., description="Search query for news") class NewsSearchWidget(BaseWidget): identifier = "news-search" title = "Search News" input_schema = NewsSearchInput invoking = "Searching..." invoked = "Search complete!" async def execute(self, input_data: NewsSearchInput, ctx): # Simple usage - uses default deployment ID from environment result = await call_metorial(f"Search for: {input_data.query}") return { "query": input_data.query, "results": result } ``` -------------------------------- ### Testing Widget with MCPJam Inspector (Bash) Source: https://github.com/dooilabs/fastapps_docs/blob/main/quickstart/index.mdx Runs the MCPJam Inspector tool to test tools and UI in a controlled environment. Requires npx and @mcpjam/inspector package; inputs public URL endpoint; outputs tabs for tool calls and LLM playground. Limitations: Deterministic testing only; requires prior app run with public URL. ```bash npx @mcpjam/inspector@latest ``` -------------------------------- ### Complete User Profile Widget Example in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/user-context/index.mdx This is a full example of a FastApps widget using UserContext for authentication, user data access, and scope checks. It requires fastapps library and auth_required decorator with scopes. Outputs user profile dictionary with authentication and permission info. Assumes fetch_user_data function for database access. ```python from fastapps import BaseWidget, auth_required, UserContext @auth_required(scopes=["user"]) class UserProfileWidget(BaseWidget): identifier = "user-profile" title = "User Profile" async def execute(self, input_data, context, user: UserContext): # Check authentication status if not user.is_authenticated: return {"error": "Authentication required"} # Access user information user_id = user.subject email = user.claims.get('email') name = user.claims.get('name') picture = user.claims.get('picture') # Check permissions is_premium = user.has_scope("premium") is_admin = user.has_scope("admin") # Fetch user data from your database user_data = await fetch_user_data(user_id) return { "user_id": user_id, "email": email, "name": name, "picture": picture, "is_premium": is_premium, "is_admin": is_admin, "profile": user_data, "scopes": user.scopes } ``` -------------------------------- ### Multi-organization support (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Widget demonstrating multi-organization membership checks. Requires user authentication and verifies organization membership via custom claim. Returns organization-specific data and user role. ```python from fastapps import BaseWidget, auth_required, UserContext from pydantic import BaseModel, Field class OrgDataInput(BaseModel): organization_id: str = Field(..., description="Organization ID") @auth_required(scopes=["user"]) class OrganizationDataWidget(BaseWidget): identifier = "org-data" title = "Organization Data" input_schema = OrgDataInput async def execute(self, input_data, context, user: UserContext): # Get user's organizations from custom claim user_orgs = user.claims.get('https://example.com/organizations', []) # Check if user belongs to requested organization if input_data.organization_id not in user_orgs: return { "error": "Access denied", "message": "You don't belong to this organization" } # Fetch organization data org_data = await fetch_org_data(input_data.organization_id) # Check user's role in this organization org_role = await get_user_org_role( user.subject, input_data.organization_id ) return { "organization": org_data, "role": org_role, "user_id": user.subject, "organizations": user_orgs } ``` -------------------------------- ### Implementing Widget Backend Logic (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/quickstart/index.mdx Defines the backend for a widget using FastApps BaseWidget, including input schema with Pydantic, execution logic, and CSP configuration. Depends on fastapps and pydantic libraries; inputs are validated via MyWidgetInput model; outputs a dictionary with processed data. Limitations: Async execution required; custom APIs need CSP updates. ```python from fastapps import BaseWidget, Field, ConfigDict from pydantic import BaseModel from typing import Dict, Any class MyWidgetInput(BaseModel): model_config = ConfigDict(populate_by_name=True) name: str = Field(default="World") class MyWidgetTool(BaseWidget): identifier = "my-widget" title = "My Widget" input_schema = MyWidgetInput invoking = "Processing..." invoked = "Done!" widget_csp = { "connect_domains": [], # APIs you'll call "resource_domains": [] # Images/fonts you'll use } async def execute(self, input_data: MyWidgetInput) -> Dict[str, Any]: # Your logic here return { "name": input_data.name, "message": f"Hello, {input_data.name}!" } ``` -------------------------------- ### Create a widget in React with FastApps Source: https://github.com/dooilabs/fastapps_docs/blob/main/what-is-fastapps/index.mdx Shows how to create a simple React widget for FastApps. The widget is a basic React component that can be displayed in the ChatGPT app. Requires React to be installed. ```javascript import React from 'react'; export default function HelloWidget() { return (

Hello world!

); } ``` -------------------------------- ### Authentication Decorator Usage Examples Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Shows correct and incorrect ways to import and apply the @auth_required decorator in FastMCP widgets. ```python # ✅ Correct from fastapps import auth_required @auth_required(scopes=["user"]) class MyWidget(BaseWidget): pass # ❌ Wrong syntax @auth_required["user"] # Wrong syntax class MyWidget(BaseWidget): pass # ❌ Wrong import from fastapps import auth # Missing _required ``` -------------------------------- ### Deploy FastApps project to cloud with Bash Source: https://context7.com/dooilabs/fastapps_docs/llms.txt Bash commands for deploying FastApps projects to the FastApps Cloud with automatic validation and custom subdomain assignment. The deployment process includes project validation, React widget building, server code packaging, and Vercel deployment. Requires the FastApps CLI to be installed. ```bash # Login to FastApps Cloud fastapps cloud login # Deploy your project fastapps cloud deploy # The deployment process automatically: # 1. Validates project structure # 2. Builds React widgets to static HTML # 3. Packages server code # 4. Deploys to Vercel serverless infrastructure # 5. Assigns custom *.dooi.app subdomain ``` -------------------------------- ### Configure Environment Variables - Metorial Setup Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/mcp-integration/index.mdx Sets up required environment variables for Metorial integration. These variables are essential for authentication and deployment configuration. The .env file should be placed in the project root directory and contains API keys and deployment identifiers. ```bash # .env METORIAL_API_KEY=your_metorial_api_key OPENAI_API_KEY=your_openai_api_key METORIAL_DEPLOYMENT_ID=your_deployment_id ``` -------------------------------- ### Build Personalized Content widget with optional authentication (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Implements a content widget that works with optional authentication, providing full content and personalization for authenticated users and a preview for anonymous visitors. Uses the optional_auth decorator and accesses user preferences, recommendations, and view history when available. Relies on FastApps BaseWidget and various content-fetching utilities. ```Python from fastapps import BaseWidget, optional_auth, UserContext\nfrom pydantic import BaseModel, Field\n\nclass ContentInput(BaseModel):\n content_id: str = Field(..., description=\"Content ID to fetch\")\n\n@optional_auth(scopes=[\"user\"])\nclass PersonalizedContentWidget(BaseWidget):\n identifier = \"personalized-content\"\n title = \"Personalized Content\"\n input_schema = ContentInput\n \n async def execute(self, input_data, context, user: UserContext):\n # Fetch base content\n content = await fetch_content(input_data.content_id)\n \n if user.is_authenticated:\n # Authenticated: full content + personalization\n user_preferences = await get_preferences(user.subject)\n recommendations = await get_recommendations(user.subject)\n view_history = await get_view_history(user.subject)\n \n # Track view\n await track_view(user.subject, input_data.content_id)\n \n return {\n \"content\": content,\n \"full_access\": True,\n \"preferences\": user_preferences,\n \"recommendations\": recommendations,\n \"history\": view_history,\n \"user_id\": user.subject\n }\n \n # Anonymous: preview only\n return {\n \"content\": content[:500] + \"...\", # Preview\n \"full_access\": False,\n \"message\": \"Sign in for full access and personalized recommendations\"\n } ``` -------------------------------- ### Verify OpenID configuration via curl Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Command line tool to check OpenID Connect configuration endpoint. Validates issuer URL and required endpoints. Requires jq for JSON parsing. Essential for troubleshooting authentication setup. ```bash curl https://your-tenant.auth0.com/.well-known/openid-configuration | jq ``` -------------------------------- ### Create FastApps Widget with Bash Source: https://github.com/dooilabs/fastapps_docs/blob/main/widgets/index.mdx This Bash command creates a new FastApps widget project by scaffolding the directory structure with server and widget components. It requires the FastApps CLI to be installed and configured. Input: Widget name (e.g., mywidget). Output: Generated project files including Python backend and React frontend. Limitations: Generates boilerplate only; custom logic must be added manually. ```bash fastapps create mywidget ``` -------------------------------- ### Implementing Widget Frontend UI (JSX) Source: https://github.com/dooilabs/fastapps_docs/blob/main/quickstart/index.mdx Renders the widget UI using React and FastApps hooks to access props from backend. Depends on React and fastapps libraries; inputs props include name and message; outputs a styled div with greeting. Limitations: Styles are inline; no additional state management shown. ```jsx import React from 'react'; import { useWidgetProps } from 'fastapps'; export default function MyWidget() { const props = useWidgetProps(); return (

{props.message}

Welcome, {props.name}!

); } ``` -------------------------------- ### Add Blog Post to Index in MDX Source: https://github.com/dooilabs/fastapps_docs/blob/main/README_BLOG.md MDX code snippet for adding a new blog post to the index. Includes HTML structure with classes for styling and metadata. Requires proper image paths and post details. ```mdx
Category Type

Your Post Title

Your post description here...

FastApps Team DD MMM YYYY
Read more
Your Post Title
``` -------------------------------- ### Document access control (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Widget for controlling document access by user and organization. Requires authentication with read:documents scope. Implements organization checks, ownership verification, and permission evaluation. ```python from fastapps import BaseWidget, auth_required, UserContext from pydantic import BaseModel, Field class DocumentInput(BaseModel): document_id: str = Field(..., description="Document ID to access") @auth_required(scopes=["user", "read:documents"]) class DocumentWidget(BaseWidget): identifier = "document-viewer" title = "Document Viewer" input_schema = DocumentInput async def execute(self, input_data, context, user: UserContext): # Fetch document document = await fetch_document(input_data.document_id) if not document: return {"error": "Document not found"} # Check if user has access user_org = user.claims.get('https://example.com/organization') if document.organization != user_org: return { "error": "Access denied", "message": "This document belongs to another organization" } # Check if user is document owner or has read permission is_owner = document.owner_id == user.subject has_read = user.has_scope("read:documents") if not (is_owner or has_read): return { "error": "Access denied", "message": "You don't have permission to view this document" } # Check write permission for editing can_edit = is_owner or user.has_scope("write:documents") can_delete = is_owner or user.has_scope("delete:documents") # Log access await log_document_access(user.subject, input_data.document_id, "read") return { "document": document, "permissions": { "read": True, "edit": can_edit, "delete": can_delete }, "user_id": user.subject, "is_owner": is_owner } ``` -------------------------------- ### Role-Based Dashboard Widget (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Implements a dashboard that displays different views based on the authenticated user's role (admin, manager, or user). It uses 'auth_required' decorator and retrieves role information from user claims. ```python from fastapps import BaseWidget, auth_required, UserContext from pydantic import BaseModel class DashboardInput(BaseModel): pass @auth_required(scopes=["user"]) class RoleBasedDashboardWidget(BaseWidget): identifier = "dashboard" title = "Dashboard" input_schema = DashboardInput async def execute(self, input_data, context, user: UserContext): # Get role from custom claims role = user.claims.get('role', 'user') if role == 'admin': return await self._admin_view(user) elif role == 'manager': return await self._manager_view(user) else: return await self._user_view(user) async def _admin_view(self, user: UserContext): return { "view": "admin", "data": await get_all_data(), "users": await get_all_users(), "analytics": await get_full_analytics(), "permissions": ["read", "write", "delete", "manage_users"] } async def _manager_view(self, user: UserContext): team_id = user.claims.get('team_id') return { ``` -------------------------------- ### Create User Profile widget displaying authenticated user data (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Defines a user profile widget that requires the "user" scope. It extracts user information from the token, fetches additional data from the database, and returns a comprehensive profile object. Depends on FastApps BaseWidget, auth_required decorator, and user data retrieval functions. ```Python from fastapps import BaseWidget, auth_required, UserContext\nfrom pydantic import BaseModel\n\nclass UserProfileInput(BaseModel):\n pass\n\n@auth_required(scopes=[\"user\"])\nclass UserProfileWidget(BaseWidget):\n identifier = \"user-profile\"\n title = \"User Profile\"\n input_schema = UserProfileInput\n \n async def execute(self, input_data, context, user: UserContext):\n # Get user information from token\n user_id = user.subject\n email = user.claims.get(\'email\')\n name = user.claims.get(\'name\')\n picture = user.claims.get(\'picture\')\n \n # Fetch additional user data from database\n user_data = await fetch_user_from_db(user_id)\n preferences = await fetch_user_preferences(user_id)\n \n return {\n \"user_id\": user_id,\n \"email\": email,\n \"name\": name,\n \"picture\": picture,\n \"joined_date\": user_data.created_at,\n \"preferences\": preferences,\n \"is_premium\": user.has_scope(\"premium\"),\n \"scopes\": user.scopes\n } ``` -------------------------------- ### HTTPS URL Configuration in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/advanced/index.mdx Demonstrates proper HTTPS URL setup for authentication resources in MCP servers. This ensures secure communication by avoiding plaintext HTTP. No external dependencies required. Input is URL string, output is configured server. ```python # ✅ Good auth_resource_server_url="https://yourdomain.com/mcp" ``` ```python # ❌ Bad auth_resource_server_url="http://yourdomain.com/mcp" ``` -------------------------------- ### Public search with user history (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Implements a public search widget that tracks history for authenticated users. Uses optional authentication with user scopes. Returns different responses for authenticated vs anonymous users with personalized results. ```python from fastapps import BaseWidget, optional_auth, UserContext from pydantic import BaseModel, Field class SearchInput(BaseModel): query: str = Field(..., description="Search query") @optional_auth(scopes=["user"]) class PublicSearchWidget(BaseWidget): identifier = "public-search" title = "Search" input_schema = SearchInput async def execute(self, input_data, context, user: UserContext): # Perform search (available to everyone) results = await search_database(input_data.query) if user.is_authenticated: # Save search history for authenticated users await save_search_history(user.subject, input_data.query) # Get user's search history history = await get_search_history(user.subject) # Personalize results results = await personalize_results(results, user.subject) return { "query": input_data.query, "results": results, "personalized": True, "history": history, "user_id": user.subject } # Anonymous search return { "query": input_data.query, "results": results, "personalized": False, "message": "Sign in to save your search history" } ``` -------------------------------- ### Async API Integration - Python External Services Source: https://context7.com/dooilabs/fastapps_docs/llms.txt Shows async/await patterns for integrating external APIs and databases. Dependencies include aiohttp for HTTP requests and asyncpg for PostgreSQL. Handles API responses with error checking and transforms results to dictionary format. Includes examples for weather API calls and database query execution with connection management. ```python from fastapps import BaseWidget from pydantic import BaseModel import aiohttp import asyncpg class WeatherInput(BaseModel): city: str units: str = "metric" class WeatherWidget(BaseWidget): identifier = "weather" title = "Weather Forecast" input_schema = WeatherInput invoking = "Fetching weather data..." invoked = "Weather forecast ready!" widget_csp = { "connect_domains": ["api.openweathermap.org"] } async def execute(self, inputs: WeatherInput, ctx) -> dict: api_key = ctx.settings.get("OPENWEATHER_API_KEY") async with aiohttp.ClientSession() as session: url = f"https://api.openweathermap.org/data/2.5/weather" params = { "q": inputs.city, "units": inputs.units, "appid": api_key } async with session.get(url, params=params) as response: if response.status == 200: data = await response.json() return { "city": data["name"], "temperature": data["main"]["temp"], "description": data["weather"][0]["description"], "humidity": data["main"]["humidity"], "wind_speed": data["wind"]["speed"] } else: return { "error": f"API error: {response.status}", "city": inputs.city } # Database integration example class DatabaseQueryWidget(BaseWidget): identifier = "db-query" title = "Database Query" input_schema = QueryInput invoking = "Querying database..." invoked = "Query complete!" async def execute(self, inputs: QueryInput, ctx) -> dict: db_url = ctx.settings.get("DATABASE_URL") conn = await asyncpg.connect(db_url) try: rows = await conn.fetch( "SELECT * FROM users WHERE active = $1 LIMIT $2", True, inputs.limit ) users = [dict(row) for row in rows] return { "users": users, "count": len(users) } finally: await conn.close() ``` -------------------------------- ### Implement Admin Dashboard widget with admin scope (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/examples/index.mdx Creates an admin dashboard widget that requires the "admin" scope. It validates the user's admin rights, fetches administrative statistics, user lists, and recent activity, then returns them. Requires FastApps BaseWidget, auth_required decorator, and asynchronous data-fetching functions. ```Python from fastapps import BaseWidget, auth_required, UserContext\nfrom pydantic import BaseModel\n\nclass AdminDashboardInput(BaseModel):\n pass\n\n@auth_required(scopes=[\"admin\"])\nclass AdminDashboardWidget(BaseWidget):\n identifier = \"admin-dashboard\"\n title = \"Admin Dashboard\"\n input_schema = AdminDashboardInput\n \n async def execute(self, input_data, context, user: UserContext):\n # Double-check admin scope\n if not user.has_scope(\"admin\"):\n return {\n \"error\": \"Admin access required\",\n \"message\": \"Contact your administrator for access\"\n }\n \n # Fetch admin statistics\n stats = await get_admin_stats()\n users = await get_user_list()\n activity = await get_recent_activity()\n \n return {\n \"admin\": user.subject,\n \"admin_email\": user.claims.get(\'email\'),\n \"stats\": stats,\n \"users\": users,\n \"activity\": activity,\n \"permissions\": user.scopes\n } ``` -------------------------------- ### Configure WidgetMCPServer with OAuth Authentication in Python Source: https://context7.com/dooilabs/fastapps_docs/llms.txt This code sets up a WidgetMCPServer instance with OAuth 2.1 configuration, specifying issuer URL, resource server, audience, required scopes, and optional JWKS endpoint. It requires the fastapps library and supports providers like Auth0, Okta, Azure AD, AWS Cognito, Clerk. The server runs when the script is executed directly. Inputs include widget tools and auth parameters; outputs a running server. Limitations: Auto-discovery of JWKS if not provided; assumes valid OAuth provider setup. ```python # Configure server with OAuth authentication server = WidgetMCPServer( name="my-widgets", widgets=tools, # OAuth 2.1 configuration (Auth0 example) auth_issuer_url="https://tenant.auth0.com", auth_resource_server_url="https://my-app.example.com/mcp", auth_audience="https://api.example.com", auth_required_scopes=["user"], # Default scopes for all widgets # Optional: Custom JWKS endpoint (auto-discovered if not provided) auth_jwks_url="https://tenant.auth0.com/.well-known/jwks.json" ) # Run the server if __name__ == "__main__": server.run() ``` -------------------------------- ### Execute GraphQL Queries using aiohttp in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/integration/index.mdx Provides a FastApps widget that sends a GraphQL query to retrieve user data. The example builds the query string, sets variables, and posts the request via aiohttp, handling errors and returning the user object along with the executed query details. Requires aiohttp and FastApps BaseWidget. ```python import aiohttp from fastapps import BaseWidget class GraphQLWidget(BaseWidget): identifier = "graphql" title = "GraphQL Widget" input_schema = GraphQLInput invoking = "Querying GraphQL API…" invoked = "Query executed!" async def execute(self, inputs: GraphQLInput, ctx): query = """ query GetUserData($userId: ID!) { user(id: $userId) { id name email posts { id title content createdAt } } } """ variables = {"userId": inputs.user_id} payload = { "query": query, "variables": variables } async with aiohttp.ClientSession() as session: async with session.post( "https://api.example.com/graphql", json=payload, headers={"Content-Type": "application/json"} ) as response: result = await response.json() if "errors" in result: raise Exception(f"GraphQL errors: {result['errors']}") return { "user": result["data"]["user"], "query": query, "variables": variables } ``` -------------------------------- ### Creating Custom Convenience Hooks in FastApps Source: https://github.com/dooilabs/fastapps_docs/blob/main/widgets/react-hooks/index.mdx Shows how to create custom hooks in FastApps to simplify access to frequently used global variables provided by `useOpenAiGlobal`. Examples include creating hooks for theme, tool input, and locale. ```tsx import { useOpenAiGlobal } from 'fastapps'; // Custom hook for theme export function useTheme() { return useOpenAiGlobal('theme'); } // Custom hook for tool input export function useToolInput() { return useOpenAiGlobal('toolInput') as T | null; } // Custom hook for locale export function useLocale() { return useOpenAiGlobal('locale'); } ``` -------------------------------- ### Enable Debug Logging for Authentication Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Configures Python logging to DEBUG and initializes the WidgetMCPServer with authentication parameters to trace the authentication flow. ```python import logging logging.basicConfig(level=logging.DEBUG) server = WidgetMCPServer( name="my-widgets", widgets=, auth_issuer_url="https://tenant.auth0.com", auth_resource_server_url="https://example.com/mcp", auth_required_scopes=["user"], ) ``` -------------------------------- ### Configure FastApps server with WidgetMCPServer (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/providers/index.mdx Creates a WidgetMCPServer instance to serve widgets, specifying server name, widget list, and Cognito authentication parameters. Requires the WidgetMCPServer class and a list of widget tools. Returns a configured server object ready to run. ```python server = WidgetMCPServer( name="my-widgets", widgets=tools, auth_issuer_url="https://cognito-idp.{region}.amazonaws.com/{user-pool-id}", auth_resource_server_url="https://yourdomain.com/mcp", auth_audience="{app-client-id}", auth_required_scopes=["user"], ) ``` -------------------------------- ### Expose Server via Ngrok Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Creates a publicly accessible tunnel to the local server on port 8001 for ChatGPT to reach the widgets. ```bash ngrok http 8001 ``` -------------------------------- ### Create authenticated server with OAuth 2.1 Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/server-configuration/index.mdx Creates a WidgetMCPServer instance with OAuth 2.1 authentication parameters. Requires auth_issuer_url and auth_resource_server_url to enable authentication. Dependencies: fastapps, fastapps.cli.loader. Uses auto-loaded tools from widget builds. ```python from fastapps import WidgetBuilder, WidgetMCPServer from fastapps.cli.loader import auto_load_tools # Build widgets builder = WidgetBuilder(PROJECT_ROOT) build_results = builder.build_all() tools = auto_load_tools(build_results) # Create server with authentication server = WidgetMCPServer( name="my-widgets", widgets=tools, auth_issuer_url="https://tenant.auth0.com", auth_resource_server_url="https://example.com/mcp", auth_required_scopes=["user"], ) app = server.get_app() ``` -------------------------------- ### CORS Middleware Setup in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/advanced/index.mdx Configures CORS for secure cross-origin requests using Starlette middleware. Allows specific origins and methods. Inputs app from server, outputs configured app with CORS. ```python from starlette.middleware.cors import CORSMiddleware app = server.get_app() app.add_middleware( CORSMiddleware, allow_origins=["https://chatgpt.com"], # Specific origins allow_methods=["POST", "GET"], # Specific methods allow_headers=["Authorization"], # Specific headers allow_credentials=True, ) ``` -------------------------------- ### Print server authentication configuration Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/troubleshooting/index.mdx Display current server authentication settings for verification. Shows issuer URL, resource server URL, and required scopes. Useful for confirming runtime configuration matches expected values. ```python # Print server configuration print(f"Auth Issuer: {server.mcp._mcp_server.auth_issuer_url}") print(f"Resource Server: {server.mcp._mcp_server.auth_resource_server_url}") print(f"Required Scopes: {server.mcp._mcp_server.auth_required_scopes}") ``` -------------------------------- ### Get OAuth Client ID in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/user-context/index.mdx This code accesses the OAuth client ID from UserContext. It uses the client_id property for logging access. Outputs the client ID string. Requires authenticated user with valid client ID. ```python client = user.client_id log_access(client_id=client, user_id=user.subject) ``` -------------------------------- ### Generate Metorial Integration - FastApps CLI Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/mcp-integration/index.mdx Uses FastApps CLI to generate the Metorial integration file. This command creates a metorial_mcp.py file under the /api folder and sets up the basic integration structure. Requires FastApps CLI to be installed and configured. ```bash fastapps use metorial ``` -------------------------------- ### Create MCP Tool Backend Source: https://github.com/dooilabs/fastapps_docs/blob/main/index.mdx Defines a simple widget backend using FastApps with Pydantic models. The tool accepts an input name and returns a greeting message. Requires FastApps and Pydantic dependencies. Output is a dictionary containing the response message. ```python from fastapps import BaseWidget, Field, ConfigDict from pydantic import BaseModel from typing import Dict, Any class MyWidgetInput(BaseModel): model_config = ConfigDict(populate_by_name=True) name: str = Field(default="World") class MyWidgetTool(BaseWidget): identifier = "my-widget" title = "My Widget" input_schema = MyWidgetInput invoking = "Processing..." invoked = "Done!" async def execute(self, input_data: MyWidgetInput) -> Dict[str, Any]: return {"message": f"Hello, {input_data.name}!"} ``` -------------------------------- ### Handle Configurations in Python Widgets Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/integration/index.mdx This widget manages settings like API timeouts, retries, and feature flags from context. It switches logic based on feature flags, using new or old API implementations. Configurable via settings with defaults provided. ```python from fastapps import BaseWidget class ConfigurableWidget(BaseWidget): identifier = "configurable" title = "Configurable Widget" input_schema = ConfigurableInput invoking = "Processing with configuration…" invoked = "Processing complete!" async def execute(self, inputs: ConfigurableInput, ctx): # Get configuration from settings config = { "api_timeout": ctx.settings.get("API_TIMEOUT", 30), "max_retries": ctx.settings.get("MAX_RETRIES", 3), "cache_ttl": ctx.settings.get("CACHE_TTL", 3600), "feature_flags": ctx.settings.get("FEATURE_FLAGS", {}), "api_endpoints": ctx.settings.get("API_ENDPOINTS", {}) } # Use configuration in your logic if config["feature_flags"].get("new_api", False): result = await self.use_new_api(inputs, config) else: result = await self.use_old_api(inputs, config) return { "result": result, "config_used": config, "feature_flags": config["feature_flags"] } async def use_new_api(self, inputs, config): # Implementation using new API pass async def use_old_api(self, inputs, config): # Implementation using old API pass ``` -------------------------------- ### Implement BaseWidget class in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/index.mdx Defines a custom widget by inheriting from BaseWidget in FastApps. Includes required attributes like identifier, title, and input_schema, along with optional ones such as description and widget_accessible. The execute method contains the business logic and returns structured data. ```python class MyWidget(BaseWidget): # Required attributes identifier = "my_widget" # Unique identifier title = "My Widget Title" # Display name input_schema = MyInputModel # Pydantic model invoking = "Setting up widget…" # Progress message invoked = "Widget ready!" # Completion message # Optional attributes description = "Widget description" # Help text widget_accessible = True # Allow component calls def execute(self, inputs, ctx): # Your business logic here return {"data": "processed"} ``` -------------------------------- ### Configure FastApps server using environment variables (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/providers/index.mdx Loads environment variables via python-dotenv and configures a WidgetMCPServer using those values, enabling secure external configuration. Requires os, dotenv, and WidgetMCPServer. ```python import os from dotenv import load_dotenv load_dotenv() server = WidgetMCPServer( name="my-widgets", widgets=tools, auth_issuer_url=os.getenv("AUTH_ISSUER_URL"), auth_resource_server_url=os.getenv("AUTH_RESOURCE_SERVER_URL"), _audience=os.getenv("AUTH_AUDIENCE"), auth_required_scopes=["user"], ) ``` -------------------------------- ### Get User Subject Identifier in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/user-context/index.mdx This code retrieves the user identifier from the JWT sub claim. It uses the subject property of UserContext. Outputs the user ID string for fetching additional data. Assumes user is authenticated; returns None if not. ```python user_id = user.subject # e.g., "auth0|123456" user_data = fetch_user_data(user_id) ``` -------------------------------- ### Logging Authentication Events in Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/advanced/index.mdx Logs access to sensitive data for auditing purposes using logging module. Applies in sensitive widget execute. Inputs user and action, outputs logged event and data. Limitations: Requires logging setup. ```python import logging @auth_required class SensitiveWidget(BaseWidget): async def execute(self, input_data, context, user: UserContext): # Log access for audit trail logging.info( f"Sensitive data accessed: user={user.subject}, " f"action={input_data.action}, " f"timestamp={datetime.utcnow()}" ) return {"data": "..."} ``` -------------------------------- ### Send follow-up messages to ChatGPT conversation in TSX Source: https://github.com/dooilabs/fastapps_docs/blob/main/widgets/advanced-patterns/index.mdx Widgets can inject follow-up messages into the ongoing ChatGPT dialogue using window.openai.sendFollowUpMessage. Inputs are message prompts; outputs trigger conversational updates seamlessly. Requires widget setup and may depend on conversation context. ```tsx export default function InteractiveWidget() { const props = useWidgetProps(); const handleAskMore = async (item) => { await window.openai.sendFollowUpMessage({ prompt: `Tell me more about ${item.name}` }); }; return (
{props.items.map((item) => (

{item.name}

))}
); } ``` -------------------------------- ### Configure FastApps MCP Server with Okta using Python Source: https://github.com/dooilabs/fastapps_docs/blob/main/auth/providers/index.mdx This code snippet sets up a WidgetMCPServer for OAuth authentication with Okta. It depends on the FastApps library, accepts auth_issuer_url, auth_resource_server_url, and scopes, and returns a configured server. Note: Limited to Okta authorization server setup. ```python server = WidgetMCPServer( name="my-widgets", widgets=tools, auth_issuer_url="https://dev-12345.okta.com/oauth2/default", auth_resource_server_url="https://yourdomain.com/mcp", auth_required_scopes=["user"], ) ``` -------------------------------- ### Use useWidgetProps Hook in React (TypeScript) Source: https://github.com/dooilabs/fastapps_docs/blob/main/widgets/react-hooks/index.mdx This example demonstrates how to retrieve widget properties provided by the MCP tool using the useWidgetProps hook. It imports the hook, defines a TypeScript interface for the expected props, and renders the data in a React component. Works in the FastApps environment and requires the fastapps package. ```tsx import { useWidgetProps } from 'fastapps'; interface MyWidgetProps { message: string; count: number; items: string[]; } export default function MyWidget() { const props = useWidgetProps(); return (

{props.message}

Count: {props.count}

    {props.items.map((item) => (
  • {item}
  • ))}
); } ``` -------------------------------- ### Async Concurrently Fetch Weather Data (Python) Source: https://github.com/dooilabs/fastapps_docs/blob/main/server/advanced/index.mdx Demonstrates using asyncio/aiohttp with BaseWidget to fetch multiple weather sources concurrently for a city. Aggregates results and returns combined weather summary. Dependencies: fastapps, aiohttp, and a custom WeatherInput schema. ```python import asyncio import aiohttp from fastapps import BaseWidget class AsyncWeatherWidget(BaseWidget): identifier = "async_weather" title = "Async Weather Widget" input_schema = WeatherInput invoking = "Fetching weather data…" invoked = "Weather data ready!" async def execute(self, inputs: WeatherInput, ctx): async with aiohttp.ClientSession() as session: # Fetch multiple weather sources concurrently tasks = [ self.fetch_weather(session, inputs.city, "openweather"), self.fetch_weather(session, inputs.city, "weather_api"), self.fetch_weather(session, inputs.city, "accuweather") ] results = await asyncio.gather(*tasks, return_exceptions=True) return { "city": inputs.city, "sources": len([r for r in results if not isinstance(r, Exception)]), "weather": self.merge_weather_data(results) } async def fetch_weather(self, session, city, provider): # Implementation details... pass ``` -------------------------------- ### Generate New FastApps Widget Source: https://context7.com/dooilabs/fastapps_docs/llms.txt Creates scaffolding for a new widget named "my-widget", generating both the Python backend tool and the React frontend component. This command accelerates development by providing ready‑made file structures. It requires an initialized FastApps project. ```bash # Create a new widget named "my-widget" fastapps create my-widget ```