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
- Website: monopigi.com
- Contact: info@monopigi.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file monopigi-0.1.3.tar.gz.
File metadata
- Download URL: monopigi-0.1.3.tar.gz
- Upload date:
- Size: 17.4 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b5a44c4810be2524b37ff015646a6b423e2af0a4813d3041dc421f87602b8a8
|
|
| MD5 |
de884a601c924d441e03f7a6a004b052
|
|
| BLAKE2b-256 |
dd7d491b5fe65dda20d82fd07dbae0f3538eb0c2ea2a82915438b249b4c0f4c6
|
File details
Details for the file monopigi-0.1.3-py3-none-any.whl.
File metadata
- Download URL: monopigi-0.1.3-py3-none-any.whl
- Upload date:
- Size: 22.1 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e982ba7fda6fbccb73567a2e334562e97fa887a60b374103e0c01e07fda13ac
|
|
| MD5 |
555eae38d4b03a3dea3b27d99e77ef04
|
|
| BLAKE2b-256 |
15a9ed1ed0982595d51dfa24cba3345820ff70cdfcfb49add8efa22138717d88
|