Skip to content

Commit cfd9eca

Browse files
delete: Add examples for file deletion using Python 3.10 and 3.11
- Introduced `delete_example.py` showcasing async file deletion with pdfRest: - A Python 3.11 version using `except*` syntax for exception groups. - A Python 3.10 version leveraging the `exceptiongroup` backport. - Updated `pyproject.toml`, `uv.lock`, and `pyrightconfig.json` to include `python-dotenv` for environment variable management. - Added `ruff.toml` configurations targeting `py310` and `py311` in examples. Assisted-by: Codex
1 parent a7b2a68 commit cfd9eca

8 files changed

Lines changed: 115 additions & 0 deletions

File tree

examples/delete/delete_example.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# /// script
2+
# requires-python = ">=3.11"
3+
# dependencies = ["pdfrest", "python-dotenv"]
4+
# ///
5+
"""Delete files with pdfRest's async client on Python 3.11+.
6+
7+
This sample shows how to:
8+
9+
1. Upload a local resource so we have a file id to delete.
10+
2. Delete that file successfully.
11+
3. Demonstrate how `PdfRestErrorGroup` behaves when we try to delete the same
12+
file again (Python 3.11 also allows `except* PdfRestDeleteError` if you want
13+
to tighten the example even further).
14+
15+
Run with `uv run --project ../.. python delete_example.py`; the script uses the
16+
checked-in `examples/resources/report.pdf` sample so no additional setup is
17+
required.
18+
"""
19+
20+
from __future__ import annotations
21+
22+
import asyncio
23+
from pathlib import Path
24+
25+
from dotenv import load_dotenv
26+
27+
from pdfrest import AsyncPdfRestClient, PdfRestDeleteError
28+
29+
RESOURCE = Path(__file__).resolve().parents[1] / "resources" / "report.pdf"
30+
31+
32+
async def delete_with_except_star() -> None:
33+
load_dotenv()
34+
async with AsyncPdfRestClient() as client:
35+
uploaded = (await client.files.create_from_paths([RESOURCE]))[0]
36+
print(f"Uploaded {uploaded.name} with id={uploaded.id}")
37+
38+
await client.files.delete(uploaded)
39+
print("First deletion succeeded.\n")
40+
41+
print("Attempting to delete the same file again to trigger errors...")
42+
try:
43+
await client.files.delete(uploaded)
44+
except* PdfRestDeleteError as group:
45+
for error in group.exceptions:
46+
print(f"- Cleanup failed for {error.file_id}: {error.detail}")
47+
else: # pragma: no cover - would require server bug
48+
print("Second deletion unexpectedly succeeded.")
49+
50+
51+
if __name__ == "__main__": # pragma: no cover - manual example
52+
asyncio.run(delete_with_except_star())
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# /// script
2+
# requires-python = "==3.10"
3+
# dependencies = ["pdfrest", "exceptiongroup", "python-dotenv"]
4+
# ///
5+
"""Delete files with pdfRest's async client on Python 3.10.
6+
7+
Python 3.10 lacks the built-in `except*` syntax, so this example uses the
8+
`exceptiongroup` backport to catch `PdfRestErrorGroup` and inspect individual
9+
`PdfRestDeleteError` instances when cleanup fails.
10+
11+
Run with `uv run --project ../.. python delete_example.py`; the shared
12+
`examples/resources/report.pdf` sample ships with the repository.
13+
"""
14+
15+
from __future__ import annotations
16+
17+
import asyncio
18+
from pathlib import Path
19+
20+
from dotenv import load_dotenv
21+
from exceptiongroup import BaseExceptionGroup, catch
22+
23+
from pdfrest import AsyncPdfRestClient, PdfRestDeleteError
24+
25+
RESOURCE = Path(__file__).resolve().parents[2] / "resources" / "report.pdf"
26+
27+
28+
def _log_delete_errors(group: BaseExceptionGroup) -> None:
29+
for error in group.exceptions:
30+
print(f"- Cleanup failed for {error.file_id}: {error.detail}")
31+
32+
33+
async def delete_with_exceptiongroup_catch() -> None:
34+
load_dotenv()
35+
async with AsyncPdfRestClient() as client:
36+
uploaded = (await client.files.create_from_paths([RESOURCE]))[0]
37+
print(f"Uploaded {uploaded.name} with id={uploaded.id}")
38+
39+
await client.files.delete(uploaded)
40+
print("First deletion succeeded.\n")
41+
42+
print("Attempting to delete the same file again to trigger errors...")
43+
with catch({PdfRestDeleteError: _log_delete_errors}):
44+
await client.files.delete(uploaded)
45+
46+
47+
if __name__ == "__main__": # pragma: no cover - manual example
48+
asyncio.run(delete_with_exceptiongroup_catch())
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Extend the `ruff.toml` file in the examples directory...
2+
3+
extend = "../../ruff.toml"
4+
target-version = "py310"

examples/resources/report.pdf

25 KB
Binary file not shown.

examples/ruff.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Extend the `pyproject.toml` file in the parent directory...
2+
3+
extend = "../pyproject.toml"
4+
target-version = "py311"

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dev = [
3232
"pytest-xdist>=3.8.0",
3333
"nox>=2025.5.1",
3434
"basedpyright>=1.34.0",
35+
"python-dotenv>=1.0.1",
3536
]
3637

3738
[tool.pytest.ini_options]

pyrightconfig.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
{
2323
"root": "src"
2424
},
25+
{
26+
"root": "examples",
27+
"pythonVersion": "3.11"
28+
},
2529
{
2630
"root": "tests",
2731
"reportUnknownLambdaType": "none",

uv.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)