noxhere 0.1.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.
- noxhere/__init__.py +3 -0
- noxhere/_operations.py +4 -0
- noxhere/client.py +175 -0
- noxhere/feedback.py +7 -0
- noxhere/incidents.py +7 -0
- noxhere/py.typed +1 -0
- noxhere-0.1.0.dist-info/METADATA +32 -0
- noxhere-0.1.0.dist-info/RECORD +9 -0
- noxhere-0.1.0.dist-info/WHEEL +4 -0
noxhere/__init__.py
ADDED
noxhere/_operations.py
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Generated from public/openapi.json. Do not edit by hand.
|
|
2
|
+
from typing import Final
|
|
3
|
+
|
|
4
|
+
OPERATIONS: Final = [('acknowledgeRepositories', 'POST', '/api/v1/repos/acknowledge', 'workspace'), ('archiveProject', 'POST', '/api/v1/projects/{projectId}/archive', 'workspace'), ('archiveSpec', 'POST', '/api/v1/specs/{specId}/archive', 'planning'), ('assignIssue', 'POST', '/api/v1/assign', 'planning'), ('assignSlackConnectionProject', 'PATCH', '/api/v1/slack/connections/{connectionId}', 'workspace'), ('backfillProjectPullRequests', 'POST', '/api/v1/projects/{projectId}/backfill-prs', 'workspace'), ('closeFeature', 'DELETE', '/api/v1/features/{number}', 'planning'), ('closePullRequest', 'POST', '/api/v1/prs/close', 'activity'), ('createApiToken', 'POST', '/api/v1/api-tokens', 'workspace'), ('createFeature', 'POST', '/api/v1/features', 'planning'), ('createGuestInvitation', 'POST', '/api/v1/guests/invites', 'workspace'), ('createNoxCueCustomFeature', 'POST', '/api/v1/cues/sources/{sourceId}/features', 'incidents'), ('createNoxCueCustomMetric', 'POST', '/api/v1/cues/sources/{sourceId}/custom-metrics', 'incidents'), ('createNoxCueKey', 'POST', '/api/v1/cues/sources/{sourceId}/keys', 'incidents'), ('createNoxCueSource', 'POST', '/api/v1/cues/sources', 'incidents'), ('createNoxSpotSite', 'POST', '/api/v1/spots/sites', 'feedback'), ('createProject', 'POST', '/api/v1/projects', 'workspace'), ('createSpec', 'POST', '/api/v1/specs', 'planning'), ('deleteFeatureAttachment', 'DELETE', '/api/v1/features/{number}/attachments/{attachmentId}', 'planning'), ('deleteNoxCueCustomFeature', 'DELETE', '/api/v1/cues/sources/{sourceId}/features/{featureKey}', 'incidents'), ('deleteNoxCueCustomMetric', 'DELETE', '/api/v1/cues/sources/{sourceId}/custom-metrics/{metricKey}', 'incidents'), ('deleteNoxCueSource', 'DELETE', '/api/v1/cues/sources/{sourceId}', 'incidents'), ('deleteNoxSpotSite', 'DELETE', '/api/v1/spots/sites/{siteId}', 'feedback'), ('deleteSpecAttachment', 'DELETE', '/api/v1/specs/{specId}/attachments/{attachmentId}', 'planning'), ('disconnectConnection', 'POST', '/api/v1/integrations/connections/{provider}/disconnect', 'workspace'), ('disconnectSlackWorkspace', 'POST', '/api/v1/slack/disconnect', 'workspace'), ('downloadFeatureAttachment', 'GET', '/api/v1/features/{number}/attachments/{attachmentId}', 'planning'), ('downloadSpecAttachment', 'GET', '/api/v1/specs/{specId}/attachments/{attachmentId}', 'planning'), ('exchangeLegacyNativeCredential', 'POST', '/api/v1/auth/native/exchange', 'workspace'), ('getActor', 'GET', '/api/v1/actors/{actorId}', 'workspace'), ('getAiSettings', 'GET', '/api/v1/llm-settings', 'activity'), ('getBootstrapStatus', 'GET', '/api/v1/bootstrap-status', 'workspace'), ('getCueProjectActions', 'GET', '/api/v1/projects/{projectId}/cue/actions', 'incidents'), ('getCueProjectAlertRules', 'GET', '/api/v1/projects/{projectId}/cue/alert-rules', 'incidents'), ('getCueProjectAlerts', 'GET', '/api/v1/projects/{projectId}/cue/alerts', 'incidents'), ('getCueProjectDashboard', 'GET', '/api/v1/projects/{projectId}/cue/dashboard', 'incidents'), ('getCueProjectStatEvents', 'GET', '/api/v1/projects/{projectId}/cue/stat-events', 'incidents'), ('getCurrentMember', 'GET', '/api/v1/me', 'workspace'), ('getCurrentWorkSummary', 'GET', '/api/v1/feed/current-summary', 'activity'), ('getEngineerActivity', 'GET', '/api/v1/engineer-activity', 'activity'), ('getEngineerStats', 'GET', '/api/v1/engineer-stats', 'activity'), ('getFeedEvent', 'GET', '/api/v1/events/{id}', 'activity'), ('getGitHubComments', 'GET', '/api/v1/github/comments', 'activity'), ('getGitHubDetails', 'GET', '/api/v1/github/details', 'activity'), ('getGitHubRateLimit', 'GET', '/api/v1/github/rate-limit', 'workspace'), ('getIdentityProfile', 'GET', '/api/v1/auth/profile', 'workspace'), ('getIntegrationStatus', 'GET', '/api/v1/integrations/status', 'workspace'), ('getIssue', 'GET', '/api/v1/issues/{repo}/{number}', 'activity'), ('getNoxCueDailyHealth', 'GET', '/api/v1/cues/metrics', 'incidents'), ('getNoxCueGitHubIssueSettings', 'GET', '/api/v1/cues/github-issues', 'incidents'), ('getNoxCueProjectMetrics', 'GET', '/api/v1/cues/projects/{projectId}/metrics', 'incidents'), ('getNoxCueProjectOverview', 'GET', '/api/v1/cues/project-overview', 'incidents'), ('getNoxFeed', 'GET', '/api/v1/feed', 'activity'), ('getNoxFeedDefaultPrompt', 'GET', '/api/v1/noxfeed/release-notes-prompt', 'activity'), ('getNoxService', 'GET', '/api/v1/services/{service}', 'workspace'), ('getNoxServiceConfig', 'GET', '/api/v1/services/{service}/config', 'workspace'), ('getNoxServiceHealth', 'GET', '/api/v1/services/{service}/health', 'workspace'), ('getNoxServiceSetup', 'GET', '/api/v1/services/{service}/setup', 'workspace'), ('getNoxSpotProjectOverview', 'GET', '/api/v1/spots/project-overview', 'feedback'), ('getNoxSpotResolutionTemplate', 'GET', '/api/v1/spots/sites/{siteId}/resolution-template', 'feedback'), ('getOperatorUsage', 'GET', '/api/v1/operator/usage', 'workspace'), ('getProjectActivity', 'GET', '/api/v1/projects/{projectId}/activity', 'workspace'), ('getProjectFeedback', 'GET', '/api/v1/projects/{projectId}/feedback', 'workspace'), ('getProjectIncident', 'GET', '/api/v1/projects/{projectId}/incidents/{incidentId}', 'workspace'), ('getProjectIncidents', 'GET', '/api/v1/projects/{projectId}/incidents', 'workspace'), ('getProjectIssues', 'GET', '/api/v1/projects/{projectId}/issues', 'workspace'), ('getProjectRouting', 'GET', '/api/v1/projects/routing', 'workspace'), ('getPublicNoxSpotConfig', 'GET', '/api/spots/public/v1/sites/{siteId}/config', 'feedback'), ('getPullRequest', 'GET', '/api/v1/prs/{repo}/{number}', 'activity'), ('getSetupPlan', 'GET', '/api/v1/integrations/setup', 'workspace'), ('getSlackRouting', 'GET', '/api/v1/integrations/slack/routing', 'workspace'), ('getSlackStatus', 'GET', '/api/v1/slack/status', 'workspace'), ('getSpec', 'GET', '/api/v1/specs/{specId}', 'planning'), ('getSyncStatus', 'GET', '/api/v1/sync', 'workspace'), ('getWorkspaceConfig', 'GET', '/api/v1/config/{key}', 'workspace'), ('ingestNoxCueEvent', 'POST', '/api/v1/cues/public/events', 'incidents'), ('listActors', 'GET', '/api/v1/actors', 'workspace'), ('listApiTokens', 'GET', '/api/v1/api-tokens', 'workspace'), ('listConnections', 'GET', '/api/v1/integrations/connections', 'workspace'), ('listFeatureAttachments', 'GET', '/api/v1/features/{number}/attachments', 'planning'), ('listFeatures', 'GET', '/api/v1/features', 'planning'), ('listFeedEvents', 'GET', '/api/v1/events', 'activity'), ('listGitHubTeams', 'GET', '/api/v1/teams', 'workspace'), ('listGuestAccess', 'GET', '/api/v1/guests', 'workspace'), ('listIssues', 'GET', '/api/v1/issues', 'activity'), ('listMembers', 'GET', '/api/v1/members', 'workspace'), ('listNoxCueCustomMetrics', 'GET', '/api/v1/cues/sources/{sourceId}/custom-metrics', 'incidents'), ('listNoxCueEvents', 'GET', '/api/v1/cues/events', 'incidents'), ('listNoxCueFeatures', 'GET', '/api/v1/cues/sources/{sourceId}/features', 'incidents'), ('listNoxCueSources', 'GET', '/api/v1/cues/sources', 'incidents'), ('listNoxServices', 'GET', '/api/v1/services', 'workspace'), ('listNoxSpotSites', 'GET', '/api/v1/spots/sites', 'feedback'), ('listOperationFailures', 'GET', '/api/v1/op-failures', 'workspace'), ('listProjects', 'GET', '/api/v1/projects', 'workspace'), ('listPullRequests', 'GET', '/api/v1/prs', 'activity'), ('listRepositories', 'GET', '/api/v1/repos', 'workspace'), ('listSlackChannels', 'GET', '/api/v1/slack/channels', 'workspace'), ('listSpecAttachments', 'GET', '/api/v1/specs/{specId}/attachments', 'planning'), ('listSpecs', 'GET', '/api/v1/specs', 'planning'), ('patchNoxServiceConfig', 'PATCH', '/api/v1/services/{service}/config', 'workspace'), ('patchSlackRouting', 'PATCH', '/api/v1/integrations/slack/routing', 'workspace'), ('pollNativeDeviceAuthorization', 'POST', '/api/v1/auth/native/device/poll', 'workspace'), ('previewNoxSpotResolutionTemplate', 'POST', '/api/v1/spots/sites/{siteId}/resolution-template/preview', 'feedback'), ('putAiSettings', 'PUT', '/api/v1/llm-settings', 'activity'), ('putNoxCueGitHubIssueSettings', 'PUT', '/api/v1/cues/github-issues', 'incidents'), ('putWorkspaceConfig', 'PUT', '/api/v1/config/{key}', 'workspace'), ('recordAppActivity', 'POST', '/api/v1/app-activity', 'workspace'), ('recoverRepositoryHistory', 'POST', '/api/v1/recover-repo-history', 'workspace'), ('refreshNativeSession', 'POST', '/api/v1/auth/native/refresh', 'workspace'), ('reopenResolvedNoxSpotReport', 'POST', '/api/spots/public/v1/resolution-responses/{token}', 'feedback'), ('restoreProject', 'DELETE', '/api/v1/projects/{projectId}/archive', 'workspace'), ('restoreSpec', 'DELETE', '/api/v1/specs/{specId}/archive', 'planning'), ('retrieveProject', 'GET', '/api/v1/projects/{projectId}/retrieval', 'workspace'), ('retryNoxSpotDeliveries', 'POST', '/api/v1/spots/sites/{siteId}/retry-deliveries', 'feedback'), ('revokeApiToken', 'DELETE', '/api/v1/api-tokens/{id}', 'workspace'), ('revokeBrowserSession', 'POST', '/api/v1/auth/logout', 'workspace'), ('revokeGuestGrant', 'DELETE', '/api/v1/guests/grants/{grantId}', 'workspace'), ('revokeGuestInvitation', 'DELETE', '/api/v1/guests/invites/{inviteId}', 'workspace'), ('revokeNativeSession', 'POST', '/api/v1/auth/native/revoke', 'workspace'), ('revokeNoxCueKey', 'DELETE', '/api/v1/cues/sources/{sourceId}/keys/{keyId}', 'incidents'), ('rotateApiToken', 'POST', '/api/v1/api-tokens/{id}/rotate', 'workspace'), ('searchWorkspace', 'GET', '/api/v1/search', 'activity'), ('setIssueState', 'POST', '/api/v1/issue-state', 'planning'), ('startConnection', 'POST', '/api/v1/integrations/connections/{provider}/start', 'workspace'), ('startNativeDeviceAuthorization', 'POST', '/api/v1/auth/native/device/start', 'workspace'), ('submitPublicNoxSpotErrors', 'POST', '/api/spots/public/v1/errors', 'feedback'), ('submitPublicNoxSpotReport', 'POST', '/api/spots/public/v1/reports', 'feedback'), ('syncGitHubData', 'POST', '/api/v1/sync', 'workspace'), ('syncGitHubEvents', 'POST', '/api/v1/sync-events', 'workspace'), ('testNoxCueSource', 'POST', '/api/v1/cues/sources/{sourceId}/health/test', 'incidents'), ('testNoxSpotResolutionTemplate', 'POST', '/api/v1/spots/sites/{siteId}/resolution-template/test', 'feedback'), ('testSlackDestination', 'POST', '/api/v1/slack/test', 'workspace'), ('testSlackRoute', 'POST', '/api/v1/integrations/slack/test', 'workspace'), ('updateActor', 'PATCH', '/api/v1/actors/{actorId}', 'workspace'), ('updateCueProjectActions', 'PUT', '/api/v1/projects/{projectId}/cue/actions', 'incidents'), ('updateFeature', 'PATCH', '/api/v1/features/{number}', 'planning'), ('updateNoxCueCustomFeature', 'PUT', '/api/v1/cues/sources/{sourceId}/features/{featureKey}', 'incidents'), ('updateNoxCueCustomMetric', 'PUT', '/api/v1/cues/sources/{sourceId}/custom-metrics/{metricKey}', 'incidents'), ('updateNoxCueErrorStatus', 'PUT', '/api/v1/cues/errors/{sourceId}/{fingerprint}', 'incidents'), ('updateNoxCueProjectMetrics', 'PUT', '/api/v1/cues/projects/{projectId}/metrics', 'incidents'), ('updateNoxCueSource', 'PUT', '/api/v1/cues/sources/{sourceId}', 'incidents'), ('updateNoxSpotReport', 'PATCH', '/api/v1/spots/reports/{reportId}', 'feedback'), ('updateNoxSpotResolutionTemplate', 'PATCH', '/api/v1/spots/sites/{siteId}/resolution-template', 'feedback'), ('updateNoxSpotSite', 'PATCH', '/api/v1/spots/sites/{siteId}', 'feedback'), ('updateProjectIncident', 'PATCH', '/api/v1/projects/{projectId}/incidents/{incidentId}', 'workspace'), ('updateProjectRouting', 'PUT', '/api/v1/projects/{projectId}/routing', 'workspace'), ('updateSpec', 'PATCH', '/api/v1/specs/{specId}', 'planning'), ('uploadFeatureAttachment', 'POST', '/api/v1/features/{number}/attachments', 'planning'), ('uploadSpecAttachment', 'POST', '/api/v1/specs/{specId}/attachments', 'planning')]
|
noxhere/client.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import re
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any, Callable, Mapping, Protocol, Sequence
|
|
7
|
+
from urllib.error import HTTPError
|
|
8
|
+
from urllib.parse import quote, urlencode, urljoin
|
|
9
|
+
from urllib.request import Request, urlopen
|
|
10
|
+
|
|
11
|
+
from ._operations import OPERATIONS
|
|
12
|
+
|
|
13
|
+
JsonValue = None | bool | int | float | str | list["JsonValue"] | dict[str, "JsonValue"]
|
|
14
|
+
TransportResult = tuple[int, Mapping[str, str], bytes]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Transport(Protocol):
|
|
18
|
+
def __call__(self, method: str, url: str, headers: Mapping[str, str], body: bytes | None) -> TransportResult: ...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class NoxHereApiError(RuntimeError):
|
|
22
|
+
def __init__(self, status: int, operation_id: str, details: Any) -> None:
|
|
23
|
+
super().__init__(f"NoxHere {operation_id} failed with HTTP {status}")
|
|
24
|
+
self.status = status
|
|
25
|
+
self.operation_id = operation_id
|
|
26
|
+
self.details = details
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class Operation:
|
|
31
|
+
operation_id: str
|
|
32
|
+
method: str
|
|
33
|
+
path: str
|
|
34
|
+
namespace: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _snake(value: str) -> str:
|
|
38
|
+
return re.sub(r"(?<!^)(?=[A-Z])", "_", value).lower()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _default_transport(method: str, url: str, headers: Mapping[str, str], body: bytes | None) -> TransportResult:
|
|
42
|
+
request = Request(url, data=body, headers=dict(headers), method=method)
|
|
43
|
+
try:
|
|
44
|
+
with urlopen(request, timeout=30) as response: # noqa: S310 - URL is bound to configured NoxHere origin
|
|
45
|
+
return response.status, dict(response.headers.items()), response.read()
|
|
46
|
+
except HTTPError as error:
|
|
47
|
+
return error.code, dict(error.headers.items()), error.read()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _payload(headers: Mapping[str, str], body: bytes) -> Any:
|
|
51
|
+
if not body:
|
|
52
|
+
return None
|
|
53
|
+
content_type = next((value for key, value in headers.items() if key.lower() == "content-type"), "")
|
|
54
|
+
if "json" in content_type.lower():
|
|
55
|
+
return json.loads(body)
|
|
56
|
+
if content_type.lower().startswith("text/"):
|
|
57
|
+
return body.decode()
|
|
58
|
+
return body
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ResourceClient:
|
|
62
|
+
def __init__(self, client: "NoxHereClient", operations: Sequence[Operation]) -> None:
|
|
63
|
+
self._client = client
|
|
64
|
+
self._operations = {_snake(operation.operation_id): operation.operation_id for operation in operations}
|
|
65
|
+
self._operations.update({operation.operation_id: operation.operation_id for operation in operations})
|
|
66
|
+
|
|
67
|
+
def __getattr__(self, name: str) -> Callable[..., Any]:
|
|
68
|
+
operation_id = self._operations.get(name)
|
|
69
|
+
if operation_id is None:
|
|
70
|
+
raise AttributeError(name)
|
|
71
|
+
|
|
72
|
+
def invoke(**kwargs: Any) -> Any:
|
|
73
|
+
return self._client.request(operation_id, **kwargs)
|
|
74
|
+
|
|
75
|
+
return invoke
|
|
76
|
+
|
|
77
|
+
def operation_ids(self) -> tuple[str, ...]:
|
|
78
|
+
return tuple(sorted(set(self._operations.values())))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class NoxHereClient:
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
*,
|
|
85
|
+
base_url: str = "https://app.noxhere.com",
|
|
86
|
+
token: str | None = None,
|
|
87
|
+
organization: str | None = None,
|
|
88
|
+
project_id: str | None = None,
|
|
89
|
+
csrf_token: str | None = None,
|
|
90
|
+
headers: Mapping[str, str] | None = None,
|
|
91
|
+
transport: Transport = _default_transport,
|
|
92
|
+
) -> None:
|
|
93
|
+
self.base_url = base_url.rstrip("/") + "/"
|
|
94
|
+
self._transport = transport
|
|
95
|
+
self._headers = dict(headers or {})
|
|
96
|
+
if token:
|
|
97
|
+
self._headers["Authorization"] = f"Bearer {token}"
|
|
98
|
+
if organization:
|
|
99
|
+
self._headers["X-Org"] = organization
|
|
100
|
+
if project_id:
|
|
101
|
+
self._headers["X-Project-ID"] = project_id
|
|
102
|
+
if csrf_token:
|
|
103
|
+
self._headers["X-CSRF-Token"] = csrf_token
|
|
104
|
+
self._operations = {
|
|
105
|
+
item[0]: Operation(operation_id=item[0], method=item[1], path=item[2], namespace=item[3])
|
|
106
|
+
for item in OPERATIONS
|
|
107
|
+
}
|
|
108
|
+
resources = {
|
|
109
|
+
namespace: ResourceClient(self, [operation for operation in self._operations.values() if operation.namespace == namespace])
|
|
110
|
+
for namespace in ("workspace", "activity", "planning", "feedback", "incidents")
|
|
111
|
+
}
|
|
112
|
+
self.workspace = resources["workspace"]
|
|
113
|
+
self.activity = resources["activity"]
|
|
114
|
+
self.planning = resources["planning"]
|
|
115
|
+
self.feedback = resources["feedback"]
|
|
116
|
+
self.incidents = resources["incidents"]
|
|
117
|
+
self.connect = self.workspace
|
|
118
|
+
self.feed = self.activity
|
|
119
|
+
self.ticket = self.planning
|
|
120
|
+
self.spot = self.feedback
|
|
121
|
+
self.cue = self.incidents
|
|
122
|
+
|
|
123
|
+
def request(
|
|
124
|
+
self,
|
|
125
|
+
operation_id: str,
|
|
126
|
+
*,
|
|
127
|
+
path: Mapping[str, str | int] | None = None,
|
|
128
|
+
query: Mapping[str, str | int | float | bool | Sequence[str | int | float | bool] | None] | None = None,
|
|
129
|
+
body: JsonValue | str | bytes | None = None,
|
|
130
|
+
headers: Mapping[str, str] | None = None,
|
|
131
|
+
) -> Any:
|
|
132
|
+
operation = self._operations.get(operation_id)
|
|
133
|
+
if operation is None:
|
|
134
|
+
raise ValueError(f"Unknown NoxHere operation: {operation_id}")
|
|
135
|
+
values = dict(path or {})
|
|
136
|
+
|
|
137
|
+
def replace(match: re.Match[str]) -> str:
|
|
138
|
+
key = match.group(1)
|
|
139
|
+
if key not in values or values[key] == "":
|
|
140
|
+
raise ValueError(f"Missing path parameter: {key}")
|
|
141
|
+
return quote(str(values[key]), safe="")
|
|
142
|
+
|
|
143
|
+
operation_path = re.sub(r"\{([^}]+)\}", replace, operation.path)
|
|
144
|
+
pairs: list[tuple[str, str]] = []
|
|
145
|
+
for key, value in (query or {}).items():
|
|
146
|
+
if value is None:
|
|
147
|
+
continue
|
|
148
|
+
items = value if isinstance(value, (list, tuple)) else [value]
|
|
149
|
+
pairs.extend((key, str(item).lower() if isinstance(item, bool) else str(item)) for item in items)
|
|
150
|
+
url = urljoin(self.base_url, operation_path)
|
|
151
|
+
if pairs:
|
|
152
|
+
url += "?" + urlencode(pairs)
|
|
153
|
+
request_headers = {**self._headers, **dict(headers or {})}
|
|
154
|
+
encoded: bytes | None
|
|
155
|
+
if body is None:
|
|
156
|
+
encoded = None
|
|
157
|
+
elif isinstance(body, bytes):
|
|
158
|
+
encoded = body
|
|
159
|
+
elif isinstance(body, str):
|
|
160
|
+
encoded = body.encode()
|
|
161
|
+
else:
|
|
162
|
+
request_headers["Content-Type"] = "application/json"
|
|
163
|
+
encoded = json.dumps(body, separators=(",", ":")).encode()
|
|
164
|
+
status, response_headers, response_body = self._transport(operation.method, url, request_headers, encoded)
|
|
165
|
+
result = _payload(response_headers, response_body)
|
|
166
|
+
if not 200 <= status < 300:
|
|
167
|
+
raise NoxHereApiError(status, operation_id, result)
|
|
168
|
+
return result
|
|
169
|
+
|
|
170
|
+
def operation_ids(self) -> tuple[str, ...]:
|
|
171
|
+
return tuple(sorted(self._operations))
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def create_noxhere(**options: Any) -> NoxHereClient:
|
|
175
|
+
return NoxHereClient(**options)
|
noxhere/feedback.py
ADDED
noxhere/incidents.py
ADDED
noxhere/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: noxhere
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unified Python SDK for every NoxHere resource
|
|
5
|
+
Project-URL: Homepage, https://app.noxhere.com
|
|
6
|
+
Project-URL: Repository, https://github.com/No-Box-Dev/NoxHere
|
|
7
|
+
Author: No Box Dev
|
|
8
|
+
License: PolyForm-Noncommercial-1.0.0
|
|
9
|
+
Keywords: activity,feedback,incidents,noxhere,planning
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# `noxhere`
|
|
17
|
+
|
|
18
|
+
The unified Python client for every NoxHere resource. Its 149-operation
|
|
19
|
+
catalog is generated from the same OpenAPI contract as `@noxhere/sdk`.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from noxhere import NoxHereClient
|
|
23
|
+
|
|
24
|
+
nox = NoxHereClient(token="nox_sk_...")
|
|
25
|
+
projects = nox.workspace.list_projects()
|
|
26
|
+
incidents = nox.incidents.get_project_incidents(path={"projectId": "project-1"})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Namespaces are `workspace`, `activity`, `planning`, `feedback`, and
|
|
30
|
+
`incidents`; `connect`, `feed`, `ticket`, `spot`, and `cue` are compatibility
|
|
31
|
+
aliases. Use `noxhere.incidents.create_incident_client` or
|
|
32
|
+
`noxhere.feedback.create_feedback_client` for focused clients.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
noxhere/__init__.py,sha256=n9Ox-W-HM2nwTgyHhwAi1fheVkyBVCU69lFoqANwHtE,167
|
|
2
|
+
noxhere/_operations.py,sha256=vNcuczoP7drTjpKD8_YJWcaeCjitWrTJZk_os26h93M,11794
|
|
3
|
+
noxhere/client.py,sha256=fI9Ox2NUyO5LpMH11QrSOTfp7qf1q_Rqeg6574sZuzc,6688
|
|
4
|
+
noxhere/feedback.py,sha256=h-fjGn9yMat4meiCUsb4SuVhpi7fZeyvGLoRX-0fvq8,183
|
|
5
|
+
noxhere/incidents.py,sha256=6pIr16M0Hw8adjl01KiLrsh3u5MAvgck5RnAC1ML6_o,184
|
|
6
|
+
noxhere/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
7
|
+
noxhere-0.1.0.dist-info/METADATA,sha256=zKiqrFiJjaY5-p076t8gr_22IyWiemXmllUgkLJfLCQ,1162
|
|
8
|
+
noxhere-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
9
|
+
noxhere-0.1.0.dist-info/RECORD,,
|