Python Cost Explorer Client
Python client and OpenStackClient plugin for the Keystone-authenticated Cost Explorer API. Reports and forecasts are estimates computed on demand; creating one does not store a resource or create an invoice.
Install
pip install vexxhost-costexplorerclient
openstack cost report create --help
This installs the openstack CLI as well. If you installed OpenStackClient with
pipx, add the commands to it instead:
pipx inject python-openstackclient vexxhost-costexplorerclient
Authentication and endpoint
Use your existing clouds.yaml, --os-cloud, or OS_* Keystone credentials.
The plugin reuses OpenStackClient's session, token, TLS settings and scope.
It does not require its own username/password and never grants additional access.
The deployed service is registered in Keystone as service type cost-explorer,
with a public endpoint in region ca-east-1. The CLI discovers it automatically:
openstack --os-cloud mycloud --os-region-name ca-east-1 --os-interface public \
cost report create \
--start 2026-09-01 --end 2026-10-01 --granularity monthly
You can also set OS_REGION_NAME=ca-east-1 and OS_INTERFACE=public, or set
region_name: ca-east-1 and interface: public in the chosen clouds.yaml
entry. This region currently contains the Cost Explorer endpoint; other cloud
services may use their existing region names. Prefer command-specific
--os-region-name ca-east-1 when using one cloud profile for multiple services.
Inspect the authenticated catalog with:
openstack --os-cloud mycloud catalog show cost-explorer
No Cost Explorer endpoint override is needed. If you configured one previously,
unset OS_COST_EXPLORER_ENDPOINT and remove cost_explorer_endpoint from the
cloud profile to use catalog discovery. Obtain a fresh token if an existing
cached catalog predates the registration.
For development or a deployment without a catalog entry, endpoint overrides
remain supported through --os-cost-explorer-endpoint URL,
OS_COST_EXPLORER_ENDPOINT, or cost_explorer_endpoint: URL in clouds.yaml.
Endpoints may be the root URL or end in /v1. API version 1 is supported
(--os-cost-explorer-api-version 1).
TLS certificate verification is enabled by the normal OpenStack session. Use
--os-cacert for a private CA. Requests have a 60-second client timeout, and API
redirects are not followed. The Python client accepts a configurable timeout.
Commands
Cost reports
# Monthly total for the authenticated project, through the current time.
openstack cost report create \
--start 2026-09-01 --end 2026-10-01 --granularity monthly
# Daily compute/volume/image breakdown, including usage quantities.
openstack cost report create \
--start 2026-09-01 --end 2026-09-17 --detail
# Operator query for a particular project; filters are repeatable.
openstack cost report create \
--start 2026-09-01 --end 2026-10-01 \
--project PROJECT_UUID --region ca-ymq-1 --service compute \
--group-by project_id --group-by usage_type --detail
# Totals only, formatted as JSON with exact decimal strings.
openstack cost report create \
--start 2026-09-01 --end 2026-10-01 --no-group -f json
Dates are interpreted as UTC midnight; timezone-aware RFC3339 timestamps are
also accepted. Start is inclusive and end exclusive. Naive timestamps are
rejected. Other options: --as-of, --usage-type, --metric cost,
--metric usage_quantity, --group-by, and --granularity hourly|daily|monthly.
Usage quantity requires grouping by usage_type; use --metric cost when you
want other groupings. --no-group defaults to cost only.
--project takes IDs, not names. It filters data and does not change the
Keystone authentication scope. --region filters report data; --os-region-name
selects the catalog endpoint. The deployment reports region ca-ymq-1 even
though its hostname contains ca-east-1.
Forecasts
# Choose dates starting today or later, within the API's 90-day horizon.
openstack cost forecast create \
--start 2026-09-18 --end 2026-09-25 --lookback-days 7
openstack cost forecast create \
--start 2026-09-18 --end 2026-09-25 \
--project PROJECT_UUID -f json
Forecast granularity is daily or monthly. Lookback is 1–90 days (default 7).
The same project, region, service and usage-type filters are available.
Output and errors
Default report tables contain one row per period/total metric. --detail
shows group/metric rows. Forecast tables contain one row per projected period.
Standard -f json|yaml|csv|table|value and -c COLUMN formatting is supported.
-f json and -f yaml serialize the same rows shown by the table formatter.
Use --detail to include report group/metric rows and -c COLUMN to select
output columns. Monetary and usage amounts remain decimal strings; the client
does not round or convert them to floats. The Python client returns the complete
API response, including metadata such as as_of and pricing version.
Errors exit nonzero and include the API's problem detail, schema errors, request ID and Retry-After value when available. Requests are not automatically retried by this client. Authorization remains server-enforced: ordinary project identities cannot read other projects.
Python usage
from keystoneauth1 import loading, session
from costexplorerclient import Client
# Reuse your application's configured Keystone session/auth plugin.
loader = loading.get_plugin_loader("v3applicationcredential")
auth = loader.load_from_options(
auth_url="https://auth.vexxhost.net/v3",
application_credential_id="YOUR_ID",
application_credential_secret="YOUR_SECRET",
)
client = Client(
"1",
session=session.Session(auth=auth),
endpoint_override="https://cost-explorer.public.ca-east-1.vexxhost.net",
timeout=60,
)
report = client.cost_reports.create(**{
"time_period": {"start": "2026-09-01T00:00:00Z", "end": "2026-10-01T00:00:00Z"},
"granularity": "monthly",
})
The versioned factory Client("1", session=...) creates a
costexplorerclient.v1.client.Client. Resource managers expose
client.cost_reports.create(**request) and
client.cost_forecasts.create(**request), returning the complete response dict.
The initial create_report(body) and create_forecast(body) convenience methods
and session-first constructor remain supported.
The transport is vexxhost-clientcore's keystoneauth1.adapter.Adapter
subclass, used with service type cost-explorer; the budget client uses the same
one. In the CLI it is built by openstack.config, so clouds.yaml settings such
as cost_explorer_endpoint_override, cost_explorer_interface and
cost_explorer_status_code_retries apply as they do to built-in services. Exceptions derive from ClientException (also exported as
CostExplorerError), which is shared by every client built on
vexxhost-clientcore and also the matching keystoneauth1.exceptions HTTP
error, and expose status_code, code, problem, request_id
and retry_after. Specific failures can be caught as Unauthorized,
Forbidden, TooManyRequests, ServiceUnavailable, etc. The library exception
hierarchy does not depend on CLI exceptions.
See OpenStack client conventions for the upstream comparison and the intentionally smaller scope of this client.
Development
python -m venv .venv
. .venv/bin/activate
pip install -e '.[test]' build
pytest
python -m build
Tests exercise real CLI plugin discovery, HTTP authentication and request construction using a local mock server. CI never requires cloud credentials.
Generated models
costexplorerclient/v1/models.py holds TypedDict models of the requests and
responses, generated from the schema cost-explorer serves, and the CLI's choices
(granularities, services, metrics, groupings) are read from them, so they follow
the API instead of being copied from it. SPEC_VERSION names the cost-explorer
build the models came from. The generator lives in vexxhost-clientcore, so every
client produces models the same way. Regenerate with:
make generate SPEC_URL=https://cost-explorer.public.global.vexxhost.net/openapi-3.0.yaml
The regenerate workflow does this daily against the repository variable
SPEC_URL and opens a pull request when the served schema changed.
The deployment currently has incomplete pricing for some internal flavors
(such as m1.amphora), and broad all-project queries may exceed server limits.
Use project filters. Server-side 503 errors are reported, not converted to
partial/zero totals. Successful responses are estimates, not billing certification.
Metadata
Release files for vexxhost-costexplorerclient 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vexxhost_costexplorerclient-0.3.1.tar.gz | 22.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vexxhost_costexplorerclient-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.6 kB
Release files / vexxhost_costexplorerclient-0.3.1.tar.gz
| Download URL | vexxhost_costexplorerclient-0.3.1.tar.gz |
|---|---|
| Size | 22.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2a724f0f873ca0de0bb841c9cd4ae844a835de165e0e98f08ca67fcd601e2350
|
|
BLAKE2b-256 checksum How to use checksums |
4ee02357a2e14943ef09b19a0b73653ff18fcbc05b516269b597deba325cf5a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / vexxhost_costexplorerclient-0.3.1-py3-none-any.whl
| Download URL | vexxhost_costexplorerclient-0.3.1-py3-none-any.whl |
|---|---|
| Size | 17.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b65ef3975b352ea03ebabf864d19bd48c174027ec12290511b345cfab50ec458
|
|
BLAKE2b-256 checksum How to use checksums |
b661fc229f1de795e0c6890cf5193c56e1af9cf7c0629e5d42181d120dee6eec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|