Spaces:
Sleeping
Sleeping
| """ | |
| Notion API simulator. | |
| Provides realistic mock responses for Notion API actions. | |
| """ | |
| from typing import Optional | |
| from .base import BaseSimulator | |
| from datetime import datetime | |
| import uuid | |
| class NotionSimulator(BaseSimulator): | |
| """Simulator for Notion API.""" | |
| def __init__(self): | |
| super().__init__('notion') | |
| def load_mock_responses(self): | |
| """Load Notion mock response templates.""" | |
| self.mock_responses = { | |
| 'create_page': self._create_page_template, | |
| 'read_database': self._read_database_template, | |
| 'update_page': self._update_page_template, | |
| 'get_page': self._get_page_template, | |
| 'query_database': self._query_database_template, | |
| 'create_database': self._create_database_template, | |
| } | |
| def get_required_permissions(self, action: str) -> set[str]: | |
| """Get required Notion permissions for an action.""" | |
| permissions_map = { | |
| 'create_page': {'pages:write'}, | |
| 'read_database': {'databases:read'}, | |
| 'update_page': {'pages:write'}, | |
| 'get_page': {'pages:read'}, | |
| 'query_database': {'databases:read'}, | |
| 'create_database': {'databases:write'}, | |
| } | |
| return permissions_map.get(action, set()) | |
| def validate_params(self, action: str, params: dict) -> tuple[bool, Optional[str]]: | |
| """Validate parameters for Notion actions.""" | |
| if action == 'create_page': | |
| required = {'parent'} | |
| missing = required - set(params.keys()) | |
| if missing: | |
| return False, f"Missing required parameters: {missing}" | |
| if 'database_id' not in params['parent'] and 'page_id' not in params['parent']: | |
| return False, "Parent must contain either database_id or page_id" | |
| elif action == 'read_database': | |
| required = {'database_id'} | |
| missing = required - set(params.keys()) | |
| if missing: | |
| return False, f"Missing required parameters: {missing}" | |
| elif action == 'update_page': | |
| required = {'page_id'} | |
| missing = required - set(params.keys()) | |
| if missing: | |
| return False, f"Missing required parameters: {missing}" | |
| elif action == 'get_page': | |
| required = {'page_id'} | |
| missing = required - set(params.keys()) | |
| if missing: | |
| return False, f"Missing required parameters: {missing}" | |
| elif action == 'query_database': | |
| required = {'database_id'} | |
| missing = required - set(params.keys()) | |
| if missing: | |
| return False, f"Missing required parameters: {missing}" | |
| elif action == 'create_database': | |
| required = {'parent', 'title', 'properties'} | |
| missing = required - set(params.keys()) | |
| if missing: | |
| return False, f"Missing required parameters: {missing}" | |
| else: | |
| return False, f"Unknown action: {action}" | |
| return True, None | |
| def generate_mock_response(self, action: str, params: dict) -> dict: | |
| """Generate realistic Notion API response.""" | |
| if action not in self.mock_responses: | |
| raise ValueError(f"Unknown action: {action}") | |
| template_func = self.mock_responses[action] | |
| return template_func(params) | |
| def _generate_id(self) -> str: | |
| """Generate a Notion-style UUID.""" | |
| return str(uuid.uuid4()) | |
| def _create_page_template(self, params: dict) -> dict: | |
| """Mock response for creating a page.""" | |
| page_id = self._generate_id() | |
| now = datetime.utcnow().isoformat() + "Z" | |
| return { | |
| "object": "page", | |
| "id": page_id, | |
| "created_time": now, | |
| "last_edited_time": now, | |
| "created_by": { | |
| "object": "user", | |
| "id": self._generate_id() | |
| }, | |
| "last_edited_by": { | |
| "object": "user", | |
| "id": self._generate_id() | |
| }, | |
| "cover": params.get('cover'), | |
| "icon": params.get('icon'), | |
| "parent": params['parent'], | |
| "archived": False, | |
| "properties": params.get('properties', { | |
| "title": { | |
| "id": "title", | |
| "type": "title", | |
| "title": [ | |
| { | |
| "type": "text", | |
| "text": { | |
| "content": "New Page", | |
| "link": None | |
| } | |
| } | |
| ] | |
| } | |
| }), | |
| "url": f"https://www.notion.so/{page_id.replace('-', '')}" | |
| } | |
| def _read_database_template(self, params: dict) -> dict: | |
| """Mock response for reading a database.""" | |
| database_id = params['database_id'] | |
| return { | |
| "object": "database", | |
| "id": database_id, | |
| "created_time": "2025-11-01T00:00:00.000Z", | |
| "last_edited_time": datetime.utcnow().isoformat() + "Z", | |
| "title": [ | |
| { | |
| "type": "text", | |
| "text": { | |
| "content": "Tasks Database" | |
| } | |
| } | |
| ], | |
| "properties": { | |
| "Name": { | |
| "id": "title", | |
| "name": "Name", | |
| "type": "title", | |
| "title": {} | |
| }, | |
| "Status": { | |
| "id": "status", | |
| "name": "Status", | |
| "type": "select", | |
| "select": { | |
| "options": [ | |
| {"name": "Not started", "color": "default"}, | |
| {"name": "In progress", "color": "blue"}, | |
| {"name": "Done", "color": "green"} | |
| ] | |
| } | |
| }, | |
| "Priority": { | |
| "id": "priority", | |
| "name": "Priority", | |
| "type": "select", | |
| "select": { | |
| "options": [ | |
| {"name": "High", "color": "red"}, | |
| {"name": "Medium", "color": "yellow"}, | |
| {"name": "Low", "color": "gray"} | |
| ] | |
| } | |
| }, | |
| "Due Date": { | |
| "id": "due", | |
| "name": "Due Date", | |
| "type": "date", | |
| "date": {} | |
| } | |
| }, | |
| "url": f"https://www.notion.so/{database_id.replace('-', '')}" | |
| } | |
| def _update_page_template(self, params: dict) -> dict: | |
| """Mock response for updating a page.""" | |
| page_id = params['page_id'] | |
| return { | |
| "object": "page", | |
| "id": page_id, | |
| "created_time": "2025-11-15T10:00:00.000Z", | |
| "last_edited_time": datetime.utcnow().isoformat() + "Z", | |
| "archived": params.get('archived', False), | |
| "properties": params.get('properties', {}), | |
| "url": f"https://www.notion.so/{page_id.replace('-', '')}" | |
| } | |
| def _get_page_template(self, params: dict) -> dict: | |
| """Mock response for getting a page.""" | |
| page_id = params['page_id'] | |
| return { | |
| "object": "page", | |
| "id": page_id, | |
| "created_time": "2025-11-15T10:00:00.000Z", | |
| "last_edited_time": "2025-11-25T14:30:00.000Z", | |
| "created_by": { | |
| "object": "user", | |
| "id": self._generate_id() | |
| }, | |
| "last_edited_by": { | |
| "object": "user", | |
| "id": self._generate_id() | |
| }, | |
| "cover": None, | |
| "icon": { | |
| "type": "emoji", | |
| "emoji": "📝" | |
| }, | |
| "parent": { | |
| "type": "database_id", | |
| "database_id": self._generate_id() | |
| }, | |
| "archived": False, | |
| "properties": { | |
| "Name": { | |
| "id": "title", | |
| "type": "title", | |
| "title": [ | |
| { | |
| "type": "text", | |
| "text": { | |
| "content": "Sample Task" | |
| } | |
| } | |
| ] | |
| }, | |
| "Status": { | |
| "id": "status", | |
| "type": "select", | |
| "select": { | |
| "name": "In progress", | |
| "color": "blue" | |
| } | |
| }, | |
| "Priority": { | |
| "id": "priority", | |
| "type": "select", | |
| "select": { | |
| "name": "High", | |
| "color": "red" | |
| } | |
| } | |
| }, | |
| "url": f"https://www.notion.so/{page_id.replace('-', '')}" | |
| } | |
| def _query_database_template(self, params: dict) -> dict: | |
| """Mock response for querying a database.""" | |
| # Return a few sample pages | |
| pages = [] | |
| for i in range(3): | |
| page_id = self._generate_id() | |
| pages.append({ | |
| "object": "page", | |
| "id": page_id, | |
| "created_time": f"2025-11-{20+i}T10:00:00.000Z", | |
| "last_edited_time": datetime.utcnow().isoformat() + "Z", | |
| "properties": { | |
| "Name": { | |
| "id": "title", | |
| "type": "title", | |
| "title": [ | |
| { | |
| "type": "text", | |
| "text": {"content": f"Task {i+1}"} | |
| } | |
| ] | |
| }, | |
| "Status": { | |
| "id": "status", | |
| "type": "select", | |
| "select": { | |
| "name": ["In progress", "Done", "Not started"][i], | |
| "color": ["blue", "green", "default"][i] | |
| } | |
| } | |
| }, | |
| "url": f"https://www.notion.so/{page_id.replace('-', '')}" | |
| }) | |
| return { | |
| "object": "list", | |
| "results": pages, | |
| "next_cursor": None, | |
| "has_more": False | |
| } | |
| def _create_database_template(self, params: dict) -> dict: | |
| """Mock response for creating a database.""" | |
| database_id = self._generate_id() | |
| now = datetime.utcnow().isoformat() + "Z" | |
| return { | |
| "object": "database", | |
| "id": database_id, | |
| "created_time": now, | |
| "last_edited_time": now, | |
| "title": params['title'], | |
| "properties": params['properties'], | |
| "parent": params['parent'], | |
| "url": f"https://www.notion.so/{database_id.replace('-', '')}" | |
| } | |