accessible-math-reader 0.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 (75) hide show
  1. accessible_math_reader-0.1.0/.env.example +41 -0
  2. accessible_math_reader-0.1.0/.gitignore +298 -0
  3. accessible_math_reader-0.1.0/.readthedocs.yaml +15 -0
  4. accessible_math_reader-0.1.0/Dockerfile +61 -0
  5. accessible_math_reader-0.1.0/LICENSE +7 -0
  6. accessible_math_reader-0.1.0/PKG-INFO +666 -0
  7. accessible_math_reader-0.1.0/README.md +601 -0
  8. accessible_math_reader-0.1.0/accessible_math_reader/__init__.py +64 -0
  9. accessible_math_reader-0.1.0/accessible_math_reader/api/__init__.py +16 -0
  10. accessible_math_reader-0.1.0/accessible_math_reader/api/app.py +315 -0
  11. accessible_math_reader-0.1.0/accessible_math_reader/api/errors.py +118 -0
  12. accessible_math_reader-0.1.0/accessible_math_reader/api/middleware.py +172 -0
  13. accessible_math_reader-0.1.0/accessible_math_reader/api/schemas.py +112 -0
  14. accessible_math_reader-0.1.0/accessible_math_reader/braille/__init__.py +4 -0
  15. accessible_math_reader-0.1.0/accessible_math_reader/braille/nemeth.py +426 -0
  16. accessible_math_reader-0.1.0/accessible_math_reader/braille/ueb.py +253 -0
  17. accessible_math_reader-0.1.0/accessible_math_reader/cli.py +391 -0
  18. accessible_math_reader-0.1.0/accessible_math_reader/config.py +306 -0
  19. accessible_math_reader-0.1.0/accessible_math_reader/core/__init__.py +4 -0
  20. accessible_math_reader-0.1.0/accessible_math_reader/core/accessibility_contract.py +312 -0
  21. accessible_math_reader-0.1.0/accessible_math_reader/core/aria_navigator.py +540 -0
  22. accessible_math_reader-0.1.0/accessible_math_reader/core/aria_renderer.py +263 -0
  23. accessible_math_reader-0.1.0/accessible_math_reader/core/parser.py +1186 -0
  24. accessible_math_reader-0.1.0/accessible_math_reader/core/renderer.py +176 -0
  25. accessible_math_reader-0.1.0/accessible_math_reader/core/semantic.py +462 -0
  26. accessible_math_reader-0.1.0/accessible_math_reader/grpc_service/__init__.py +11 -0
  27. accessible_math_reader-0.1.0/accessible_math_reader/grpc_service/proto/math_service.proto +89 -0
  28. accessible_math_reader-0.1.0/accessible_math_reader/grpc_service/server.py +126 -0
  29. accessible_math_reader-0.1.0/accessible_math_reader/jupyter/__init__.py +154 -0
  30. accessible_math_reader-0.1.0/accessible_math_reader/observability/__init__.py +23 -0
  31. accessible_math_reader-0.1.0/accessible_math_reader/observability/logging.py +141 -0
  32. accessible_math_reader-0.1.0/accessible_math_reader/observability/metrics.py +243 -0
  33. accessible_math_reader-0.1.0/accessible_math_reader/observability/tracing.py +133 -0
  34. accessible_math_reader-0.1.0/accessible_math_reader/plugins/__init__.py +4 -0
  35. accessible_math_reader-0.1.0/accessible_math_reader/plugins/base.py +399 -0
  36. accessible_math_reader-0.1.0/accessible_math_reader/reader.py +195 -0
  37. accessible_math_reader-0.1.0/accessible_math_reader/server.py +130 -0
  38. accessible_math_reader-0.1.0/accessible_math_reader/speech/__init__.py +4 -0
  39. accessible_math_reader-0.1.0/accessible_math_reader/speech/coqui_backend.py +105 -0
  40. accessible_math_reader-0.1.0/accessible_math_reader/speech/engine.py +217 -0
  41. accessible_math_reader-0.1.0/accessible_math_reader/speech/espeak_backend.py +124 -0
  42. accessible_math_reader-0.1.0/accessible_math_reader/speech/pyttsx3_backend.py +107 -0
  43. accessible_math_reader-0.1.0/accessible_math_reader/speech/rules.py +402 -0
  44. accessible_math_reader-0.1.0/accessible_math_reader/validation/__init__.py +15 -0
  45. accessible_math_reader-0.1.0/accessible_math_reader/validation/validator.py +233 -0
  46. accessible_math_reader-0.1.0/app.py +59 -0
  47. accessible_math_reader-0.1.0/docker-compose.yml +39 -0
  48. accessible_math_reader-0.1.0/docs/accessibility.md +228 -0
  49. accessible_math_reader-0.1.0/docs/api.md +458 -0
  50. accessible_math_reader-0.1.0/docs/architecture.md +107 -0
  51. accessible_math_reader-0.1.0/docs/configuration.md +235 -0
  52. accessible_math_reader-0.1.0/docs/contributing.md +68 -0
  53. accessible_math_reader-0.1.0/docs/deployment.md +214 -0
  54. accessible_math_reader-0.1.0/docs/examples.md +351 -0
  55. accessible_math_reader-0.1.0/docs/getting-started/installation.md +79 -0
  56. accessible_math_reader-0.1.0/docs/getting-started/quickstart.md +66 -0
  57. accessible_math_reader-0.1.0/docs/index.md +56 -0
  58. accessible_math_reader-0.1.0/docs/input-formats.md +253 -0
  59. accessible_math_reader-0.1.0/mkdocs.yml +104 -0
  60. accessible_math_reader-0.1.0/output/Function.brf +3 -0
  61. accessible_math_reader-0.1.0/output/integral.brf +3 -0
  62. accessible_math_reader-0.1.0/output/math-braille (1).brf +3 -0
  63. accessible_math_reader-0.1.0/output/math-braille.brf +3 -0
  64. accessible_math_reader-0.1.0/pyproject.toml +96 -0
  65. accessible_math_reader-0.1.0/requirements.txt +9 -0
  66. accessible_math_reader-0.1.0/src/__init__.py +0 -0
  67. accessible_math_reader-0.1.0/src/braille_converter.py +23 -0
  68. accessible_math_reader-0.1.0/src/latex_parser.py +273 -0
  69. accessible_math_reader-0.1.0/src/speech_converter.py +30 -0
  70. accessible_math_reader-0.1.0/static/css/style.css +1129 -0
  71. accessible_math_reader-0.1.0/static/js/app.js +653 -0
  72. accessible_math_reader-0.1.0/static/js/clipboard.js +837 -0
  73. accessible_math_reader-0.1.0/static/output.mp3 +0 -0
  74. accessible_math_reader-0.1.0/templates/index.html +582 -0
  75. accessible_math_reader-0.1.0/tests/.gitkeep +0 -0
@@ -0,0 +1,41 @@
1
+ # ============================================================================
2
+ # Accessible Math Reader — Environment Configuration
3
+ # ============================================================================
4
+ # Copy this file to .env and customise as needed.
5
+ #
6
+ # All variables are optional — sensible defaults are applied.
7
+ # ============================================================================
8
+
9
+ # ── Server ─────────────────────────────────────────────────────────────────
10
+ AMR_PORT=8000
11
+ AMR_MAX_REQUEST_SIZE=1048576
12
+
13
+ # ── Logging ────────────────────────────────────────────────────────────────
14
+ # Format: "json" for structured logs, "text" for human-readable
15
+ AMR_LOG_FORMAT=text
16
+ # Level: DEBUG, INFO, WARNING, ERROR
17
+ AMR_LOG_LEVEL=INFO
18
+
19
+ # ── Speech Engine ──────────────────────────────────────────────────────────
20
+ # Options: gtts (default, needs internet), espeak, pyttsx3, coqui
21
+ AMR_SPEECH_ENGINE=gtts
22
+
23
+ # ── Metrics (Prometheus) ──────────────────────────────────────────────────
24
+ # Set to "true" to enable the /metrics endpoint
25
+ AMR_METRICS=false
26
+
27
+ # ── Tracing (OpenTelemetry) ──────────────────────────────────────────────
28
+ AMR_TRACING=false
29
+ AMR_SERVICE_NAME=amr
30
+
31
+ # ── Authentication ────────────────────────────────────────────────────────
32
+ # Set to "true" to require X-API-Key header on API endpoints
33
+ AMR_ENABLE_AUTH=false
34
+ # Comma-separated list of valid API keys
35
+ AMR_API_KEYS=
36
+
37
+ # ── Rate Limiting ─────────────────────────────────────────────────────────
38
+ # Set to "true" to enable per-IP rate limiting on API endpoints
39
+ AMR_ENABLE_RATE_LIMIT=false
40
+ # Format: "<count>/<period>" where period is second/minute/hour/day
41
+ AMR_RATE_LIMIT=100/minute
@@ -0,0 +1,298 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/flask,python,pythonvanilla
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=flask,python,pythonvanilla
3
+
4
+ ### Flask ###
5
+ instance/*
6
+ !instance/.gitignore
7
+ .webassets-cache
8
+ .env
9
+
10
+ ### Flask.Python Stack ###
11
+ # Byte-compiled / optimized / DLL files
12
+ __pycache__/
13
+ *.py[cod]
14
+ *$py.class
15
+
16
+ # C extensions
17
+ *.so
18
+
19
+ # Project specific ignores
20
+ */static/audio/
21
+ static/audio/*.mp3
22
+ static/audio/*.ssml
23
+
24
+ # Distribution / packaging
25
+ .Python
26
+ build/
27
+ develop-eggs/
28
+ dist/
29
+ downloads/
30
+ eggs/
31
+ .eggs/
32
+ lib/
33
+ lib64/
34
+ parts/
35
+ sdist/
36
+ var/
37
+ wheels/
38
+ share/python-wheels/
39
+ *.egg-info/
40
+ .installed.cfg
41
+ *.egg
42
+ MANIFEST
43
+
44
+ # PyInstaller
45
+ # Usually these files are written by a python script from a template
46
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
47
+ *.manifest
48
+ *.spec
49
+
50
+ # Installer logs
51
+ pip-log.txt
52
+ pip-delete-this-directory.txt
53
+
54
+ # Project Specifics
55
+ static/audio/
56
+ *.static/audio/.mp3
57
+
58
+ # Unit test / coverage reports
59
+ htmlcov/
60
+ .tox/
61
+ .nox/
62
+ .coverage
63
+ .coverage.*
64
+ .cache
65
+ nosetests.xml
66
+ coverage.xml
67
+ *.cover
68
+ *.py,cover
69
+ .hypothesis/
70
+ .pytest_cache/
71
+ cover/
72
+
73
+ # Translations
74
+ *.mo
75
+ *.pot
76
+
77
+ # Django stuff:
78
+ *.log
79
+ local_settings.py
80
+ db.sqlite3
81
+ db.sqlite3-journal
82
+
83
+ # Flask stuff:
84
+ instance/
85
+
86
+ # Scrapy stuff:
87
+ .scrapy
88
+
89
+ # Sphinx documentation
90
+ docs/_build/
91
+
92
+ # PyBuilder
93
+ .pybuilder/
94
+ target/
95
+
96
+ # Jupyter Notebook
97
+ .ipynb_checkpoints
98
+
99
+ # IPython
100
+ profile_default/
101
+ ipython_config.py
102
+
103
+ # pyenv
104
+ # For a library or package, you might want to ignore these files since the code is
105
+ # intended to run in multiple environments; otherwise, check them in:
106
+ # .python-version
107
+
108
+ # pipenv
109
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
110
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
111
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
112
+ # install all needed dependencies.
113
+ #Pipfile.lock
114
+
115
+ # poetry
116
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
117
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
118
+ # commonly ignored for libraries.
119
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
120
+ #poetry.lock
121
+
122
+ # pdm
123
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
124
+ #pdm.lock
125
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
126
+ # in version control.
127
+ # https://pdm.fming.dev/#use-with-ide
128
+ .pdm.toml
129
+
130
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
131
+ __pypackages__/
132
+
133
+ # Celery stuff
134
+ celerybeat-schedule
135
+ celerybeat.pid
136
+
137
+ # SageMath parsed files
138
+ *.sage.py
139
+
140
+ # Environments
141
+ .venv
142
+ env/
143
+ venv/
144
+ ENV/
145
+ env.bak/
146
+ venv.bak/
147
+
148
+ # Spyder project settings
149
+ .spyderproject
150
+ .spyproject
151
+
152
+ # Rope project settings
153
+ .ropeproject
154
+
155
+ # mkdocs documentation
156
+ /site
157
+
158
+ # mypy
159
+ .mypy_cache/
160
+ .dmypy.json
161
+ dmypy.json
162
+
163
+ # Pyre type checker
164
+ .pyre/
165
+
166
+ # pytype static type analyzer
167
+ .pytype/
168
+
169
+ # Cython debug symbols
170
+ cython_debug/
171
+
172
+ # PyCharm
173
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
174
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
175
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
176
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
177
+ #.idea/
178
+
179
+ ### Python ###
180
+ # Byte-compiled / optimized / DLL files
181
+
182
+ # C extensions
183
+
184
+ # Distribution / packaging
185
+
186
+ # PyInstaller
187
+ # Usually these files are written by a python script from a template
188
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
189
+
190
+ # Installer logs
191
+
192
+ # Unit test / coverage reports
193
+
194
+ # Translations
195
+
196
+ # Django stuff:
197
+
198
+ # Flask stuff:
199
+
200
+ # Scrapy stuff:
201
+
202
+ # Sphinx documentation
203
+
204
+ # PyBuilder
205
+
206
+ # Jupyter Notebook
207
+
208
+ # IPython
209
+
210
+ # pyenv
211
+ # For a library or package, you might want to ignore these files since the code is
212
+ # intended to run in multiple environments; otherwise, check them in:
213
+ # .python-version
214
+
215
+ # pipenv
216
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
217
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
218
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
219
+ # install all needed dependencies.
220
+
221
+ # poetry
222
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
223
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
224
+ # commonly ignored for libraries.
225
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
226
+
227
+ # pdm
228
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
229
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
230
+ # in version control.
231
+ # https://pdm.fming.dev/#use-with-ide
232
+
233
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
234
+
235
+ # Celery stuff
236
+
237
+ # SageMath parsed files
238
+
239
+ # Environments
240
+
241
+ # Spyder project settings
242
+
243
+ # Rope project settings
244
+
245
+ # mkdocs documentation
246
+
247
+ # mypy
248
+
249
+ # Pyre type checker
250
+
251
+ # pytype static type analyzer
252
+
253
+ # Cython debug symbols
254
+
255
+ # PyCharm
256
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
257
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
258
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
259
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
260
+
261
+ ### Python Patch ###
262
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
263
+ poetry.toml
264
+
265
+ # ruff
266
+ .ruff_cache/
267
+
268
+ # LSP config files
269
+ pyrightconfig.json
270
+
271
+ ### PythonVanilla ###
272
+ # Byte-compiled / optimized / DLL files
273
+
274
+ # C extensions
275
+
276
+ # Distribution / packaging
277
+
278
+ # Installer logs
279
+
280
+ # Unit test / coverage reports
281
+
282
+ # Translations
283
+
284
+ # pyenv
285
+ # For a library or package, you might want to ignore these files since the code is
286
+ # intended to run in multiple environments; otherwise, check them in:
287
+ # .python-version
288
+
289
+ # pipenv
290
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
291
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
292
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
293
+ # install all needed dependencies.
294
+
295
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
296
+
297
+
298
+ # End of https://www.toptal.com/developers/gitignore/api/flask,python,pythonvanilla
@@ -0,0 +1,15 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-22.04
5
+ tools:
6
+ python: "3.11"
7
+
8
+ mkdocs:
9
+ configuration: mkdocs.yml
10
+
11
+ python:
12
+ install:
13
+ - method: pip
14
+ path: .
15
+ - requirements: requirements.txt
@@ -0,0 +1,61 @@
1
+ # ============================================================================
2
+ # Accessible Math Reader — Dockerfile
3
+ # ============================================================================
4
+ # Multi-stage production build.
5
+ #
6
+ # Build: docker build -t amr .
7
+ # Run: docker run -p 8000:8000 amr
8
+ # Compose: docker compose up -d
9
+ # ============================================================================
10
+
11
+ # ── Stage 1: Builder ──────────────────────────────────────────────────────
12
+ FROM python:3.12-slim AS builder
13
+
14
+ WORKDIR /build
15
+
16
+ # Install build dependencies
17
+ COPY pyproject.toml requirements.txt ./
18
+ COPY accessible_math_reader/ accessible_math_reader/
19
+ COPY src/ src/
20
+ COPY templates/ templates/
21
+ COPY static/ static/
22
+ COPY app.py ./
23
+ COPY README.md LICENSE ./
24
+
25
+ # Install the package and its API extras
26
+ RUN pip install --no-cache-dir --prefix=/install \
27
+ ".[api]" \
28
+ gunicorn
29
+
30
+ # ── Stage 2: Runtime ─────────────────────────────────────────────────────
31
+ FROM python:3.12-slim AS runtime
32
+
33
+ # Security: run as non-root user
34
+ RUN groupadd -r amr && useradd -r -g amr amr
35
+
36
+ WORKDIR /app
37
+
38
+ # Copy installed packages from builder
39
+ COPY --from=builder /install /usr/local
40
+ COPY --from=builder /build /app
41
+
42
+ # Ensure audio directory exists
43
+ RUN mkdir -p /app/static/audio && chown -R amr:amr /app
44
+
45
+ USER amr
46
+
47
+ # Expose port
48
+ EXPOSE 8000
49
+
50
+ # Health check
51
+ HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
52
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
53
+
54
+ # Production WSGI server
55
+ CMD ["gunicorn", \
56
+ "accessible_math_reader.server:create_app()", \
57
+ "--bind", "0.0.0.0:8000", \
58
+ "--workers", "4", \
59
+ "--timeout", "120", \
60
+ "--access-logfile", "-", \
61
+ "--error-logfile", "-"]
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2026 Andrew Fernandes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.