Skip to main content
Glama
urls.py4.09 kB
from __future__ import annotations import os import re from collections.abc import Mapping from typing import Any def _base_url() -> str: base = os.getenv('DUNE_API_URL', 'https://api.dune.com/api/v1').rstrip('/') return base url_templates = { 'execution_status': _base_url() + '/execution/{execution_id}/status', 'execution_results': _base_url() + '/execution/{execution_id}/results/csv', 'execution_sql': _base_url() + '/execution/sql', 'query_execution': _base_url() + '/query/{query_id}/execute', 'query_results': _base_url() + '/query/{query_id}/results/csv', 'query_results_json': _base_url() + '/query/{query_id}/results', 'query_create': _base_url() + '/query/', 'query': _base_url() + '/query/{query_id}', 'query_fork': _base_url() + '/query/{query_id}/fork', 'query_archive': _base_url() + '/query/{query_id}/archive', 'query_unarchive': _base_url() + '/query/{query_id}/unarchive', } def get_query_execute_url(query: int | str) -> str: if isinstance(query, str): return query elif isinstance(query, int): return url_templates['query_execution'].format(query_id=query) else: raise Exception('unknown query format: ' + str(type(query))) def get_query_results_url( query: int | str, parameters: dict[str, Any], csv: bool = True ) -> str: query_id = get_query_id(query) if csv: template = url_templates['query_results'] else: template = url_templates['query_results_json'] url = template.format(query_id=query_id) parameters = dict(parameters.items()) if 'query_parameters' in parameters: parameters['params'] = parameters.pop('query_parameters') for key, value in list(parameters.items()): if isinstance(value, dict): del parameters[key] for subkey, subvalue in value.items(): parameters[key + '.' + subkey] = subvalue return add_args_to_url(url, parameters=parameters) def get_execution_status_url(execution_id: str) -> str: return url_templates['execution_status'].format(execution_id=execution_id) def get_execution_results_url( execution_id: str, parameters: Mapping[str, Any] ) -> str: url = url_templates['execution_results'].format(execution_id=execution_id) return add_args_to_url(url, parameters=parameters) def add_args_to_url(url: str, parameters: Mapping[str, Any]) -> str: """Append query params to a base URL. - Flattens nested dicts like {"a": {"b": 1}} -> "a.b=1" - Joins lists via commas - Skips None values """ # Flatten nested dicts once (shallow nesting like key: {sub: val}) flat: dict[str, Any] = {} for key, value in parameters.items(): if value is None: continue if isinstance(value, dict): for subkey, subvalue in value.items(): flat[f"{key}.{subkey}"] = subvalue else: flat[key] = value # Build query string parts: list[str] = [] for key, value in flat.items(): if value is None: continue if isinstance(value, list): value = ','.join(str(item) for item in value) parts.append(f"{key}={value}") sep = '&' if '?' in url else '?' return url + (sep if parts else '') + '&'.join(parts) def get_api_key() -> str: """get dune api key""" return os.environ['DUNE_API_KEY'] def get_query_id(query: str | int) -> int: """get id of a query""" if isinstance(query, int): return query elif isinstance(query, str): m = re.search(r"/api/v1/query/(\d+)", query) if m: query = m.group(1) else: m2 = re.search(r"dune\.com/queries/(\d+)", query) if m2: query = m2.group(1) try: return int(query) except ValueError: raise Exception('invalid query id: ' + str(query)) def get_headers(*, api_key: str | None = None) -> Mapping[str, str]: if api_key is None: api_key = get_api_key() return {'X-Dune-API-Key': api_key}

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/Evan-Kim2028/spice-mcp'

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