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
Binary file modified .chainlink/issues.db
Binary file not shown.
61 changes: 40 additions & 21 deletions .github/workflows/uv-publish-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#

name: Build and upload package to PyPI

on:
Expand All @@ -9,38 +7,59 @@ on:

permissions:
contents: read
id-token: write

jobs:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

uv-build-release-pypi-publish:
name: "Build release distribution and publish to PyPI"
jobs:
build:
name: Build release distribution
runs-on: ubuntu-latest
environment:
name: pypi


steps:
- uses: actions/checkout@v5
- name: "Set up Python"

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

- name: Install uv
uses: astral-sh/setup-uv@v6

with:
enable-cache: true

- name: Install project
run: uv sync --all-extras --dev
# TODO Better to use --locked for author control over versions?
# run: uv sync --locked --all-extras --dev

run: uv sync --locked --all-extras --dev

- name: Build release distributions
run: uv build

- name: Publish to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.UV_PUBLISH_TOKEN }}
run: uv publish

- name: Upload dist artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

##
publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: build
environment:
name: pypi
url: https://pypi.org/project/atdata/

steps:
- name: Download dist artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Publish to PyPI
run: uv publish --trusted-publishing always dist/*
59 changes: 40 additions & 19 deletions .github/workflows/uv-test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#

name: Run tests with `uv`

on:
Expand All @@ -11,33 +9,60 @@ on:
branches:
- main

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
uv-test:
name: Run tests
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true

- name: Install the project
run: uv sync --locked --dev

- name: Run ruff check
run: uv run ruff check src/ tests/

- name: Run ruff format check
run: uv run ruff format --check src/ tests/

test:
name: Test (py${{ matrix.python-version }}, redis${{ matrix.redis-version }})
runs-on: ubuntu-latest
environment:
name: test
strategy:
fail-fast: false
matrix:
python-version: [3.12, 3.13, 3.14]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
redis-version: [6, 7]

steps:
- uses: actions/checkout@v5

- name: "Set up Python"
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
# python-version-file: "pyproject.toml"

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true

- name: Install the project
run: uv sync --all-extras --dev
# TODO Better to use --locked for author control over versions?
# run: uv sync --locked --all-extras --dev
run: uv sync --locked --all-extras --dev

- name: Start Redis
uses: supercharge/redis-github-action@1.8.1
Expand All @@ -47,12 +72,8 @@ jobs:
- name: Run tests with coverage
run: uv run pytest --cov=atdata --cov-report=xml --cov-report=term

# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v5
# with:
# # file: ./coverage.xml # Claude hallucination -- fascinating!
# fail_ci_if_error: false
# token: ${{ secrets.CODECOV_TOKEN }}


#
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
# Don't commit any .env files
**/*.env
# Don't commit `uv` lockfiles
**/uv.lock
# (SIKE it turns out we actually do want to commit)
# **/uv.lock
# Development tooling (keep local, not in upstream)
# (SIKE it turns out we actually do want to commit)
# .chainlink/
# .claude/

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Comprehensive integration test suite**: 593 tests covering E2E flows, error handling, edge cases

### Changed
- Review GitHub workflows and recommend CI improvements (#405)
- Fix type signatures for Dataset.ordered and Dataset.shuffled (GH#28) (#404)
- Investigate quartodoc Example section rendering - missing CSS classes on pre/code tags (#401)
- Update all docstrings from Example: to Examples: format (#403)
- Create GitHub issues for v0.3 roadmap feature domains (#402)
- Expand Quarto documentation with architectural narrative (#395)
- Expand atmosphere tutorial with federation context (#400)
- Expand local-workflow tutorial with system narrative (#399)
Expand Down
66 changes: 28 additions & 38 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ def test_repo_insert_with_s3(mock_s3, clean_redis):

## Docstring Formatting

This project uses **Google-style docstrings** with quartodoc for API documentation generation. The most important formatting requirement is for **Example sections**.
This project uses **Google-style docstrings** with quartodoc for API documentation generation. The most important formatting requirement is for **Examples sections**.

### Example Section Format
### Examples Section Format

Example sections must use reStructuredText literal block syntax (`::`) to render correctly in quartodoc-generated documentation:
Use `Examples:` (plural) for code examples. This is recognized by griffe's Google docstring parser and rendered with proper syntax highlighting by quartodoc:

```python
def my_function():
Expand All @@ -227,50 +227,44 @@ def my_function():
Returns:
Description of return value.

Example:
::

>>> result = my_function()
>>> print(result)
'output'
Examples:
>>> result = my_function()
>>> print(result)
'output'
"""
```

**Key formatting rules:**

1. `Example:` with a colon, 4-space indented from the docstring margin
2. `::` on its own line, 8-space indented (4 more than `Example:`)
3. Blank line after `::`
4. Code examples indented 12 spaces (4 more than `::`)
5. Use `>>>` for Python prompts and `...` for continuation lines
1. Use `Examples:` (plural, not `Example:` singular)
2. Code examples are indented 8 spaces (4 more than `Examples:`)
3. Use `>>>` for Python prompts and `...` for continuation lines
4. No `::` marker needed - griffe handles the parsing automatically

**Incorrect format (will not render properly):**
**Incorrect format (will not render with syntax highlighting):**
```python
Example:
>>> code_here() # Wrong - missing :: and extra indentation
Example: # Wrong - singular form is treated as an admonition
:: # Wrong - reST literal block marker not needed
>>> code_here()
```

**Correct format:**
```python
Example:
::

>>> code_here() # Correct - has :: and proper indentation
Examples:
>>> code_here() # Correct - plural form, proper indentation
```

### Multiple Examples

For multiple examples, use the same pattern:
For multiple examples, continue in the same section:

```python
Example:
::

>>> # First example
>>> x = create_thing()
Examples:
>>> # First example
>>> x = create_thing()

>>> # Second example
>>> y = other_thing()
>>> # Second example
>>> y = other_thing()
```

### Class and Method Docstrings
Expand All @@ -281,20 +275,16 @@ Apply the same format to class docstrings and method docstrings:
class MyClass:
"""Class description.

Example:
::

>>> obj = MyClass()
>>> obj.do_something()
Examples:
>>> obj = MyClass()
>>> obj.do_something()
"""

def method(self):
"""Method description.

Example:
::

>>> self.method()
Examples:
>>> self.method()
"""
```

Expand Down
15 changes: 7 additions & 8 deletions docs/api/AbstractDataStore.html
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ <h2 id="toc-title">On this page</h2>
<ul>
<li><a href="#atdata.AbstractDataStore" id="toc-atdata.AbstractDataStore" class="nav-link active" data-scroll-target="#atdata.AbstractDataStore">AbstractDataStore</a>
<ul class="collapse">
<li><a href="#example" id="toc-example" class="nav-link" data-scroll-target="#example">Example</a></li>
<li><a href="#examples" id="toc-examples" class="nav-link" data-scroll-target="#examples">Examples</a></li>
<li><a href="#methods" id="toc-methods" class="nav-link" data-scroll-target="#methods">Methods</a>
<ul class="collapse">
<li><a href="#atdata.AbstractDataStore.read_url" id="toc-atdata.AbstractDataStore.read_url" class="nav-link" data-scroll-target="#atdata.AbstractDataStore.read_url">read_url</a></li>
Expand All @@ -426,13 +426,12 @@ <h1>AbstractDataStore</h1>
<p>Protocol for data storage operations.</p>
<p>This protocol abstracts over different storage backends for dataset data: - S3DataStore: S3-compatible object storage - PDSBlobStore: ATProto PDS blob storage (future)</p>
<p>The separation of index (metadata) from data store (actual files) allows flexible deployment: local index with S3 storage, atmosphere index with S3 storage, or atmosphere index with PDS blobs.</p>
<section id="example" class="level2 doc-section doc-section-example">
<h2 class="doc-section doc-section-example anchored" data-anchor-id="example">Example</h2>
<p>::</p>
<pre><code>&gt;&gt;&gt; store = S3DataStore(credentials, bucket="my-bucket")
&gt;&gt;&gt; urls = store.write_shards(dataset, prefix="training/v1")
&gt;&gt;&gt; print(urls)
['s3://my-bucket/training/v1/shard-000000.tar', ...]</code></pre>
<section id="examples" class="level2 doc-section doc-section-examples">
<h2 class="doc-section doc-section-examples anchored" data-anchor-id="examples">Examples</h2>
<div class="sourceCode" id="cb2"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> store <span class="op">=</span> S3DataStore(credentials, bucket<span class="op">=</span><span class="st">"my-bucket"</span>)</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> urls <span class="op">=</span> store.write_shards(dataset, prefix<span class="op">=</span><span class="st">"training/v1"</span>)</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="bu">print</span>(urls)</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>[<span class="st">'s3://my-bucket/training/v1/shard-000000.tar'</span>, ...]</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
</section>
<section id="methods" class="level2">
<h2 class="anchored" data-anchor-id="methods">Methods</h2>
Expand Down
Loading