unstructured-platform-plugins 0.1.0__tar.gz → 0.1.2__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 (26) hide show
  1. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/PKG-INFO +1 -1
  2. unstructured_platform_plugins-0.1.2/unstructured_platform_plugins/__version__.py +1 -0
  3. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/etl_uvicorn/api_generator.py +40 -4
  4. unstructured_platform_plugins-0.1.0/unstructured_platform_plugins/__version__.py +0 -1
  5. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/.gitignore +0 -0
  6. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/LICENSE.md +0 -0
  7. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/README.md +0 -0
  8. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/pyproject.toml +0 -0
  9. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/__init__.py +0 -0
  10. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/etl_uvicorn/__init__.py +0 -0
  11. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/etl_uvicorn/main.py +0 -0
  12. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/etl_uvicorn/otel.py +0 -0
  13. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/etl_uvicorn/utils.py +0 -0
  14. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/generated/__init__.py +0 -0
  15. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/generated/error_audience_v1.py +0 -0
  16. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/generated/invocation_context_v1.py +0 -0
  17. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/invocation_context.py +0 -0
  18. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/invocation_settings.py +0 -0
  19. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/schema/__init__.py +0 -0
  20. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/schema/filedata_meta.py +0 -0
  21. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/schema/json_schema.py +0 -0
  22. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/schema/model.py +0 -0
  23. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/schema/usage.py +0 -0
  24. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/schema/utils.py +0 -0
  25. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/type_hints.py +0 -0
  26. {unstructured_platform_plugins-0.1.0 → unstructured_platform_plugins-0.1.2}/unstructured_platform_plugins/validate_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: unstructured_platform_plugins
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Wrapper to convert arbitrary code into a uvicorn/fastapi implementation for Unstructured Platform
5
5
  License-File: LICENSE.md
6
6
  Classifier: Development Status :: 4 - Beta
@@ -0,0 +1 @@
1
+ __version__ = "0.1.2" # pragma: no cover
@@ -3,6 +3,7 @@ import hashlib
3
3
  import inspect
4
4
  import json
5
5
  import logging
6
+ import re
6
7
  from typing import Any, Callable, Optional, Union, get_origin
7
8
 
8
9
  from fastapi import FastAPI, HTTPException, status
@@ -12,7 +13,7 @@ from pydantic import BaseModel, Field, create_model
12
13
  from starlette.responses import RedirectResponse
13
14
  from typing_extensions import deprecated
14
15
  from unstructured_ingest.data_types.file_data import BatchFileData, FileData, file_data_from_dict
15
- from unstructured_ingest.error import UnstructuredIngestError, UserError
16
+ from unstructured_ingest.error import RateLimitError, UnstructuredIngestError, UserError
16
17
  from uvicorn.config import LOG_LEVELS
17
18
  from uvicorn.importer import import_from_string
18
19
 
@@ -111,19 +112,54 @@ def failure_category_of(error: BaseException) -> Optional[str]:
111
112
  return category if isinstance(category, str) else None
112
113
 
113
114
 
115
+ def _as_error_reason(category: Optional[str]) -> Optional[str]:
116
+ """Render a failure_category as an ``error.reason`` token, or None when it cannot be.
117
+
118
+ ``failure_category`` and ``error.reason`` are two vocabularies, not one: the preflight
119
+ categories are SCREAMING_SNAKE (``AUTH_PERMISSION_DENIED``) while ``error.reason`` is
120
+ specified lower_snake_case. ``failure_category`` still rides its own top-level response
121
+ field verbatim, so nothing is lost by normalizing the copy that lands here.
122
+
123
+ The category is plugin-supplied free text rather than a closed enum, so lowercasing
124
+ alone would not produce a snake_case token; punctuation and whitespace collapse to
125
+ single underscores and a category with no usable characters yields None.
126
+ """
127
+ if category is None:
128
+ return None
129
+ # -- str.lower, not category.lower: the isinstance check upstream admits str SUBCLASSES,
130
+ # -- and this renders an error response, where raising is the one thing it must not do --
131
+ reason = re.sub(r"[^a-z0-9]+", "_", str.lower(category)).strip("_")
132
+ return reason or None
133
+
134
+
114
135
  def plugin_error_of(error: BaseException) -> Optional[PluginErrorMetadata]:
115
136
  """Map the legacy UserError family onto the canonical plugin-error envelope.
116
137
 
117
138
  The ratified ErrorAudience vocabulary owns the wire spelling. A non-user failure remains
118
139
  unclassified: orchestrators must not infer actionability from its HTTP status.
140
+
141
+ Terminal is the safe default, so a transient condition has to declare itself: a provider
142
+ rate limit is the one member of this family that clears on its own, and it mirrors the
143
+ utic_plugin_base ``RateLimitError`` declaration (platform-libs #889) field for field.
144
+ Retryability is orthogonal to audience -- a throttled request is still the caller's
145
+ quota, so the audience stays ``user``.
146
+
147
+ The class picks the DEFAULT reason; an explicit ``failure_category`` still wins, on this
148
+ branch as on every other. A plugin that declares a category has said something more
149
+ specific than the class did (a rate limit raised as ``PROVIDER_RATE_LIMITED``), and
150
+ dropping it here would discard the more precise of the two.
119
151
  """
120
152
  if not isinstance(error, UserError):
121
153
  return None
154
+ if isinstance(error, RateLimitError):
155
+ error_type, default_reason, retryable = "dependency", "rate_limited", True
156
+ else:
157
+ error_type, default_reason, retryable = "configuration", "invalid_input", False
122
158
  return PluginErrorMetadata(
123
- error_type="configuration",
124
- error_reason=failure_category_of(error) or "invalid_input",
159
+ error_type=error_type,
160
+ error_reason=_as_error_reason(failure_category_of(error)) or default_reason,
125
161
  audience=ErrorAudience.USER,
126
- retryable=False,
162
+ retryable=retryable,
127
163
  )
128
164
 
129
165
 
@@ -1 +0,0 @@
1
- __version__ = "0.1.0" # pragma: no cover