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
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
uses: astral-sh/setup-uv@v10.2.0
with:
version: "latest"
python-version: "3.12"

- name: Set up Python
uses: actions/setup-python@v7
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
uses: astral-sh/setup-uv@v10.2.0
with:
version: "latest"
python-version: "3.12"

- name: Set up Python
uses: actions/setup-python@v7
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ jobs:
uses: astral-sh/setup-uv@v10.2.0
with:
version: "latest"
# uv reads .python-version, not the interpreter setup-python puts on PATH.
python-version: ${{ matrix.python-version }}

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
Expand Down Expand Up @@ -193,6 +195,7 @@ jobs:
uses: astral-sh/setup-uv@v10.2.0
with:
version: "latest"
python-version: "3.12"

- name: Set up Python
uses: actions/setup-python@v7
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `options.expirations()` returns a `no_data` DataFrame with the same index as a populated one (`expirations` index, `updated` column), so concatenating results across symbols keeps the index name and gains no stray `expirations` column (#84)
- The CSV output of `stocks.candles()` and `options.quotes()` is merged from the answers themselves: the file keeps the header the API sent (the requested `columns`, the human-readable names) and every row of every chunk or symbol; it used to compare each body against the model's field list and silently drop every body that differed, so a `columns=` request or a human-readable `options.quotes()` produced a header-only file, and an undecodable body (an HTML error page) vanished without a word. Such a body now raises `ParseError`, and so does a body the `csv` module cannot read (a field past its size limit), which escaped as a raw `csv.Error` (#86)
- DataFrame dates under `DateFormat.TIMESTAMP` and `DateFormat.SPREADSHEET` are the US/Eastern datetimes the default format gives, on pandas and polars. polars left `timestamp` datetimes as strings, a `timestamp` date (`2026-09-21`) landed at 20:00 the day before on both, and a spreadsheet serial, which the API writes as US/Eastern wall-clock time, was read as UTC, four or five hours early. A serial now reads to the second, without the float noise pandas kept (#143)
- CI runs each job on the Python version it names. uv took the version from `.python-version` (3.10) instead of the interpreter `actions/setup-python` installed, so the `test (3.11)` and `test (3.12)` jobs and the live suite, set up on 3.12, all ran on 3.10, and so did the release gate that calls the `Tests` workflow. The 3.11 and 3.12 jobs now also run numpy 2.3.5, which the lock installs from 3.11 on. `Lint` and the release build run on the 3.12 they set up as well (#156)
- The `no_data` DataFrame and the header-only CSV carry the requested columns under a `columns=` filter, in request order, as a populated answer does; API names select the human-readable twins under `use_human_readable=True`, and under `add_headers=False` the empty CSV is an empty file. Known limit: the API's own aliases (`open` for `o`, `price`, `date`) are not translated, because the accepted set depends on the endpoint, so filtering on one of those still gives an empty frame of a different shape than the populated answer (#87)
- A `404` `no_data` whose body is not JSON (a CDN or a proxy answering the 404 without one) returns the empty result on the JSON output too, instead of raising `ParseError` there while the other three formats returned their empty value: the output format never decides whether a call raises (#87)
- The CSV fan-out merge compares the headers of two answers through the same case- and space-insensitive key it validates them with, so the same column spelled differently no longer fails a valid request; a different column order is still refused (#86)
Expand Down
Loading