pulp-engine 0.85.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.
pulp_engine/types.py ADDED
@@ -0,0 +1,394 @@
1
+ """Pydantic models mirroring the TS SDK's response types."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+
10
+ class _Base(BaseModel):
11
+ """Base model that ignores unknown fields for forward compatibility."""
12
+
13
+ model_config = ConfigDict(extra="ignore")
14
+
15
+
16
+ # ── Templates ─────────────────────────────────────────────────────────────
17
+
18
+
19
+ class TemplateSummary(_Base):
20
+ """Template summary returned by list and create operations."""
21
+
22
+ key: str
23
+ name: str
24
+ current_version: str = Field(alias="currentVersion")
25
+ description: str | None = None
26
+
27
+
28
+ class TemplateWithDefinition(_Base):
29
+ """Full template with definition returned by get operations."""
30
+
31
+ key: str
32
+ name: str
33
+ current_version: str = Field(alias="currentVersion")
34
+ description: str | None = None
35
+ definition: dict[str, Any]
36
+
37
+
38
+ class VersionSummary(_Base):
39
+ """Version summary returned by version history listing."""
40
+
41
+ version: str
42
+ created_at: str = Field(alias="createdAt")
43
+ created_by: str | None = Field(default=None, alias="createdBy")
44
+
45
+
46
+ class ValidationIssue(_Base):
47
+ message: str
48
+ path: str | None = None
49
+ code: str | None = None
50
+
51
+
52
+ class ValidationResult(_Base):
53
+ """Validation result returned by the validate endpoint."""
54
+
55
+ valid: bool
56
+ issues: list[ValidationIssue]
57
+
58
+
59
+ # ── Template diff ─────────────────────────────────────────────────────────
60
+
61
+
62
+ class TemplateDiffPropertyChange(_Base):
63
+ """Single property-level change in a TemplateDiff."""
64
+
65
+ path: str
66
+ before: Any = None
67
+ after: Any = None
68
+
69
+
70
+ class TemplateDiffNodeChange(_Base):
71
+ """Structural change to a single AST node in a TemplateDiff."""
72
+
73
+ node_id: str = Field(alias="nodeId")
74
+ node_type: str = Field(alias="nodeType")
75
+ kind: Literal["added", "removed", "modified", "moved"]
76
+ from_path: str | None = Field(default=None, alias="fromPath")
77
+ to_path: str | None = Field(default=None, alias="toPath")
78
+ properties: list[TemplateDiffPropertyChange] | None = None
79
+
80
+
81
+ class TemplateDiffDiagnostic(_Base):
82
+ """Non-fatal diagnostic surfaced by the diff engine."""
83
+
84
+ level: Literal["warn"]
85
+ message: str
86
+
87
+
88
+ class TemplateDiffSummary(_Base):
89
+ """Aggregate counts for a TemplateDiff."""
90
+
91
+ nodes_added: int = Field(alias="nodesAdded")
92
+ nodes_removed: int = Field(alias="nodesRemoved")
93
+ nodes_modified: int = Field(alias="nodesModified")
94
+ nodes_moved: int = Field(alias="nodesMoved")
95
+ properties_changed: int = Field(alias="propertiesChanged")
96
+
97
+
98
+ class TemplateDiff(_Base):
99
+ """Structural diff between two stored versions of a template.
100
+
101
+ Mirrors the ``TemplateDiff`` envelope from ``@pulp-engine/template-diff``.
102
+ Returned by :meth:`TemplatesResource.diff`.
103
+ """
104
+
105
+ template_key: str = Field(alias="templateKey")
106
+ metadata_changes: list[TemplateDiffPropertyChange] = Field(alias="metadataChanges")
107
+ render_config_changes: list[TemplateDiffPropertyChange] = Field(
108
+ alias="renderConfigChanges"
109
+ )
110
+ input_schema_changes: list[TemplateDiffPropertyChange] = Field(
111
+ alias="inputSchemaChanges"
112
+ )
113
+ field_mapping_changes: list[TemplateDiffPropertyChange] = Field(
114
+ alias="fieldMappingChanges"
115
+ )
116
+ document_root_changes: list[TemplateDiffPropertyChange] = Field(
117
+ alias="documentRootChanges"
118
+ )
119
+ document_changes: list[TemplateDiffNodeChange] = Field(alias="documentChanges")
120
+ diagnostics: list[TemplateDiffDiagnostic]
121
+ summary: TemplateDiffSummary
122
+
123
+
124
+ # ── Render ────────────────────────────────────────────────────────────────
125
+
126
+
127
+ class RenderOptions(_Base):
128
+ paper_size: Literal["A4", "A3", "Letter", "Legal", "Tabloid"] | None = Field(
129
+ default=None, alias="paperSize"
130
+ )
131
+ orientation: Literal["portrait", "landscape"] | None = None
132
+
133
+
134
+ # ── Dry run (Stage 3) ─────────────────────────────────────────────────────
135
+ #
136
+ # Mirrors the TS SDK's DryRunResult / DryRunExpressionLocation /
137
+ # DryRunExpressionSuggestion / DryRunExpressionError types. Returned by
138
+ # RenderResource.dry_run() — never raises on template author errors,
139
+ # surfaces them in the result so callers can display them to users.
140
+
141
+
142
+ class DryRunValidationError(_Base):
143
+ """Single schema validation failure from a dry-run result."""
144
+
145
+ path: str
146
+ message: str
147
+
148
+
149
+ class DryRunExpressionLocation(_Base):
150
+ """Structured location of a template expression failure (mirrors API response)."""
151
+
152
+ node_id: str = Field(alias="nodeId")
153
+ node_type: str = Field(alias="nodeType")
154
+ node_path: str = Field(alias="nodePath")
155
+ line: int | None = None
156
+ column: int | None = None
157
+
158
+
159
+ class DryRunExpressionSuggestion(_Base):
160
+ '''"Did you mean?" suggestion for an undefined Handlebars variable.'''
161
+
162
+ variable: str
163
+ suggestions: list[str]
164
+
165
+
166
+ class DryRunExpressionError(_Base):
167
+ """A single template expression failure from a dry-run result."""
168
+
169
+ message: str
170
+ location: DryRunExpressionLocation | None = None
171
+ suggestion: DryRunExpressionSuggestion | None = None
172
+
173
+
174
+ class DryRunValidationSection(_Base):
175
+ valid: bool
176
+ errors: list[DryRunValidationError]
177
+
178
+
179
+ class DryRunExpressionsSection(_Base):
180
+ valid: bool
181
+ errors: list[DryRunExpressionError]
182
+
183
+
184
+ class DryRunResult(_Base):
185
+ """Result of a dry-run render — JSON envelope, never raises on template errors.
186
+
187
+ Returned by :meth:`RenderResource.dry_run`. Same shape as the TS SDK's
188
+ ``DryRunResult``. ``valid`` is true iff both ``validation.valid`` and
189
+ ``expressions.valid`` are true.
190
+ """
191
+
192
+ dry_run: Literal[True] = Field(alias="dryRun")
193
+ valid: bool
194
+ validation: DryRunValidationSection
195
+ expressions: DryRunExpressionsSection
196
+ field_mappings_applied: int = Field(alias="fieldMappingsApplied")
197
+ data_sources_resolved: int = Field(alias="dataSourcesResolved")
198
+
199
+
200
+ # ── Batch ─────────────────────────────────────────────────────────────────
201
+
202
+
203
+ class BatchItemError(_Base):
204
+ """A failed batch item's error envelope (API-4), mirroring the
205
+ single-render error contract. Present only when ``success`` is False."""
206
+
207
+ message: str
208
+ code: str | None = None
209
+ details: object | None = None
210
+
211
+
212
+ class BatchResultItem(_Base):
213
+ index: int
214
+ template: str
215
+ success: bool
216
+ pdf: str | None = None
217
+ docx: str | None = None
218
+ error: BatchItemError | None = None
219
+
220
+
221
+ class BatchResult(_Base):
222
+ total: int
223
+ succeeded: int
224
+ failed: int
225
+ results: list[BatchResultItem]
226
+
227
+
228
+ class AsyncJobAccepted(_Base):
229
+ job_id: str = Field(alias="jobId")
230
+ status: Literal["pending"]
231
+ created_at: str = Field(alias="createdAt")
232
+ poll_url: str = Field(alias="pollUrl")
233
+
234
+
235
+ class AsyncJobStatus(_Base):
236
+ job_id: str = Field(alias="jobId")
237
+ status: Literal["pending", "processing", "completed", "failed"]
238
+ created_at: str = Field(alias="createdAt")
239
+ completed_at: str | None = Field(default=None, alias="completedAt")
240
+ format: Literal["pdf", "docx"]
241
+ item_count: int = Field(alias="itemCount")
242
+ webhook_delivered: bool = Field(alias="webhookDelivered")
243
+ results: BatchResult | None = None
244
+
245
+
246
+ # ── Assets ────────────────────────────────────────────────────────────────
247
+
248
+
249
+ class AssetReference(_Base):
250
+ key: str
251
+ name: str
252
+ current_version: str = Field(alias="currentVersion")
253
+
254
+
255
+ class AssetRecord(_Base):
256
+ id: str
257
+ filename: str
258
+ original_name: str = Field(alias="originalName")
259
+ mime_type: str = Field(alias="mimeType")
260
+ size_bytes: int = Field(alias="sizeBytes")
261
+ url: str
262
+ created_at: str = Field(alias="createdAt")
263
+ created_by: str | None = Field(default=None, alias="createdBy")
264
+ referenced_by: list[AssetReference] | None = Field(default=None, alias="referencedBy")
265
+
266
+
267
+ # ── Audit events ──────────────────────────────────────────────────────────
268
+
269
+
270
+ class AuditEvent(_Base):
271
+ id: str
272
+ timestamp: str
273
+ event: str
274
+ operation: str
275
+ resource_type: str | None = Field(default=None, alias="resourceType")
276
+ resource_id: str | None = Field(default=None, alias="resourceId")
277
+ actor: str | None = None
278
+ credential_scope: str | None = Field(default=None, alias="credentialScope")
279
+ details: dict[str, Any] | None = None
280
+
281
+
282
+ # ── Admin ─────────────────────────────────────────────────────────────────
283
+
284
+
285
+ class UserRecord(_Base):
286
+ id: str
287
+ display_name: str = Field(alias="displayName")
288
+ role: Literal["editor", "admin"]
289
+ key_hint: str = Field(alias="keyHint")
290
+ token_issued_after: str | None = Field(default=None, alias="tokenIssuedAfter")
291
+
292
+
293
+ # ── Auth ──────────────────────────────────────────────────────────────────
294
+
295
+
296
+ class AuthStatus(_Base):
297
+ auth_required: bool = Field(alias="authRequired")
298
+ editor_login_available: bool = Field(alias="editorLoginAvailable")
299
+ identity_mode: Literal["named-users", "shared-key"] = Field(alias="identityMode")
300
+ login_unavailable_reason: str | None = Field(default=None, alias="loginUnavailableReason")
301
+
302
+
303
+ class EditorTokenResponse(_Base):
304
+ token: str
305
+ expires_at: str = Field(alias="expiresAt")
306
+ actor: str | None = None
307
+ display_name: str | None = Field(default=None, alias="displayName")
308
+
309
+
310
+ # ── Health ────────────────────────────────────────────────────────────────
311
+
312
+
313
+ class HealthResponse(_Base):
314
+ status: Literal["ok"]
315
+ version: str
316
+ timestamp: str
317
+
318
+
319
+ class ReadinessResponse(_Base):
320
+ status: Literal["ok", "degraded"]
321
+ version: str
322
+ timestamp: str
323
+ checks: dict[str, str]
324
+
325
+
326
+ # ── Schedules ─────────────────────────────────────────────────────────────
327
+
328
+
329
+ class DataSource(_Base):
330
+ type: Literal["static", "url"]
331
+ data: dict[str, Any] | None = None
332
+ url: str | None = None
333
+ headers: dict[str, str] | None = None
334
+ timeout_ms: int | None = Field(default=None, alias="timeoutMs")
335
+
336
+
337
+ class DeliveryTarget(_Base):
338
+ type: Literal["email", "s3", "webhook"]
339
+ # email fields
340
+ to: list[str] | None = None
341
+ cc: list[str] | None = None
342
+ subject: str | None = None
343
+ body: str | None = None
344
+ attachment_name: str | None = Field(default=None, alias="attachmentName")
345
+ # s3 fields
346
+ key: str | None = None
347
+ bucket: str | None = None
348
+ region: str | None = None
349
+ # webhook fields
350
+ url: str | None = None
351
+ secret: str | None = None
352
+ include_body: bool | None = Field(default=None, alias="includeBody")
353
+
354
+
355
+ class Schedule(_Base):
356
+ id: str
357
+ name: str
358
+ enabled: bool
359
+ cron_expression: str = Field(alias="cronExpression")
360
+ timezone: str
361
+ template_key: str = Field(alias="templateKey")
362
+ template_version: str | None = Field(default=None, alias="templateVersion")
363
+ format: Literal["pdf", "docx"]
364
+ data_source: DataSource = Field(alias="dataSource")
365
+ delivery_targets: list[DeliveryTarget] = Field(alias="deliveryTargets")
366
+ render_options: dict[str, Any] | None = Field(default=None, alias="renderOptions")
367
+ next_fire_at: str | None = Field(default=None, alias="nextFireAt")
368
+ last_fired_at: str | None = Field(default=None, alias="lastFiredAt")
369
+ created_at: str = Field(alias="createdAt")
370
+ updated_at: str = Field(alias="updatedAt")
371
+ created_by: str | None = Field(default=None, alias="createdBy")
372
+
373
+
374
+ class DeliveryTargetResult(_Base):
375
+ target_type: str = Field(alias="targetType")
376
+ delivered: bool
377
+ attempts: int
378
+ error: str | None = None
379
+
380
+
381
+ class ScheduleExecution(_Base):
382
+ id: str
383
+ schedule_id: str = Field(alias="scheduleId")
384
+ fire_time: str = Field(alias="fireTime")
385
+ status: str
386
+ claimed_by: str | None = Field(default=None, alias="claimedBy")
387
+ claimed_at: str | None = Field(default=None, alias="claimedAt")
388
+ render_duration_ms: int | None = Field(default=None, alias="renderDurationMs")
389
+ delivery_results: list[DeliveryTargetResult] | None = Field(
390
+ default=None, alias="deliveryResults"
391
+ )
392
+ last_error: str | None = Field(default=None, alias="lastError")
393
+ created_at: str = Field(alias="createdAt")
394
+ updated_at: str = Field(alias="updatedAt")
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: pulp-engine
3
+ Version: 0.85.0
4
+ Summary: Python client for the Pulp Engine document generation API
5
+ Project-URL: Homepage, https://github.com/TroyCoderBoy/pulp-engine
6
+ Project-URL: Documentation, https://github.com/TroyCoderBoy/pulp-engine/tree/main/packages/sdk-python
7
+ Project-URL: Issues, https://github.com/TroyCoderBoy/pulp-engine/issues
8
+ Project-URL: Source, https://github.com/TroyCoderBoy/pulp-engine
9
+ Project-URL: Changelog, https://github.com/TroyCoderBoy/pulp-engine/blob/main/CHANGELOG.md
10
+ Author: Pulp Engine
11
+ License-Expression: MIT
12
+ Keywords: document-generation,pdf,pulp-engine,templates
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: httpx>=0.27.0
24
+ Requires-Dist: pydantic>=2.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: build>=1.2.0; extra == 'dev'
27
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
28
+ Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
29
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
30
+ Requires-Dist: ruff>=0.6.0; extra == 'dev'
31
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Pulp Engine Python SDK
35
+
36
+ Typed Python client for the [PulpEngine](https://github.com/TroyCoderBoy/pulp-engine) document generation API.
37
+
38
+ Mirrors the [TypeScript SDK](../sdk-typescript) 1:1 with snake_case method names and Pythonic conventions (context manager, type hints, Pydantic response models).
39
+
40
+ ## Installation
41
+
42
+ > **Not yet published to PyPI.** This SDK currently ships in-repo only; registry
43
+ > publication is pending trusted-publisher setup. Until then, install from the
44
+ > workspace path (`pip install -e packages/sdk-python`). The command below will
45
+ > work once the package is live on PyPI.
46
+
47
+ ```bash
48
+ pip install pulp-engine
49
+ ```
50
+
51
+ Requires Python 3.11+.
52
+
53
+ ## Quickstart
54
+
55
+ ```python
56
+ from pulp_engine import PulpEngineClient
57
+
58
+ with PulpEngineClient(
59
+ base_url="https://pulp-engine.example.com",
60
+ api_key="dk_admin_...",
61
+ ) as client:
62
+ # List templates
63
+ templates = client.templates.list()
64
+ for t in templates.items:
65
+ print(t.key, t.current_version)
66
+
67
+ # Render a PDF
68
+ result = client.render.pdf("invoice", {"amount": 100, "customer": "Acme"})
69
+ result.save("invoice.pdf")
70
+
71
+ # Render to HTML (returns string)
72
+ html = client.render.html("invoice", {"amount": 100, "customer": "Acme"})
73
+ print(html)
74
+ ```
75
+
76
+ ## Preview routes in production
77
+
78
+ The Pulp Engine OpenAPI spec this SDK is generated from includes `/render/preview/html` and `/render/preview/pdf` routes. In production (`NODE_ENV=production`), those routes return `404` unless the API operator has explicitly enabled them with `PREVIEW_ROUTES_ENABLED=true`. They are intended for the live editor, not for production rendering pipelines.
79
+
80
+ Before calling a preview method against an unknown deployment, query `GET /capabilities` at runtime and check the advertised preview capability. Use the production render endpoints (`POST /render/pdf` — `POST /render` is a deprecated alias — and the per-format routes `POST /render/html|csv|xlsx|docx|pptx`, plus `POST /render/batch` for bulk jobs) for all production document generation — they are always registered and are not affected by this flag.
81
+
82
+ ## Authentication
83
+
84
+ Pass either an API key (`X-Api-Key` header) or an editor session token (`X-Editor-Token` header):
85
+
86
+ ```python
87
+ # API key
88
+ client = PulpEngineClient(base_url="...", api_key="dk_admin_...")
89
+
90
+ # Editor session token
91
+ client = PulpEngineClient(base_url="...", editor_token="...")
92
+
93
+ # Switch at runtime
94
+ client.set_api_key("new-key")
95
+ client.set_editor_token("new-token")
96
+ ```
97
+
98
+ ## Available resources
99
+
100
+ | Resource | Methods |
101
+ |---|---|
102
+ | `client.templates` | `list`, `get`, `create`, `update`, `delete`, `schema`, `sample`, `validate`, `versions`, `get_version`, `restore` |
103
+ | `client.render` | `pdf`, `html`, `csv`, `xlsx`, `docx`, `pptx`, `dry_run`, `validate` |
104
+ | `client.batch` | `pdf`, `docx`, `submit_async`, `submit_async_docx`, `poll_job`, `wait_for_job` |
105
+ | `client.pdf_transform` | `merge`, `watermark`, `insert` |
106
+ | `client.assets` | `list`, `upload`, `delete` |
107
+ | `client.audit_events` | `list`, `purge` |
108
+ | `client.admin` | `list_users`, `create_user`, `update_user`, `delete_user`, `reload_users` |
109
+ | `client.auth` | `status`, `editor_token` |
110
+ | `client.health` | `liveness`, `readiness` |
111
+ | `client.schedules` | `list`, `get`, `create`, `update`, `patch`, `delete`, `trigger`, `list_executions`, `get_execution` |
112
+
113
+ ## Error handling
114
+
115
+ All methods raise `PulpEngineError` on non-2xx responses:
116
+
117
+ ```python
118
+ from pulp_engine import PulpEngineClient, PulpEngineError
119
+
120
+ try:
121
+ client.render.pdf("missing-template", {})
122
+ except PulpEngineError as e:
123
+ print(e.status) # 404
124
+ print(e.error) # "NotFound"
125
+ print(e.code) # None (or e.g. "template_expression_error" for render errors)
126
+ print(e.issues) # None (or list[ValidationIssue] for 400/422)
127
+ print(str(e)) # Human-readable message
128
+ ```
129
+
130
+ ## Dry-run mode (CI/CD pre-flight checks)
131
+
132
+ `client.render.dry_run()` validates input data and exercises all template
133
+ expressions via a trial HTML render, then returns a structured result without
134
+ producing any binary output. Skips Chromium / DOCX / PPTX entirely — typical
135
+ latency is 5–50 ms vs 1–10 s for a full PDF render. Useful for CI/CD
136
+ pre-flight checks and integration tests.
137
+
138
+ Unlike the normal render methods, `dry_run()` does **not** raise on template
139
+ author errors (validation failures, undefined variables, etc.) — those are
140
+ surfaced in the result so callers can display them to users. The only way it
141
+ raises is if the request itself is malformed (network error, 4xx auth, etc.).
142
+
143
+ ```python
144
+ result = client.render.dry_run("invoice", {"amount": 100})
145
+
146
+ if result.valid:
147
+ print(f"Template OK ({result.field_mappings_applied} field mappings applied)")
148
+ else:
149
+ # Validation errors (schema mismatches)
150
+ for err in result.validation.errors:
151
+ print(f"Validation: {err.path}: {err.message}")
152
+
153
+ # Expression errors (Handlebars failures, undefined variables)
154
+ for err in result.expressions.errors:
155
+ location = err.location.node_path if err.location else "(no location)"
156
+ print(f"Expression at {location}: {err.message}")
157
+ if err.suggestion:
158
+ print(f" Did you mean: {', '.join(err.suggestion.suggestions)}?")
159
+ ```
160
+
161
+ The `format` parameter selects which per-format route to hit (defaults to
162
+ `"pdf"`). The result shape is identical regardless of format — the selector
163
+ only matters when different formats have different rate limits or feature
164
+ gates server-side:
165
+
166
+ ```python
167
+ client.render.dry_run("invoice", data, format="html")
168
+ client.render.dry_run("invoice", data, format="docx")
169
+ ```
170
+
171
+ ## Binary results
172
+
173
+ PDF, CSV, XLSX, DOCX, and PPTX renders return a `BinaryResult` (or `PptxResult`) with:
174
+
175
+ - `.data` — raw bytes
176
+ - `.content_type` — response Content-Type header
177
+ - `.content_disposition` — response Content-Disposition header
178
+ - `.save(path)` — convenience method to write bytes to a file (creates parent dirs)
179
+
180
+ ```python
181
+ result = client.render.pdf("invoice", {"amount": 100})
182
+ result.save("output/invoice.pdf") # creates output/ if needed
183
+ ```
184
+
185
+ `PptxResult` adds:
186
+
187
+ - `.warning_count` — number of structured warnings parsed from the `X-Render-Warnings` header
188
+
189
+ ## Pagination
190
+
191
+ List endpoints return a `PaginatedResult[T]` envelope:
192
+
193
+ ```python
194
+ page = client.templates.list(limit=20, offset=0)
195
+ print(page.total) # total count across all pages
196
+ print(len(page.items)) # items on this page
197
+
198
+ # Auto-paginate with the helper
199
+ from pulp_engine import paginate
200
+
201
+ for template in paginate(lambda offset, limit: client.templates.list(limit=limit, offset=offset)):
202
+ print(template.key)
203
+ ```
204
+
205
+ ## Development
206
+
207
+ ```bash
208
+ cd packages/sdk-python
209
+ pip install -e ".[dev]"
210
+ pytest
211
+ ```
212
+
213
+ ## Releasing
214
+
215
+ See [RELEASING.md](./RELEASING.md) for the publish runbook. Releases are
216
+ automated via the [`publish-sdk-python.yml`](../../.github/workflows/publish-sdk-python.yml)
217
+ GitHub Actions workflow using PyPI Trusted Publishing (no API tokens).
@@ -0,0 +1,21 @@
1
+ pulp_engine/__init__.py,sha256=eCrLNPlY7SrDE4sUgmrD5CTFw92M9Fwq5tfh0IERJM8,1279
2
+ pulp_engine/_http.py,sha256=nez7KS1NXr6_ccL-ESSYv2iXdfRk2hHlAqHWcDfyUm4,7831
3
+ pulp_engine/client.py,sha256=uVKAHxr2C8u9VEypzJ7j9A5EtJfmcgqWfH4bqgtgM5s,3049
4
+ pulp_engine/errors.py,sha256=Uko4DnkBIm3joaNTXwE-E2rItKdmrU0e1rzWXiBOWRc,5308
5
+ pulp_engine/pagination.py,sha256=KXClcGCCO-QGRbH-CQoftOGVhxL7nyM54wk0SmeTA4Y,1314
6
+ pulp_engine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ pulp_engine/types.py,sha256=ztUUIgqi01VYReCyQHZ9KOrbNHsMCay19yOqCZZ3jfw,13322
8
+ pulp_engine/resources/__init__.py,sha256=WfFCv5xa3YuWpLxRLH4HQBs7pgY5pcG0ZUVlx9VclYU,714
9
+ pulp_engine/resources/admin.py,sha256=xnXBS0RqeFJgvdJYRoPP-edOG4_yYJL3LOtwGO0i8Gg,2271
10
+ pulp_engine/resources/assets.py,sha256=oKiD8hAsKwjOnsNv-Z-klZ0qdAVqF9sNjlKYNs6OyoY,2026
11
+ pulp_engine/resources/audit_events.py,sha256=1mKk7MXPs7KYnRBFduYNJYmrxrSxOHQsJFuwJDUqcVw,1899
12
+ pulp_engine/resources/auth.py,sha256=00Ulu37_UErWAIyINZmuG8tj9_In6KbsETwnHsPu_so,1025
13
+ pulp_engine/resources/batch.py,sha256=cnxjfe2jkty1OZLJi9UWnUFe6pyRnN7RRXOXLsbgh_I,5730
14
+ pulp_engine/resources/health.py,sha256=FdccWhFk_fowiuLw5ffwSXmTXiSTYee6v9UMqJ4SioQ,767
15
+ pulp_engine/resources/pdf_transform.py,sha256=LOWx8IdGVQi-D1sPwL0NXktkCKyNpPZNdIwheZb7Y-k,2920
16
+ pulp_engine/resources/render.py,sha256=A1s-OCOOMfImsPuIBwqi5HlHOQJ-mzI0X0jwYdux2D8,11219
17
+ pulp_engine/resources/schedules.py,sha256=Isa6Iskm0tDWdkaEjYdeiwL6q5fEGvZl9RyLWO6LEc4,3485
18
+ pulp_engine/resources/templates.py,sha256=JD6M9PZqIty1ncfygHKkdyMJ3gFZxlF6NLn9DsfWKww,5376
19
+ pulp_engine-0.85.0.dist-info/METADATA,sha256=GeK-gLW-gFKAqG8ZHy0M8XPmbWqdXvbWqH5BhQlbY7U,8384
20
+ pulp_engine-0.85.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
21
+ pulp_engine-0.85.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any