Skip to main content

Python SDK and CLI for the Monopigi Greek Government Data API

Project description

monopigi

Python SDK and CLI for the Monopigi Greek Government Data API.

One API. 31M+ government decisions. 18K+ EU procurement notices. 10K+ energy permits. Millions of open data records. Normalized JSON. One bearer token.

Installation

# Base package
pip install monopigi

# With Polars DataFrame support
pip install monopigi[df]

# With interactive TUI browser
pip install monopigi[fuzzy]

# Everything
pip install monopigi[all]

Requires Python 3.12+.


Quick Start

Python SDK

from monopigi_sdk import MonopigiClient

with MonopigiClient("mp_live_your_token_here") as client:
    # Search across all 6 data sources
    results = client.search("hospital procurement", limit=10)
    for doc in results.results:
        print(f"{doc.source}: {doc.title}")

CLI

# Save your token (once)
monopigi auth login mp_live_your_token_here

# Search
monopigi search "hospital procurement"

# Get your API key at https://monopigi.com

Data Sources

Source What it contains Volume
Diavgeia Government spending decisions, contracts, financial data 31M+ decisions
TED (EU) EU public procurement notices for Greece (EL/EN) 18K+ notices
RAE Energy Energy permits — wind, solar, hydro with GeoJSON 10K+ permits
data.gov.gr National open data — health, economy, crime, energy 84 datasets, millions of records
ELSTAT Statistical time series — GDP, unemployment, trade 28 indicators, decades of data
Mitos Government org registry — names, addresses, VAT 2,886 orgs

SDK Reference

Client

from monopigi_sdk import MonopigiClient, AsyncMonopigiClient

# Sync client
client = MonopigiClient(token="mp_live_...", base_url="https://api.monopigi.com")

# With caching (5 min TTL)
client = MonopigiClient(token="mp_live_...", cache_ttl=300)

# With custom retry (default: 3)
client = MonopigiClient(token="mp_live_...", max_retries=5)

# Context manager (auto-closes connection)
with MonopigiClient("mp_live_...") as client:
    ...

# Async client
async with AsyncMonopigiClient("mp_live_...") as client:
    results = await client.search("hospital")

Core Methods

# Search across all sources
results = client.search("hospital procurement", limit=100, offset=0)

# Query a specific source
docs = client.documents("ted", limit=50, since="2026-01-01")

# List available sources
sources = client.sources()

# Platform statistics
stats = client.stats()

# Your API usage today
usage = client.usage()

Source-Specific Clients

Typed convenience wrappers for each data source:

# TED EU procurement
tenders = client.ted.notices(limit=100, since="2026-01-01")

# Diavgeia government decisions
decisions = client.diavgeia.decisions(limit=50)

# ELSTAT statistics
datasets = client.elstat.datasets()

# RAE energy permits
permits = client.rae.permits()

# data.gov.gr national data
data = client.data_gov_gr.datasets()

# Mitos government organizations
orgs = client.mitos.organizations()

Auto-Pagination

Iterate through all results without manual offset management:

# Yields every document, auto-fetches next pages
for doc in client.search_iter("procurement"):
    print(doc.title)

# Same for source-specific queries
for doc in client.documents_iter("ted", since="2026-01-01"):
    process(doc)

DataFrame Conversion

Convert any response to a Polars DataFrame (requires [df] extra):

df = client.search("hospital").to_df()
df = client.documents("ted", limit=500).to_df()

Bulk Export

Export entire sources to files with progress bars:

# JSON
count = client.export("ted", "tenders.json", format="json")

# CSV
count = client.export("diavgeia", "decisions.csv", format="csv", since="2026-01-01")

# Parquet (requires polars)
count = client.export("ted", "tenders.parquet", format="parquet")

Caching

Disk-based cache with TTL to avoid repeated API calls:

# Cache responses for 1 hour
client = MonopigiClient("mp_live_...", cache_ttl=3600)

# First call hits the API
results1 = client.search("hospital")

# Second identical call served from disk cache
results2 = client.search("hospital")  # instant, no API call

Cache is stored in ~/.monopigi/cache/ as SHA-256 keyed JSON files.

Rate-Limit Handling

The client automatically handles HTTP 429 (rate limit exceeded):

# Auto-waits when rate-limited, retries up to max_retries times
client = MonopigiClient("mp_live_...", max_retries=3)

# If rate limit is hit, the client:
# 1. Reads X-RateLimit-Reset header
# 2. Waits until reset time (capped at 5 min)
# 3. Retries the request
# 4. Raises RateLimitError only after exhausting retries

Error Handling

from monopigi_sdk import MonopigiClient, AuthError, RateLimitError, NotFoundError, MonopigiError

try:
    client = MonopigiClient("invalid_token")
    client.sources()
except AuthError:
    print("Invalid API token")
except RateLimitError as e:
    print(f"Rate limited. Resets at: {e.reset_at}")
except NotFoundError:
    print("Source not found")
except MonopigiError:
    print("Something went wrong")

Response Models

All responses are typed Pydantic models with full autocomplete:

from monopigi_sdk.models import (
    Source,          # name, label, status, description
    Document,        # source_id, source, title, doc_type, published_at, quality_score, ...
    SearchResponse,  # query, results, total, limit, offset
    DocumentsResponse,
    StatsResponse,
    UsageResponse,
    SourceStatus,    # Enum: ACTIVE, UNAVAILABLE, PLANNED
    Tier,            # Enum: FREE, PRO, ENTERPRISE
)

CLI Reference

Authentication

# Save your API token
monopigi auth login mp_live_your_token_here

# Check auth status
monopigi auth status

# Remove saved token
monopigi auth logout

Token is stored in ~/.monopigi/config.toml:

token = "mp_live_..."
base_url = "https://api.monopigi.com"

Configuration

CLI settings are stored separately in ~/.monopigi/settings.json:

# Set API base URL (for self-hosted or development)
monopigi config set base_url http://localhost:8000

# Set default output format (table, json, jsonl, csv)
monopigi config set default_format json

# Set default source for documents/diff/export commands
monopigi config set default_source ted

# Set cache TTL in seconds (default: 300)
monopigi config set cache_ttl 600

# Get a config value
monopigi config get cache_ttl

# List all config (auth + settings)
monopigi config list
Key Default Description
base_url https://api.monopigi.com API base URL
default_format table Output format: table, json, jsonl, csv
default_source Default source for documents, diff, export
cache_ttl 300 Local cache TTL in seconds

Searching

# Search all sources (Rich table output)
monopigi search "hospital procurement"

# Limit results
monopigi search "tender" --limit 20

# Output as JSON (syntax-highlighted on terminal)
monopigi search "hospital" --format json

# Output as CSV
monopigi search "hospital" --format csv

# Select specific fields
monopigi search "hospital" --fields source,title,published_at

# Just count results
monopigi search "Athens" --count

# Cache results for repeated queries
monopigi search "hospital" --cache

Querying Sources

# Query a specific source
monopigi documents ted --limit 20

# Filter by date
monopigi documents diavgeia --since 2026-01-01

# Output as JSONL (one object per line)
monopigi documents ted --format jsonl

Watching for Changes

# Poll every 60 seconds for new results
monopigi watch "hospital procurement"

# Custom interval
monopigi watch "tender" --interval 30

# Stream to file
monopigi watch "procurement" --format jsonl | tee new_results.jsonl

Diffing

# What's new since last check?
monopigi diff ted

# Since a specific date
monopigi diff diavgeia --since 2026-03-15

Exporting

# Export to JSON
monopigi export ted tenders.json

# Export to CSV
monopigi export diavgeia decisions.csv --format csv --since 2026-01-01

# Export to Parquet
monopigi export ted tenders.parquet --format parquet

# Limit export size
monopigi export ted sample.json --limit 100

Interactive Browser

Requires monopigi[fuzzy]:

# Browse documents from a source
monopigi browse ted

# Browse with a pre-filter
monopigi browse --query "hospital" --limit 200

Piping (stdin enrichment)

# Search for each line from stdin
echo "hospital" | monopigi pipe

# Enrich a list of queries
cat search_terms.txt | monopigi pipe --limit 5

# Chain with other monopigi commands
monopigi documents ted --format jsonl | jq -r '.title' | monopigi pipe

Configuration

# Set a config value
monopigi config set cache_ttl 600
monopigi config set default_format json

# Get a config value
monopigi config get cache_ttl

# List all config
monopigi config list

Valid keys: base_url, default_format, default_source, cache_ttl.

Shell Completions

# Show installation instructions
monopigi completions

# Or use Typer's built-in
monopigi --install-completion

Platform Info

# Platform statistics
monopigi stats

# Your API usage
monopigi usage

# Available data sources
monopigi sources

Unix Pipe Recipes

The CLI is pipe-friendly — it auto-switches to JSONL output when piped.

# Filter with jq
monopigi search "hospital" | jq 'select(.quality_score > 0.9)'

# Count results
monopigi search "Athens" --count

# Extract titles
monopigi documents ted --format jsonl | jq -r '.title'

# Find procurement over EUR 1M
monopigi documents ted --format jsonl | jq 'select(.title | test("1.000.000|1,000,000"))'

# Deduplicate across sources
monopigi search "procurement" --format jsonl | jq -s 'unique_by(.source_id)'

# Top sources by document count
monopigi stats | jq '.sources | to_entries | sort_by(-.value.documents) | .[].key'

Pricing

Tier Price Daily Queries
Free EUR 0 5
Pro EUR 299/mo 5,000
Enterprise Custom Unlimited

Get your API key at monopigi.com.


Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

monopigi-0.1.1.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

monopigi-0.1.1-py3-none-any.whl (22.2 kB view details)

Uploaded Python 3

File details

Details for the file monopigi-0.1.1.tar.gz.

File metadata

  • Download URL: monopigi-0.1.1.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for monopigi-0.1.1.tar.gz
Algorithm Hash digest
SHA256 42f757d129f539d6174ee146549477beab78224b765323671de903c45400f422
MD5 1e5278f0de49e54f214b2f513100c3e1
BLAKE2b-256 52933b8e0215c2caadc92ba1c1f3beb017999efed9c540f3cdf890e23653d034

See more details on using hashes here.

File details

Details for the file monopigi-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: monopigi-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 22.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for monopigi-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9437e0f592a8cf45c9c1cde5b887ac2230ca9afd136b1ac3732c8b8e242d5a82
MD5 9a5e382d03cd0246795067385dbb36a0
BLAKE2b-256 c9b1f84c89aef90bd4f0d6b31c85ddf948fe7616438742b81daacfbb6035b72b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page