haystack-py 0.1.3__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 (123) hide show
  1. haystack_py-0.1.3/.dockerignore +17 -0
  2. haystack_py-0.1.3/.github/workflows/ci.yml +102 -0
  3. haystack_py-0.1.3/.github/workflows/release.yml +164 -0
  4. haystack_py-0.1.3/.gitignore +49 -0
  5. haystack_py-0.1.3/.python-version +1 -0
  6. haystack_py-0.1.3/CHANGELOG.md +39 -0
  7. haystack_py-0.1.3/Dockerfile +36 -0
  8. haystack_py-0.1.3/LICENSE +21 -0
  9. haystack_py-0.1.3/Makefile +89 -0
  10. haystack_py-0.1.3/PKG-INFO +446 -0
  11. haystack_py-0.1.3/README.md +421 -0
  12. haystack_py-0.1.3/docker/docker-compose.yml +68 -0
  13. haystack_py-0.1.3/docker/gen_tls_certs.py +42 -0
  14. haystack_py-0.1.3/docker/tls/.gitignore +2 -0
  15. haystack_py-0.1.3/docs/_static/.gitkeep +0 -0
  16. haystack_py-0.1.3/docs/api/core.rst +40 -0
  17. haystack_py-0.1.3/docs/api/encoding.rst +47 -0
  18. haystack_py-0.1.3/docs/api/filter.rst +40 -0
  19. haystack_py-0.1.3/docs/api/ontology.rst +47 -0
  20. haystack_py-0.1.3/docs/api/security.rst +39 -0
  21. haystack_py-0.1.3/docs/api/storage.rst +47 -0
  22. haystack_py-0.1.3/docs/api/types.rst +33 -0
  23. haystack_py-0.1.3/docs/api/websocket.rst +39 -0
  24. haystack_py-0.1.3/docs/changelog.md +1 -0
  25. haystack_py-0.1.3/docs/conf.py +66 -0
  26. haystack_py-0.1.3/docs/features.rst +201 -0
  27. haystack_py-0.1.3/docs/getting-started.rst +206 -0
  28. haystack_py-0.1.3/docs/guide/client-guide.rst +379 -0
  29. haystack_py-0.1.3/docs/guide/data-types.rst +239 -0
  30. haystack_py-0.1.3/docs/guide/encoding-guide.rst +306 -0
  31. haystack_py-0.1.3/docs/guide/error-handling.rst +215 -0
  32. haystack_py-0.1.3/docs/guide/filter-guide.rst +222 -0
  33. haystack_py-0.1.3/docs/guide/observability.rst +187 -0
  34. haystack_py-0.1.3/docs/guide/ontology-guide.rst +355 -0
  35. haystack_py-0.1.3/docs/guide/server-guide.rst +327 -0
  36. haystack_py-0.1.3/docs/guide/storage-guide.rst +234 -0
  37. haystack_py-0.1.3/docs/guide/tls-guide.rst +227 -0
  38. haystack_py-0.1.3/docs/guide/watch-guide.rst +262 -0
  39. haystack_py-0.1.3/docs/guide/websocket-guide.rst +351 -0
  40. haystack_py-0.1.3/docs/index.rst +79 -0
  41. haystack_py-0.1.3/pyproject.toml +63 -0
  42. haystack_py-0.1.3/ruff.toml +56 -0
  43. haystack_py-0.1.3/scripts/exercise.py +363 -0
  44. haystack_py-0.1.3/scripts/stress.py +299 -0
  45. haystack_py-0.1.3/scripts/ws_stress.py +381 -0
  46. haystack_py-0.1.3/src/hs_py/__init__.py +160 -0
  47. haystack_py-0.1.3/src/hs_py/__main__.py +119 -0
  48. haystack_py-0.1.3/src/hs_py/_scram_core.py +309 -0
  49. haystack_py-0.1.3/src/hs_py/auth.py +406 -0
  50. haystack_py-0.1.3/src/hs_py/auth_types.py +107 -0
  51. haystack_py-0.1.3/src/hs_py/client.py +581 -0
  52. haystack_py-0.1.3/src/hs_py/content_negotiation.py +144 -0
  53. haystack_py-0.1.3/src/hs_py/convert.py +83 -0
  54. haystack_py-0.1.3/src/hs_py/encoding/__init__.py +37 -0
  55. haystack_py-0.1.3/src/hs_py/encoding/csv.py +103 -0
  56. haystack_py-0.1.3/src/hs_py/encoding/json.py +667 -0
  57. haystack_py-0.1.3/src/hs_py/encoding/scanner.py +638 -0
  58. haystack_py-0.1.3/src/hs_py/encoding/trio.py +292 -0
  59. haystack_py-0.1.3/src/hs_py/encoding/zinc.py +337 -0
  60. haystack_py-0.1.3/src/hs_py/errors.py +57 -0
  61. haystack_py-0.1.3/src/hs_py/fastapi_server.py +477 -0
  62. haystack_py-0.1.3/src/hs_py/filter/__init__.py +34 -0
  63. haystack_py-0.1.3/src/hs_py/filter/ast.py +121 -0
  64. haystack_py-0.1.3/src/hs_py/filter/eval.py +178 -0
  65. haystack_py-0.1.3/src/hs_py/filter/lexer.py +316 -0
  66. haystack_py-0.1.3/src/hs_py/filter/parser.py +168 -0
  67. haystack_py-0.1.3/src/hs_py/grid.py +212 -0
  68. haystack_py-0.1.3/src/hs_py/kinds.py +302 -0
  69. haystack_py-0.1.3/src/hs_py/metrics.py +68 -0
  70. haystack_py-0.1.3/src/hs_py/ontology/__init__.py +62 -0
  71. haystack_py-0.1.3/src/hs_py/ontology/defs.py +138 -0
  72. haystack_py-0.1.3/src/hs_py/ontology/namespace.py +261 -0
  73. haystack_py-0.1.3/src/hs_py/ontology/normalize.py +153 -0
  74. haystack_py-0.1.3/src/hs_py/ontology/rdf.py +131 -0
  75. haystack_py-0.1.3/src/hs_py/ontology/reflect.py +109 -0
  76. haystack_py-0.1.3/src/hs_py/ontology/taxonomy.py +114 -0
  77. haystack_py-0.1.3/src/hs_py/ops.py +423 -0
  78. haystack_py-0.1.3/src/hs_py/py.typed +0 -0
  79. haystack_py-0.1.3/src/hs_py/redis_ops.py +127 -0
  80. haystack_py-0.1.3/src/hs_py/storage/__init__.py +34 -0
  81. haystack_py-0.1.3/src/hs_py/storage/memory.py +338 -0
  82. haystack_py-0.1.3/src/hs_py/storage/protocol.py +178 -0
  83. haystack_py-0.1.3/src/hs_py/storage/redis.py +789 -0
  84. haystack_py-0.1.3/src/hs_py/storage/timescale.py +867 -0
  85. haystack_py-0.1.3/src/hs_py/tls.py +311 -0
  86. haystack_py-0.1.3/src/hs_py/watch.py +191 -0
  87. haystack_py-0.1.3/src/hs_py/ws.py +399 -0
  88. haystack_py-0.1.3/src/hs_py/ws_client.py +1432 -0
  89. haystack_py-0.1.3/src/hs_py/ws_codec.py +147 -0
  90. haystack_py-0.1.3/src/hs_py/ws_server.py +477 -0
  91. haystack_py-0.1.3/tests/__init__.py +0 -0
  92. haystack_py-0.1.3/tests/conftest.py +1 -0
  93. haystack_py-0.1.3/tests/test_auth.py +636 -0
  94. haystack_py-0.1.3/tests/test_client.py +272 -0
  95. haystack_py-0.1.3/tests/test_content_negotiation.py +173 -0
  96. haystack_py-0.1.3/tests/test_convert.py +237 -0
  97. haystack_py-0.1.3/tests/test_csv_encoding.py +311 -0
  98. haystack_py-0.1.3/tests/test_e2e_docker.py +786 -0
  99. haystack_py-0.1.3/tests/test_e2e_fastapi.py +451 -0
  100. haystack_py-0.1.3/tests/test_errors.py +56 -0
  101. haystack_py-0.1.3/tests/test_filter.py +376 -0
  102. haystack_py-0.1.3/tests/test_grid.py +116 -0
  103. haystack_py-0.1.3/tests/test_json_encoding.py +876 -0
  104. haystack_py-0.1.3/tests/test_kinds.py +281 -0
  105. haystack_py-0.1.3/tests/test_metrics.py +153 -0
  106. haystack_py-0.1.3/tests/test_ontology.py +271 -0
  107. haystack_py-0.1.3/tests/test_rdf_export.py +178 -0
  108. haystack_py-0.1.3/tests/test_redis_ops.py +1005 -0
  109. haystack_py-0.1.3/tests/test_redis_tls.py +365 -0
  110. haystack_py-0.1.3/tests/test_reflect.py +111 -0
  111. haystack_py-0.1.3/tests/test_scram_core.py +318 -0
  112. haystack_py-0.1.3/tests/test_server.py +1059 -0
  113. haystack_py-0.1.3/tests/test_smoke.py +5 -0
  114. haystack_py-0.1.3/tests/test_storage_memory.py +599 -0
  115. haystack_py-0.1.3/tests/test_storage_timescale.py +1688 -0
  116. haystack_py-0.1.3/tests/test_taxonomy.py +234 -0
  117. haystack_py-0.1.3/tests/test_tls.py +355 -0
  118. haystack_py-0.1.3/tests/test_trio.py +838 -0
  119. haystack_py-0.1.3/tests/test_watch.py +590 -0
  120. haystack_py-0.1.3/tests/test_ws.py +742 -0
  121. haystack_py-0.1.3/tests/test_ws_codec.py +180 -0
  122. haystack_py-0.1.3/tests/test_zinc_encoding.py +703 -0
  123. haystack_py-0.1.3/uv.lock +1900 -0
@@ -0,0 +1,17 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .git/
5
+ .github/
6
+ .claude/
7
+ .mypy_cache/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+ dist/
13
+ docs/_build/
14
+ _plan/
15
+ _ctx/
16
+ *.egg-info/
17
+ docker/tls/
@@ -0,0 +1,102 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v4
15
+ with:
16
+ enable-cache: true
17
+ - run: uv python install
18
+ - run: uv sync --locked --group lint
19
+ - name: Ruff check
20
+ run: uv run ruff check src/ tests/
21
+ - name: Ruff format check
22
+ run: uv run ruff format --check src/ tests/
23
+
24
+ typecheck:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: astral-sh/setup-uv@v4
29
+ with:
30
+ enable-cache: true
31
+ - run: uv python install
32
+ - run: uv sync --locked --group type-check --all-extras
33
+ - name: Mypy
34
+ run: uv run mypy
35
+
36
+ test:
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - uses: astral-sh/setup-uv@v4
41
+ with:
42
+ enable-cache: true
43
+ - run: uv python install
44
+ - run: uv sync --locked --group test --all-extras
45
+ - name: Version consistency check
46
+ run: |
47
+ PYPROJECT_VER=$(python3 -c "
48
+ import re, pathlib
49
+ text = pathlib.Path('pyproject.toml').read_text()
50
+ print(re.search(r'^version\s*=\s*\"([^\"]+)\"', text, re.M).group(1))
51
+ ")
52
+ INIT_VER=$(python3 -c "
53
+ import re, pathlib
54
+ text = pathlib.Path('src/hs_py/__init__.py').read_text()
55
+ print(re.search(r'^__version__\s*=\s*\"([^\"]+)\"', text, re.M).group(1))
56
+ ")
57
+ echo "pyproject.toml: $PYPROJECT_VER"
58
+ echo "__init__.py: $INIT_VER"
59
+ if [ "$PYPROJECT_VER" != "$INIT_VER" ]; then
60
+ echo "::error::Version mismatch! pyproject.toml and __init__.py must declare the same version."
61
+ exit 1
62
+ fi
63
+ - name: Pytest
64
+ run: uv run pytest --tb=short -q
65
+
66
+ docs:
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+ - uses: astral-sh/setup-uv@v4
71
+ with:
72
+ enable-cache: true
73
+ - run: uv python install
74
+ - run: uv sync --locked --group docs --all-extras
75
+ - name: Sphinx build
76
+ run: uv run sphinx-build -W -b html docs docs/_build/html
77
+
78
+ deploy-docs:
79
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
80
+ needs: [lint, typecheck, test, docs]
81
+ runs-on: ubuntu-latest
82
+ permissions:
83
+ contents: read
84
+ pages: write
85
+ id-token: write
86
+ environment:
87
+ name: github-pages
88
+ url: ${{ steps.deployment.outputs.page_url }}
89
+ steps:
90
+ - uses: actions/checkout@v4
91
+ - uses: astral-sh/setup-uv@v4
92
+ with:
93
+ enable-cache: true
94
+ - run: uv python install
95
+ - run: uv sync --locked --group docs --all-extras
96
+ - name: Sphinx build
97
+ run: uv run sphinx-build -W -b html docs docs/_build/html
98
+ - uses: actions/upload-pages-artifact@v3
99
+ with:
100
+ path: docs/_build/html
101
+ - id: deployment
102
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,164 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_run:
5
+ workflows: ["CI"]
6
+ types: [completed]
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: release
11
+ cancel-in-progress: false
12
+
13
+ jobs:
14
+ release:
15
+ if: github.event.workflow_run.conclusion == 'success'
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ contents: write
19
+ outputs:
20
+ new_release: ${{ steps.check_tag.outputs.exists == 'false' }}
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ with:
24
+ ref: ${{ github.event.workflow_run.head_sha }}
25
+ fetch-depth: 0
26
+
27
+ - name: Extract version from pyproject.toml
28
+ id: version
29
+ run: |
30
+ VERSION=$(python3 -c "
31
+ import re, pathlib
32
+ text = pathlib.Path('pyproject.toml').read_text()
33
+ print(re.search(r'^version\s*=\s*\"([^\"]+)\"', text, re.M).group(1))
34
+ ")
35
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
36
+ echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
37
+
38
+ - name: Check if tag already exists
39
+ id: check_tag
40
+ run: |
41
+ if git rev-parse "refs/tags/${{ steps.version.outputs.tag }}" >/dev/null 2>&1; then
42
+ echo "exists=true" >> "$GITHUB_OUTPUT"
43
+ else
44
+ echo "exists=false" >> "$GITHUB_OUTPUT"
45
+ fi
46
+
47
+ - name: Extract changelog section
48
+ if: steps.check_tag.outputs.exists == 'false'
49
+ id: changelog
50
+ run: |
51
+ python3 -c "
52
+ import re, pathlib, os
53
+ text = pathlib.Path('CHANGELOG.md').read_text()
54
+ version = '${{ steps.version.outputs.version }}'
55
+ pattern = rf'## \[{re.escape(version)}\][^\n]*\n(.*?)(?=\n## \[|\Z)'
56
+ match = re.search(pattern, text, re.DOTALL)
57
+ body = match.group(1).strip() if match else 'No changelog entry found.'
58
+ # Write to file to avoid shell escaping issues
59
+ pathlib.Path('release_body.md').write_text(body)
60
+ "
61
+
62
+ - name: Create and push tag
63
+ if: steps.check_tag.outputs.exists == 'false'
64
+ run: |
65
+ git config user.name "github-actions[bot]"
66
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
67
+ git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}"
68
+ git push origin "${{ steps.version.outputs.tag }}"
69
+
70
+ - name: Create GitHub Release
71
+ if: steps.check_tag.outputs.exists == 'false'
72
+ uses: softprops/action-gh-release@v2
73
+ with:
74
+ tag_name: ${{ steps.version.outputs.tag }}
75
+ name: ${{ steps.version.outputs.tag }}
76
+ body_path: release_body.md
77
+ draft: false
78
+ prerelease: false
79
+
80
+ build:
81
+ needs: release
82
+ if: needs.release.outputs.new_release == 'true'
83
+ runs-on: ubuntu-latest
84
+ steps:
85
+ - uses: actions/checkout@v4
86
+ with:
87
+ ref: ${{ github.event.workflow_run.head_sha }}
88
+
89
+ - uses: actions/setup-python@v5
90
+ with:
91
+ python-version: "3.13"
92
+
93
+ - name: Build package
94
+ run: |
95
+ pip install build
96
+ python -m build
97
+
98
+ - name: Upload distributions
99
+ uses: actions/upload-artifact@v4
100
+ with:
101
+ name: python-package-distributions
102
+ path: dist/
103
+
104
+ upload-release-assets:
105
+ needs: [release, build]
106
+ if: needs.release.outputs.new_release == 'true'
107
+ runs-on: ubuntu-latest
108
+ permissions:
109
+ contents: write
110
+ steps:
111
+ - name: Download distributions
112
+ uses: actions/download-artifact@v4
113
+ with:
114
+ name: python-package-distributions
115
+ path: dist/
116
+
117
+ - name: Extract version tag
118
+ id: version
119
+ run: |
120
+ VERSION=$(ls dist/*.tar.gz | sed 's|dist/haystack_py-||;s|\.tar\.gz||')
121
+ echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
122
+
123
+ - name: Upload assets to GitHub Release
124
+ uses: softprops/action-gh-release@v2
125
+ with:
126
+ tag_name: ${{ steps.version.outputs.tag }}
127
+ files: dist/*
128
+
129
+ # ──────────────────────────────────────────────────────────
130
+ # PyPI Publish
131
+ #
132
+ # Prerequisites (one-time setup):
133
+ # 1. Go to https://pypi.org/manage/account/publishing/
134
+ # 2. Add a pending publisher:
135
+ # - Package name: haystack-py
136
+ # - Owner: jscott3201
137
+ # - Repository: hs-py
138
+ # - Workflow: release.yml
139
+ # - Environment: pypi
140
+ # 3. In GitHub repo Settings → Environments, create a "pypi"
141
+ # environment. Optionally enable required reviewers for
142
+ # manual approval before each publish.
143
+ # ──────────────────────────────────────────────────────────
144
+
145
+ publish:
146
+ needs: build
147
+ runs-on: ubuntu-latest
148
+ environment:
149
+ name: pypi
150
+ url: https://pypi.org/p/haystack-py
151
+ permissions:
152
+ id-token: write
153
+ attestations: write
154
+ steps:
155
+ - name: Download distributions
156
+ uses: actions/download-artifact@v4
157
+ with:
158
+ name: python-package-distributions
159
+ path: dist/
160
+
161
+ - name: Publish to PyPI
162
+ uses: pypa/gh-action-pypi-publish@release/v1
163
+ with:
164
+ print-hash: true
@@ -0,0 +1,49 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ build/
9
+ dist/
10
+ wheels/
11
+ *.egg-info/
12
+ *.egg
13
+
14
+ # Virtual environments
15
+ .venv
16
+
17
+ # Environment variables
18
+ .env
19
+ .env.*
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/
24
+ *.swp
25
+ *.swo
26
+
27
+ # Testing / coverage
28
+ .pytest_cache/
29
+ .coverage
30
+ htmlcov/
31
+ .mypy_cache/
32
+
33
+ # Jupyter
34
+ .ipynb_checkpoints/
35
+
36
+ # Claude Code
37
+ CLAUDE.md
38
+ .claude/
39
+
40
+ # Docs
41
+ docs/_build/
42
+
43
+ # Context & planning
44
+ _ctx/
45
+ _plan/
46
+ _data/
47
+
48
+ # Docker local certs
49
+ docker/.certs/
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
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
+
8
+ ## [0.1.3] - 2026-02-24
9
+
10
+ ### Changed
11
+
12
+ - Renamed PyPI package from ``hs-py`` to ``haystack-py``.
13
+
14
+ ## [0.1.2] - 2026-02-24
15
+
16
+ ### Fixed
17
+
18
+ - Fixed SCRAM middleware tests using monotonic-relative timestamps for reliable CI.
19
+
20
+ ## [0.1.1] - 2026-02-24
21
+
22
+ ### Changed
23
+
24
+ - Made `rdflib` a core dependency (no longer optional).
25
+ - Local `make` targets now run with `--all-extras` to match CI.
26
+
27
+ ### Fixed
28
+
29
+ - Fixed SCRAM auth middleware tests (stale handshake purge and token expiry).
30
+ - Fixed RDF turtle export test assertion for prefixed namespace output.
31
+
32
+ ### Added
33
+
34
+ - MIT license file.
35
+ - License metadata in `pyproject.toml`.
36
+
37
+ ## [0.1.0] - 2026-02-24
38
+
39
+ Initial release.
@@ -0,0 +1,36 @@
1
+ # Stage 1: build dependencies + install project
2
+ FROM ghcr.io/astral-sh/uv:python3.13-alpine AS builder
3
+
4
+ ENV UV_COMPILE_BYTECODE=1 \
5
+ UV_LINK_MODE=copy \
6
+ UV_PYTHON_DOWNLOADS=0
7
+
8
+ WORKDIR /app
9
+
10
+ # Install dependencies first (cached layer — changes only when lockfile changes)
11
+ RUN --mount=type=cache,target=/root/.cache/uv \
12
+ --mount=type=bind,source=uv.lock,target=uv.lock \
13
+ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
14
+ uv sync --locked --no-install-project --no-dev --extra server
15
+
16
+ # Copy source and install the project itself
17
+ COPY . /app
18
+ RUN --mount=type=cache,target=/root/.cache/uv \
19
+ uv sync --locked --no-dev --extra server
20
+
21
+ # Stage 2: minimal runtime
22
+ FROM python:3.13-alpine
23
+
24
+ RUN addgroup -g 1000 app && adduser -u 1000 -G app -D app
25
+
26
+ COPY --from=builder --chown=app:app /app/.venv /app/.venv
27
+ COPY --from=builder --chown=app:app /app/src /app/src
28
+
29
+ ENV PATH="/app/.venv/bin:$PATH" \
30
+ DATA_DIR="/app/_data"
31
+
32
+ WORKDIR /app
33
+ USER app
34
+ EXPOSE 8080
35
+
36
+ CMD ["python", "-m", "hs_py"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Justin Scott
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,89 @@
1
+ .PHONY: lint typecheck test check fix format coverage coverage-html docs \
2
+ docker-redis docker-test docker-clean \
3
+ docker-server docker-server-clean docker-test-e2e \
4
+ docker-tls-certs docker-redis-tls docker-test-tls \
5
+ docker-timescale docker-test-timescale docker-clean-timescale
6
+
7
+ lint:
8
+ uv run ruff check src/ tests/
9
+ uv run ruff format --check src/ tests/
10
+
11
+ typecheck:
12
+ uv run --all-extras mypy
13
+
14
+ test:
15
+ uv run --all-extras pytest --tb=short -q
16
+
17
+ check: lint typecheck test
18
+
19
+ fix:
20
+ uv run ruff check --fix src/ tests/
21
+ uv run ruff format src/ tests/
22
+
23
+ format:
24
+ uv run ruff format src/ tests/
25
+
26
+ coverage:
27
+ uv run --all-extras pytest --cov --cov-report=term-missing
28
+
29
+ coverage-html:
30
+ uv run --all-extras pytest --cov --cov-report=html
31
+
32
+ docs:
33
+ uv run --group docs sphinx-build -W -b html docs docs/_build/html
34
+
35
+ # ---------------------------------------------------------------------------
36
+ # Docker / Server
37
+ # ---------------------------------------------------------------------------
38
+
39
+ docker-server:
40
+ $(COMPOSE) up -d --build redis server
41
+
42
+ docker-server-clean:
43
+ $(COMPOSE) down
44
+
45
+ docker-test-e2e: docker-server
46
+ $(COMPOSE) up -d --wait server
47
+ HS_PY_DOCKER_E2E=1 uv run pytest tests/test_e2e_docker.py --tb=short -q
48
+
49
+ # ---------------------------------------------------------------------------
50
+ # Docker / Redis integration tests
51
+ # ---------------------------------------------------------------------------
52
+
53
+ COMPOSE := docker compose -f docker/docker-compose.yml
54
+
55
+ docker-redis:
56
+ $(COMPOSE) up -d redis
57
+
58
+ docker-test: docker-redis
59
+ $(COMPOSE) up -d --wait redis
60
+ uv run pytest tests/test_redis_ops.py --tb=short -q
61
+
62
+ docker-clean:
63
+ $(COMPOSE) down -v --remove-orphans
64
+
65
+ # ---------------------------------------------------------------------------
66
+ # Docker / Redis TLS integration tests
67
+ # ---------------------------------------------------------------------------
68
+
69
+ docker-tls-certs:
70
+ uv run python docker/gen_tls_certs.py
71
+
72
+ docker-redis-tls: docker-tls-certs
73
+ $(COMPOSE) up -d --wait redis-tls
74
+
75
+ docker-test-tls: docker-redis-tls
76
+ uv run pytest tests/test_redis_tls.py --tb=short -q
77
+
78
+ # ---------------------------------------------------------------------------
79
+ # Docker / TimescaleDB integration tests
80
+ # ---------------------------------------------------------------------------
81
+
82
+ docker-timescale:
83
+ $(COMPOSE) up -d --wait timescaledb
84
+
85
+ docker-test-timescale: docker-timescale
86
+ uv run pytest tests/test_storage_timescale.py --tb=short -q
87
+
88
+ docker-clean-timescale:
89
+ $(COMPOSE) down -v --remove-orphans timescaledb