Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ plugins:
timeout: 120 # HTTP timeout in seconds
# api_key: "${CKAN_API_KEY}" # Optional: CKAN API key for authenticated requests

# Built-in: ArcGIS Hub (for ArcGIS Hub open data portals)
# Examples: hub.arcgis.com, data-boston.hub.arcgis.com
arcgis:
enabled: false # Set to true to use
portal_url: "https://hub.arcgis.com"
city_name: "Your City"
timeout: 120
# token: "${ARCGIS_TOKEN}" # Optional: Bearer token for private items

# yamllint disable rule:comments-indentation
# Custom: Add your own plugins here
# Example:
Expand Down
2 changes: 1 addition & 1 deletion config.yaml
1 change: 1 addition & 0 deletions plugins/arcgis/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""ArcGIS Hub plugin for OpenContext."""
44 changes: 44 additions & 0 deletions plugins/arcgis/config_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Pydantic configuration schema for ArcGIS Hub plugin."""

from typing import Optional
from urllib.parse import urlparse

from pydantic import BaseModel, ConfigDict, Field, field_validator


class ArcGISPluginConfig(BaseModel):
"""Configuration schema for ArcGIS Hub plugin.

This schema validates ArcGIS Hub plugin configuration from config.yaml.
"""

enabled: bool = Field(default=False, description="Whether plugin is enabled")
portal_url: str = Field(
default="https://hub.arcgis.com",
description="Base URL of ArcGIS Hub portal (e.g., https://hub.arcgis.com)",
)
city_name: str = Field(..., description="Name of the city/organization")
timeout: int = Field(
default=120, ge=1, le=300, description="HTTP request timeout in seconds"
)
token: Optional[str] = Field(
None, description="Optional Bearer token for authenticated requests"
)

@field_validator("portal_url")
@classmethod
def validate_url(cls, v: str) -> str:
"""Validate that URL is well-formed."""
if not v:
raise ValueError("URL cannot be empty")
try:
result = urlparse(v)
if not result.scheme or not result.netloc:
raise ValueError("URL must include scheme (http/https) and hostname")
if result.scheme not in ("http", "https"):
raise ValueError("URL scheme must be http or https")
except Exception as e:
raise ValueError(f"Invalid URL format: {e}")
return v.rstrip("/")

model_config = ConfigDict(extra="forbid")
Loading
Loading