pipelex-api 0.71.0__py3-none-any.whl

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 (46) hide show
  1. pipelex_api/__init__.py +0 -0
  2. pipelex_api/api.toml +21 -0
  3. pipelex_api/api_config.py +144 -0
  4. pipelex_api/bundle.py +243 -0
  5. pipelex_api/disclosure.py +43 -0
  6. pipelex_api/error_types.py +80 -0
  7. pipelex_api/error_uri.py +45 -0
  8. pipelex_api/errors.py +130 -0
  9. pipelex_api/exception_handlers.py +693 -0
  10. pipelex_api/json_body.py +182 -0
  11. pipelex_api/limits.py +67 -0
  12. pipelex_api/main.py +221 -0
  13. pipelex_api/method_cache.py +241 -0
  14. pipelex_api/method_source.py +215 -0
  15. pipelex_api/middleware.py +209 -0
  16. pipelex_api/openapi_responses.py +186 -0
  17. pipelex_api/openapi_schema.py +83 -0
  18. pipelex_api/problem_document.py +134 -0
  19. pipelex_api/py.typed +0 -0
  20. pipelex_api/routes/__init__.py +23 -0
  21. pipelex_api/routes/health.py +24 -0
  22. pipelex_api/routes/pipelex/__init__.py +21 -0
  23. pipelex_api/routes/pipelex/agent/__init__.py +11 -0
  24. pipelex_api/routes/pipelex/agent/concept.py +60 -0
  25. pipelex_api/routes/pipelex/agent/models.py +49 -0
  26. pipelex_api/routes/pipelex/agent/pipe_spec.py +59 -0
  27. pipelex_api/routes/pipelex/build/__init__.py +11 -0
  28. pipelex_api/routes/pipelex/build/inputs.py +192 -0
  29. pipelex_api/routes/pipelex/build/output.py +163 -0
  30. pipelex_api/routes/pipelex/build/runner.py +236 -0
  31. pipelex_api/routes/pipelex/codegen.py +164 -0
  32. pipelex_api/routes/pipelex/crate_ops.py +331 -0
  33. pipelex_api/routes/pipelex/pipe_io.py +186 -0
  34. pipelex_api/routes/pipelex/pipeline.py +938 -0
  35. pipelex_api/routes/pipelex/resolve.py +81 -0
  36. pipelex_api/routes/pipelex/tools.py +111 -0
  37. pipelex_api/routes/pipelex/utils.py +6 -0
  38. pipelex_api/routes/pipelex/validate.py +473 -0
  39. pipelex_api/routes/version.py +51 -0
  40. pipelex_api/schemas/__init__.py +0 -0
  41. pipelex_api/schemas/models.py +653 -0
  42. pipelex_api/security.py +284 -0
  43. pipelex_api-0.71.0.dist-info/METADATA +188 -0
  44. pipelex_api-0.71.0.dist-info/RECORD +46 -0
  45. pipelex_api-0.71.0.dist-info/WHEEL +4 -0
  46. pipelex_api-0.71.0.dist-info/licenses/LICENSE +95 -0
pipelex_api/errors.py ADDED
@@ -0,0 +1,130 @@
1
+ """API-authored error helpers — RFC 7807 problem responses for the 4xx/5xx the API owns.
2
+
3
+ These cover failures the API detects at its own boundary — request validation,
4
+ auth, payload-size limits, server misconfiguration — as opposed to pipelex
5
+ domain errors, which carry an `ErrorReport` and are translated by the global
6
+ `PipelexError` handler in `pipelex_api.exception_handlers`.
7
+
8
+ Each helper builds an RFC 7807 problem document (`build_problem_document_from_api_error`)
9
+ and raises `ApiError`. The `handle_api_error` handler registered in
10
+ `pipelex_api.exception_handlers` renders it as `application/problem+json`. Routes do
11
+ NOT catch pipelex exceptions themselves — anything that is not an
12
+ API-authored `ApiError` propagates to the global handlers. There are no
13
+ catch tuples here anymore: the global `PipelexError` / `Exception` handlers
14
+ are the single translation point for everything the API does not author
15
+ itself.
16
+ """
17
+
18
+ from typing import Any, NoReturn
19
+
20
+ from pipelex.base_exceptions import ErrorDomain
21
+
22
+ from pipelex_api.error_types import ErrorType
23
+ from pipelex_api.problem_document import build_problem_document_from_api_error
24
+
25
+
26
+ class ApiError(Exception):
27
+ """An API-authored error carrying a ready-rendered RFC 7807 problem document.
28
+
29
+ Raised by the `raise_*` helpers below; rendered by `handle_api_error` in
30
+ `pipelex_api.exception_handlers` as `application/problem+json`. Distinct from a pipelex
31
+ `PipelexError`: there is no `ErrorReport` behind it — the failure is the
32
+ API's own request validation, auth, or configuration check. The problem
33
+ document is built at raise time, less the request context: `instance` and
34
+ `request_id` are stamped by the handler, which is the frame that holds the
35
+ `Request`.
36
+ """
37
+
38
+ def __init__(self, *, status_code: int, document: dict[str, Any], headers: dict[str, str] | None = None) -> None:
39
+ self.status_code = status_code
40
+ self.document = document
41
+ self.headers: dict[str, str] = headers or {}
42
+ super().__init__(str(document.get("detail", "")))
43
+
44
+
45
+ def _raise_api_error(
46
+ *,
47
+ error_type: ErrorType,
48
+ message: str,
49
+ status: int,
50
+ error_domain: ErrorDomain,
51
+ headers: dict[str, str] | None = None,
52
+ ) -> NoReturn:
53
+ """Build the RFC 7807 document and raise `ApiError`.
54
+
55
+ The document is built without the request context: `instance` and
56
+ `request_id` are stamped by `handle_api_error`, from the `Request` it is
57
+ handed. That keeps these helpers parameter-clean — a call site deep inside
58
+ a route still needs no `Request` — while leaving the API with no ambient
59
+ request state of its own, and it is how the three error paths end up
60
+ reading the route and the id from exactly one place.
61
+ """
62
+ document = build_problem_document_from_api_error(
63
+ error_type,
64
+ message,
65
+ status,
66
+ instance=None,
67
+ request_id=None,
68
+ error_domain=error_domain,
69
+ )
70
+ raise ApiError(status_code=status, document=document, headers=headers)
71
+
72
+
73
+ def raise_validation_error(message: str, error_type: ErrorType = ErrorType.VALIDATION_ERROR) -> NoReturn:
74
+ """Raise a 422 RFC 7807 problem response for invalid caller input."""
75
+ _raise_api_error(error_type=error_type, message=message, status=422, error_domain=ErrorDomain.INPUT)
76
+
77
+
78
+ def raise_bad_request(message: str, error_type: ErrorType = ErrorType.BAD_REQUEST) -> NoReturn:
79
+ """Raise a 400 RFC 7807 problem response for a malformed request."""
80
+ _raise_api_error(error_type=error_type, message=message, status=400, error_domain=ErrorDomain.INPUT)
81
+
82
+
83
+ def raise_payload_too_large(message: str) -> NoReturn:
84
+ """Raise a 413 RFC 7807 problem response for an over-limit payload."""
85
+ _raise_api_error(error_type=ErrorType.PAYLOAD_TOO_LARGE, message=message, status=413, error_domain=ErrorDomain.INPUT)
86
+
87
+
88
+ def raise_forbidden(message: str, error_type: ErrorType = ErrorType.FORBIDDEN) -> NoReturn:
89
+ """Raise a 403 RFC 7807 problem response for an authorization failure."""
90
+ _raise_api_error(error_type=error_type, message=message, status=403, error_domain=ErrorDomain.INPUT)
91
+
92
+
93
+ def raise_unauthenticated(message: str, error_type: ErrorType = ErrorType.UNAUTHENTICATED) -> NoReturn:
94
+ """Raise a 401 RFC 7807 problem response, with the `WWW-Authenticate: Bearer` challenge.
95
+
96
+ RFC 7807 fully supports the challenge header: moving the body to
97
+ `application/problem+json` does not break an OAuth/JWT client that parses
98
+ `WWW-Authenticate`.
99
+ """
100
+ _raise_api_error(
101
+ error_type=error_type,
102
+ message=message,
103
+ status=401,
104
+ error_domain=ErrorDomain.INPUT,
105
+ headers={"WWW-Authenticate": "Bearer"},
106
+ )
107
+
108
+
109
+ def raise_not_implemented(message: str, error_type: ErrorType) -> NoReturn:
110
+ """Raise a 501 RFC 7807 problem response for a spec'd capability this server does not implement yet.
111
+
112
+ For request shapes the published contract accepts but this deployment cannot serve (e.g. a
113
+ `method_ref` closure selector before the method registry exists). A no-verdict condition —
114
+ distinct from a 422 (the request is well-formed per the contract) and from a 200 invalid
115
+ verdict (nothing was diagnosed). Classified `CONFIG` domain: neither the request nor the
116
+ content is at fault.
117
+ """
118
+ _raise_api_error(error_type=error_type, message=message, status=501, error_domain=ErrorDomain.CONFIG)
119
+
120
+
121
+ def raise_internal_server_error(message: str, error_type: ErrorType) -> NoReturn:
122
+ """Raise a 500 RFC 7807 problem response for an API-owned server fault.
123
+
124
+ For the API's own configuration / invariant failures — a missing secret, a
125
+ storage backend that cannot presign, absent package metadata. NOT for
126
+ pipelex domain errors, which carry an `ErrorReport` and are handled by the
127
+ global `PipelexError` handler. Classified `CONFIG` domain: an operator, not
128
+ the caller, fixes it.
129
+ """
130
+ _raise_api_error(error_type=error_type, message=message, status=500, error_domain=ErrorDomain.CONFIG)