ippx 0.1.0__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.
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ python-version: ["3.11", "3.12", "3.13"]
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: actions/setup-python@v5
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+ - run: pip install -e .[dev]
23
+ - run: ruff check src tests
24
+ - run: ruff format --check src tests
25
+ - run: mypy
26
+ - run: pytest -q
@@ -0,0 +1,24 @@
1
+ name: release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+ permissions:
15
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+ - run: pip install --upgrade build twine
22
+ - run: python -m build
23
+ - run: twine check dist/*
24
+ - uses: pypa/gh-action-pypi-publish@release/v1
ippx-0.1.0/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-06-13
11
+
12
+ ### Added
13
+ - Initial release.
14
+ - Synchronous `IppClient` and asynchronous `AsyncIppClient`.
15
+ - Sans-IO IPP/IPPS codec (RFC 8010) with full request encoding and response
16
+ decoding, including nested collections.
17
+ - IPP operation set (RFC 8011) with the IANA operation registry through 0x46.
18
+ - Print-Job submission, verified end to end against real hardware
19
+ (HP Color LaserJet Pro M283fdw over IPPS).
20
+ - TLS support with certificate fingerprint pinning, configurable verification,
21
+ and legacy-cipher (SECLEVEL) handling for older printers.
22
+ - Distinct exception taxonomy (`IppDecodeError`, `IppResponseError`,
23
+ `IppHttpError`, `FingerprintMismatch`).
24
+ - Typed API shipping `py.typed`, checked under strict mypy.
25
+
26
+ [Unreleased]: https://github.com/smck83/ippx/compare/v0.1.0...HEAD
27
+ [0.1.0]: https://github.com/smck83/ippx/releases/tag/v0.1.0
ippx-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright(c) 2026 smck83
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
ippx-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: ippx
3
+ Version: 0.1.0
4
+ Summary: Sync and async IPP/IPPS client: send print jobs and monitor network printers
5
+ Project-URL: Homepage, https://github.com/smck83/ippx
6
+ Project-URL: Repository, https://github.com/smck83/ippx
7
+ Project-URL: Issues, https://github.com/smck83/ippx/issues
8
+ Project-URL: Changelog, https://github.com/smck83/ippx/blob/main/CHANGELOG.md
9
+ Author: Scott McKenzie
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ipp,ipps,print-job,printer,printing
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Printing
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: httpx>=0.27
22
+ Provides-Extra: dev
23
+ Requires-Dist: mypy>=1.10; extra == 'dev'
24
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
25
+ Requires-Dist: pytest>=8; extra == 'dev'
26
+ Requires-Dist: respx>=0.21; extra == 'dev'
27
+ Requires-Dist: ruff>=0.4; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # ippx
31
+
32
+ Sync and async IPP/IPPS client for Python. Send print jobs and monitor network
33
+ printers, including printers exposed over the internet behind TLS with source
34
+ IP allowlisting.
35
+
36
+ Built on [httpx](https://www.python-httpx.org/) with a pure sans-IO codec for
37
+ the IPP binary protocol (RFC 8010) and the RFC 8011 required operation set.
38
+
39
+ ippx is a plain library: the only runtime dependency is httpx. No framework,
40
+ no server, no Docker required. Use it from a script, a CLI, a cron job, a
41
+ serverless function, or an async web app.
42
+
43
+ ## Why
44
+
45
+ [pyipp](https://pypi.org/project/pyipp/) is monitoring only. ippx can actually
46
+ print, in both async (FastAPI-native) and sync code, with first-class support
47
+ for the realities of network printers: self-signed certificates, legacy cipher
48
+ suites, HTTP Basic auth, and flaky WAN links.
49
+
50
+ ## Install
51
+
52
+ ```
53
+ pip install ippx
54
+ ```
55
+
56
+ Python 3.11+. Single runtime dependency: httpx. Fully typed (PEP 561).
57
+
58
+ ## Quick start (async, e.g. inside FastAPI)
59
+
60
+ ```python
61
+ from ippx import AsyncIppClient, BasicAuth, TlsConfig
62
+
63
+ async def print_invoice(pdf_bytes: bytes) -> None:
64
+ async with AsyncIppClient(
65
+ "ipps://printer.example.com:631/ipp/print",
66
+ auth=BasicAuth("user", "password"),
67
+ tls=TlsConfig(fingerprint="sha256:AB:CD:..."),
68
+ ) as printer:
69
+ job = await printer.print_job(
70
+ pdf_bytes,
71
+ document_format="application/pdf",
72
+ job_name="invoice-123",
73
+ job_attributes={"copies": 1, "sides": "two-sided-long-edge"},
74
+ )
75
+ result = await printer.wait_for_job(job.job_id, timeout=120)
76
+ print(result.state, result.state_reasons)
77
+ ```
78
+
79
+ ## Quick start (sync)
80
+
81
+ ```python
82
+ from ippx import IppClient
83
+
84
+ with IppClient("ipps://203.0.113.10:631/ipp/print") as printer:
85
+ caps = printer.get_printer_attributes()
86
+ print(caps.make_and_model, caps.state, caps.document_formats)
87
+ job = printer.print_job(pdf_bytes, document_format="application/pdf")
88
+ ```
89
+
90
+ ## Operations
91
+
92
+ The RFC 8011 required operation set, supported by every conformant printer:
93
+
94
+ | Method | IPP operation |
95
+ |---|---|
96
+ | `print_job(document, ...)` | Print-Job |
97
+ | `validate_job(...)` | Validate-Job (pre-flight without printing) |
98
+ | `cancel_job(job_id)` | Cancel-Job |
99
+ | `get_printer_attributes(...)` | Get-Printer-Attributes |
100
+ | `get_job_attributes(job_id, ...)` | Get-Job-Attributes |
101
+ | `get_jobs(...)` | Get-Jobs |
102
+ | `wait_for_job(job_id, timeout=...)` | polling helper over Get-Job-Attributes |
103
+
104
+ `wait_for_job` polls with exponential backoff (1s doubling to a 15s cap by
105
+ default) until the job reaches a terminal state (completed, canceled,
106
+ aborted) and raises `JobTimeoutError` otherwise.
107
+
108
+ A printer's full `operations-supported` list decodes to the named `Operation`
109
+ enum (the complete IANA IPP registry, not just the implemented set), so you
110
+ can introspect capabilities like `Operation.IDENTIFY_PRINTER`.
111
+
112
+ Note that for `get_jobs` most printers only return `job-id` and `job-uri` by
113
+ default, per RFC 8011; pass
114
+ `requested_attributes=["job-id", "job-state", "job-name"]` to get more.
115
+
116
+ ## Authentication
117
+
118
+ - **HTTP Basic**: `auth=ippx.BasicAuth("user", "pw")` (or a plain
119
+ `("user", "pw")` tuple)
120
+ - **HTTP Digest**: `auth=ippx.DigestAuth("user", "pw")`
121
+ - **TLS client certificate**: `tls=TlsConfig(client_cert=("cert.pem", "key.pem"))`
122
+ - **requesting-user-name**: set via `requesting_user_name=`, sent on every
123
+ request (identification only, not authentication)
124
+
125
+ ## TLS
126
+
127
+ Printers almost universally ship self-signed certificates. `TlsConfig` gives
128
+ you four options, strongest first:
129
+
130
+ ```python
131
+ TlsConfig() # system CA validation (default)
132
+ TlsConfig(verify="/path/to/printer-ca.pem") # custom CA bundle
133
+ TlsConfig(fingerprint="sha256:AB:CD:...") # pin the exact certificate
134
+ TlsConfig(verify=False) # no validation (last resort)
135
+ ```
136
+
137
+ Fingerprint pinning verifies the SHA-256 digest of the server certificate
138
+ during the TLS handshake itself, so there is no window between checking and
139
+ using the connection. Get a printer's fingerprint with:
140
+
141
+ ```
142
+ openssl s_client -connect printer:631 < /dev/null 2>/dev/null \
143
+ | openssl x509 -fingerprint -sha256 -noout
144
+ ```
145
+
146
+ For an internet-exposed printer (port forward locked to a source WAN IP),
147
+ the recommended setup is fingerprint pinning plus HTTP Basic auth.
148
+
149
+ Two behaviours worth knowing:
150
+
151
+ - Printers very commonly offer only plain-RSA key exchange (no ECDHE), which
152
+ stock OpenSSL policy rejects with a bare handshake-failure alert. Every
153
+ context ippx builds therefore uses `DEFAULT:@SECLEVEL=1` ciphers so real
154
+ hardware is reachable and genuine certificate problems surface as truthful
155
+ certificate errors; override with `TlsConfig(ciphers=...)` to tighten or
156
+ loosen.
157
+ - With a custom CA bundle, hostname verification is disabled (printers are
158
+ usually addressed by IP), so any certificate issued by that CA is accepted.
159
+
160
+ ## Job attributes
161
+
162
+ Pass common Job Template attributes as a plain dict; tags are inferred for
163
+ `copies`, `sides`, `media`, `print-quality`, `print-color-mode`,
164
+ `orientation-requested`, `output-bin`, `number-up`, `printer-resolution` and
165
+ others. For anything else, pass `ippx.Attribute` objects with explicit tags.
166
+
167
+ ## Verified hardware
168
+
169
+ | Printer | Print-Job | Status | Notes |
170
+ |---|---|---|---|
171
+ | HP Color LaserJet Pro M283fdw | yes | verified | Full IPPS path with fingerprint pinning: Get-Printer-Attributes (128 attrs incl. nested media-col collections), Validate-Job, Print-Job to completion, job polling, Get-Jobs, sync and async. Offers RSA-key-exchange ciphers only, handled by the default `TlsConfig` cipher policy. |
172
+
173
+ Also verified end-to-end against a live CUPS 2.4 server (Get-Printer-Attributes,
174
+ Validate-Job, Print-Job, job polling to completion, Get-Jobs, sync and async
175
+ clients). Contributions to this table are welcome.
176
+
177
+ ## Not in scope (yet)
178
+
179
+ - Document conversion: bring your own PDF/PCL/PWG raster bytes
180
+ - Create-Job / Send-Document multi-document jobs
181
+ - IPP event subscriptions (RFC 3995): printer firmware support is too rare
182
+ to rely on; use `wait_for_job` polling
183
+ - Encoding IPP collections in requests (decoding is fully supported)
184
+ - mDNS/driverless discovery
185
+
186
+ ## Development
187
+
188
+ ```
189
+ pip install -e .[dev]
190
+ ruff check src tests
191
+ pytest
192
+ ```
193
+
194
+ ## License
195
+
196
+ MIT
ippx-0.1.0/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # ippx
2
+
3
+ Sync and async IPP/IPPS client for Python. Send print jobs and monitor network
4
+ printers, including printers exposed over the internet behind TLS with source
5
+ IP allowlisting.
6
+
7
+ Built on [httpx](https://www.python-httpx.org/) with a pure sans-IO codec for
8
+ the IPP binary protocol (RFC 8010) and the RFC 8011 required operation set.
9
+
10
+ ippx is a plain library: the only runtime dependency is httpx. No framework,
11
+ no server, no Docker required. Use it from a script, a CLI, a cron job, a
12
+ serverless function, or an async web app.
13
+
14
+ ## Why
15
+
16
+ [pyipp](https://pypi.org/project/pyipp/) is monitoring only. ippx can actually
17
+ print, in both async (FastAPI-native) and sync code, with first-class support
18
+ for the realities of network printers: self-signed certificates, legacy cipher
19
+ suites, HTTP Basic auth, and flaky WAN links.
20
+
21
+ ## Install
22
+
23
+ ```
24
+ pip install ippx
25
+ ```
26
+
27
+ Python 3.11+. Single runtime dependency: httpx. Fully typed (PEP 561).
28
+
29
+ ## Quick start (async, e.g. inside FastAPI)
30
+
31
+ ```python
32
+ from ippx import AsyncIppClient, BasicAuth, TlsConfig
33
+
34
+ async def print_invoice(pdf_bytes: bytes) -> None:
35
+ async with AsyncIppClient(
36
+ "ipps://printer.example.com:631/ipp/print",
37
+ auth=BasicAuth("user", "password"),
38
+ tls=TlsConfig(fingerprint="sha256:AB:CD:..."),
39
+ ) as printer:
40
+ job = await printer.print_job(
41
+ pdf_bytes,
42
+ document_format="application/pdf",
43
+ job_name="invoice-123",
44
+ job_attributes={"copies": 1, "sides": "two-sided-long-edge"},
45
+ )
46
+ result = await printer.wait_for_job(job.job_id, timeout=120)
47
+ print(result.state, result.state_reasons)
48
+ ```
49
+
50
+ ## Quick start (sync)
51
+
52
+ ```python
53
+ from ippx import IppClient
54
+
55
+ with IppClient("ipps://203.0.113.10:631/ipp/print") as printer:
56
+ caps = printer.get_printer_attributes()
57
+ print(caps.make_and_model, caps.state, caps.document_formats)
58
+ job = printer.print_job(pdf_bytes, document_format="application/pdf")
59
+ ```
60
+
61
+ ## Operations
62
+
63
+ The RFC 8011 required operation set, supported by every conformant printer:
64
+
65
+ | Method | IPP operation |
66
+ |---|---|
67
+ | `print_job(document, ...)` | Print-Job |
68
+ | `validate_job(...)` | Validate-Job (pre-flight without printing) |
69
+ | `cancel_job(job_id)` | Cancel-Job |
70
+ | `get_printer_attributes(...)` | Get-Printer-Attributes |
71
+ | `get_job_attributes(job_id, ...)` | Get-Job-Attributes |
72
+ | `get_jobs(...)` | Get-Jobs |
73
+ | `wait_for_job(job_id, timeout=...)` | polling helper over Get-Job-Attributes |
74
+
75
+ `wait_for_job` polls with exponential backoff (1s doubling to a 15s cap by
76
+ default) until the job reaches a terminal state (completed, canceled,
77
+ aborted) and raises `JobTimeoutError` otherwise.
78
+
79
+ A printer's full `operations-supported` list decodes to the named `Operation`
80
+ enum (the complete IANA IPP registry, not just the implemented set), so you
81
+ can introspect capabilities like `Operation.IDENTIFY_PRINTER`.
82
+
83
+ Note that for `get_jobs` most printers only return `job-id` and `job-uri` by
84
+ default, per RFC 8011; pass
85
+ `requested_attributes=["job-id", "job-state", "job-name"]` to get more.
86
+
87
+ ## Authentication
88
+
89
+ - **HTTP Basic**: `auth=ippx.BasicAuth("user", "pw")` (or a plain
90
+ `("user", "pw")` tuple)
91
+ - **HTTP Digest**: `auth=ippx.DigestAuth("user", "pw")`
92
+ - **TLS client certificate**: `tls=TlsConfig(client_cert=("cert.pem", "key.pem"))`
93
+ - **requesting-user-name**: set via `requesting_user_name=`, sent on every
94
+ request (identification only, not authentication)
95
+
96
+ ## TLS
97
+
98
+ Printers almost universally ship self-signed certificates. `TlsConfig` gives
99
+ you four options, strongest first:
100
+
101
+ ```python
102
+ TlsConfig() # system CA validation (default)
103
+ TlsConfig(verify="/path/to/printer-ca.pem") # custom CA bundle
104
+ TlsConfig(fingerprint="sha256:AB:CD:...") # pin the exact certificate
105
+ TlsConfig(verify=False) # no validation (last resort)
106
+ ```
107
+
108
+ Fingerprint pinning verifies the SHA-256 digest of the server certificate
109
+ during the TLS handshake itself, so there is no window between checking and
110
+ using the connection. Get a printer's fingerprint with:
111
+
112
+ ```
113
+ openssl s_client -connect printer:631 < /dev/null 2>/dev/null \
114
+ | openssl x509 -fingerprint -sha256 -noout
115
+ ```
116
+
117
+ For an internet-exposed printer (port forward locked to a source WAN IP),
118
+ the recommended setup is fingerprint pinning plus HTTP Basic auth.
119
+
120
+ Two behaviours worth knowing:
121
+
122
+ - Printers very commonly offer only plain-RSA key exchange (no ECDHE), which
123
+ stock OpenSSL policy rejects with a bare handshake-failure alert. Every
124
+ context ippx builds therefore uses `DEFAULT:@SECLEVEL=1` ciphers so real
125
+ hardware is reachable and genuine certificate problems surface as truthful
126
+ certificate errors; override with `TlsConfig(ciphers=...)` to tighten or
127
+ loosen.
128
+ - With a custom CA bundle, hostname verification is disabled (printers are
129
+ usually addressed by IP), so any certificate issued by that CA is accepted.
130
+
131
+ ## Job attributes
132
+
133
+ Pass common Job Template attributes as a plain dict; tags are inferred for
134
+ `copies`, `sides`, `media`, `print-quality`, `print-color-mode`,
135
+ `orientation-requested`, `output-bin`, `number-up`, `printer-resolution` and
136
+ others. For anything else, pass `ippx.Attribute` objects with explicit tags.
137
+
138
+ ## Verified hardware
139
+
140
+ | Printer | Print-Job | Status | Notes |
141
+ |---|---|---|---|
142
+ | HP Color LaserJet Pro M283fdw | yes | verified | Full IPPS path with fingerprint pinning: Get-Printer-Attributes (128 attrs incl. nested media-col collections), Validate-Job, Print-Job to completion, job polling, Get-Jobs, sync and async. Offers RSA-key-exchange ciphers only, handled by the default `TlsConfig` cipher policy. |
143
+
144
+ Also verified end-to-end against a live CUPS 2.4 server (Get-Printer-Attributes,
145
+ Validate-Job, Print-Job, job polling to completion, Get-Jobs, sync and async
146
+ clients). Contributions to this table are welcome.
147
+
148
+ ## Not in scope (yet)
149
+
150
+ - Document conversion: bring your own PDF/PCL/PWG raster bytes
151
+ - Create-Job / Send-Document multi-document jobs
152
+ - IPP event subscriptions (RFC 3995): printer firmware support is too rare
153
+ to rely on; use `wait_for_job` polling
154
+ - Encoding IPP collections in requests (decoding is fully supported)
155
+ - mDNS/driverless discovery
156
+
157
+ ## Development
158
+
159
+ ```
160
+ pip install -e .[dev]
161
+ ruff check src tests
162
+ pytest
163
+ ```
164
+
165
+ ## License
166
+
167
+ MIT
@@ -0,0 +1,59 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "ippx"
7
+ version = "0.1.0"
8
+ description = "Sync and async IPP/IPPS client: send print jobs and monitor network printers"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.11"
13
+ authors = [{ name = "Scott McKenzie" }]
14
+ keywords = ["ipp", "ipps", "printing", "printer", "print-job"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Printing",
22
+ "Typing :: Typed",
23
+ ]
24
+ dependencies = ["httpx>=0.27"]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/smck83/ippx"
28
+ Repository = "https://github.com/smck83/ippx"
29
+ Issues = "https://github.com/smck83/ippx/issues"
30
+ Changelog = "https://github.com/smck83/ippx/blob/main/CHANGELOG.md"
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest>=8",
35
+ "pytest-asyncio>=0.23",
36
+ "respx>=0.21",
37
+ "ruff>=0.4",
38
+ "mypy>=1.10",
39
+ ]
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/ippx"]
43
+
44
+ [tool.ruff]
45
+ line-length = 100
46
+ target-version = "py311"
47
+ src = ["src", "tests"]
48
+
49
+ [tool.ruff.lint]
50
+ select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
51
+
52
+ [tool.pytest.ini_options]
53
+ asyncio_mode = "auto"
54
+ testpaths = ["tests"]
55
+
56
+ [tool.mypy]
57
+ python_version = "3.11"
58
+ strict = true
59
+ files = ["src/ippx"]
@@ -0,0 +1,43 @@
1
+ """ippx: sync and async IPP/IPPS client for sending print jobs and
2
+ monitoring network printers."""
3
+
4
+ from httpx import BasicAuth, DigestAuth
5
+
6
+ from ._async import AsyncIppClient
7
+ from ._codec import Attribute, IppMessage, Resolution, Tag, decode, encode
8
+ from ._models import Job, JobState, Operation, Printer, PrinterState
9
+ from ._sync import IppClient
10
+ from ._tls import TlsConfig
11
+ from .exceptions import (
12
+ IppDecodeError,
13
+ IppError,
14
+ IppHttpError,
15
+ IppResponseError,
16
+ JobTimeoutError,
17
+ )
18
+
19
+ __version__ = "0.1.0"
20
+
21
+ __all__ = [
22
+ "AsyncIppClient",
23
+ "Attribute",
24
+ "BasicAuth",
25
+ "DigestAuth",
26
+ "IppClient",
27
+ "IppDecodeError",
28
+ "IppError",
29
+ "IppHttpError",
30
+ "IppMessage",
31
+ "IppResponseError",
32
+ "Job",
33
+ "JobState",
34
+ "JobTimeoutError",
35
+ "Operation",
36
+ "Printer",
37
+ "PrinterState",
38
+ "Resolution",
39
+ "Tag",
40
+ "TlsConfig",
41
+ "decode",
42
+ "encode",
43
+ ]