Skip to main content
Glama
test_notion_integration.py10.1 kB
""" Integration tests for Notion API via mcp-openapi-proxy, FastMCP mode. Requires NOTION_API_KEY in .env to run. """ import os import json import pytest from dotenv import load_dotenv from mcp_openapi_proxy.utils import fetch_openapi_spec from mcp_openapi_proxy.server_fastmcp import list_functions, call_function load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '../../.env')) SPEC_URL = "https://storage.googleapis.com/versori-assets/public-specs/20240214/NotionAPI.yml" SERVER_URL = "https://api.notion.com" EXTRA_HEADERS = "Notion-Version: 2022-06-28" TOOL_PREFIX = "notion_" def setup_notion_env(env_key, notion_api_key): """Set up environment variables for Notion tests.""" os.environ[env_key] = SPEC_URL os.environ["API_KEY"] = notion_api_key os.environ["SERVER_URL_OVERRIDE"] = SERVER_URL os.environ["EXTRA_HEADERS"] = EXTRA_HEADERS os.environ["TOOL_NAME_PREFIX"] = TOOL_PREFIX os.environ["DEBUG"] = "true" print(f"DEBUG: API_KEY set to: {os.environ['API_KEY'][:5]}...") def get_tool_name(tools, original_name): """Find tool name by original endpoint name.""" return next((tool["name"] for tool in tools if tool["original_name"] == original_name), None) @pytest.fixture def notion_ids(reset_env_and_module): """Fixture to fetch a page ID and database ID from Notion.""" env_key = reset_env_and_module notion_api_key = os.getenv("NOTION_API_KEY") print(f"DEBUG: NOTION_API_KEY: {notion_api_key if notion_api_key else 'Not set'}") if not notion_api_key or "your_key" in notion_api_key: print("DEBUG: Skipping due to missing or placeholder NOTION_API_KEY") pytest.skip("NOTION_API_KEY missing or placeholder—set it in .env, please!") setup_notion_env(env_key, notion_api_key) print(f"DEBUG: Fetching spec from {SPEC_URL}") spec = fetch_openapi_spec(SPEC_URL) assert spec, f"Failed to fetch spec from {SPEC_URL}" print("DEBUG: Listing available functions") tools_json = list_functions(env_key=env_key) tools = json.loads(tools_json) print(f"DEBUG: Tools: {tools_json}") assert tools, "No functions generated" search_tool = get_tool_name(tools, "POST /v1/search") assert search_tool, "Search tool not found!" print(f"DEBUG: Calling {search_tool} to find IDs") response_json = call_function( function_name=search_tool, parameters={"query": ""}, env_key=env_key ) print(f"DEBUG: Search response: {response_json}") response = json.loads(response_json) assert "results" in response, "No results in search response" page_id = None db_id = None for item in response["results"]: if item["object"] == "page" and not page_id: page_id = item["id"] elif item["object"] == "database" and not db_id: db_id = item["id"] if page_id and db_id: break if not page_id or not db_id: print(f"DEBUG: Page ID: {page_id}, DB ID: {db_id}") pytest.skip("No page or database found in search—please add some to Notion!") return env_key, tools, page_id, db_id @pytest.mark.integration def test_notion_users_list(notion_ids): """Test Notion /v1/users endpoint with NOTION_API_KEY.""" env_key, tools, _, _ = notion_ids tool_name = get_tool_name(tools, "GET /v1/users") assert tool_name, "Function for GET /v1/users not found!" print(f"DEBUG: Calling {tool_name} for user list") response_json = call_function(function_name=tool_name, parameters={}, env_key=env_key) print(f"DEBUG: Raw response: {response_json}") try: response = json.loads(response_json) if isinstance(response, dict) and "error" in response: print(f"DEBUG: Error occurred: {response['error']}") if "401" in response["error"] or "invalid_token" in response["error"]: assert False, "NOTION_API_KEY is invalid—please check your token!" assert False, f"Notion API returned an error: {response_json}" assert isinstance(response, dict), f"Response is not a dictionary: {response_json}" assert "results" in response, f"No 'results' key in response: {response_json}" assert isinstance(response["results"], list), "Results is not a list" print(f"DEBUG: Found {len(response['results'])} users—excellent!") except json.JSONDecodeError: assert False, f"Response is not valid JSON: {response_json}" @pytest.mark.integration def test_notion_users_me(notion_ids): """Test Notion /v1/users/me endpoint with NOTION_API_KEY.""" env_key, tools, _, _ = notion_ids tool_name = get_tool_name(tools, "GET /v1/users/me") assert tool_name, "Function for GET /v1/users/me not found!" print(f"DEBUG: Calling {tool_name} for bot user") response_json = call_function(function_name=tool_name, parameters={}, env_key=env_key) print(f"DEBUG: Raw response: {response_json}") try: response = json.loads(response_json) if isinstance(response, dict) and "error" in response: print(f"DEBUG: Error occurred: {response['error']}") if "401" in response["error"] or "invalid_token" in response["error"]: assert False, "NOTION_API_KEY is invalid—please check your token!" assert False, f"Notion API returned an error: {response_json}" assert isinstance(response, dict), f"Response is not a dictionary: {response_json}" assert "object" in response and response["object"] == "user", "Response is not a user object" assert "type" in response and response["type"] == "bot", "Expected bot user" print(f"DEBUG: Got bot user: {response.get('name', 'Unnamed')}—excellent!") except json.JSONDecodeError: assert False, f"Response is not valid JSON: {response_json}" @pytest.mark.integration def test_notion_search(notion_ids): """Test Notion /v1/search endpoint with NOTION_API_KEY.""" env_key, tools, _, _ = notion_ids tool_name = get_tool_name(tools, "POST /v1/search") assert tool_name, "Function for POST /v1/search not found!" print(f"DEBUG: Calling {tool_name} for search") response_json = call_function( function_name=tool_name, parameters={"query": "test"}, env_key=env_key ) print(f"DEBUG: Raw response: {response_json}") try: response = json.loads(response_json) if isinstance(response, dict) and "error" in response: print(f"DEBUG: Error occurred: {response['error']}") if "401" in response["error"] or "invalid_token" in response["error"]: assert False, "NOTION_API_KEY is invalid—please check your token!" assert False, f"Notion API returned an error: {response_json}" assert isinstance(response, dict), f"Response is not a dictionary: {response_json}" assert "results" in response, f"No 'results' key in response: {response_json}" assert isinstance(response["results"], list), "Results is not a list" print(f"DEBUG: Found {len(response['results'])} search results—excellent!") except json.JSONDecodeError: assert False, f"Response is not valid JSON: {response_json}" @pytest.mark.integration def test_notion_get_page(notion_ids): """Test Notion /v1/pages/{id} endpoint with NOTION_API_KEY.""" env_key, tools, page_id, _ = notion_ids tool_name = get_tool_name(tools, "GET /v1/pages/{id}") assert tool_name, "Function for GET /v1/pages/{id} not found!" print(f"DEBUG: Calling {tool_name} for page {page_id}") response_json = call_function( function_name=tool_name, parameters={"id": page_id}, env_key=env_key ) print(f"DEBUG: Raw response: {response_json}") try: response = json.loads(response_json) if isinstance(response, dict) and "error" in response: print(f"DEBUG: Error occurred: {response['error']}") if "401" in response["error"] or "invalid_token" in response["error"]: assert False, "NOTION_API_KEY is invalid—please check your token!" assert False, f"Notion API returned an error: {response_json}" assert isinstance(response, dict), f"Response is not a dictionary: {response_json}" assert "object" in response and response["object"] == "page", "Response is not a page object" assert response["id"] == page_id, f"Expected page ID {page_id}, got {response['id']}" print(f"DEBUG: Got page: {response.get('url', 'No URL')}—excellent!") except json.JSONDecodeError: assert False, f"Response is not valid JSON: {response_json}" @pytest.mark.integration def test_notion_query_database(notion_ids): """Test Notion /v1/databases/{id}/query endpoint with NOTION_API_KEY.""" env_key, tools, _, db_id = notion_ids tool_name = get_tool_name(tools, "POST /v1/databases/{id}/query") assert tool_name, "Function for POST /v1/databases/{id}/query not found!" print(f"DEBUG: Calling {tool_name} for database {db_id}") response_json = call_function( function_name=tool_name, parameters={"id": db_id}, env_key=env_key ) print(f"DEBUG: Raw response: {response_json}") try: response = json.loads(response_json) if isinstance(response, dict) and "error" in response: print(f"DEBUG: Error occurred: {response['error']}") if "401" in response["error"] or "invalid_token" in response["error"]: assert False, "NOTION_API_KEY is invalid—please check your token!" assert False, f"Notion API returned an error: {response_json}" assert isinstance(response, dict), f"Response is not a dictionary: {response_json}" assert "results" in response, f"No 'results' key in response: {response_json}" assert isinstance(response["results"], list), "Results is not a list" print(f"DEBUG: Found {len(response['results'])} database entries—excellent!") except json.JSONDecodeError: assert False, f"Response is not valid JSON: {response_json}"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/matthewhand/mcp-openapi-proxy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server