labapi 1.0.3__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. {labapi-1.0.3 → labapi-1.1.0}/.github/ISSUE_TEMPLATE/bug_report.yml +2 -0
  2. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/docs.yml +2 -2
  3. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/format.yml +0 -1
  4. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/integration_tests.yml +1 -1
  5. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/lint.yml +0 -1
  6. labapi-1.1.0/.github/workflows/pages.yml +91 -0
  7. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/publish.yml +2 -2
  8. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/python_check.yml +1 -1
  9. {labapi-1.0.3 → labapi-1.1.0}/.gitignore +2 -2
  10. labapi-1.1.0/.python-version +1 -0
  11. labapi-1.1.0/CHANGELOG.md +99 -0
  12. {labapi-1.0.3/src/labapi.egg-info → labapi-1.1.0}/PKG-INFO +18 -14
  13. {labapi-1.0.3 → labapi-1.1.0}/README.md +12 -11
  14. labapi-1.1.0/conftest.py +467 -0
  15. labapi-1.1.0/docs/source/_templates/version-switcher.html +25 -0
  16. {labapi-1.0.3 → labapi-1.1.0}/docs/source/conf.py +25 -1
  17. {labapi-1.0.3 → labapi-1.1.0}/docs/source/examples/csv_table.rst +19 -9
  18. {labapi-1.0.3 → labapi-1.1.0}/docs/source/examples/folder_download.rst +37 -3
  19. {labapi-1.0.3 → labapi-1.1.0}/docs/source/examples/index.rst +6 -5
  20. {labapi-1.0.3 → labapi-1.1.0}/docs/source/examples/json_sync.rst +31 -2
  21. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/contributing.rst +4 -2
  22. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/entries.rst +29 -6
  23. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/paths.rst +41 -2
  24. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/creating_pages.rst +1 -4
  25. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/installation.rst +1 -1
  26. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/uploading_files.rst +17 -6
  27. labapi-1.1.0/examples/csv_table/README.md +63 -0
  28. labapi-1.1.0/examples/csv_table/csv_table.py +357 -0
  29. {labapi-1.0.3 → labapi-1.1.0}/examples/csv_table/pyproject.toml +1 -3
  30. labapi-1.1.0/examples/folder_download/README.md +93 -0
  31. labapi-1.1.0/examples/folder_download/folder_download.py +349 -0
  32. {labapi-1.0.3 → labapi-1.1.0}/examples/folder_download/pyproject.toml +1 -0
  33. labapi-1.1.0/examples/json_sync/README.md +82 -0
  34. labapi-1.1.0/examples/json_sync/json_sync.py +266 -0
  35. {labapi-1.0.3 → labapi-1.1.0}/examples/json_sync/pyproject.toml +0 -3
  36. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/README.md +4 -1
  37. {labapi-1.0.3 → labapi-1.1.0}/examples/notebook_logging/README.md +4 -2
  38. {labapi-1.0.3 → labapi-1.1.0}/examples/notebook_logging/notebook_logger.py +13 -14
  39. {labapi-1.0.3 → labapi-1.1.0}/pyproject.toml +129 -135
  40. {labapi-1.0.3 → labapi-1.1.0}/pyrightconfig.json +1 -1
  41. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/__init__.py +2 -0
  42. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/client.py +4 -14
  43. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/__init__.py +2 -1
  44. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/attachment.py +226 -191
  45. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/collection.py +21 -8
  46. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/entries/__init__.py +2 -1
  47. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/entries/attachment.py +3 -1
  48. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/entries/base.py +50 -15
  49. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/entries/text.py +3 -1
  50. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/entries/unknown.py +27 -3
  51. labapi-1.1.0/src/labapi/entry/entries/widget.py +22 -0
  52. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/tree/collection.py +3 -1
  53. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/tree/directory.py +1 -1
  54. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/tree/mixins.py +13 -6
  55. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/tree/notebook.py +19 -3
  56. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/tree/page.py +36 -40
  57. labapi-1.1.0/src/labapi/tree/search.py +118 -0
  58. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/util/__init__.py +4 -14
  59. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/util/browser.py +131 -125
  60. labapi-1.1.0/src/labapi/util/env.py +43 -0
  61. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/util/extract.py +4 -2
  62. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/util/path.py +187 -121
  63. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/util/types.py +6 -6
  64. {labapi-1.0.3 → labapi-1.1.0/src/labapi.egg-info}/PKG-INFO +18 -14
  65. {labapi-1.0.3 → labapi-1.1.0}/src/labapi.egg-info/SOURCES.txt +6 -0
  66. {labapi-1.0.3 → labapi-1.1.0}/src/labapi.egg-info/requires.txt +1 -0
  67. labapi-1.1.0/tests/__init__.py +1 -0
  68. {labapi-1.0.3 → labapi-1.1.0}/tests/conftest.py +4 -4
  69. labapi-1.1.0/tests/entry/__init__.py +1 -0
  70. labapi-1.1.0/tests/entry/entries/__init__.py +1 -0
  71. {labapi-1.0.3 → labapi-1.1.0}/tests/entry/entries/test_attachment.py +10 -12
  72. labapi-1.1.0/tests/entry/entries/test_base.py +117 -0
  73. {labapi-1.0.3 → labapi-1.1.0}/tests/entry/entries/test_text.py +15 -18
  74. {labapi-1.0.3 → labapi-1.1.0}/tests/entry/entries/test_widget.py +5 -2
  75. {labapi-1.0.3 → labapi-1.1.0}/tests/entry/test_attachment.py +52 -14
  76. {labapi-1.0.3 → labapi-1.1.0}/tests/entry/test_collection.py +31 -89
  77. labapi-1.1.0/tests/examples/__init__.py +1 -0
  78. labapi-1.1.0/tests/examples/test_csv_table.py +246 -0
  79. labapi-1.1.0/tests/examples/test_folder_download.py +357 -0
  80. labapi-1.1.0/tests/examples/test_json_sync.py +331 -0
  81. {labapi-1.0.3 → labapi-1.1.0}/tests/test_browser.py +191 -175
  82. {labapi-1.0.3 → labapi-1.1.0}/tests/test_client.py +53 -35
  83. {labapi-1.0.3 → labapi-1.1.0}/tests/test_integration.py +18 -18
  84. {labapi-1.0.3 → labapi-1.1.0}/tests/test_user.py +15 -18
  85. labapi-1.1.0/tests/tree/__init__.py +1 -0
  86. {labapi-1.0.3 → labapi-1.1.0}/tests/tree/test_collection.py +15 -18
  87. {labapi-1.0.3 → labapi-1.1.0}/tests/tree/test_directory.py +12 -34
  88. {labapi-1.0.3 → labapi-1.1.0}/tests/tree/test_mixins.py +115 -137
  89. labapi-1.1.0/tests/tree/test_notebook.py +270 -0
  90. {labapi-1.0.3 → labapi-1.1.0}/tests/tree/test_page.py +117 -106
  91. labapi-1.1.0/tests/util/__init__.py +1 -0
  92. labapi-1.1.0/tests/util/test_path.py +346 -0
  93. {labapi-1.0.3 → labapi-1.1.0}/uv.lock +671 -129
  94. labapi-1.0.3/conftest.py +0 -391
  95. labapi-1.0.3/examples/csv_table/README.md +0 -58
  96. labapi-1.0.3/examples/csv_table/csv_table.py +0 -299
  97. labapi-1.0.3/examples/folder_download/README.md +0 -60
  98. labapi-1.0.3/examples/folder_download/folder_download.py +0 -224
  99. labapi-1.0.3/examples/json_sync/README.md +0 -55
  100. labapi-1.0.3/examples/json_sync/json_sync.py +0 -212
  101. labapi-1.0.3/src/labapi/entry/entries/widget.py +0 -29
  102. labapi-1.0.3/tests/__init__.py +0 -1
  103. labapi-1.0.3/tests/entry/__init__.py +0 -1
  104. labapi-1.0.3/tests/entry/entries/__init__.py +0 -1
  105. labapi-1.0.3/tests/entry/entries/test_base.py +0 -66
  106. labapi-1.0.3/tests/examples/__init__.py +0 -1
  107. labapi-1.0.3/tests/examples/test_csv_table.py +0 -153
  108. labapi-1.0.3/tests/examples/test_folder_download.py +0 -89
  109. labapi-1.0.3/tests/examples/test_json_sync.py +0 -149
  110. labapi-1.0.3/tests/tree/__init__.py +0 -1
  111. labapi-1.0.3/tests/tree/test_notebook.py +0 -47
  112. labapi-1.0.3/tests/util/__init__.py +0 -1
  113. labapi-1.0.3/tests/util/test_path.py +0 -143
  114. {labapi-1.0.3 → labapi-1.1.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  115. {labapi-1.0.3 → labapi-1.1.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  116. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/typecheck.yml +0 -0
  117. {labapi-1.0.3 → labapi-1.1.0}/.github/workflows/unit_tests.yml +0 -0
  118. {labapi-1.0.3 → labapi-1.1.0}/.mockenv +0 -0
  119. {labapi-1.0.3 → labapi-1.1.0}/.pre-commit-config.yaml +0 -0
  120. {labapi-1.0.3 → labapi-1.1.0}/.zenodo.json +0 -0
  121. {labapi-1.0.3 → labapi-1.1.0}/CLAUDE.md +0 -0
  122. {labapi-1.0.3 → labapi-1.1.0}/CONTRIBUTING.md +0 -0
  123. {labapi-1.0.3 → labapi-1.1.0}/LICENSE +0 -0
  124. {labapi-1.0.3 → labapi-1.1.0}/docs/Makefile +0 -0
  125. {labapi-1.0.3 → labapi-1.1.0}/docs/make.bat +0 -0
  126. {labapi-1.0.3 → labapi-1.1.0}/docs/source/_static/.gitkeep +0 -0
  127. {labapi-1.0.3 → labapi-1.1.0}/docs/source/_templates/custom-class-template.rst +0 -0
  128. {labapi-1.0.3 → labapi-1.1.0}/docs/source/_templates/custom-module-template.rst +0 -0
  129. {labapi-1.0.3 → labapi-1.1.0}/docs/source/faq.rst +0 -0
  130. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/api_calls.rst +0 -0
  131. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/architecture.rst +0 -0
  132. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/auth.rst +0 -0
  133. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/clearing_cache.rst +0 -0
  134. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/exceptions.rst +0 -0
  135. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/index.rst +0 -0
  136. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/index_access.rst +0 -0
  137. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/integration_design.rst +0 -0
  138. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/json_entries.rst +0 -0
  139. {labapi-1.0.3 → labapi-1.1.0}/docs/source/guide/limitations.rst +0 -0
  140. {labapi-1.0.3 → labapi-1.1.0}/docs/source/index.rst +0 -0
  141. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/copying.rst +0 -0
  142. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/deleting.rst +0 -0
  143. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/first_calls.rst +0 -0
  144. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/index.rst +0 -0
  145. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/navigating.rst +0 -0
  146. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/tutorial.rst +0 -0
  147. {labapi-1.0.3 → labapi-1.1.0}/docs/source/quick_start/writing_rich_text.rst +0 -0
  148. {labapi-1.0.3 → labapi-1.1.0}/docs/source/reference/index.rst +0 -0
  149. {labapi-1.0.3 → labapi-1.1.0}/examples/csv_table/sample_data.csv +0 -0
  150. {labapi-1.0.3 → labapi-1.1.0}/examples/folder_download/populate_notebook.py +0 -0
  151. {labapi-1.0.3 → labapi-1.1.0}/examples/json_sync/sample_data/config.json +0 -0
  152. {labapi-1.0.3 → labapi-1.1.0}/examples/json_sync/sample_data/results.json +0 -0
  153. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/model_logger.py +0 -0
  154. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/pyproject.toml +0 -0
  155. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/run_test.py +0 -0
  156. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/test_data/dummy_figure.png +0 -0
  157. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/test_data/metrics.json +0 -0
  158. {labapi-1.0.3 → labapi-1.1.0}/examples/model_logging/test_data/results.csv +0 -0
  159. {labapi-1.0.3 → labapi-1.1.0}/examples/notebook_logging/.gitignore +0 -0
  160. {labapi-1.0.3 → labapi-1.1.0}/examples/notebook_logging/example.ipynb +0 -0
  161. {labapi-1.0.3 → labapi-1.1.0}/examples/notebook_logging/pyproject.toml +0 -0
  162. {labapi-1.0.3 → labapi-1.1.0}/setup.cfg +0 -0
  163. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/entry/comment.py +0 -0
  164. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/exceptions.py +0 -0
  165. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/py.typed +0 -0
  166. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/tree/__init__.py +0 -0
  167. {labapi-1.0.3 → labapi-1.1.0}/src/labapi/user.py +0 -0
  168. {labapi-1.0.3 → labapi-1.1.0}/src/labapi.egg-info/dependency_links.txt +0 -0
  169. {labapi-1.0.3 → labapi-1.1.0}/src/labapi.egg-info/top_level.txt +0 -0
  170. {labapi-1.0.3 → labapi-1.1.0}/tests/test_entry.json +0 -0
  171. {labapi-1.0.3 → labapi-1.1.0}/tests/util/test_behavior.py +0 -0
  172. {labapi-1.0.3 → labapi-1.1.0}/tests/util/test_extract.py +0 -0
  173. {labapi-1.0.3 → labapi-1.1.0}/tests/util/test_index.py +0 -0
  174. {labapi-1.0.3 → labapi-1.1.0}/tests/util/test_notebookinit.py +0 -0
@@ -30,6 +30,8 @@ body:
30
30
  label: Python version
31
31
  description: Which Python version reproduces the issue?
32
32
  options:
33
+ - "3.10"
34
+ - "3.11"
33
35
  - "3.12"
34
36
  - "3.13"
35
37
  - Other
@@ -20,10 +20,10 @@ jobs:
20
20
  version: "latest"
21
21
 
22
22
  - name: Set up Python
23
- run: uv python install 3.13
23
+ run: uv python install
24
24
 
25
25
  - name: Install dependencies
26
26
  run: uv sync --all-groups
27
27
 
28
28
  - name: Build Sphinx docs
29
- run: uv run sphinx-build -b html docs/source docs/_build
29
+ run: uv run sphinx-build -b html docs/source docs/_build/html
@@ -10,4 +10,3 @@ jobs:
10
10
  with:
11
11
  job_name: Ruff format
12
12
  command: uv run ruff format --check .
13
- python_versions: '["3.13"]'
@@ -27,7 +27,7 @@ jobs:
27
27
  version: "latest"
28
28
 
29
29
  - name: Set up Python
30
- run: uv python install 3.13
30
+ run: uv python install 3.10
31
31
 
32
32
  - name: Install dependencies
33
33
  run: uv sync --all-groups
@@ -10,4 +10,3 @@ jobs:
10
10
  with:
11
11
  job_name: Ruff lint
12
12
  command: uv run ruff check .
13
- python_versions: '["3.13"]'
@@ -0,0 +1,91 @@
1
+ name: Pages
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+ pages: write
12
+ id-token: write
13
+
14
+ concurrency:
15
+ group: pages
16
+ cancel-in-progress: false
17
+
18
+ jobs:
19
+ build:
20
+ name: Build docs site
21
+ runs-on: ubuntu-latest
22
+ env:
23
+ # Older release tags import typing.Self and typing.override.
24
+ UV_PYTHON: "3.12"
25
+
26
+ steps:
27
+ - name: Checkout code
28
+ uses: actions/checkout@v5
29
+ with:
30
+ fetch-depth: 0
31
+
32
+ - name: Configure GitHub Pages
33
+ uses: actions/configure-pages@v5
34
+
35
+ - name: Install uv
36
+ uses: astral-sh/setup-uv@v7
37
+ with:
38
+ enable-cache: true
39
+ version: "latest"
40
+
41
+ - name: Set up Python
42
+ run: uv python install
43
+
44
+ - name: Install dependencies
45
+ run: uv sync --all-groups
46
+
47
+ - name: Build versioned Sphinx docs
48
+ run: uv run sphinx-multiversion docs/source docs/_build/html
49
+
50
+ - name: Add Pages root files
51
+ run: |
52
+ set -eu
53
+ latest="$(find docs/_build/html -maxdepth 1 -mindepth 1 -type d -printf '%f\n' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1)"
54
+ if [ -z "$latest" ]; then
55
+ echo "No versioned docs directories found." >&2
56
+ exit 1
57
+ fi
58
+
59
+ touch docs/_build/html/.nojekyll
60
+ cat > docs/_build/html/index.html <<EOF
61
+ <!doctype html>
62
+ <html lang="en">
63
+ <head>
64
+ <meta charset="utf-8">
65
+ <meta http-equiv="refresh" content="0; url=./${latest}/index.html">
66
+ <link rel="canonical" href="./${latest}/index.html">
67
+ <title>Redirecting...</title>
68
+ </head>
69
+ <body>
70
+ <p>Redirecting to <a href="./${latest}/index.html">${latest}</a>.</p>
71
+ </body>
72
+ </html>
73
+ EOF
74
+
75
+ - name: Upload Pages artifact
76
+ uses: actions/upload-pages-artifact@v4
77
+ with:
78
+ path: docs/_build/html
79
+
80
+ deploy:
81
+ name: Deploy docs site
82
+ runs-on: ubuntu-latest
83
+ needs: build
84
+ environment:
85
+ name: github-pages
86
+ url: ${{ steps.deployment.outputs.page_url }}
87
+
88
+ steps:
89
+ - name: Deploy to GitHub Pages
90
+ id: deployment
91
+ uses: actions/deploy-pages@v4
@@ -31,10 +31,10 @@ jobs:
31
31
  version: "latest"
32
32
 
33
33
  - name: Set up Python
34
- run: uv python install 3.13
34
+ run: uv python install 3.10
35
35
 
36
36
  - name: Build distributions
37
- run: uv build --python 3.13 --clear --no-build-logs
37
+ run: uv build --python 3.10 --clear --no-build-logs
38
38
 
39
39
  - name: Publish to PyPI
40
40
  run: uv publish --trusted-publishing always
@@ -16,7 +16,7 @@ on:
16
16
  python_versions:
17
17
  required: false
18
18
  type: string
19
- default: '["3.12", "3.13"]'
19
+ default: '["3.10", "3.11", "3.12", "3.13"]'
20
20
 
21
21
  jobs:
22
22
  check:
@@ -11,7 +11,6 @@ wheels/
11
11
  .venv
12
12
 
13
13
  .env
14
- .python-version
15
14
  .ruff_cache/
16
15
  .mypy_cache/
17
16
 
@@ -52,4 +51,5 @@ docs/source/reference/generated/
52
51
 
53
52
 
54
53
  .ipynb-checkpoints
55
- .tmpdocs
54
+ .tmpdocs
55
+ .complexipy_cache/
@@ -0,0 +1 @@
1
+ 3.10
@@ -0,0 +1,99 @@
1
+ # Changelog
2
+
3
+ All notable changes to `labapi` are documented here in release order.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ This changelog is written for package users and maintainers, so entries call
8
+ out user-visible behavior, supported runtime changes, and release-engineering
9
+ details that affect development workflows.
10
+
11
+ ## 1.1.0 - 2026-06-02
12
+
13
+ ### Added
14
+
15
+ - `Attachment.from_file()` now accepts filesystem `str` or `Path` objects in
16
+ addition to file-like objects.
17
+ - `Notebook.search()` for paginated LabArchives entry search results using
18
+ normal entry objects.
19
+ - Support for escaped separators (`\/`) in notebook paths, enabling access to
20
+ and creation of notebook nodes with literal slashes in their names.
21
+ - Official support for Python 3.10 and 3.11.
22
+ - `typing-extensions` as a runtime dependency so code can use backported typing
23
+ helpers such as `Self`, `override`, and `Buffer` while supporting Python 3.10.
24
+ - Lazy environment-variable loading through `labapi.util.env.getenv()`. When
25
+ `python-dotenv` is installed, `.env` is loaded on first credential lookup
26
+ instead of during `labapi.client` import.
27
+
28
+ ### Changed
29
+
30
+ - Refactored the `json_sync` example into a reusable utility with
31
+ comprehensive tests.
32
+ - Rewrote the `csv_table` example for improved clarity and usability.
33
+ - Refactored the `folder_download` example into clearer reusable download
34
+ logic.
35
+ - Reworked entry factory fallback handling. Unknown upstream LabArchives part
36
+ types now load as `UnknownEntry`, while recognized but unimplemented part
37
+ types load as `UnimplementedEntry`; both still reject unsupported updates.
38
+ - Updated attachment cloning to use an explicit random-access capability check
39
+ instead of requiring every file-like object to expose a reliable
40
+ `seekable()` method.
41
+ - Kept spooled attachment buffers open after `Attachment.from_file()` returns,
42
+ while still preserving the caller's original file cursor position.
43
+
44
+ ### Fixed
45
+
46
+ - Fixed runtime typing in `Attachment.from_file()` to support both file-like
47
+ and path-like inputs correctly.
48
+ - Improved `Attachment.from_file()` support for random-access binary streams
49
+ that do not expose `seekable()`.
50
+ - Fixed relative path resolution bugs when using the `/` operator with absolute
51
+ and relative `NotebookPath` objects.
52
+
53
+ ## 1.0.3 - 2026-04-15
54
+
55
+ ### Changed
56
+
57
+ - Refined the client auth flow and browser detection behavior.
58
+ - Simplified tree path handling.
59
+ - Switched the `1.0` type-check workflow from `mypy` to `ty`.
60
+ - Refreshed package metadata, README content, and Zenodo configuration.
61
+ - Updated `pillow` and `pytest`.
62
+
63
+ ### Fixed
64
+
65
+ - Restored datetime-based URL signing support.
66
+ - Improved browser detection robustness when detectable values arrive with
67
+ incorrect types.
68
+ - Fixed test compatibility issues in the `1.0` maintenance branch.
69
+ - Reduced tree creation complexity in the `v1.0.3` stabilization pass.
70
+
71
+ ## 1.0.2 - 2026-04-10
72
+
73
+ ### Changed
74
+
75
+ - Cleaned up the PyPI README and related package metadata.
76
+
77
+ ## 1.0.1 - 2026-04-10
78
+
79
+ ### Added
80
+
81
+ - Initial TestPyPI publishing workflow.
82
+ - GitHub issue templates.
83
+ - Reusable GitHub Actions checks and broader local tooling support.
84
+
85
+ ### Changed
86
+
87
+ - Improved versioning and generated documentation metadata.
88
+ - Refreshed contributor and Sphinx configuration docs.
89
+ - Updated `cryptography`, `pygments`, and `requests`.
90
+
91
+ ## 1.0.0 - 2026-04-01
92
+
93
+ ### Added
94
+
95
+ - Initial stable release of `labapi`.
96
+ - Support for LabArchives authentication, notebook tree traversal, and
97
+ page and entry operations from Python.
98
+ - Project documentation and example workflows for common notebook automation
99
+ tasks.
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: labapi
3
- Version: 1.0.3
3
+ Version: 1.1.0
4
4
  Summary: A Python client for the LabArchives API.
5
5
  Author-email: Christoph Li <christoph.li@nih.gov>, Joshua Lawrimore <josh.lawrimore@nih.gov>
6
6
  License: CC0-1.0
7
- Project-URL: Documentation, https://github.com/nimh-dsst/labapi/tree/main/docs/source
7
+ Project-URL: Documentation, https://nimh-dsst.github.io/labapi/
8
8
  Project-URL: Issues, https://github.com/nimh-dsst/labapi/issues
9
9
  Project-URL: Source, https://github.com/nimh-dsst/labapi
10
10
  Classifier: Development Status :: 5 - Production/Stable
@@ -15,6 +15,8 @@ Classifier: Natural Language :: English
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
18
20
  Classifier: Programming Language :: Python :: 3.12
19
21
  Classifier: Programming Language :: Python :: 3.13
20
22
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -23,12 +25,13 @@ Classifier: Topic :: Scientific/Engineering
23
25
  Classifier: Topic :: Software Development :: Libraries
24
26
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
27
  Classifier: Typing :: Typed
26
- Requires-Python: >=3.12
28
+ Requires-Python: >=3.10
27
29
  Description-Content-Type: text/markdown
28
30
  License-File: LICENSE
29
31
  Requires-Dist: cryptography>=46.0.3
30
32
  Requires-Dist: lxml>=6.0.2
31
33
  Requires-Dist: requests>=2.32.5
34
+ Requires-Dist: typing-extensions>=4.12.2
32
35
  Provides-Extra: builtin-auth
33
36
  Requires-Dist: selenium>=4.39.0; extra == "builtin-auth"
34
37
  Requires-Dist: installed-browsers>=0.1.5; extra == "builtin-auth"
@@ -40,25 +43,26 @@ Dynamic: license-file
40
43
 
41
44
  A Python client for the LabArchives API.
42
45
 
43
- [![Python Version](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
46
+ [![Python Version](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
44
47
  [![Tests](https://github.com/nimh-dsst/labapi/actions/workflows/unit_tests.yml/badge.svg?branch=main)](https://github.com/nimh-dsst/labapi/actions/workflows/unit_tests.yml)
48
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19599400.svg)](https://doi.org/10.5281/zenodo.19599400)
45
49
  [![License: CC0-1.0](https://img.shields.io/badge/License-CC0_1.0-lightgrey.svg)](https://creativecommons.org/publicdomain/zero/1.0/)
46
50
 
47
51
  `labapi` helps you authenticate with LabArchives, navigate notebook trees, and create or update notebook content from Python.
48
52
 
49
- [Source](https://github.com/nimh-dsst/labapi) | [Docs](https://github.com/nimh-dsst/labapi/tree/main/docs/source) | [Issues](https://github.com/nimh-dsst/labapi/issues)
53
+ [Source](https://github.com/nimh-dsst/labapi) | [Docs](https://nimh-dsst.github.io/labapi/) | [Issues](https://github.com/nimh-dsst/labapi/issues)
50
54
 
51
55
  ## Start Here
52
56
 
53
- - New to `labapi`? Follow the [First Success Tutorial](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/tutorial.rst) for the fastest path from install to a visible change in LabArchives.
54
- - Already using `labapi`? Jump to the [Quick Start](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/index.rst), [User Guide](https://github.com/nimh-dsst/labapi/blob/main/docs/source/guide/index.rst), [Examples](https://github.com/nimh-dsst/labapi/blob/main/docs/source/examples/index.rst), or [FAQ](https://github.com/nimh-dsst/labapi/blob/main/docs/source/faq.rst).
57
+ - New to `labapi`? Follow the [First Success Tutorial](https://nimh-dsst.github.io/labapi/quick_start/tutorial.html) for the fastest path from install to a visible change in LabArchives.
58
+ - Already using `labapi`? Jump to the [Quick Start](https://nimh-dsst.github.io/labapi/quick_start/index.html), [User Guide](https://nimh-dsst.github.io/labapi/guide/index.html), [Examples](https://nimh-dsst.github.io/labapi/examples/index.html), or [FAQ](https://nimh-dsst.github.io/labapi/faq.html).
55
59
  - Working on the package itself? Start with [CONTRIBUTING.md](https://github.com/nimh-dsst/labapi/blob/main/CONTRIBUTING.md).
56
60
 
57
61
  ## Install
58
62
 
59
63
  Requirements:
60
64
 
61
- - Python 3.12+
65
+ - Python 3.10+
62
66
  - `uv` (recommended) or `pip`
63
67
 
64
68
  Recommended install for local use:
@@ -176,12 +180,12 @@ page = notebook.traverse("Experiments/2026/Results")
176
180
 
177
181
  ## Documentation Map
178
182
 
179
- - [First Success Tutorial](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/tutorial.rst): shortest path from install to a successful write.
180
- - [Quick Start](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/index.rst): setup, navigation, page creation, uploads, and basic write operations.
181
- - [Authentication Guide](https://github.com/nimh-dsst/labapi/blob/main/docs/source/guide/auth.rst): local browser auth, manual flows, and callback-based integration patterns.
182
- - [User Guide](https://github.com/nimh-dsst/labapi/blob/main/docs/source/guide/index.rst): paths, entries, API behavior, exceptions, limits, and architecture notes.
183
- - [Examples](https://github.com/nimh-dsst/labapi/blob/main/docs/source/examples/index.rst): end-to-end scripts for real workflows.
184
- - [FAQ](https://github.com/nimh-dsst/labapi/blob/main/docs/source/faq.rst): troubleshooting and environment questions.
183
+ - [First Success Tutorial](https://nimh-dsst.github.io/labapi/quick_start/tutorial.html): shortest path from install to a successful write.
184
+ - [Quick Start](https://nimh-dsst.github.io/labapi/quick_start/index.html): setup, navigation, page creation, uploads, and basic write operations.
185
+ - [Authentication Guide](https://nimh-dsst.github.io/labapi/guide/auth.html): local browser auth, manual flows, and callback-based integration patterns.
186
+ - [User Guide](https://nimh-dsst.github.io/labapi/guide/index.html): paths, entries, API behavior, exceptions, limits, and architecture notes.
187
+ - [Examples](https://nimh-dsst.github.io/labapi/examples/index.html): end-to-end scripts for real workflows.
188
+ - [FAQ](https://nimh-dsst.github.io/labapi/faq.html): troubleshooting and environment questions.
185
189
 
186
190
  ## Development
187
191
 
@@ -2,25 +2,26 @@
2
2
 
3
3
  A Python client for the LabArchives API.
4
4
 
5
- [![Python Version](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
5
+ [![Python Version](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
6
6
  [![Tests](https://github.com/nimh-dsst/labapi/actions/workflows/unit_tests.yml/badge.svg?branch=main)](https://github.com/nimh-dsst/labapi/actions/workflows/unit_tests.yml)
7
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19599400.svg)](https://doi.org/10.5281/zenodo.19599400)
7
8
  [![License: CC0-1.0](https://img.shields.io/badge/License-CC0_1.0-lightgrey.svg)](https://creativecommons.org/publicdomain/zero/1.0/)
8
9
 
9
10
  `labapi` helps you authenticate with LabArchives, navigate notebook trees, and create or update notebook content from Python.
10
11
 
11
- [Source](https://github.com/nimh-dsst/labapi) | [Docs](https://github.com/nimh-dsst/labapi/tree/main/docs/source) | [Issues](https://github.com/nimh-dsst/labapi/issues)
12
+ [Source](https://github.com/nimh-dsst/labapi) | [Docs](https://nimh-dsst.github.io/labapi/) | [Issues](https://github.com/nimh-dsst/labapi/issues)
12
13
 
13
14
  ## Start Here
14
15
 
15
- - New to `labapi`? Follow the [First Success Tutorial](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/tutorial.rst) for the fastest path from install to a visible change in LabArchives.
16
- - Already using `labapi`? Jump to the [Quick Start](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/index.rst), [User Guide](https://github.com/nimh-dsst/labapi/blob/main/docs/source/guide/index.rst), [Examples](https://github.com/nimh-dsst/labapi/blob/main/docs/source/examples/index.rst), or [FAQ](https://github.com/nimh-dsst/labapi/blob/main/docs/source/faq.rst).
16
+ - New to `labapi`? Follow the [First Success Tutorial](https://nimh-dsst.github.io/labapi/quick_start/tutorial.html) for the fastest path from install to a visible change in LabArchives.
17
+ - Already using `labapi`? Jump to the [Quick Start](https://nimh-dsst.github.io/labapi/quick_start/index.html), [User Guide](https://nimh-dsst.github.io/labapi/guide/index.html), [Examples](https://nimh-dsst.github.io/labapi/examples/index.html), or [FAQ](https://nimh-dsst.github.io/labapi/faq.html).
17
18
  - Working on the package itself? Start with [CONTRIBUTING.md](https://github.com/nimh-dsst/labapi/blob/main/CONTRIBUTING.md).
18
19
 
19
20
  ## Install
20
21
 
21
22
  Requirements:
22
23
 
23
- - Python 3.12+
24
+ - Python 3.10+
24
25
  - `uv` (recommended) or `pip`
25
26
 
26
27
  Recommended install for local use:
@@ -138,12 +139,12 @@ page = notebook.traverse("Experiments/2026/Results")
138
139
 
139
140
  ## Documentation Map
140
141
 
141
- - [First Success Tutorial](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/tutorial.rst): shortest path from install to a successful write.
142
- - [Quick Start](https://github.com/nimh-dsst/labapi/blob/main/docs/source/quick_start/index.rst): setup, navigation, page creation, uploads, and basic write operations.
143
- - [Authentication Guide](https://github.com/nimh-dsst/labapi/blob/main/docs/source/guide/auth.rst): local browser auth, manual flows, and callback-based integration patterns.
144
- - [User Guide](https://github.com/nimh-dsst/labapi/blob/main/docs/source/guide/index.rst): paths, entries, API behavior, exceptions, limits, and architecture notes.
145
- - [Examples](https://github.com/nimh-dsst/labapi/blob/main/docs/source/examples/index.rst): end-to-end scripts for real workflows.
146
- - [FAQ](https://github.com/nimh-dsst/labapi/blob/main/docs/source/faq.rst): troubleshooting and environment questions.
142
+ - [First Success Tutorial](https://nimh-dsst.github.io/labapi/quick_start/tutorial.html): shortest path from install to a successful write.
143
+ - [Quick Start](https://nimh-dsst.github.io/labapi/quick_start/index.html): setup, navigation, page creation, uploads, and basic write operations.
144
+ - [Authentication Guide](https://nimh-dsst.github.io/labapi/guide/auth.html): local browser auth, manual flows, and callback-based integration patterns.
145
+ - [User Guide](https://nimh-dsst.github.io/labapi/guide/index.html): paths, entries, API behavior, exceptions, limits, and architecture notes.
146
+ - [Examples](https://nimh-dsst.github.io/labapi/examples/index.html): end-to-end scripts for real workflows.
147
+ - [FAQ](https://nimh-dsst.github.io/labapi/faq.html): troubleshooting and environment questions.
147
148
 
148
149
  ## Development
149
150