Skip to content

Latest commit

 

History

History
105 lines (79 loc) · 3.98 KB

File metadata and controls

105 lines (79 loc) · 3.98 KB

cnmv-cli

A small Python CLI for listing, downloading, and comparing explicitly selected CNMV annual filings. It reads the official CNMV website directly.

Setup

Python 3.11 or newer and uv are required.

uv sync
uv run cnmv --help

List annual filings

uv run cnmv filing list --nif A08001851

The default and only output format is JSON Lines: one filing object per line. Each object includes its registration number, period end, publication date, auditor, available audit details, and available source document URLs classified as individual_xhtml, consolidated_xhtml, or consolidated_zip.

Download a document

Pass an explicit HTTPS URL found in the list output:

uv run cnmv filing download \
  --url 'https://www.cnmv.es/webservices/verdocumento/ver?e=…' \
  --output downloads/filing.xhtml

The command creates missing parent directories, streams up to 256 MiB into a temporary file, and atomically replaces the output after a successful download. It prints one JSON provenance object containing the final URL, SHA-256 digest, byte count, content type, and output path. Only HTTPS URLs on cnmv.es or its subdomains are accepted, including at every redirect.

Compare two XHTML filings

Pass two explicit CNMV URLs and, optionally, a local database directory:

uv run cnmv filing compare \
  --older-url 'https://www.cnmv.es/path/older.xhtml' \
  --newer-url 'https://www.cnmv.es/path/newer.xhtml' \
  --database .cnmv-filing-delta

The database defaults to .cnmv-filing-delta. Both documents are downloaded with the same HTTPS-origin, redirect, and size checks as filing download. Only HTML/XHTML responses are accepted. Visible block text is stored in persistent Chroma collections identified by each document's SHA-256 hash, so a collection from another document cannot be silently reused.

The command prints one compact JSON object with the final URL, SHA-256 hash, and byte count for both documents. Its changes list contains newer chunks that are not present verbatim in the older filing; each entry has new_text, closest_old_text, and distance. Embeddings are generated by a small deterministic token-hash function and require no API key or model download.

Development

uv sync
uv run pytest
uv run python -m compileall -q src tests

The default test suite uses local fixtures and mocked HTTP responses; it does not access the network.

Automated CLI checks

The CLI checks workflow runs the regression suite, lint, compilation, and installed-command help checks on Python 3.11 and 3.14 for every pull request, push to main, and nightly at 21:00 Madrid time (Europe/Madrid, automatically adjusting for daylight saving time). It also supports Run workflow in the repository's Actions tab.

Nightly and manual runs include a separate Live CNMV job. It lists filings for A08001851, selects the latest two distinct periods with consolidated XHTML documents, downloads one and verifies its hash and size, then compares the pair using a temporary Chroma database. The job validates JSON output and provenance and logs the selected periods, registration numbers, URLs, hashes, and change count. It retries a reported upstream request failure once; persistent failures fail the job. A live failure can also indicate a CNMV outage or page change.

To run the same live check locally:

CNMV_LIVE_TESTS=1 uv run pytest -v -s tests/test_live.py

No API keys or repository secrets are required. Results and failing commands appear in Actions; enable GitHub Actions notifications in your GitHub account if you want email alerts. Scheduled runs begin once the workflow is on main; GitHub may delay them and disables schedules in public repositories after 60 days without repository activity.

This MVP intentionally does not implement XBRL extraction, financial metrics, LLM-generated narrative, or external services.