UncountablePythonSDK 0.0.121__py3-none-any.whl → 0.0.122__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.
Potentially problematic release.
This version of UncountablePythonSDK might be problematic. Click here for more details.
- docs/conf.py +32 -4
- docs/index.md +3 -0
- docs/requirements.txt +2 -1
- examples/integration-server/jobs/materials_auto/example_http.py +13 -1
- uncountable/integration/job.py +32 -0
- uncountable/types/exports_t.py +1 -0
- {uncountablepythonsdk-0.0.121.dist-info → uncountablepythonsdk-0.0.122.dist-info}/METADATA +1 -1
- {uncountablepythonsdk-0.0.121.dist-info → uncountablepythonsdk-0.0.122.dist-info}/RECORD +10 -10
- {uncountablepythonsdk-0.0.121.dist-info → uncountablepythonsdk-0.0.122.dist-info}/WHEEL +0 -0
- {uncountablepythonsdk-0.0.121.dist-info → uncountablepythonsdk-0.0.122.dist-info}/top_level.txt +0 -0
docs/conf.py
CHANGED
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
import datetime
|
|
10
10
|
|
|
11
|
+
from docutils import nodes # type: ignore[import-untyped]
|
|
12
|
+
from sphinx.addnodes import pending_xref # type: ignore[import-not-found]
|
|
13
|
+
from sphinx.application import Sphinx # type: ignore[import-not-found]
|
|
14
|
+
from sphinx.environment import BuildEnvironment # type: ignore[import-not-found]
|
|
15
|
+
|
|
11
16
|
project = "Uncountable SDK"
|
|
12
17
|
copyright = f"{datetime.datetime.now(tz=datetime.UTC).date().year}, Uncountable Inc"
|
|
13
18
|
author = "Uncountable Inc"
|
|
@@ -27,17 +32,18 @@ myst_enable_extensions = ["fieldlist", "deflist"]
|
|
|
27
32
|
autoapi_dirs = ["../uncountable"]
|
|
28
33
|
autoapi_options = [
|
|
29
34
|
"members",
|
|
35
|
+
"inherited-members",
|
|
30
36
|
"undoc-members",
|
|
31
|
-
"show-inheritance",
|
|
32
|
-
"show-module-summary",
|
|
33
|
-
"imported-members",
|
|
34
37
|
]
|
|
38
|
+
autoapi_root = "api"
|
|
35
39
|
autoapi_ignore = ["*integration*"]
|
|
36
40
|
autodoc_typehints = "description"
|
|
41
|
+
autoapi_member_order = "groupwise"
|
|
42
|
+
autoapi_own_page_level = "class"
|
|
37
43
|
|
|
38
44
|
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
39
45
|
|
|
40
|
-
|
|
46
|
+
python_use_unqualified_type_names = True
|
|
41
47
|
# -- Options for HTML output -------------------------------------------------
|
|
42
48
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
43
49
|
|
|
@@ -55,3 +61,25 @@ favicons = [
|
|
|
55
61
|
"favicons/mstile-150x150.png",
|
|
56
62
|
"favicons/safari-pinned-tab.svg",
|
|
57
63
|
]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _hook_missing_reference(
|
|
67
|
+
_app: Sphinx, _env: BuildEnvironment, node: pending_xref, contnode: nodes.Text
|
|
68
|
+
) -> nodes.reference | None:
|
|
69
|
+
"""
|
|
70
|
+
Manually resolve reference when autoapi reference resolution fails.
|
|
71
|
+
This is necessary because autoapi does not fully support type aliases.
|
|
72
|
+
"""
|
|
73
|
+
target = node.get("reftarget", "")
|
|
74
|
+
if not target.startswith("uncountable"):
|
|
75
|
+
return None
|
|
76
|
+
module, name = target.rsplit(".", 1)
|
|
77
|
+
return nodes.reference(
|
|
78
|
+
text=name if python_use_unqualified_type_names else target,
|
|
79
|
+
children=[contnode],
|
|
80
|
+
refuri=f"/{autoapi_root}/{module.replace('.', '/')}/#{target}",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def setup(app: Sphinx) -> None:
|
|
85
|
+
app.connect("missing-reference", _hook_missing_reference)
|
docs/index.md
CHANGED
docs/requirements.txt
CHANGED
|
@@ -4,6 +4,7 @@ from uncountable.integration.http_server import (
|
|
|
4
4
|
GenericHttpRequest,
|
|
5
5
|
GenericHttpResponse,
|
|
6
6
|
)
|
|
7
|
+
from uncountable.integration.http_server.types import HttpException
|
|
7
8
|
from uncountable.integration.job import CustomHttpJob, register_job
|
|
8
9
|
from uncountable.types import job_definition_t
|
|
9
10
|
|
|
@@ -14,6 +15,9 @@ class ExampleWebhookPayload:
|
|
|
14
15
|
message: str
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
_EXPECTED_USER_ID = 1
|
|
19
|
+
|
|
20
|
+
|
|
17
21
|
@register_job
|
|
18
22
|
class HttpExample(CustomHttpJob):
|
|
19
23
|
@staticmethod
|
|
@@ -23,7 +27,15 @@ class HttpExample(CustomHttpJob):
|
|
|
23
27
|
job_definition: job_definition_t.HttpJobDefinitionBase, # noqa: ARG004
|
|
24
28
|
profile_meta: job_definition_t.ProfileMetadata, # noqa: ARG004
|
|
25
29
|
) -> None:
|
|
26
|
-
|
|
30
|
+
if (
|
|
31
|
+
CustomHttpJob.get_validated_oauth_request_user_id(
|
|
32
|
+
request=request, profile_metadata=profile_meta
|
|
33
|
+
)
|
|
34
|
+
!= _EXPECTED_USER_ID
|
|
35
|
+
):
|
|
36
|
+
raise HttpException(
|
|
37
|
+
message="unauthorized; invalid oauth token", error_code=401
|
|
38
|
+
)
|
|
27
39
|
|
|
28
40
|
@staticmethod
|
|
29
41
|
def handle_request(
|
uncountable/integration/job.py
CHANGED
|
@@ -12,6 +12,7 @@ from uncountable.core.async_batch import AsyncBatchProcessor
|
|
|
12
12
|
from uncountable.core.client import Client
|
|
13
13
|
from uncountable.core.environment import get_local_admin_server_port
|
|
14
14
|
from uncountable.core.file_upload import FileUpload
|
|
15
|
+
from uncountable.core.types import AuthDetailsOAuth
|
|
15
16
|
from uncountable.integration.http_server import (
|
|
16
17
|
GenericHttpRequest,
|
|
17
18
|
GenericHttpResponse,
|
|
@@ -93,6 +94,19 @@ class WebhookResponse:
|
|
|
93
94
|
pass
|
|
94
95
|
|
|
95
96
|
|
|
97
|
+
class _RequestValidatorClient(Client):
|
|
98
|
+
def __init__(self, *, base_url: str, oauth_bearer_token: str):
|
|
99
|
+
super().__init__(
|
|
100
|
+
base_url=base_url,
|
|
101
|
+
auth_details=AuthDetailsOAuth(refresh_token=""),
|
|
102
|
+
config=None,
|
|
103
|
+
)
|
|
104
|
+
self._oauth_bearer_token = oauth_bearer_token
|
|
105
|
+
|
|
106
|
+
def _get_oauth_bearer_token(self, *, oauth_details: AuthDetailsOAuth) -> str:
|
|
107
|
+
return self._oauth_bearer_token
|
|
108
|
+
|
|
109
|
+
|
|
96
110
|
class CustomHttpJob(Job[GenericHttpRequest]):
|
|
97
111
|
@property
|
|
98
112
|
def payload_type(self) -> type[GenericHttpRequest]:
|
|
@@ -112,6 +126,24 @@ class CustomHttpJob(Job[GenericHttpRequest]):
|
|
|
112
126
|
"""
|
|
113
127
|
...
|
|
114
128
|
|
|
129
|
+
@staticmethod
|
|
130
|
+
def get_validated_oauth_request_user_id(
|
|
131
|
+
*, profile_metadata: ProfileMetadata, request: GenericHttpRequest
|
|
132
|
+
) -> base_t.ObjectId:
|
|
133
|
+
token = request.headers.get("Authorization", "").replace("Bearer ", "")
|
|
134
|
+
if token == "":
|
|
135
|
+
raise HttpException(
|
|
136
|
+
message="unauthorized; no bearer token in request", error_code=401
|
|
137
|
+
)
|
|
138
|
+
return (
|
|
139
|
+
_RequestValidatorClient(
|
|
140
|
+
base_url=profile_metadata.base_url,
|
|
141
|
+
oauth_bearer_token=token,
|
|
142
|
+
)
|
|
143
|
+
.get_current_user_info()
|
|
144
|
+
.user_id
|
|
145
|
+
)
|
|
146
|
+
|
|
115
147
|
@staticmethod
|
|
116
148
|
@abstractmethod
|
|
117
149
|
def handle_request(
|
uncountable/types/exports_t.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.122
|
|
4
4
|
Summary: Uncountable SDK
|
|
5
5
|
Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
docs/.gitignore,sha256=_ebkZUcwfvfnGEJ95rfj1lxoBNd6EE9ZvtOc7FsbfFE,7
|
|
2
|
-
docs/conf.py,sha256=
|
|
3
|
-
docs/index.md,sha256=
|
|
2
|
+
docs/conf.py,sha256=Qaw_Ys35RUUXKpFyGjiX120kABf6keZIq7iUdsUQxGY,2843
|
|
3
|
+
docs/index.md,sha256=HOQ3H-hErtHlVJMQ-gZjWF_xj1U68Au4aHa_Rc-K8uk,363
|
|
4
4
|
docs/justfile,sha256=WymCEQ6W2A8Ak79iUPmecmuaUNN2htb7STUrz5K7ELE,273
|
|
5
5
|
docs/quickstart.md,sha256=3GuJ0MB1O5kjlsrgAmdSkDq0rYqATrYy-tzEHDy8H-c,422
|
|
6
|
-
docs/requirements.txt,sha256=
|
|
6
|
+
docs/requirements.txt,sha256=Q5qvOf7nQa19R4kCWb_1DBhwW-Vtm3SAtZTPDR_aF9c,171
|
|
7
7
|
docs/static/logo_blue.png,sha256=SyYpMTVhhBbhF5Wl8lWaVwz-_p1MIR6dW6bVhufQRME,46708
|
|
8
8
|
docs/static/favicons/android-chrome-192x192.png,sha256=XoF-AhD55JlSBDGsEPJKfT_VeXT-awhwKyZnxLhrwvk,1369
|
|
9
9
|
docs/static/favicons/android-chrome-512x512.png,sha256=1S4xwY9YtJQ5ifFsZ-DOzssoyBYs0t9uwdOUmYx0Xso,3888
|
|
@@ -26,7 +26,7 @@ examples/upload_files.py,sha256=qMaSvMSdTMPOOP55y1AwEurc0SOdZAMvEydlqJPsGpg,432
|
|
|
26
26
|
examples/integration-server/pyproject.toml,sha256=-ZZ1R3B-Pf-F6gQX0-Me6u3G9cVW2B2_eechemCe7_4,9149
|
|
27
27
|
examples/integration-server/jobs/materials_auto/concurrent_cron.py,sha256=xsK3H9ZEaniedC2nJUB0rqOcFI8y-ojfl_nLSJb9AMM,312
|
|
28
28
|
examples/integration-server/jobs/materials_auto/example_cron.py,sha256=spUMiiTEFaepbVXecjD_4aEEfqEtZGGZuWTKs9J6Xcw,736
|
|
29
|
-
examples/integration-server/jobs/materials_auto/example_http.py,sha256=
|
|
29
|
+
examples/integration-server/jobs/materials_auto/example_http.py,sha256=eIL46ElWo8SKY7W5JWWkwZk6Qo7KRd9EJBxfy7YQ_sE,1429
|
|
30
30
|
examples/integration-server/jobs/materials_auto/example_instrument.py,sha256=czJF3qBFay1S8fuESOvmkvBv1wCtZGAlHjwvCyYr-Mw,2336
|
|
31
31
|
examples/integration-server/jobs/materials_auto/example_runsheet_wh.py,sha256=_wILTnbzzLf9zrcQb_KQKytxxcya1ej6MqQnoUSS4fA,1180
|
|
32
32
|
examples/integration-server/jobs/materials_auto/example_wh.py,sha256=PN-skP27yJwDZboWk5g5EZEc3AKfVayQLfnopjsDKJc,659
|
|
@@ -105,7 +105,7 @@ uncountable/integration/cli.py,sha256=eshJ0lv4u00UOFrlkCwamE8NaxX1qN2q79wCJcsFrJ
|
|
|
105
105
|
uncountable/integration/construct_client.py,sha256=I53mGcdS88hba3HFwgXmWQaTd1d5u0jWNSwyc_vlVsQ,1937
|
|
106
106
|
uncountable/integration/cron.py,sha256=6eH-kIs3sdYPCyb62_L2M7U_uQTdMTdwY5hreEJb0hw,887
|
|
107
107
|
uncountable/integration/entrypoint.py,sha256=BHOYPQgKvZE6HG8Rv15MkdYl8lRkvfDgv1OdLo0oQ9Q,433
|
|
108
|
-
uncountable/integration/job.py,sha256=
|
|
108
|
+
uncountable/integration/job.py,sha256=HFYA3YxqwyCvQLqXpMnKxp2IJUjFgjMsWVz_DTb_5eo,8229
|
|
109
109
|
uncountable/integration/scan_profiles.py,sha256=RHBmPc5E10YZzf4cmglwrn2yAy0jHBhQ-P_GlAk2TeU,2919
|
|
110
110
|
uncountable/integration/scheduler.py,sha256=KK-1XCr8Rxi8puaynb3H0BySvsDBJJaPcGumy49ZMB8,4864
|
|
111
111
|
uncountable/integration/server.py,sha256=lL9zmzqkQRf7V1fBT20SvIy-7ryz5hFf7DF4QX4pj1E,4699
|
|
@@ -167,7 +167,7 @@ uncountable/types/entity_t.py,sha256=cULJs6qZAWnN4U8pZadcsf9A5KmlLTkIlwW_sQf627I
|
|
|
167
167
|
uncountable/types/experiment_groups.py,sha256=qUpFOx1AKgzaT_4khCOv5Xs6jwiQGbvHH-GUh3v1nv4,288
|
|
168
168
|
uncountable/types/experiment_groups_t.py,sha256=29Ct-WPejpYMuGfnFfOoosU9iSfjzxpabpBX6oTPFUA,761
|
|
169
169
|
uncountable/types/exports.py,sha256=VMmxUO2PpV1Y63hZ2AnVor4H-B6aswJ7YpSru_u89lU,334
|
|
170
|
-
uncountable/types/exports_t.py,sha256=
|
|
170
|
+
uncountable/types/exports_t.py,sha256=p_ub9Ltk6bGE4CCe07Mfz7y4-uDMCIo5_jZr1l55zsE,912
|
|
171
171
|
uncountable/types/field_values.py,sha256=iG4TvITLnlz023GuhFrlDwXB7oov5DPpAs_FBaMaJR8,1713
|
|
172
172
|
uncountable/types/field_values_t.py,sha256=Br2D2dibU9avbomfkaXHXw1ineUcIkATBbEm0eZm1SE,10076
|
|
173
173
|
uncountable/types/fields.py,sha256=M0_ZZr0QdNLXkdHAGo5mfU90kEtHedCSKrcod-FG30Y,245
|
|
@@ -326,7 +326,7 @@ uncountable/types/api/uploader/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr
|
|
|
326
326
|
uncountable/types/api/uploader/invoke_uploader.py,sha256=Bj7Dq4A90k00suacwk3bLA_dCb2aovS1kAbVam2AQnM,1395
|
|
327
327
|
uncountable/types/api/user/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
|
|
328
328
|
uncountable/types/api/user/get_current_user_info.py,sha256=Avqi_RXtRgbefrT_dwJ9MrO6eDNSSa_Nu650FSuESlg,1109
|
|
329
|
-
uncountablepythonsdk-0.0.
|
|
330
|
-
uncountablepythonsdk-0.0.
|
|
331
|
-
uncountablepythonsdk-0.0.
|
|
332
|
-
uncountablepythonsdk-0.0.
|
|
329
|
+
uncountablepythonsdk-0.0.122.dist-info/METADATA,sha256=KCzmpzYEmy6LpOZxLn9tvAVP2Q7H3UE5KeRynwvn9rM,2174
|
|
330
|
+
uncountablepythonsdk-0.0.122.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
331
|
+
uncountablepythonsdk-0.0.122.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
|
|
332
|
+
uncountablepythonsdk-0.0.122.dist-info/RECORD,,
|
|
File without changes
|
{uncountablepythonsdk-0.0.121.dist-info → uncountablepythonsdk-0.0.122.dist-info}/top_level.txt
RENAMED
|
File without changes
|