vws-python 2023.12.26__tar.gz → 2024.2.4__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 (56) hide show
  1. {vws-python-2023.12.26 → vws-python-2024.2.4}/.github/workflows/ci.yml +2 -2
  2. {vws-python-2023.12.26 → vws-python-2024.2.4}/.github/workflows/release.yml +14 -2
  3. {vws-python-2023.12.26 → vws-python-2024.2.4}/.github/workflows/windows-ci.yml +1 -1
  4. {vws-python-2023.12.26 → vws-python-2024.2.4}/.vscode/settings.json +1 -1
  5. {vws-python-2023.12.26 → vws-python-2024.2.4}/CHANGELOG.rst +11 -0
  6. {vws-python-2023.12.26 → vws-python-2024.2.4}/Makefile +1 -0
  7. {vws-python-2023.12.26 → vws-python-2024.2.4}/PKG-INFO +13 -12
  8. {vws-python-2023.12.26 → vws-python-2024.2.4}/conftest.py +3 -3
  9. {vws-python-2023.12.26 → vws-python-2024.2.4}/lint.mk +6 -2
  10. {vws-python-2023.12.26 → vws-python-2024.2.4}/pyproject.toml +50 -14
  11. {vws-python-2023.12.26 → vws-python-2024.2.4}/spelling_private_dict.txt +1 -1
  12. vws-python-2024.2.4/src/vws/exceptions/custom_exceptions.py +87 -0
  13. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/exceptions/vws_exceptions.py +0 -7
  14. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/query.py +8 -0
  15. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/vws.py +52 -6
  16. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws_python.egg-info/PKG-INFO +13 -12
  17. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws_python.egg-info/SOURCES.txt +0 -1
  18. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws_python.egg-info/requires.txt +12 -11
  19. {vws-python-2023.12.26 → vws-python-2024.2.4}/tests/test_vws_exceptions.py +5 -3
  20. vws-python-2023.12.26/MANIFEST.in +0 -2
  21. vws-python-2023.12.26/src/vws/exceptions/custom_exceptions.py +0 -26
  22. {vws-python-2023.12.26 → vws-python-2024.2.4}/.git_archival.txt +0 -0
  23. {vws-python-2023.12.26 → vws-python-2024.2.4}/.gitattributes +0 -0
  24. {vws-python-2023.12.26 → vws-python-2024.2.4}/.github/dependabot.yml +0 -0
  25. {vws-python-2023.12.26 → vws-python-2024.2.4}/.gitignore +0 -0
  26. {vws-python-2023.12.26 → vws-python-2024.2.4}/.vscode/extensions.json +0 -0
  27. {vws-python-2023.12.26 → vws-python-2024.2.4}/CODE_OF_CONDUCT.rst +0 -0
  28. {vws-python-2023.12.26 → vws-python-2024.2.4}/LICENSE +0 -0
  29. {vws-python-2023.12.26 → vws-python-2024.2.4}/README.rst +0 -0
  30. {vws-python-2023.12.26 → vws-python-2024.2.4}/codecov.yaml +0 -0
  31. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/Makefile +0 -0
  32. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/__init__.py +0 -0
  33. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/api-reference.rst +0 -0
  34. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/changelog.rst +0 -0
  35. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/conf.py +0 -0
  36. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/contributing.rst +0 -0
  37. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/exceptions.rst +0 -0
  38. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/index.rst +0 -0
  39. {vws-python-2023.12.26 → vws-python-2024.2.4}/docs/source/release-process.rst +0 -0
  40. {vws-python-2023.12.26 → vws-python-2024.2.4}/readthedocs.yaml +0 -0
  41. {vws-python-2023.12.26 → vws-python-2024.2.4}/setup.cfg +0 -0
  42. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/__init__.py +0 -0
  43. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/exceptions/__init__.py +0 -0
  44. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/exceptions/base_exceptions.py +0 -0
  45. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/exceptions/cloud_reco_exceptions.py +0 -0
  46. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/include_target_data.py +0 -0
  47. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/py.typed +0 -0
  48. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws/reports.py +0 -0
  49. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws_python.egg-info/dependency_links.txt +0 -0
  50. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws_python.egg-info/not-zip-safe +0 -0
  51. {vws-python-2023.12.26 → vws-python-2024.2.4}/src/vws_python.egg-info/top_level.txt +0 -0
  52. {vws-python-2023.12.26 → vws-python-2024.2.4}/tests/__init__.py +0 -0
  53. {vws-python-2023.12.26 → vws-python-2024.2.4}/tests/conftest.py +0 -0
  54. {vws-python-2023.12.26 → vws-python-2024.2.4}/tests/test_cloud_reco_exceptions.py +0 -0
  55. {vws-python-2023.12.26 → vws-python-2024.2.4}/tests/test_query.py +0 -0
  56. {vws-python-2023.12.26 → vws-python-2024.2.4}/tests/test_vws.py +0 -0
@@ -29,7 +29,7 @@ jobs:
29
29
  with:
30
30
  python-version: ${{ matrix.python-version }}
31
31
 
32
- - uses: actions/cache@v3
32
+ - uses: actions/cache@v4
33
33
  with:
34
34
  path: ~/.cache/pip
35
35
  key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
@@ -55,4 +55,4 @@ jobs:
55
55
  pytest -s -vvv --cov-fail-under 100 --cov=src/ --cov=tests . --cov-report=xml
56
56
 
57
57
  - name: "Upload coverage to Codecov"
58
- uses: "codecov/codecov-action@v3"
58
+ uses: "codecov/codecov-action@v4"
@@ -9,6 +9,17 @@ jobs:
9
9
  name: Publish a release
10
10
  runs-on: ubuntu-latest
11
11
 
12
+ # Specifying an environment is strongly recommended by PyPI.
13
+ # See https://github.com/pypa/gh-action-pypi-publish/tree/release/v1/?tab=readme-ov-file#trusted-publishing.
14
+ environment: release
15
+
16
+ permissions:
17
+ # This is needed for PyPI publishing.
18
+ # See https://github.com/pypa/gh-action-pypi-publish/tree/release/v1/?tab=readme-ov-file#trusted-publishing.
19
+ id-token: write
20
+ # This is needed for https://github.com/stefanzweifel/git-auto-commit-action.
21
+ contents: write
22
+
12
23
  strategy:
13
24
  matrix:
14
25
  python-version: ["3.12"]
@@ -65,12 +76,13 @@ jobs:
65
76
  run: |
66
77
  # Checkout the latest tag - the one we just created.
67
78
  git fetch --tags
68
- git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
79
+ git checkout "$(git describe --tags "$(git rev-list --tags --max-count=1)")"
69
80
  python -m pip install build
70
81
  python -m build --sdist --wheel --outdir dist/ .
71
82
 
83
+ # We use PyPI trusted publishing rather than a PyPI API token.
84
+ # See https://github.com/pypa/gh-action-pypi-publish/tree/release/v1/?tab=readme-ov-file#trusted-publishing.
72
85
  - name: Publish distribution 📦 to PyPI
73
86
  uses: pypa/gh-action-pypi-publish@release/v1
74
87
  with:
75
- password: ${{ secrets.PYPI_API_TOKEN }}
76
88
  verbose: true
@@ -29,7 +29,7 @@ jobs:
29
29
  with:
30
30
  python-version: ${{ matrix.python-version }}
31
31
 
32
- - uses: actions/cache@v3
32
+ - uses: actions/cache@v4
33
33
  with:
34
34
  path: ~\AppData\Local\pip\Cache
35
35
  key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "[python]": {
3
3
  "editor.codeActionsOnSave": {
4
- "source.fixAll": true
4
+ "source.fixAll": "explicit"
5
5
  },
6
6
  "editor.defaultFormatter": "charliermarsh.ruff",
7
7
  "editor.formatOnSave": true
@@ -4,6 +4,17 @@ Changelog
4
4
  Next
5
5
  ----
6
6
 
7
+ 2024.02.04
8
+ ------------
9
+
10
+ * Return a new error (``vws.custom_exceptions.ServerError``) when the server returns a 5xx status code.
11
+
12
+ 2023.12.27
13
+ ------------
14
+
15
+ * Breaking change: The ``vws.exceptions.cloud_reco_exceptions.UnknownVWSErrorPossiblyBadName`` is now ``vws.exceptions.custom_exceptions.OopsAnErrorOccurredPossiblyBadName``.
16
+ * ``vws.exceptions.custom_exceptions.OopsAnErrorOccurredPossiblyBadName`` now has a ``response`` parameter and attribute.
17
+
7
18
  2023.12.26
8
19
  ------------
9
20
 
@@ -7,6 +7,7 @@ SPHINXOPTS := -W
7
7
 
8
8
  .PHONY: lint
9
9
  lint: \
10
+ actionlint \
10
11
  check-manifest \
11
12
  doc8 \
12
13
  linkcheck \
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vws-python
3
- Version: 2023.12.26
3
+ Version: 2024.2.4
4
4
  Summary: Interact with the Vuforia Web Services (VWS) API.
5
5
  Author-email: Adam Dangoor <adamdangoor@gmail.com>
6
6
  License: The MIT License
@@ -40,34 +40,35 @@ Requires-Dist: requests
40
40
  Requires-Dist: urllib3
41
41
  Requires-Dist: VWS-Auth-Tools
42
42
  Provides-Extra: dev
43
+ Requires-Dist: actionlint-py==1.6.26.11; extra == "dev"
43
44
  Requires-Dist: check-manifest==0.49; extra == "dev"
44
45
  Requires-Dist: doc8==1.1.1; extra == "dev"
45
46
  Requires-Dist: dodgy==0.2.1; extra == "dev"
46
47
  Requires-Dist: freezegun==1.4.0; extra == "dev"
47
- Requires-Dist: furo==2023.9.10; extra == "dev"
48
+ Requires-Dist: furo==2024.1.29; extra == "dev"
48
49
  Requires-Dist: mypy==1.8.0; extra == "dev"
49
- Requires-Dist: pdm==2.11.1; extra == "dev"
50
+ Requires-Dist: pdm==2.12.3; extra == "dev"
50
51
  Requires-Dist: pip_check_reqs==2.5.3; extra == "dev"
51
52
  Requires-Dist: pydocstyle==6.3; extra == "dev"
52
53
  Requires-Dist: pyenchant==3.2.2; extra == "dev"
53
54
  Requires-Dist: Pygments==2.17.2; extra == "dev"
54
55
  Requires-Dist: pylint==3.0.3; extra == "dev"
55
- Requires-Dist: pyproject-fmt==1.5.3; extra == "dev"
56
- Requires-Dist: pyright==1.1.343; extra == "dev"
56
+ Requires-Dist: pyproject-fmt==1.7.0; extra == "dev"
57
+ Requires-Dist: pyright==1.1.349; extra == "dev"
57
58
  Requires-Dist: pyroma==4.2; extra == "dev"
58
- Requires-Dist: pytest==7.4.3; extra == "dev"
59
+ Requires-Dist: pytest==8.0.0; extra == "dev"
59
60
  Requires-Dist: pytest-cov==4.1; extra == "dev"
60
61
  Requires-Dist: PyYAML==6.0.1; extra == "dev"
61
- Requires-Dist: ruff==0.1.9; extra == "dev"
62
+ Requires-Dist: ruff==0.2.0; extra == "dev"
62
63
  Requires-Dist: Sphinx==7.2.6; extra == "dev"
63
- Requires-Dist: sphinx-autodoc-typehints==1.25.2; extra == "dev"
64
+ Requires-Dist: sphinx-autodoc-typehints==1.25.3; extra == "dev"
64
65
  Requires-Dist: sphinx-prompt==1.8; extra == "dev"
65
66
  Requires-Dist: Sphinx-Substitution-Extensions==2022.2.16; extra == "dev"
66
67
  Requires-Dist: sphinxcontrib-spelling==8; extra == "dev"
67
- Requires-Dist: sybil==6.0.2; extra == "dev"
68
- Requires-Dist: types-requests==2.31.0.10; extra == "dev"
69
- Requires-Dist: vulture==2.10; extra == "dev"
70
- Requires-Dist: VWS-Python-Mock==2023.5.21; extra == "dev"
68
+ Requires-Dist: sybil==6.0.3; extra == "dev"
69
+ Requires-Dist: types-requests==2.31.0.20240125; extra == "dev"
70
+ Requires-Dist: vulture==2.11; extra == "dev"
71
+ Requires-Dist: VWS-Python-Mock==2024.1.21; extra == "dev"
71
72
  Requires-Dist: VWS-Test-Fixtures==2023.3.5; extra == "dev"
72
73
 
73
74
  |Build Status| |codecov| |PyPI| |Documentation Status|
@@ -2,14 +2,14 @@
2
2
 
3
3
  from doctest import ELLIPSIS
4
4
 
5
- from sybil import Sybil # pyright: ignore[reportMissingTypeStubs]
6
- from sybil.parsers.rest import ( # pyright: ignore[reportMissingTypeStubs]
5
+ from sybil import Sybil
6
+ from sybil.parsers.rest import (
7
7
  ClearNamespaceParser,
8
8
  DocTestParser,
9
9
  PythonCodeBlockParser,
10
10
  )
11
11
 
12
- pytest_collect_file = Sybil( # pyright: ignore[reportUnknownVariableType]
12
+ pytest_collect_file = Sybil(
13
13
  parsers=[
14
14
  ClearNamespaceParser(),
15
15
  DocTestParser(optionflags=ELLIPSIS),
@@ -2,6 +2,10 @@
2
2
 
3
3
  SHELL := /bin/bash -euxo pipefail
4
4
 
5
+ .PHONY: actionlint
6
+ actionlint:
7
+ actionlint
8
+
5
9
  .PHONY: mypy
6
10
  mypy:
7
11
  mypy .
@@ -54,11 +58,11 @@ linkcheck:
54
58
 
55
59
  .PHONY: pyproject-fmt
56
60
  pyproject-fmt:
57
- pyproject-fmt --keep-full-version --check --indent=4 pyproject.toml
61
+ pyproject-fmt --check pyproject.toml
58
62
 
59
63
  .PHONY: fix-pyproject-fmt
60
64
  fix-pyproject-fmt:
61
- pyproject-fmt --keep-full-version --indent=4 pyproject.toml
65
+ pyproject-fmt pyproject.toml
62
66
 
63
67
  .PHONY: spelling
64
68
  spelling:
@@ -10,9 +10,28 @@
10
10
 
11
11
  # List of plugins (as comma separated values of python modules names) to load,
12
12
  # usually to register additional checkers.
13
+ # See https://chezsoi.org/lucas/blog/pylint-strict-base-configuration.html.
14
+ # We do not use the plugins:
15
+ # - pylint.extensions.code_style
16
+ # - pylint.extensions.magic_value
17
+ # - pylint.extensions.while_used
18
+ # as they seemed to get in the way.
13
19
  load-plugins = [
20
+ 'pylint.extensions.bad_builtin',
21
+ 'pylint.extensions.comparison_placement',
22
+ 'pylint.extensions.consider_refactoring_into_while_condition',
14
23
  'pylint.extensions.docparams',
24
+ 'pylint.extensions.dunder',
25
+ 'pylint.extensions.eq_without_hash',
26
+ 'pylint.extensions.for_any_all',
27
+ 'pylint.extensions.mccabe',
15
28
  'pylint.extensions.no_self_use',
29
+ 'pylint.extensions.overlapping_exceptions',
30
+ 'pylint.extensions.private_import',
31
+ 'pylint.extensions.redefined_loop_name',
32
+ 'pylint.extensions.redefined_variable_type',
33
+ 'pylint.extensions.set_membership',
34
+ 'pylint.extensions.typing',
16
35
  ]
17
36
 
18
37
  # Allow loading of arbitrary C extensions. Extensions are imported into the
@@ -26,7 +45,11 @@
26
45
  # multiple time (only on the command line, not in the configuration file where
27
46
  # it should appear only once). See also the "--disable" option for examples.
28
47
  enable = [
48
+ 'bad-inline-option',
49
+ 'deprecated-pragma',
50
+ 'file-ignored',
29
51
  'spelling',
52
+ 'use-symbolic-message-instead',
30
53
  'useless-suppression',
31
54
  ]
32
55
 
@@ -89,7 +112,7 @@
89
112
  branch = true
90
113
 
91
114
  [tool.coverage.report]
92
- exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"]
115
+ exclude_also = ["if TYPE_CHECKING:"]
93
116
 
94
117
  [tool.pytest.ini_options]
95
118
 
@@ -150,14 +173,18 @@ requires = [
150
173
  universal = true
151
174
 
152
175
  [tool.ruff]
153
- select = ["ALL"]
154
176
  line-length = 79
155
177
 
178
+ [tool.ruff.lint]
179
+ select = ["ALL"]
180
+
156
181
  ignore = [
157
182
  # We do not annotate the type of 'self'.
158
183
  "ANN101",
159
184
  # We are happy to manage our own "complexity".
160
185
  "C901",
186
+ # Ruff warns that this conflicts with the formatter.
187
+ "COM812",
161
188
  # Allow our chosen docstring line-style - no one-line summary.
162
189
  "D200",
163
190
  "D203",
@@ -170,6 +197,9 @@ ignore = [
170
197
  # docstrings.
171
198
  "D406",
172
199
  "D407",
200
+ "D413",
201
+ # Ruff warns that this conflicts with the formatter.
202
+ "ISC001",
173
203
  # We have an existing interface to support and so we do not want to change
174
204
  # exception names.
175
205
  "N818",
@@ -187,7 +217,7 @@ ignore = [
187
217
  # is sometimes annoyingly removed.
188
218
  unfixable = ["ERA001"]
189
219
 
190
- [tool.ruff.per-file-ignores]
220
+ [tool.ruff.lint.per-file-ignores]
191
221
  "tests/test_*.py" = [
192
222
  # Do not require tests to have a one-line summary.
193
223
  "D205",
@@ -223,34 +253,35 @@ dependencies = [
223
253
  ]
224
254
  [project.optional-dependencies]
225
255
  dev = [
256
+ "actionlint-py==1.6.26.11",
226
257
  "check-manifest==0.49",
227
258
  "doc8==1.1.1",
228
259
  "dodgy==0.2.1",
229
260
  "freezegun==1.4.0",
230
- "furo==2023.9.10",
261
+ "furo==2024.1.29",
231
262
  "mypy==1.8.0",
232
- "pdm==2.11.1",
263
+ "pdm==2.12.3",
233
264
  "pip_check_reqs==2.5.3",
234
265
  "pydocstyle==6.3",
235
266
  "pyenchant==3.2.2",
236
267
  "Pygments==2.17.2",
237
268
  "pylint==3.0.3",
238
- "pyproject-fmt==1.5.3",
239
- "pyright==1.1.343",
269
+ "pyproject-fmt==1.7.0",
270
+ "pyright==1.1.349",
240
271
  "pyroma==4.2",
241
- "pytest==7.4.3",
272
+ "pytest==8.0.0",
242
273
  "pytest-cov==4.1",
243
274
  "PyYAML==6.0.1",
244
- "ruff==0.1.9",
275
+ "ruff==0.2.0",
245
276
  "Sphinx==7.2.6",
246
- "sphinx-autodoc-typehints==1.25.2",
277
+ "sphinx-autodoc-typehints==1.25.3",
247
278
  "sphinx-prompt==1.8",
248
279
  "Sphinx-Substitution-Extensions==2022.2.16",
249
280
  "sphinxcontrib-spelling==8",
250
- "sybil==6.0.2",
251
- "types-requests==2.31.0.10",
252
- "vulture==2.10",
253
- "VWS-Python-Mock==2023.5.21",
281
+ "sybil==6.0.3",
282
+ "types-requests==2.31.0.20240125",
283
+ "vulture==2.11",
284
+ "VWS-Python-Mock==2024.1.21",
254
285
  "VWS-Test-Fixtures==2023.3.5",
255
286
  ]
256
287
  [project.urls]
@@ -268,6 +299,11 @@ vws = ["py.typed"]
268
299
 
269
300
  [tool.setuptools_scm]
270
301
 
302
+ [tool.pyproject-fmt]
303
+ indent = 4
304
+ keep_full_version = true
305
+
271
306
  [tool.pyright]
272
307
 
308
+ reportUnnecessaryTypeIgnoreComment = true
273
309
  typeCheckingMode = "strict"
@@ -22,7 +22,7 @@ TargetStatusProcessing
22
22
  TooManyRequests
23
23
  Ubuntu
24
24
  UnknownTarget
25
- UnknownVWSErrorPossiblyBadName
25
+ OopsAnErrorOccurredPossiblyBadName
26
26
  admin
27
27
  api
28
28
  args
@@ -0,0 +1,87 @@
1
+ """
2
+ Exceptions which do not map to errors at
3
+ https://library.vuforia.com/web-api/cloud-targets-web-services-api#result-codes
4
+ or simple errors given by the cloud recognition service.
5
+ """
6
+
7
+
8
+ from requests import Response
9
+
10
+
11
+ class OopsAnErrorOccurredPossiblyBadName(Exception):
12
+ """
13
+ Exception raised when VWS returns an HTML page which says "Oops, an error
14
+ occurred".
15
+
16
+ This has been seen to happen when the given name includes a bad character.
17
+ """
18
+
19
+ def __init__(self, response: Response) -> None:
20
+ """
21
+ Args:
22
+ response: The response returned by Vuforia.
23
+ """
24
+ super().__init__(response.text)
25
+ self._response = response
26
+
27
+ @property
28
+ def response(self) -> Response:
29
+ """
30
+ The response returned by Vuforia which included this error.
31
+ """
32
+ return self._response
33
+
34
+
35
+ class RequestEntityTooLarge(Exception):
36
+ """
37
+ Exception raised when the given image is too large.
38
+ """
39
+
40
+
41
+ class TargetProcessingTimeout(Exception):
42
+ """
43
+ Exception raised when waiting for a target to be processed times out.
44
+ """
45
+
46
+
47
+ class ServerError(Exception): # pragma: no cover
48
+ """
49
+ Exception raised when VWS returns a server error.
50
+ """
51
+
52
+ def __init__(self, response: Response) -> None:
53
+ """
54
+ Args:
55
+ response: The response returned by Vuforia.
56
+ """
57
+ super().__init__(response.text)
58
+ self._response = response
59
+
60
+ @property
61
+ def response(self) -> Response:
62
+ """
63
+ The response returned by Vuforia which included this error.
64
+ """
65
+ return self._response
66
+
67
+
68
+ class TooManyRequests(Exception): # pragma: no cover
69
+ """
70
+ Exception raised when Vuforia returns a response with a result code
71
+ 'TooManyRequests'.
72
+ """
73
+
74
+ def __init__(self, response: Response) -> None:
75
+ """
76
+ Args:
77
+ response: The response returned by Vuforia.
78
+ """
79
+ super().__init__(response.text)
80
+ self._response = response
81
+
82
+ @property
83
+ def response(self) -> Response:
84
+ """
85
+ The response returned by Vuforia which included this error.
86
+ """
87
+ return self._response
@@ -56,13 +56,6 @@ class RequestQuotaReached(VWSException): # pragma: no cover
56
56
  """
57
57
 
58
58
 
59
- class TooManyRequests(VWSException): # pragma: no cover
60
- """
61
- Exception raised when Vuforia returns a response with a result code
62
- 'TooManyRequests'.
63
- """
64
-
65
-
66
59
  class TargetStatusProcessing(VWSException):
67
60
  """
68
61
  Exception raised when Vuforia returns a response with a result code
@@ -22,6 +22,7 @@ from vws.exceptions.cloud_reco_exceptions import (
22
22
  )
23
23
  from vws.exceptions.custom_exceptions import (
24
24
  RequestEntityTooLarge,
25
+ ServerError,
25
26
  )
26
27
  from vws.include_target_data import CloudRecoIncludeTargetData
27
28
  from vws.reports import QueryResult, TargetData
@@ -94,6 +95,8 @@ class CloudRecoService:
94
95
  file in the grayscale or RGB color space.
95
96
  ~vws.exceptions.custom_exceptions.RequestEntityTooLarge: The given
96
97
  image is too large.
98
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
99
+ with Vuforia's servers.
97
100
 
98
101
  Returns:
99
102
  An ordered list of target details of matching targets.
@@ -145,6 +148,11 @@ class CloudRecoService:
145
148
  if "Integer out of range" in response.text:
146
149
  raise MaxNumResultsOutOfRange(response=response)
147
150
 
151
+ if (
152
+ response.status_code >= HTTPStatus.INTERNAL_SERVER_ERROR
153
+ ): # pragma: no cover
154
+ raise ServerError(response=response)
155
+
148
156
  result_code = response.json()["result_code"]
149
157
  if result_code != "Success":
150
158
  exception = {
@@ -17,8 +17,10 @@ from requests import Response
17
17
  from vws_auth_tools import authorization_header, rfc_1123_date
18
18
 
19
19
  from vws.exceptions.custom_exceptions import (
20
+ OopsAnErrorOccurredPossiblyBadName,
21
+ ServerError,
20
22
  TargetProcessingTimeout,
21
- UnknownVWSErrorPossiblyBadName,
23
+ TooManyRequests,
22
24
  )
23
25
  from vws.exceptions.vws_exceptions import (
24
26
  AuthenticationFailure,
@@ -36,7 +38,6 @@ from vws.exceptions.vws_exceptions import (
36
38
  TargetQuotaReached,
37
39
  TargetStatusNotSuccess,
38
40
  TargetStatusProcessing,
39
- TooManyRequests,
40
41
  UnknownTarget,
41
42
  )
42
43
  from vws.reports import (
@@ -162,10 +163,14 @@ class VWS:
162
163
  The response to the request made by `requests`.
163
164
 
164
165
  Raises:
165
- ~vws.exceptions.UnknownVWSErrorPossiblyBadName: Vuforia returns an
166
- HTML page with the text "Oops, an error occurred". This has
166
+ ~vws.exceptions.OopsAnErrorOccurredPossiblyBadName: Vuforia returns
167
+ an HTML page with the text "Oops, an error occurred". This has
167
168
  been seen to happen when the given name includes a bad
168
169
  character.
170
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
171
+ with Vuforia's servers.
172
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
173
+ limiting access.
169
174
  json.decoder.JSONDecodeError: The server did not respond with valid
170
175
  JSON. This may happen if the server address is not a valid
171
176
  Vuforia server.
@@ -180,7 +185,7 @@ class VWS:
180
185
  )
181
186
 
182
187
  if "Oops, an error occurred" in response.text:
183
- raise UnknownVWSErrorPossiblyBadName
188
+ raise OopsAnErrorOccurredPossiblyBadName(response=response)
184
189
 
185
190
  if (
186
191
  response.status_code == HTTPStatus.TOO_MANY_REQUESTS
@@ -188,6 +193,11 @@ class VWS:
188
193
  # The Vuforia API returns a 429 response with no JSON body.
189
194
  raise TooManyRequests(response=response)
190
195
 
196
+ if (
197
+ response.status_code >= HTTPStatus.INTERNAL_SERVER_ERROR
198
+ ): # pragma: no cover
199
+ raise ServerError(response=response)
200
+
191
201
  result_code = response.json()["result_code"]
192
202
 
193
203
  if result_code == expected_result_code:
@@ -264,10 +274,14 @@ class VWS:
264
274
  inactive.
265
275
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
266
276
  error with the time sent to Vuforia.
267
- ~vws.exceptions.custom_exceptions.UnknownVWSErrorPossiblyBadName:
277
+ ~vws.exceptions.custom_exceptions.OopsAnErrorOccurredPossiblyBadName:
268
278
  Vuforia returns an HTML page with the text "Oops, an error
269
279
  occurred". This has been seen to happen when the given name
270
280
  includes a bad character.
281
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
282
+ with Vuforia's servers.
283
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
284
+ limiting access.
271
285
  """
272
286
  image_data = _get_image_data(image=image)
273
287
  image_data_encoded = base64.b64encode(image_data).decode("ascii")
@@ -314,6 +328,10 @@ class VWS:
314
328
  does not match a target in the database.
315
329
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
316
330
  error with the time sent to Vuforia.
331
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
332
+ with Vuforia's servers.
333
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
334
+ limiting access.
317
335
  """
318
336
  response = self._make_request(
319
337
  method="GET",
@@ -371,6 +389,10 @@ class VWS:
371
389
  does not match a target in the database.
372
390
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
373
391
  error with the time sent to Vuforia.
392
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
393
+ with Vuforia's servers.
394
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
395
+ limiting access.
374
396
  """
375
397
  start_time = time.monotonic()
376
398
  while True:
@@ -402,6 +424,10 @@ class VWS:
402
424
  known database.
403
425
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
404
426
  error with the time sent to Vuforia.
427
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
428
+ with Vuforia's servers.
429
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
430
+ limiting access.
405
431
  """
406
432
  response = self._make_request(
407
433
  method="GET",
@@ -435,6 +461,10 @@ class VWS:
435
461
  does not match a target in the database.
436
462
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
437
463
  error with the time sent to Vuforia.
464
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
465
+ with Vuforia's servers.
466
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
467
+ limiting access.
438
468
  """
439
469
  response = self._make_request(
440
470
  method="GET",
@@ -474,6 +504,10 @@ class VWS:
474
504
  known database.
475
505
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
476
506
  error with the time sent to Vuforia.
507
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
508
+ with Vuforia's servers.
509
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
510
+ limiting access.
477
511
  """
478
512
  response = self._make_request(
479
513
  method="GET",
@@ -520,6 +554,10 @@ class VWS:
520
554
  target is in the processing state.
521
555
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
522
556
  error with the time sent to Vuforia.
557
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
558
+ with Vuforia's servers.
559
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
560
+ limiting access.
523
561
  """
524
562
  self._make_request(
525
563
  method="DELETE",
@@ -553,6 +591,10 @@ class VWS:
553
591
  inactive.
554
592
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
555
593
  error with the time sent to Vuforia.
594
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
595
+ with Vuforia's servers.
596
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
597
+ limiting access.
556
598
  """
557
599
  response = self._make_request(
558
600
  method="GET",
@@ -612,6 +654,10 @@ class VWS:
612
654
  inactive.
613
655
  ~vws.exceptions.vws_exceptions.RequestTimeTooSkewed: There is an
614
656
  error with the time sent to Vuforia.
657
+ ~vws.exceptions.custom_exceptions.ServerError: There is an error
658
+ with Vuforia's servers.
659
+ ~vws.exceptions.custom_exceptions.TooManyRequests: Vuforia is rate
660
+ limiting access.
615
661
  """
616
662
  data: dict[str, str | bool | float | int] = {}
617
663
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vws-python
3
- Version: 2023.12.26
3
+ Version: 2024.2.4
4
4
  Summary: Interact with the Vuforia Web Services (VWS) API.
5
5
  Author-email: Adam Dangoor <adamdangoor@gmail.com>
6
6
  License: The MIT License
@@ -40,34 +40,35 @@ Requires-Dist: requests
40
40
  Requires-Dist: urllib3
41
41
  Requires-Dist: VWS-Auth-Tools
42
42
  Provides-Extra: dev
43
+ Requires-Dist: actionlint-py==1.6.26.11; extra == "dev"
43
44
  Requires-Dist: check-manifest==0.49; extra == "dev"
44
45
  Requires-Dist: doc8==1.1.1; extra == "dev"
45
46
  Requires-Dist: dodgy==0.2.1; extra == "dev"
46
47
  Requires-Dist: freezegun==1.4.0; extra == "dev"
47
- Requires-Dist: furo==2023.9.10; extra == "dev"
48
+ Requires-Dist: furo==2024.1.29; extra == "dev"
48
49
  Requires-Dist: mypy==1.8.0; extra == "dev"
49
- Requires-Dist: pdm==2.11.1; extra == "dev"
50
+ Requires-Dist: pdm==2.12.3; extra == "dev"
50
51
  Requires-Dist: pip_check_reqs==2.5.3; extra == "dev"
51
52
  Requires-Dist: pydocstyle==6.3; extra == "dev"
52
53
  Requires-Dist: pyenchant==3.2.2; extra == "dev"
53
54
  Requires-Dist: Pygments==2.17.2; extra == "dev"
54
55
  Requires-Dist: pylint==3.0.3; extra == "dev"
55
- Requires-Dist: pyproject-fmt==1.5.3; extra == "dev"
56
- Requires-Dist: pyright==1.1.343; extra == "dev"
56
+ Requires-Dist: pyproject-fmt==1.7.0; extra == "dev"
57
+ Requires-Dist: pyright==1.1.349; extra == "dev"
57
58
  Requires-Dist: pyroma==4.2; extra == "dev"
58
- Requires-Dist: pytest==7.4.3; extra == "dev"
59
+ Requires-Dist: pytest==8.0.0; extra == "dev"
59
60
  Requires-Dist: pytest-cov==4.1; extra == "dev"
60
61
  Requires-Dist: PyYAML==6.0.1; extra == "dev"
61
- Requires-Dist: ruff==0.1.9; extra == "dev"
62
+ Requires-Dist: ruff==0.2.0; extra == "dev"
62
63
  Requires-Dist: Sphinx==7.2.6; extra == "dev"
63
- Requires-Dist: sphinx-autodoc-typehints==1.25.2; extra == "dev"
64
+ Requires-Dist: sphinx-autodoc-typehints==1.25.3; extra == "dev"
64
65
  Requires-Dist: sphinx-prompt==1.8; extra == "dev"
65
66
  Requires-Dist: Sphinx-Substitution-Extensions==2022.2.16; extra == "dev"
66
67
  Requires-Dist: sphinxcontrib-spelling==8; extra == "dev"
67
- Requires-Dist: sybil==6.0.2; extra == "dev"
68
- Requires-Dist: types-requests==2.31.0.10; extra == "dev"
69
- Requires-Dist: vulture==2.10; extra == "dev"
70
- Requires-Dist: VWS-Python-Mock==2023.5.21; extra == "dev"
68
+ Requires-Dist: sybil==6.0.3; extra == "dev"
69
+ Requires-Dist: types-requests==2.31.0.20240125; extra == "dev"
70
+ Requires-Dist: vulture==2.11; extra == "dev"
71
+ Requires-Dist: VWS-Python-Mock==2024.1.21; extra == "dev"
71
72
  Requires-Dist: VWS-Test-Fixtures==2023.3.5; extra == "dev"
72
73
 
73
74
  |Build Status| |codecov| |PyPI| |Documentation Status|
@@ -4,7 +4,6 @@
4
4
  CHANGELOG.rst
5
5
  CODE_OF_CONDUCT.rst
6
6
  LICENSE
7
- MANIFEST.in
8
7
  Makefile
9
8
  README.rst
10
9
  codecov.yaml
@@ -3,32 +3,33 @@ urllib3
3
3
  VWS-Auth-Tools
4
4
 
5
5
  [dev]
6
+ actionlint-py==1.6.26.11
6
7
  check-manifest==0.49
7
8
  doc8==1.1.1
8
9
  dodgy==0.2.1
9
10
  freezegun==1.4.0
10
- furo==2023.9.10
11
+ furo==2024.1.29
11
12
  mypy==1.8.0
12
- pdm==2.11.1
13
+ pdm==2.12.3
13
14
  pip_check_reqs==2.5.3
14
15
  pydocstyle==6.3
15
16
  pyenchant==3.2.2
16
17
  Pygments==2.17.2
17
18
  pylint==3.0.3
18
- pyproject-fmt==1.5.3
19
- pyright==1.1.343
19
+ pyproject-fmt==1.7.0
20
+ pyright==1.1.349
20
21
  pyroma==4.2
21
- pytest==7.4.3
22
+ pytest==8.0.0
22
23
  pytest-cov==4.1
23
24
  PyYAML==6.0.1
24
- ruff==0.1.9
25
+ ruff==0.2.0
25
26
  Sphinx==7.2.6
26
- sphinx-autodoc-typehints==1.25.2
27
+ sphinx-autodoc-typehints==1.25.3
27
28
  sphinx-prompt==1.8
28
29
  Sphinx-Substitution-Extensions==2022.2.16
29
30
  sphinxcontrib-spelling==8
30
- sybil==6.0.2
31
- types-requests==2.31.0.10
32
- vulture==2.10
33
- VWS-Python-Mock==2023.5.21
31
+ sybil==6.0.3
32
+ types-requests==2.31.0.20240125
33
+ vulture==2.11
34
+ VWS-Python-Mock==2024.1.21
34
35
  VWS-Test-Fixtures==2023.3.5
@@ -13,7 +13,7 @@ from mock_vws.database import VuforiaDatabase
13
13
  from mock_vws.states import States
14
14
  from vws import VWS
15
15
  from vws.exceptions.base_exceptions import VWSException
16
- from vws.exceptions.custom_exceptions import UnknownVWSErrorPossiblyBadName
16
+ from vws.exceptions.custom_exceptions import OopsAnErrorOccurredPossiblyBadName
17
17
  from vws.exceptions.vws_exceptions import (
18
18
  AuthenticationFailure,
19
19
  BadImage,
@@ -69,11 +69,11 @@ def test_invalid_given_id(vws_client: VWS) -> None:
69
69
  def test_add_bad_name(vws_client: VWS, high_quality_image: io.BytesIO) -> None:
70
70
  """
71
71
  When a name with a bad character is given, an
72
- ``UnknownVWSErrorPossiblyBadName`` exception is raised.
72
+ ``OopsAnErrorOccurredPossiblyBadName`` exception is raised.
73
73
  """
74
74
  max_char_value = 65535
75
75
  bad_name = chr(max_char_value + 1)
76
- with pytest.raises(UnknownVWSErrorPossiblyBadName):
76
+ with pytest.raises(OopsAnErrorOccurredPossiblyBadName) as exc:
77
77
  vws_client.add_target(
78
78
  name=bad_name,
79
79
  width=1,
@@ -82,6 +82,8 @@ def test_add_bad_name(vws_client: VWS, high_quality_image: io.BytesIO) -> None:
82
82
  application_metadata=None,
83
83
  )
84
84
 
85
+ assert exc.value.response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR
86
+
85
87
 
86
88
  def test_request_quota_reached() -> None:
87
89
  """
@@ -1,2 +0,0 @@
1
- include src/vws/py.typed
2
- include pyproject.toml
@@ -1,26 +0,0 @@
1
- """
2
- Exceptions which do not map to errors at
3
- https://library.vuforia.com/web-api/cloud-targets-web-services-api#result-codes
4
- or simple errors given by the cloud recognition service.
5
- """
6
-
7
-
8
- class UnknownVWSErrorPossiblyBadName(Exception):
9
- """
10
- Exception raised when VWS returns an HTML page which says "Oops, an error
11
- occurred".
12
-
13
- This has been seen to happen when the given name includes a bad character.
14
- """
15
-
16
-
17
- class RequestEntityTooLarge(Exception):
18
- """
19
- Exception raised when the given image is too large.
20
- """
21
-
22
-
23
- class TargetProcessingTimeout(Exception):
24
- """
25
- Exception raised when waiting for a target to be processed times out.
26
- """
File without changes
File without changes