reconify-python 0.1.0__tar.gz → 1.0.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.
Files changed (53) hide show
  1. {reconify_python-0.1.0 → reconify_python-1.0.0}/.bumpversion.cfg +1 -1
  2. reconify_python-1.0.0/.conductor/settings.toml +18 -0
  3. {reconify_python-0.1.0 → reconify_python-1.0.0}/.github/workflows/ci.yml +1 -0
  4. reconify_python-1.0.0/.github/workflows/sync-contract.yml +36 -0
  5. {reconify_python-0.1.0 → reconify_python-1.0.0}/.gitignore +1 -0
  6. reconify_python-1.0.0/.openapi-contract.json +4 -0
  7. reconify_python-1.0.0/AGENTS.md +29 -0
  8. reconify_python-1.0.0/CHANGELOG.md +16 -0
  9. reconify_python-1.0.0/PKG-INFO +96 -0
  10. reconify_python-1.0.0/README.md +78 -0
  11. reconify_python-1.0.0/UPGRADING.md +17 -0
  12. reconify_python-1.0.0/context7.json +15 -0
  13. {reconify_python-0.1.0 → reconify_python-1.0.0}/pyproject.toml +1 -1
  14. reconify_python-1.0.0/scripts/fetch_contract.py +65 -0
  15. {reconify_python-0.1.0 → reconify_python-1.0.0}/src/reconify/__init__.py +1 -1
  16. reconify_python-1.0.0/src/reconify/client.py +157 -0
  17. reconify_python-1.0.0/src/reconify/models.py +247 -0
  18. {reconify_python-0.1.0 → reconify_python-1.0.0}/src/reconify/pagination.py +1 -1
  19. reconify_python-1.0.0/src/reconify/resources/__init__.py +54 -0
  20. reconify_python-1.0.0/src/reconify/resources/events.py +58 -0
  21. reconify_python-1.0.0/src/reconify/resources/ingestion.py +36 -0
  22. reconify_python-1.0.0/src/reconify/resources/issues.py +129 -0
  23. reconify_python-1.0.0/src/reconify/resources/metadata.py +24 -0
  24. reconify_python-1.0.0/src/reconify/resources/organization.py +41 -0
  25. {reconify_python-0.1.0 → reconify_python-1.0.0}/src/reconify/transport.py +5 -5
  26. reconify_python-1.0.0/tests/test_client.py +218 -0
  27. reconify_python-1.0.0/tests/test_openapi_coverage.py +66 -0
  28. {reconify_python-0.1.0 → reconify_python-1.0.0}/tests/test_pagination.py +12 -17
  29. {reconify_python-0.1.0 → reconify_python-1.0.0}/uv.lock +1 -1
  30. reconify_python-0.1.0/CHANGELOG.md +0 -8
  31. reconify_python-0.1.0/PKG-INFO +0 -125
  32. reconify_python-0.1.0/README.md +0 -107
  33. reconify_python-0.1.0/src/reconify/client.py +0 -264
  34. reconify_python-0.1.0/src/reconify/models.py +0 -1067
  35. reconify_python-0.1.0/src/reconify/resources/__init__.py +0 -124
  36. reconify_python-0.1.0/src/reconify/resources/alerts.py +0 -58
  37. reconify_python-0.1.0/src/reconify/resources/events.py +0 -79
  38. reconify_python-0.1.0/src/reconify/resources/ingestion.py +0 -94
  39. reconify_python-0.1.0/src/reconify/resources/issues.py +0 -207
  40. reconify_python-0.1.0/src/reconify/resources/ledger.py +0 -205
  41. reconify_python-0.1.0/src/reconify/resources/reconciliations.py +0 -236
  42. reconify_python-0.1.0/src/reconify/resources/search.py +0 -37
  43. reconify_python-0.1.0/src/reconify/resources/setup.py +0 -311
  44. reconify_python-0.1.0/src/reconify/resources/transactions.py +0 -58
  45. reconify_python-0.1.0/src/reconify/resources/wallets.py +0 -79
  46. reconify_python-0.1.0/tests/test_client.py +0 -204
  47. reconify_python-0.1.0/tests/test_openapi_coverage.py +0 -88
  48. {reconify_python-0.1.0 → reconify_python-1.0.0}/.github/workflows/release.yml +0 -0
  49. {reconify_python-0.1.0 → reconify_python-1.0.0}/LICENSE +0 -0
  50. {reconify_python-0.1.0 → reconify_python-1.0.0}/reports/api-error-data-report.md +0 -0
  51. {reconify_python-0.1.0 → reconify_python-1.0.0}/src/reconify/errors.py +0 -0
  52. {reconify_python-0.1.0 → reconify_python-1.0.0}/src/reconify/py.typed +0 -0
  53. {reconify_python-0.1.0 → reconify_python-1.0.0}/src/reconify/resources/base.py +0 -0
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 0.1.0
2
+ current_version = 1.0.0
3
3
  commit = True
4
4
  tag = True
5
5
  tag_name = v{new_version}
@@ -0,0 +1,18 @@
1
+ "$schema" = "https://conductor.build/schemas/settings.repo.schema.json"
2
+
3
+ [scripts]
4
+ setup = "python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'"
5
+ run_mode = "concurrent"
6
+
7
+ [scripts.run.verify]
8
+ command = ".venv/bin/python scripts/fetch_contract.py && .venv/bin/ruff check . && .venv/bin/mypy src && .venv/bin/pytest -q && .venv/bin/python -m build"
9
+ icon = "check"
10
+ default = true
11
+
12
+ [scripts.run.sync-contract]
13
+ command = ".venv/bin/python scripts/fetch_contract.py --latest && .venv/bin/python -m pytest -q tests/test_openapi_coverage.py"
14
+ icon = "refresh-cw"
15
+
16
+ [scripts.run.release-check]
17
+ command = ".venv/bin/ruff check . && .venv/bin/mypy src && .venv/bin/pytest -q && .venv/bin/python -m build"
18
+ icon = "package-check"
@@ -14,6 +14,7 @@ jobs:
14
14
  python-version: "3.12"
15
15
  - run: python -m pip install --upgrade pip
16
16
  - run: pip install ".[dev]"
17
+ - run: python scripts/fetch_contract.py
17
18
  - run: ruff check .
18
19
  - run: mypy src
19
20
  - run: pytest -q
@@ -0,0 +1,36 @@
1
+ name: Sync public OpenAPI contract
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ schedule:
6
+ - cron: "23 6 * * 1"
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
11
+
12
+ jobs:
13
+ sync:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ - run: python -m pip install --upgrade pip
21
+ - run: pip install ".[dev]"
22
+ - run: python scripts/fetch_contract.py --latest
23
+ - run: python -m pytest -q tests/test_openapi_coverage.py
24
+ - run: ruff check .
25
+ - run: mypy src
26
+ - run: pytest -q
27
+ - run: python -m build
28
+ - uses: peter-evans/create-pull-request@v7
29
+ with:
30
+ branch: automation/openapi-contract-sync
31
+ delete-branch: true
32
+ commit-message: "chore: sync public OpenAPI contract"
33
+ title: "chore: sync public OpenAPI contract"
34
+ body: |
35
+ This automated update was generated from the public Reconify OpenAPI
36
+ manifest. Review generated API models, examples, and migration notes before merging.
@@ -4,6 +4,7 @@ __pycache__/
4
4
  .mypy_cache/
5
5
  .ruff_cache/
6
6
  .venv/
7
+ .contract/
7
8
  dist/
8
9
  build/
9
10
  *.egg-info/
@@ -0,0 +1,4 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "sha256": "04170b7eda8a7bacef6591a7132b9a5cbdb62963af9ca6260e1948c1ee8233c1"
4
+ }
@@ -0,0 +1,29 @@
1
+ # Reconify Python SDK agent guide
2
+
3
+ This repository publishes reconify-python, the typed synchronous and
4
+ asynchronous client for the public Reconify /v1 API.
5
+
6
+ ## Contract authority
7
+
8
+ The SaaS Go API owns the contract. Fetch the pinned public artifact with
9
+ python scripts/fetch_contract.py, or update to the manifest version with
10
+ python scripts/fetch_contract.py --latest.
11
+
12
+ For local SaaS work, set RECONIFY_OPENAPI_SPEC to an explicit OpenAPI JSON
13
+ file. Do not use sibling repositories or absolute workspace paths.
14
+
15
+ The resource and transport layers are handwritten for Python ergonomics.
16
+ tests/test_openapi_coverage.py is the contract boundary and must remain
17
+ spec-driven. Keep Pydantic models aligned with the downloaded schemas.
18
+
19
+ ## Supported surface
20
+
21
+ The SDK exposes metadata, events, ingestion, issues, and organization
22
+ resources. Internal /business/v1 routes and the former ledger, wallet, setup,
23
+ search, alert, and reconciliation surface are not public SDK APIs.
24
+
25
+ ## Verification
26
+
27
+ Run ruff check ., mypy src, pytest -q, and python -m build before releasing.
28
+ Keep credentials out of errors and logs, preserve request IDs, and update
29
+ examples and migration notes when the public contract changes.
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ - Rebuilt the client for the current 13-operation public monitoring API.
6
+ - Added metadata, organization, issue notes, and issue-linked event resources.
7
+ - Removed the obsolete ledger, wallet, setup, search, alert, and reconciliation
8
+ surface.
9
+ - Added pinned public OpenAPI synchronization and contract coverage checks.
10
+
11
+ ## 0.1.0
12
+
13
+ - Initial typed Reconify Python SDK.
14
+ - Added sync and async clients for the retained 50-operation API surface.
15
+ - Excluded deep reconciliation adjustment, evidence, lifecycle, report-item,
16
+ and signoff operations.
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.5
2
+ Name: reconify-python
3
+ Version: 1.0.0
4
+ Summary: Typed Python client for the Reconify Public API
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: httpx<1,>=0.27
9
+ Requires-Dist: pydantic<3,>=2.7
10
+ Provides-Extra: dev
11
+ Requires-Dist: build>=1.2; extra == 'dev'
12
+ Requires-Dist: bump2version>=1.0; extra == 'dev'
13
+ Requires-Dist: mypy>=1.10; extra == 'dev'
14
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
15
+ Requires-Dist: pytest>=8; extra == 'dev'
16
+ Requires-Dist: ruff>=0.5; extra == 'dev'
17
+ Description-Content-Type: text/markdown
18
+
19
+ # Reconify Python SDK
20
+
21
+ Typed synchronous and asynchronous clients for the public Reconify v1 API.
22
+
23
+ ## Installation and quickstart
24
+
25
+ ```sh
26
+ pip install reconify-python
27
+ ```
28
+
29
+ ```python
30
+ from reconify import Reconify
31
+
32
+ with Reconify(api_key="rk_...") as client:
33
+ events = client.events.list_events(limit=25)
34
+ for event in events.events:
35
+ print(event.id, event.status)
36
+ ```
37
+
38
+ The API key may also come from `RECONIFY_API_KEY`. The default endpoint is
39
+ `https://api.reconifyhq.com/v1`. `RECONIFY_API_URL` or `base_url` can select a
40
+ staging or self-hosted endpoint, and URLs with or without `/v1` are accepted.
41
+
42
+ ## Public resources
43
+
44
+ The client exposes metadata, events, ingestion, issues, and organization. The
45
+ current public contract contains exactly 13 operations. Python methods use
46
+ `snake_case` names and typed Pydantic v2 models from `reconify.models`.
47
+
48
+ Sync and async clients provide cursor iterators:
49
+
50
+ ```python
51
+ from reconify import AsyncReconify
52
+
53
+ async with AsyncReconify() as client:
54
+ async for event in client.iter_events(limit=100):
55
+ print(event.id)
56
+ ```
57
+
58
+ Every operation supports `raw=True` for `RawResponse` and per-request timeout
59
+ through the `timeout` keyword. API errors expose status, detail, code,
60
+ validation details, response headers, and request ID without including keys or
61
+ request bodies. Safe methods retry bounded `429`, `503`, and transport failures
62
+ by default; unsafe retries require `RetryConfig(retry_unsafe_methods=True)`.
63
+
64
+ ## Contract synchronization
65
+
66
+ ```sh
67
+ python scripts/fetch_contract.py
68
+ python scripts/fetch_contract.py --latest
69
+ pytest -q tests/test_openapi_coverage.py
70
+ ```
71
+
72
+ The default source is the public manifest at
73
+ <https://docs.reconifyhq.com/openapi/manifest.json>. For local SaaS changes,
74
+ set `RECONIFY_OPENAPI_SPEC` to an explicit OpenAPI JSON file. The SDK never
75
+ depends on another checkout or an absolute workspace path.
76
+
77
+ ## Migration to 1.0.0
78
+
79
+ Version `1.0.0` targets the current monitoring and issue-investigation API. The
80
+ former ledger, wallet, setup, search, alert, and reconciliation methods are
81
+ removed because they are not part of the public contract. See
82
+ [UPGRADING.md](UPGRADING.md).
83
+
84
+ ## Build and release
85
+
86
+ ```sh
87
+ ruff check .
88
+ mypy src
89
+ pytest -q
90
+ python -m build
91
+ ```
92
+
93
+ The release workflow publishes the built wheel to PyPI after a GitHub release.
94
+ Additive contract changes require a minor SDK release; SDK fixes require a
95
+ patch release; breaking public API changes require a new API version and SDK
96
+ major release.
@@ -0,0 +1,78 @@
1
+ # Reconify Python SDK
2
+
3
+ Typed synchronous and asynchronous clients for the public Reconify v1 API.
4
+
5
+ ## Installation and quickstart
6
+
7
+ ```sh
8
+ pip install reconify-python
9
+ ```
10
+
11
+ ```python
12
+ from reconify import Reconify
13
+
14
+ with Reconify(api_key="rk_...") as client:
15
+ events = client.events.list_events(limit=25)
16
+ for event in events.events:
17
+ print(event.id, event.status)
18
+ ```
19
+
20
+ The API key may also come from `RECONIFY_API_KEY`. The default endpoint is
21
+ `https://api.reconifyhq.com/v1`. `RECONIFY_API_URL` or `base_url` can select a
22
+ staging or self-hosted endpoint, and URLs with or without `/v1` are accepted.
23
+
24
+ ## Public resources
25
+
26
+ The client exposes metadata, events, ingestion, issues, and organization. The
27
+ current public contract contains exactly 13 operations. Python methods use
28
+ `snake_case` names and typed Pydantic v2 models from `reconify.models`.
29
+
30
+ Sync and async clients provide cursor iterators:
31
+
32
+ ```python
33
+ from reconify import AsyncReconify
34
+
35
+ async with AsyncReconify() as client:
36
+ async for event in client.iter_events(limit=100):
37
+ print(event.id)
38
+ ```
39
+
40
+ Every operation supports `raw=True` for `RawResponse` and per-request timeout
41
+ through the `timeout` keyword. API errors expose status, detail, code,
42
+ validation details, response headers, and request ID without including keys or
43
+ request bodies. Safe methods retry bounded `429`, `503`, and transport failures
44
+ by default; unsafe retries require `RetryConfig(retry_unsafe_methods=True)`.
45
+
46
+ ## Contract synchronization
47
+
48
+ ```sh
49
+ python scripts/fetch_contract.py
50
+ python scripts/fetch_contract.py --latest
51
+ pytest -q tests/test_openapi_coverage.py
52
+ ```
53
+
54
+ The default source is the public manifest at
55
+ <https://docs.reconifyhq.com/openapi/manifest.json>. For local SaaS changes,
56
+ set `RECONIFY_OPENAPI_SPEC` to an explicit OpenAPI JSON file. The SDK never
57
+ depends on another checkout or an absolute workspace path.
58
+
59
+ ## Migration to 1.0.0
60
+
61
+ Version `1.0.0` targets the current monitoring and issue-investigation API. The
62
+ former ledger, wallet, setup, search, alert, and reconciliation methods are
63
+ removed because they are not part of the public contract. See
64
+ [UPGRADING.md](UPGRADING.md).
65
+
66
+ ## Build and release
67
+
68
+ ```sh
69
+ ruff check .
70
+ mypy src
71
+ pytest -q
72
+ python -m build
73
+ ```
74
+
75
+ The release workflow publishes the built wheel to PyPI after a GitHub release.
76
+ Additive contract changes require a minor SDK release; SDK fixes require a
77
+ patch release; breaking public API changes require a new API version and SDK
78
+ major release.
@@ -0,0 +1,17 @@
1
+ # Upgrading to 1.0.0
2
+
3
+ The 1.0.0 client is rebuilt against the current public Reconify v1 contract.
4
+ It removes methods that described private or retired ledger, wallet, setup,
5
+ search, alert, and reconciliation routes.
6
+
7
+ Use these resources:
8
+
9
+ - metadata: API information and health
10
+ - events: event listing, lookup, and issue-linked evidence
11
+ - ingestion: monitoring event batches
12
+ - issues: issue listing, lookup, assignment, notes, and linked data
13
+ - organization: organization and member reads
14
+
15
+ Python models use snake_case fields and preserve unknown enum values through
16
+ tolerant string enums. Regenerate or refresh the models after downloading a
17
+ new public contract version.
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://context7.com/schema/context7.json",
3
+ "projectTitle": "Reconify Python SDK",
4
+ "description": "Typed synchronous and asynchronous Python clients for the Reconify Public API.",
5
+ "folders": ["src"],
6
+ "excludeFolders": ["tests", "reports"],
7
+ "rules": [
8
+ "Use Reconify for synchronous code and AsyncReconify for asynchronous code.",
9
+ "Provide the API key with api_key or RECONIFY_API_KEY; configure staging or self-hosted deployments with base_url.",
10
+ "Treat pagination cursors as opaque. When an endpoint accepts both cursor and offset pagination, after takes precedence.",
11
+ "Safe methods retry 429, 503, and transient transport failures by default. Mutating methods require RetryConfig(retry_unsafe_methods=True) to opt into retries.",
12
+ "Reuse each row's idempotencyKey when retrying transaction ingestion.",
13
+ "Use raw=True when callers need status, headers, request IDs, and raw response bodies; use the per-request timeout override when needed."
14
+ ]
15
+ }
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "reconify-python"
7
- version = "0.1.0"
7
+ version = "1.0.0"
8
8
  description = "Typed Python client for the Reconify Public API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,65 @@
1
+ """Fetch and verify the pinned public OpenAPI contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+ from urllib.parse import urljoin
11
+ from urllib.request import urlopen
12
+
13
+ ROOT = Path(__file__).resolve().parents[1]
14
+ PIN_PATH = ROOT / ".openapi-contract.json"
15
+ DEFAULT_OUTPUT = ROOT / ".contract" / "reconify.openapi.json"
16
+ DEFAULT_MANIFEST_URL = "https://docs.reconifyhq.com/openapi/manifest.json"
17
+
18
+
19
+ def main() -> None:
20
+ output = Path(os.environ.get("RECONIFY_OPENAPI_SPEC", str(DEFAULT_OUTPUT)))
21
+ update_to_latest = "--latest" in sys.argv
22
+ if os.environ.get("RECONIFY_OPENAPI_SPEC"):
23
+ content = output.read_bytes()
24
+ if update_to_latest:
25
+ document = json.loads(content)
26
+ version = document.get("info", {}).get("version")
27
+ if not version:
28
+ raise SystemExit("Local OpenAPI contract has no info.version")
29
+ PIN_PATH.write_text(
30
+ json.dumps(
31
+ {
32
+ "version": version,
33
+ "sha256": hashlib.sha256(content).hexdigest(),
34
+ },
35
+ indent=2,
36
+ )
37
+ + "\n"
38
+ )
39
+ print(f"Using local OpenAPI contract: {output}")
40
+ return
41
+
42
+ pinned = json.loads(PIN_PATH.read_text())
43
+ manifest_url = os.environ.get("RECONIFY_OPENAPI_MANIFEST_URL", DEFAULT_MANIFEST_URL)
44
+ with urlopen(manifest_url, timeout=30) as response:
45
+ manifest = json.loads(response.read())
46
+ version = manifest["contract_version"] if update_to_latest else pinned["version"]
47
+ artifact = manifest["versions"].get(version)
48
+ if artifact is None:
49
+ raise SystemExit(f"OpenAPI manifest has no version {version}")
50
+ if not update_to_latest and artifact["sha256"] != pinned["sha256"]:
51
+ raise SystemExit(f"OpenAPI manifest checksum changed for pinned version {version}")
52
+ with urlopen(urljoin(manifest_url, artifact["url"]), timeout=30) as response:
53
+ content = response.read()
54
+ digest = hashlib.sha256(content).hexdigest()
55
+ if update_to_latest:
56
+ PIN_PATH.write_text(json.dumps({"version": version, "sha256": digest}, indent=2) + "\n")
57
+ elif digest != pinned["sha256"]:
58
+ raise SystemExit(f"OpenAPI checksum mismatch: expected {pinned['sha256']}, got {digest}")
59
+ output.parent.mkdir(parents=True, exist_ok=True)
60
+ output.write_bytes(content)
61
+ print(f"Fetched OpenAPI {version} to {output}")
62
+
63
+
64
+ if __name__ == "__main__":
65
+ main()
@@ -1,6 +1,6 @@
1
1
  """Typed clients for the Reconify Public API."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "1.0.0"
4
4
 
5
5
  from .client import AsyncReconify, Reconify
6
6
  from .errors import (
@@ -0,0 +1,157 @@
1
+ """Top-level synchronous and asynchronous Reconify clients."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from collections.abc import AsyncIterator, Iterator
7
+ from typing import Any
8
+
9
+ import httpx
10
+
11
+ from .errors import ReconifyValidationError
12
+ from .pagination import aiter_cursor_pages, iter_cursor_pages
13
+ from .resources import (
14
+ ASYNC_RESOURCE_CLASSES,
15
+ SYNC_RESOURCE_CLASSES,
16
+ AsyncEvents,
17
+ AsyncIngestion,
18
+ AsyncIssues,
19
+ AsyncMetadata,
20
+ AsyncOrganization,
21
+ Events,
22
+ Ingestion,
23
+ Issues,
24
+ Metadata,
25
+ Organization,
26
+ )
27
+ from .transport import AsyncTransport, RetryConfig, SyncTransport
28
+
29
+ DEFAULT_BASE_URL = "https://api.reconifyhq.com/v1"
30
+
31
+
32
+ def _normalize_base_url(base_url: str | None) -> str:
33
+ value = (base_url or os.getenv("RECONIFY_API_URL") or DEFAULT_BASE_URL).rstrip("/")
34
+ return value if value.endswith("/v1") else f"{value}/v1"
35
+
36
+
37
+ def _api_key(api_key: str | None) -> str:
38
+ value = api_key or os.getenv("RECONIFY_API_KEY")
39
+ if not value:
40
+ raise ReconifyValidationError("An API key is required; set api_key or RECONIFY_API_KEY")
41
+ if not value.startswith("rk_"):
42
+ raise ReconifyValidationError("Reconify public API keys must start with rk_")
43
+ return value
44
+
45
+
46
+ class Reconify:
47
+ """Synchronous typed Reconify API client."""
48
+
49
+ metadata: Metadata
50
+ events: Events
51
+ ingestion: Ingestion
52
+ issues: Issues
53
+ organization: Organization
54
+
55
+ def __init__(
56
+ self,
57
+ api_key: str | None = None,
58
+ *,
59
+ base_url: str | None = None,
60
+ timeout: float | httpx.Timeout = 30.0,
61
+ request_id: str | None = None,
62
+ retry: RetryConfig | None = None,
63
+ http_client: httpx.Client | None = None,
64
+ ) -> None:
65
+ self._transport = SyncTransport(
66
+ base_url=_normalize_base_url(base_url),
67
+ api_key=_api_key(api_key),
68
+ timeout=timeout,
69
+ request_id=request_id,
70
+ retry=retry,
71
+ client=http_client,
72
+ )
73
+ for name, resource_class in SYNC_RESOURCE_CLASSES.items():
74
+ setattr(self, name, resource_class(self._transport))
75
+
76
+ def close(self) -> None:
77
+ self._transport.close()
78
+
79
+ def __enter__(self) -> Reconify:
80
+ return self
81
+
82
+ def __exit__(self, *_: Any) -> None:
83
+ self.close()
84
+
85
+ def iter_events(self, **query: Any) -> Iterator[Any]:
86
+ return iter_cursor_pages(
87
+ lambda params: self.events.list_events(**params), item_field="events", query=query
88
+ )
89
+
90
+ def iter_issues(self, **query: Any) -> Iterator[Any]:
91
+ return iter_cursor_pages(
92
+ lambda params: self.issues.list_issues(**params), item_field="issues", query=query
93
+ )
94
+
95
+ def iter_issue_events(self, issue_id: str, **query: Any) -> Iterator[Any]:
96
+ return iter_cursor_pages(
97
+ lambda params: self.events.list_issue_events(issue_id, **params),
98
+ item_field="events",
99
+ query=query,
100
+ )
101
+
102
+
103
+ class AsyncReconify:
104
+ """Asynchronous typed Reconify API client."""
105
+
106
+ metadata: AsyncMetadata
107
+ events: AsyncEvents
108
+ ingestion: AsyncIngestion
109
+ issues: AsyncIssues
110
+ organization: AsyncOrganization
111
+
112
+ def __init__(
113
+ self,
114
+ api_key: str | None = None,
115
+ *,
116
+ base_url: str | None = None,
117
+ timeout: float | httpx.Timeout = 30.0,
118
+ request_id: str | None = None,
119
+ retry: RetryConfig | None = None,
120
+ http_client: httpx.AsyncClient | None = None,
121
+ ) -> None:
122
+ self._transport = AsyncTransport(
123
+ base_url=_normalize_base_url(base_url),
124
+ api_key=_api_key(api_key),
125
+ timeout=timeout,
126
+ request_id=request_id,
127
+ retry=retry,
128
+ client=http_client,
129
+ )
130
+ for name, resource_class in ASYNC_RESOURCE_CLASSES.items():
131
+ setattr(self, name, resource_class(self._transport))
132
+
133
+ async def aclose(self) -> None:
134
+ await self._transport.aclose()
135
+
136
+ async def __aenter__(self) -> AsyncReconify:
137
+ return self
138
+
139
+ async def __aexit__(self, *_: Any) -> None:
140
+ await self.aclose()
141
+
142
+ def iter_events(self, **query: Any) -> AsyncIterator[Any]:
143
+ return aiter_cursor_pages(
144
+ lambda params: self.events.list_events(**params), item_field="events", query=query
145
+ )
146
+
147
+ def iter_issues(self, **query: Any) -> AsyncIterator[Any]:
148
+ return aiter_cursor_pages(
149
+ lambda params: self.issues.list_issues(**params), item_field="issues", query=query
150
+ )
151
+
152
+ def iter_issue_events(self, issue_id: str, **query: Any) -> AsyncIterator[Any]:
153
+ return aiter_cursor_pages(
154
+ lambda params: self.events.list_issue_events(issue_id, **params),
155
+ item_field="events",
156
+ query=query,
157
+ )