Skip to content

Commit af551a4

Browse files
committed
docs pipeline standardization and minor doc fixes
1 parent a8d97fc commit af551a4

8 files changed

Lines changed: 88 additions & 51 deletions

File tree

.github/workflows/publish.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,4 @@ jobs:
4848
source_repo: clamsproject/clams-python
4949
source_ref: ${{ needs.check-pypi.outputs.version }}
5050
project_name: clams-python
51-
build_command: 'echo "${{ needs.check-pypi.outputs.version }}" > VERSION && python3 build-tools/docs.py --output-dir docs'
52-
docs_output_dir: 'docs'
53-
python_version: '3.11'
5451
secrets: inherit

build-tools/docs.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ def main():
7676
parser = argparse.ArgumentParser(
7777
description="Build documentation for the clams-python project."
7878
)
79+
parser.add_argument(
80+
'--build-ver',
81+
metavar='<version>',
82+
default=None,
83+
help='Accepted for CLI compatibility with other SDK repos. '
84+
'Ignored by this script (clams-python uses '
85+
'unversioned documentation).')
7986
parser.add_argument(
8087
'--output-dir', type=Path, default=None,
8188
help='Output directory for built docs (default: docs-test)')

clams/appmetadata/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,18 @@ def add_input(self, at_type: Union[str, vocabulary.ThingTypesBase], required: bo
438438
return new
439439

440440
def add_input_oneof(self, *inputs: Union[str, Input, vocabulary.ThingTypesBase]):
441+
"""
442+
Helper method to add a ``oneOf`` (disjunctive) group to
443+
the ``input`` list. When a single type is given, it is
444+
added as a regular (conjunctive) input. When multiple
445+
types are given, they are wrapped in a nested list to
446+
indicate that exactly one of them is required.
447+
448+
:param inputs: one or more input types (as URI strings,
449+
:class:`Input` objects, or vocabulary types)
450+
:raises ValueError: if any input in a ``oneOf`` group is
451+
optional, or if a duplicate input is detected
452+
"""
441453
newinputs = []
442454
if len(inputs) == 1:
443455
if isinstance(inputs[0], Input):
@@ -520,6 +532,13 @@ def add_more(self, key: str, value: str):
520532
raise ValueError("Key and value should not be empty!")
521533

522534
def jsonify(self, pretty=False):
535+
"""
536+
Serialize the app metadata to a JSON string.
537+
538+
:param pretty: if True, indent the output with 2 spaces
539+
:returns: JSON string of the metadata
540+
:rtype: str
541+
"""
523542
return self.model_dump_json(exclude_defaults=True, by_alias=True, indent=2 if pretty else None)
524543

525544

documentation/appmetadata.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Format
1313

1414
A CLAMS App Metadata should be able to be serialized into a JSON string.
1515

16-
Input/Output type specification
16+
Input/Output Type Specification
1717
===============================
1818

1919
Essentially, all CLAMS apps are designed to take one MMIF file as input and produce another MMIF file as output. In this
@@ -29,7 +29,7 @@ how that information should be formatted in terms of the App Metadata syntax, co
2929
additional information about submission. Visit the `CLAMS app directory <https://apps.clams.ai>`_ to see how the app
3030
metadata is rendered.
3131

32-
Annotation types in MMIF
32+
Annotation Types in MMIF
3333
------------------------
3434

3535
As described in the `MMIF documentation <https://mmif.clams.ai>`_, MMIF files can contain annotations of various types.
@@ -56,8 +56,8 @@ needs to add additional information to the type definition, they can do so by ad
5656
definition in action. In such a case, the app developer is expected to provide the explanation of the extended type in
5757
the app metadata. See below for the syntax of I/O specification in the app metadata.
5858

59-
Syntax for I/O specification in App Metadata
60-
--------------------------------------------
59+
Syntax for I/O Specification in App Metadata
60+
---------------------------------------------
6161

6262
In the App Metadata, the input and output types are specified as lists of objects. Each object in the list should have
6363
the following fields:
@@ -69,7 +69,7 @@ the following fields:
6969
defaults to ``true``. Not applicable for output types.
7070

7171

72-
Simple case - using types as defined in the vocabularies
72+
Simple Case - Using Types as Defined in the Vocabularies
7373
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7474

7575
In the simplest case, where a developer merely re-uses an annotation type definition and pre-defined properties, an
@@ -195,14 +195,14 @@ Note that in the actual output MMIF, more properties can be stored in the ``Time
195195
specification in the app metadata is a subset of the properties to be produced that are useful for type checking
196196
in the downstream apps, as well as for human readers to understand the output.
197197

198-
Extended case - adding custom properties to the type definition
198+
Extended Case - Adding Custom Properties to the Type Definition
199199
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200200

201201
When the type definition is extended on the fly, developers are expected to provide the extended specification in the
202202
form of key-value pairs in the ``properties`` field. The grammar of the JSON object does not change, but developers are
203203
expected to provide a verbose description of the type extension in the ``description`` field.
204204

205-
Runtime parameter specification
205+
Runtime Parameter Specification
206206
===============================
207207

208208
CLAMS apps designed to be run as HTTP servers, preferably as `stateless <https://en.wikipedia.org/wiki/Stateless_protocol>`_.
@@ -219,7 +219,7 @@ can be specified as ``multivalued=True`` to accept multiple values as a list. Fo
219219
parameter value parsing works, please refer to the App Metadata json scheme (in the `below <#clams-app-runtime-parameter>`_
220220
section).
221221

222-
Syntax for parameter specification in App Metadata
222+
Syntax for Parameter Specification in App Metadata
223223
--------------------------------------------------
224224

225225
Metadata Schema

documentation/cli.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
``clams`` shell command
44
=======================
55

6-
``clams-python`` comes with a command line interface (CLI) that allows you to
6+
``clams-python`` comes with a command line interface (CLI) for creating a new CLAMS app from a template (``develop`` subcommand).
77

8-
#. create a new CLAMS app from a template
9-
#. create a new MMIF file with selected source documents and an empty view
8+
The CLI is installed as the ``clams`` shell command. For backward compatibility, it also exposes all ``mmif`` subcommands (``source``, ``rewind``, ``describe``, ``summarize``). See the `mmif-python CLI documentation <https://clams.ai/mmif-python/cli>`_ for details on those commands.
109

11-
The CLI is installed as ``clams`` shell command. To see the available commands, run
10+
To see the available commands, run
1211

13-
.. code-block:: bash
12+
.. code-block:: bash
1413
1514
clams --help

documentation/conf.py

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
# documentation root, use os.path.abspath to make it absolute, like shown here.
1212

1313
import datetime
14-
from pathlib import Path
15-
import shutil
16-
import sys
1714
import inspect
15+
import json
1816
import os
17+
import re
18+
import shutil
19+
import subprocess
20+
import sys
21+
from pathlib import Path
1922

2023
import mmif
2124

@@ -134,40 +137,50 @@ def linkcode_resolve(domain, info):
134137

135138

136139
def generate_whatsnew_rst(app):
137-
import subprocess
140+
"""
141+
Generate whatsnew.md by fetching the latest release PR body
142+
from GitHub via ``gh pr list``.
143+
144+
Falls back gracefully if ``gh`` is unavailable (local builds).
145+
"""
138146
output_path = (proj_root_dir / 'documentation'
139147
/ 'whatsnew.md')
140-
content = None
148+
repo = f'clamsproject/{project}'
149+
141150
try:
142-
jq_expr = (
143-
'sort_by(.mergedAt)'
144-
' | if length > 0 then .[-1].body'
145-
' else "" end'
146-
)
147151
result = subprocess.run(
148152
['gh', 'pr', 'list',
149-
'-R', f'clamsproject/{project}',
150-
'-s', 'merged',
151-
'--search',
152-
f'releasing {version} in:title',
153-
'--json', 'body,mergedAt',
154-
'--jq', jq_expr],
155-
capture_output=True, text=True, timeout=10
153+
'-s', 'merged', '-B', 'main',
154+
'-L', '100',
155+
'--json', 'title,body',
156+
'--repo', repo],
157+
capture_output=True, text=True, timeout=15,
156158
)
157-
if result.returncode == 0:
158-
content = result.stdout.strip() or None
159-
except (FileNotFoundError, subprocess.TimeoutExpired):
160-
pass
159+
if result.returncode != 0:
160+
raise RuntimeError(result.stderr)
161+
162+
prs = json.loads(result.stdout)
163+
pr = next(
164+
(p for p in prs
165+
if p['title'].startswith('releasing ')),
166+
None,
167+
)
168+
if pr is None:
169+
raise RuntimeError("No release PR found")
170+
title = pr['title']
171+
body = pr.get('body', '')
161172

162-
with open(output_path, 'w') as f:
163-
if content:
164-
f.write(
165-
f"## What's New in {version}\n\n"
166-
f"(Full changelog available in the "
167-
f"[CHANGELOG.md]({blob_base_url}"
168-
f"/main/CHANGELOG.md))\n"
169-
)
170-
f.write(content)
173+
with open(output_path, 'w') as f:
174+
f.write(f"## {title}\n\n")
175+
f.write(f"(Full changelog: "
176+
f"[CHANGELOG.md]"
177+
f"({blob_base_url}/main/CHANGELOG.md))\n\n")
178+
if body:
179+
f.write(body)
180+
181+
except Exception as e:
182+
with open(output_path, 'w') as f:
183+
f.write("")
171184

172185

173186
def generate_jsonschema(app):
@@ -186,6 +199,9 @@ def update_target_spec(app):
186199
target_vers_csv = Path(__file__).parent / 'target-versions.csv'
187200
with open(proj_root_dir / "VERSION", 'r') as version_f:
188201
version = version_f.read().strip()
202+
# Skip dev/dummy versions to avoid dirtying the git-tracked CSV
203+
if 'dev' in version or not re.match(r'^\d+\.\d+\.\d+$', version):
204+
return
189205
mmifver = mmif.__version__
190206
specver = mmif.__specver__
191207
with open(target_vers_csv) as in_f, open(f'{target_vers_csv}.new', 'w') as out_f:

documentation/index.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Welcome to CLAMS Python SDK documentation!
2-
==========================================
1+
CLAMS Python SDK
2+
================
33

44
.. mdinclude:: ../README.md
55

@@ -28,9 +28,8 @@ Welcome to CLAMS Python SDK documentation!
2828

2929
modules
3030

31-
Indices and tables
31+
Indices and Tables
3232
==================
3333

3434
* :ref:`genindex`
3535
* :ref:`modindex`
36-
* :ref:`search`

documentation/introduction.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.. _introduction:
22

3-
Getting started
3+
Getting Started
44
===============
55

66
Overview

0 commit comments

Comments
 (0)