omdev 0.0.0.dev213__py3-none-any.whl → 0.0.0.dev215__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- omdev/.manifests.json +1 -1
- omdev/ci/__init__.py +1 -0
- omdev/ci/cache.py +100 -121
- omdev/ci/ci.py +120 -118
- omdev/ci/cli.py +50 -24
- omdev/ci/compose.py +1 -8
- omdev/ci/consts.py +1 -0
- omdev/ci/docker.py +4 -6
- omdev/ci/github/{cacheapi.py → api.py} +0 -1
- omdev/ci/github/bootstrap.py +8 -1
- omdev/ci/github/cache.py +36 -289
- omdev/ci/github/cli.py +9 -5
- omdev/ci/github/client.py +492 -0
- omdev/ci/github/env.py +21 -0
- omdev/ci/requirements.py +0 -1
- omdev/ci/shell.py +0 -1
- omdev/ci/utils.py +2 -14
- omdev/scripts/ci.py +1149 -922
- omdev/scripts/pyproject.py +79 -12
- omdev/tools/docker.py +6 -0
- {omdev-0.0.0.dev213.dist-info → omdev-0.0.0.dev215.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev213.dist-info → omdev-0.0.0.dev215.dist-info}/RECORD +26 -24
- omdev/ci/github/curl.py +0 -209
- {omdev-0.0.0.dev213.dist-info → omdev-0.0.0.dev215.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev213.dist-info → omdev-0.0.0.dev215.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev213.dist-info → omdev-0.0.0.dev215.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev213.dist-info → omdev-0.0.0.dev215.dist-info}/top_level.txt +0 -0
omdev/scripts/pyproject.py
CHANGED
@@ -4962,6 +4962,7 @@ inj = InjectionApi()
|
|
4962
4962
|
TODO:
|
4963
4963
|
- pickle stdlib objs? have to pin to 3.8 pickle protocol, will be cross-version
|
4964
4964
|
- literals
|
4965
|
+
- Options.sequence_cls = list, mapping_cls = dict, ... - def with_mutable_containers() -> Options
|
4965
4966
|
"""
|
4966
4967
|
|
4967
4968
|
|
@@ -5114,21 +5115,55 @@ class IterableObjMarshaler(ObjMarshaler):
|
|
5114
5115
|
@dc.dataclass(frozen=True)
|
5115
5116
|
class FieldsObjMarshaler(ObjMarshaler):
|
5116
5117
|
ty: type
|
5117
|
-
|
5118
|
+
|
5119
|
+
@dc.dataclass(frozen=True)
|
5120
|
+
class Field:
|
5121
|
+
att: str
|
5122
|
+
key: str
|
5123
|
+
m: ObjMarshaler
|
5124
|
+
|
5125
|
+
omit_if_none: bool = False
|
5126
|
+
|
5127
|
+
fs: ta.Sequence[Field]
|
5128
|
+
|
5118
5129
|
non_strict: bool = False
|
5119
5130
|
|
5131
|
+
#
|
5132
|
+
|
5133
|
+
_fs_by_att: ta.ClassVar[ta.Mapping[str, Field]]
|
5134
|
+
_fs_by_key: ta.ClassVar[ta.Mapping[str, Field]]
|
5135
|
+
|
5136
|
+
def __post_init__(self) -> None:
|
5137
|
+
fs_by_att: dict = {}
|
5138
|
+
fs_by_key: dict = {}
|
5139
|
+
for f in self.fs:
|
5140
|
+
check.not_in(check.non_empty_str(f.att), fs_by_att)
|
5141
|
+
check.not_in(check.non_empty_str(f.key), fs_by_key)
|
5142
|
+
fs_by_att[f.att] = f
|
5143
|
+
fs_by_key[f.key] = f
|
5144
|
+
self.__dict__['_fs_by_att'] = fs_by_att
|
5145
|
+
self.__dict__['_fs_by_key'] = fs_by_key
|
5146
|
+
|
5147
|
+
#
|
5148
|
+
|
5120
5149
|
def marshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
5121
|
-
|
5122
|
-
|
5123
|
-
|
5124
|
-
|
5150
|
+
d = {}
|
5151
|
+
for f in self.fs:
|
5152
|
+
mv = f.m.marshal(getattr(o, f.att), ctx)
|
5153
|
+
if mv is None and f.omit_if_none:
|
5154
|
+
continue
|
5155
|
+
d[f.key] = mv
|
5156
|
+
return d
|
5125
5157
|
|
5126
5158
|
def unmarshal(self, o: ta.Any, ctx: 'ObjMarshalContext') -> ta.Any:
|
5127
|
-
|
5128
|
-
|
5129
|
-
|
5130
|
-
|
5131
|
-
|
5159
|
+
kw = {}
|
5160
|
+
for k, v in o.items():
|
5161
|
+
if (f := self._fs_by_key.get(k)) is None:
|
5162
|
+
if not (self.non_strict or ctx.options.non_strict_fields):
|
5163
|
+
raise KeyError(k)
|
5164
|
+
continue
|
5165
|
+
kw[f.att] = f.m.unmarshal(v, ctx)
|
5166
|
+
return self.ty(**kw)
|
5132
5167
|
|
5133
5168
|
|
5134
5169
|
@dc.dataclass(frozen=True)
|
@@ -5263,6 +5298,22 @@ def register_single_field_type_obj_marshaler(fld, ty=None):
|
|
5263
5298
|
##
|
5264
5299
|
|
5265
5300
|
|
5301
|
+
class ObjMarshalerFieldMetadata:
|
5302
|
+
def __new__(cls, *args, **kwargs): # noqa
|
5303
|
+
raise TypeError
|
5304
|
+
|
5305
|
+
|
5306
|
+
class OBJ_MARSHALER_FIELD_KEY(ObjMarshalerFieldMetadata): # noqa
|
5307
|
+
pass
|
5308
|
+
|
5309
|
+
|
5310
|
+
class OBJ_MARSHALER_OMIT_IF_NONE(ObjMarshalerFieldMetadata): # noqa
|
5311
|
+
pass
|
5312
|
+
|
5313
|
+
|
5314
|
+
##
|
5315
|
+
|
5316
|
+
|
5266
5317
|
class ObjMarshalerManager:
|
5267
5318
|
def __init__(
|
5268
5319
|
self,
|
@@ -5322,14 +5373,30 @@ class ObjMarshalerManager:
|
|
5322
5373
|
if dc.is_dataclass(ty):
|
5323
5374
|
return FieldsObjMarshaler(
|
5324
5375
|
ty,
|
5325
|
-
|
5376
|
+
[
|
5377
|
+
FieldsObjMarshaler.Field(
|
5378
|
+
att=f.name,
|
5379
|
+
key=check.non_empty_str(fk),
|
5380
|
+
m=rec(f.type),
|
5381
|
+
omit_if_none=check.isinstance(f.metadata.get(OBJ_MARSHALER_OMIT_IF_NONE, False), bool),
|
5382
|
+
)
|
5383
|
+
for f in dc.fields(ty)
|
5384
|
+
if (fk := f.metadata.get(OBJ_MARSHALER_FIELD_KEY, f.name)) is not None
|
5385
|
+
],
|
5326
5386
|
non_strict=non_strict_fields,
|
5327
5387
|
)
|
5328
5388
|
|
5329
5389
|
if issubclass(ty, tuple) and hasattr(ty, '_fields'):
|
5330
5390
|
return FieldsObjMarshaler(
|
5331
5391
|
ty,
|
5332
|
-
|
5392
|
+
[
|
5393
|
+
FieldsObjMarshaler.Field(
|
5394
|
+
att=p.name,
|
5395
|
+
key=p.name,
|
5396
|
+
m=rec(p.annotation),
|
5397
|
+
)
|
5398
|
+
for p in inspect.signature(ty).parameters.values()
|
5399
|
+
],
|
5333
5400
|
non_strict=non_strict_fields,
|
5334
5401
|
)
|
5335
5402
|
|
omdev/tools/docker.py
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
"""
|
2
2
|
TODO:
|
3
3
|
- https://github.com/zeromake/docker-debug
|
4
|
+
- prune
|
5
|
+
- docker container prune --force
|
6
|
+
- docker system prune --all --force --filter "until=720h"
|
7
|
+
- docker container prune --force --filter "until=720h"
|
8
|
+
- docker image prune --all --force --filter "until=720h"
|
9
|
+
- docker builder prune --all --force --filter "until=720h"
|
4
10
|
"""
|
5
11
|
import os
|
6
12
|
import re
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: omdev
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev215
|
4
4
|
Summary: omdev
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: >=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omlish==0.0.0.dev215
|
16
16
|
Provides-Extra: all
|
17
17
|
Requires-Dist: black~=24.10; extra == "all"
|
18
18
|
Requires-Dist: pycparser~=2.22; extra == "all"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
omdev/.manifests.json,sha256=
|
1
|
+
omdev/.manifests.json,sha256=VUg0T7DFMxatE-hsLqocMvGoNmELDiZZaudO1tcz-FE,9092
|
2
2
|
omdev/__about__.py,sha256=j3vFclhFvyPICV6FK4aDApFzMCqJWxv9FaWwdwXrSgw,1215
|
3
3
|
omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
omdev/bracepy.py,sha256=I8EdqtDvxzAi3I8TuMEW-RBfwXfqKbwp06CfOdj3L1o,2743
|
@@ -69,22 +69,24 @@ omdev/cexts/_distutils/compilers/__init__.py,sha256=amL_zrFlba0lHIvpqDne9uhqhLem
|
|
69
69
|
omdev/cexts/_distutils/compilers/ccompiler.py,sha256=cTs88qrvj0hBVXHfemSDE_du_nEA4_qo3Qst5TpQkVI,43606
|
70
70
|
omdev/cexts/_distutils/compilers/options.py,sha256=H7r5IcLvga5Fs3jjXWIT-6ap3JBduXRKgtpDmSGCZxs,3818
|
71
71
|
omdev/cexts/_distutils/compilers/unixccompiler.py,sha256=o1h8QuyupLntv4F21_XjzAZmCiwwxJuTmOirvBSL-Qw,15419
|
72
|
-
omdev/ci/__init__.py,sha256=
|
72
|
+
omdev/ci/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
73
73
|
omdev/ci/__main__.py,sha256=Jsrv3P7LX2Cg08W7ByZfZ1JQT4lgLDPW1qNAmShFuMk,75
|
74
|
-
omdev/ci/cache.py,sha256=
|
75
|
-
omdev/ci/ci.py,sha256=
|
76
|
-
omdev/ci/cli.py,sha256=
|
77
|
-
omdev/ci/compose.py,sha256=
|
78
|
-
omdev/ci/
|
79
|
-
omdev/ci/
|
80
|
-
omdev/ci/
|
81
|
-
omdev/ci/
|
74
|
+
omdev/ci/cache.py,sha256=hHV7ovvOwkSRcIF49ovb1A7s43mUl0IWXi1iIQeRMdA,3643
|
75
|
+
omdev/ci/ci.py,sha256=lEP5wgX0rInvkLJtGZQ-NSLO1Fc0CdQjVaUoMmeRCjQ,8110
|
76
|
+
omdev/ci/cli.py,sha256=0KBGKxaKzhSbhk3YFDOgzrb_OVOY22a4qpIaTu5zBeA,6243
|
77
|
+
omdev/ci/compose.py,sha256=vHLuXO5e2paafBC0Kf-OUGoamtIJmQ19r2U3_oikk_g,4541
|
78
|
+
omdev/ci/consts.py,sha256=1puYfksvGOaVWEnbARM_sdMqs8oTn_VvsevsOtLsFno,21
|
79
|
+
omdev/ci/docker.py,sha256=d3wQyL-N4mmzkIVbSgNx2Xd-K6RniFQN8nR-THKuDZs,3770
|
80
|
+
omdev/ci/requirements.py,sha256=iKAINTDyVQaqESGlfE9OXkKiW_CZ9kP70PEc121Ix-Q,2100
|
81
|
+
omdev/ci/shell.py,sha256=cBPLMKiAJuNpPGj3ou6hpl88Xw7r99xpL91KJBQ0rqw,835
|
82
|
+
omdev/ci/utils.py,sha256=mnf6yZmholvj0s_7JGbaO0Q1EWCn_saSv6BKMQQUCoQ,1450
|
82
83
|
omdev/ci/github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
|
-
omdev/ci/github/
|
84
|
-
omdev/ci/github/
|
85
|
-
omdev/ci/github/
|
86
|
-
omdev/ci/github/cli.py,sha256=
|
87
|
-
omdev/ci/github/
|
84
|
+
omdev/ci/github/api.py,sha256=Vqza7Hm1OCSfZYgdXF4exkjneqNjFcdO1pl8qmODskU,5198
|
85
|
+
omdev/ci/github/bootstrap.py,sha256=9OuftAz7CUd7uf2Or3sJFVozQQiwu0RGAlTOQNpLQIY,430
|
86
|
+
omdev/ci/github/cache.py,sha256=cXbPPMIWK-qjGyuCScEJGe-l4QKLwGBkW0GxOhGO_8E,1801
|
87
|
+
omdev/ci/github/cli.py,sha256=6mG0CllwrOoC7MDzKfKDqBHAjfF0gEI6aT5UAGMmuss,1114
|
88
|
+
omdev/ci/github/client.py,sha256=cSewCoHC4cDM4BMQObcrf5g2wwD6rTlil_h2repAkf8,14341
|
89
|
+
omdev/ci/github/env.py,sha256=FQFjP_m7JWM7es9I51U-6UgJTwAt_UCVHFIYKTd9NKM,394
|
88
90
|
omdev/cli/__init__.py,sha256=V_l6VP1SZMlJbO-8CJwSuO9TThOy2S_oaPepNYgIrbE,37
|
89
91
|
omdev/cli/__main__.py,sha256=mOJpgc07o0r5luQ1DlX4tk2PqZkgmbwPbdzJ3KmtjgQ,138
|
90
92
|
omdev/cli/_pathhack.py,sha256=kxqb2kHap68Lkh8b211rDbcgj06hidBiAKA3f9posyc,2119
|
@@ -172,12 +174,12 @@ omdev/pyproject/resources/docker-dev.sh,sha256=DHkz5D18jok_oDolfg2mqrvGRWFoCe9GQ
|
|
172
174
|
omdev/pyproject/resources/python.sh,sha256=jvrwddYw2KNttpuImLbdCdJK0HsUNMrHtTnmLvhxQxg,757
|
173
175
|
omdev/scripts/__init__.py,sha256=MKCvUAEQwsIvwLixwtPlpBqmkMXLCnjjXyAXvVpDwVk,91
|
174
176
|
omdev/scripts/bumpversion.py,sha256=Kn7fo73Hs8uJh3Hi3EIyLOlzLPWAC6dwuD_lZ3cIzuY,1064
|
175
|
-
omdev/scripts/ci.py,sha256=
|
177
|
+
omdev/scripts/ci.py,sha256=yDx6VsztaY1VqYWF1i9Ywt2YTIseSc5wYtdvtmh5qyI,108870
|
176
178
|
omdev/scripts/execrss.py,sha256=mR0G0wERBYtQmVIn63lCIIFb5zkCM6X_XOENDFYDBKc,651
|
177
179
|
omdev/scripts/exectime.py,sha256=sFb376GflU6s9gNX-2-we8hgH6w5MuQNS9g6i4SqJIo,610
|
178
180
|
omdev/scripts/importtrace.py,sha256=oa7CtcWJVMNDbyIEiRHej6ICfABfErMeo4_haIqe18Q,14041
|
179
181
|
omdev/scripts/interp.py,sha256=7NrLbOkiDjBldnzpf-EpL8UTmU6U3lakvHqhSlY3X_U,141851
|
180
|
-
omdev/scripts/pyproject.py,sha256=
|
182
|
+
omdev/scripts/pyproject.py,sha256=HDors8tvpSgCUzESwQ2E-Gx5jLisaYoOApOTCgmQ5P0,245595
|
181
183
|
omdev/scripts/slowcat.py,sha256=lssv4yrgJHiWfOiHkUut2p8E8Tq32zB-ujXESQxFFHY,2728
|
182
184
|
omdev/scripts/tmpexec.py,sha256=WTYcf56Tj2qjYV14AWmV8SfT0u6Y8eIU6cKgQRvEK3c,1442
|
183
185
|
omdev/tokens/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -187,7 +189,7 @@ omdev/tokens/utils.py,sha256=DJA2jsDzrtQxnO0bdkUk1-GmenX4ECugdhl1xOBe7QI,1448
|
|
187
189
|
omdev/tools/__init__.py,sha256=iVJAOQ0viGTQOm0DLX4uZLro-9jOioYJGLg9s0kDx1A,78
|
188
190
|
omdev/tools/cloc.py,sha256=jYlMHBae9oGKN4VKeBGuqjiQNcM2be7KIoTF0oNwx_I,5205
|
189
191
|
omdev/tools/doc.py,sha256=wvgGhv6aFaV-Zl-Qivejx37i-lKQ207rZ-4K2fPf-Ss,2547
|
190
|
-
omdev/tools/docker.py,sha256=
|
192
|
+
omdev/tools/docker.py,sha256=mRd5ziNOnJSJ__9MlldASIF6bBD7m48fDKCD1VEUNUw,7633
|
191
193
|
omdev/tools/git.py,sha256=fiQc4w2w63PELLLyMXdwpmgpzFzs7UNn35vewWckScM,7514
|
192
194
|
omdev/tools/importscan.py,sha256=nhJIhtjDY6eFVlReP7fegvv6L5ZjN-Z2VeyhsBonev4,4639
|
193
195
|
omdev/tools/linehisto.py,sha256=0ZNm34EuiZBE9Q2YC6KNLNNydNT8QPSOwvYzXiU9S2Q,8881
|
@@ -209,9 +211,9 @@ omdev/tools/json/rendering.py,sha256=tMcjOW5edfozcMSTxxvF7WVTsbYLoe9bCKFh50qyaGw
|
|
209
211
|
omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
210
212
|
omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
|
211
213
|
omdev/tools/pawk/pawk.py,sha256=zsEkfQX0jF5bn712uqPAyBSdJt2dno1LH2oeSMNfXQI,11424
|
212
|
-
omdev-0.0.0.
|
213
|
-
omdev-0.0.0.
|
214
|
-
omdev-0.0.0.
|
215
|
-
omdev-0.0.0.
|
216
|
-
omdev-0.0.0.
|
217
|
-
omdev-0.0.0.
|
214
|
+
omdev-0.0.0.dev215.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
215
|
+
omdev-0.0.0.dev215.dist-info/METADATA,sha256=oNR4sVjlhZ4v-B5bp8h4XPFlDnI8aniDWCUq9WLk-ZM,1638
|
216
|
+
omdev-0.0.0.dev215.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
217
|
+
omdev-0.0.0.dev215.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
218
|
+
omdev-0.0.0.dev215.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
219
|
+
omdev-0.0.0.dev215.dist-info/RECORD,,
|
omdev/ci/github/curl.py
DELETED
@@ -1,209 +0,0 @@
|
|
1
|
-
# ruff: noqa: UP006 UP007
|
2
|
-
# @omlish-lite
|
3
|
-
import dataclasses as dc
|
4
|
-
import json
|
5
|
-
import os
|
6
|
-
import shlex
|
7
|
-
import typing as ta
|
8
|
-
|
9
|
-
from omlish.lite.check import check
|
10
|
-
from omlish.lite.contextmanagers import defer
|
11
|
-
from omlish.lite.json import json_dumps_compact
|
12
|
-
from omlish.subprocesses import subprocesses
|
13
|
-
|
14
|
-
from ..shell import ShellCmd
|
15
|
-
from ..utils import make_temp_file
|
16
|
-
|
17
|
-
|
18
|
-
##
|
19
|
-
|
20
|
-
|
21
|
-
class GithubServiceCurlClient:
|
22
|
-
def __init__(
|
23
|
-
self,
|
24
|
-
service_url: str,
|
25
|
-
auth_token: ta.Optional[str] = None,
|
26
|
-
*,
|
27
|
-
api_version: ta.Optional[str] = None,
|
28
|
-
) -> None:
|
29
|
-
super().__init__()
|
30
|
-
|
31
|
-
self._service_url = check.non_empty_str(service_url)
|
32
|
-
self._auth_token = auth_token
|
33
|
-
self._api_version = api_version
|
34
|
-
|
35
|
-
#
|
36
|
-
|
37
|
-
_MISSING = object()
|
38
|
-
|
39
|
-
def build_headers(
|
40
|
-
self,
|
41
|
-
headers: ta.Optional[ta.Mapping[str, str]] = None,
|
42
|
-
*,
|
43
|
-
auth_token: ta.Any = _MISSING,
|
44
|
-
content_type: ta.Optional[str] = None,
|
45
|
-
) -> ta.Dict[str, str]:
|
46
|
-
dct = {
|
47
|
-
'Accept': ';'.join([
|
48
|
-
'application/json',
|
49
|
-
*([f'api-version={self._api_version}'] if self._api_version else []),
|
50
|
-
]),
|
51
|
-
}
|
52
|
-
|
53
|
-
if auth_token is self._MISSING:
|
54
|
-
auth_token = self._auth_token
|
55
|
-
if auth_token:
|
56
|
-
dct['Authorization'] = f'Bearer {auth_token}'
|
57
|
-
|
58
|
-
if content_type is not None:
|
59
|
-
dct['Content-Type'] = content_type
|
60
|
-
|
61
|
-
if headers:
|
62
|
-
dct.update(headers)
|
63
|
-
|
64
|
-
return dct
|
65
|
-
|
66
|
-
#
|
67
|
-
|
68
|
-
HEADER_AUTH_TOKEN_ENV_KEY_PREFIX = '_GITHUB_SERVICE_AUTH_TOKEN' # noqa
|
69
|
-
|
70
|
-
@property
|
71
|
-
def header_auth_token_env_key(self) -> str:
|
72
|
-
return f'{self.HEADER_AUTH_TOKEN_ENV_KEY_PREFIX}_{id(self)}'
|
73
|
-
|
74
|
-
def build_cmd(
|
75
|
-
self,
|
76
|
-
method: str,
|
77
|
-
url: str,
|
78
|
-
*,
|
79
|
-
json_content: bool = False,
|
80
|
-
content_type: ta.Optional[str] = None,
|
81
|
-
headers: ta.Optional[ta.Dict[str, str]] = None,
|
82
|
-
) -> ShellCmd:
|
83
|
-
if content_type is None and json_content:
|
84
|
-
content_type = 'application/json'
|
85
|
-
|
86
|
-
env = {}
|
87
|
-
|
88
|
-
header_auth_token: ta.Optional[str]
|
89
|
-
if self._auth_token:
|
90
|
-
header_env_key = self.header_auth_token_env_key
|
91
|
-
env[header_env_key] = self._auth_token
|
92
|
-
header_auth_token = f'${header_env_key}'
|
93
|
-
else:
|
94
|
-
header_auth_token = None
|
95
|
-
|
96
|
-
built_hdrs = self.build_headers(
|
97
|
-
headers,
|
98
|
-
auth_token=header_auth_token,
|
99
|
-
content_type=content_type,
|
100
|
-
)
|
101
|
-
|
102
|
-
url = f'{self._service_url}/{url}'
|
103
|
-
|
104
|
-
cmd = ' '.join([
|
105
|
-
'curl',
|
106
|
-
'-s',
|
107
|
-
'-X', method,
|
108
|
-
url,
|
109
|
-
*[f'-H "{k}: {v}"' for k, v in built_hdrs.items()],
|
110
|
-
])
|
111
|
-
|
112
|
-
return ShellCmd(
|
113
|
-
cmd,
|
114
|
-
env=env,
|
115
|
-
)
|
116
|
-
|
117
|
-
def build_post_json_cmd(
|
118
|
-
self,
|
119
|
-
url: str,
|
120
|
-
obj: ta.Any,
|
121
|
-
**kwargs: ta.Any,
|
122
|
-
) -> ShellCmd:
|
123
|
-
curl_cmd = self.build_cmd(
|
124
|
-
'POST',
|
125
|
-
url,
|
126
|
-
json_content=True,
|
127
|
-
**kwargs,
|
128
|
-
)
|
129
|
-
|
130
|
-
obj_json = json_dumps_compact(obj)
|
131
|
-
|
132
|
-
return dc.replace(curl_cmd, s=f'{curl_cmd.s} -d {shlex.quote(obj_json)}')
|
133
|
-
|
134
|
-
#
|
135
|
-
|
136
|
-
@dc.dataclass()
|
137
|
-
class Error(RuntimeError):
|
138
|
-
status_code: int
|
139
|
-
body: ta.Optional[bytes]
|
140
|
-
|
141
|
-
def __str__(self) -> str:
|
142
|
-
return repr(self)
|
143
|
-
|
144
|
-
@dc.dataclass(frozen=True)
|
145
|
-
class Result:
|
146
|
-
status_code: int
|
147
|
-
body: ta.Optional[bytes]
|
148
|
-
|
149
|
-
def as_error(self) -> 'GithubServiceCurlClient.Error':
|
150
|
-
return GithubServiceCurlClient.Error(
|
151
|
-
status_code=self.status_code,
|
152
|
-
body=self.body,
|
153
|
-
)
|
154
|
-
|
155
|
-
def run_cmd(
|
156
|
-
self,
|
157
|
-
cmd: ShellCmd,
|
158
|
-
*,
|
159
|
-
raise_: bool = False,
|
160
|
-
**subprocess_kwargs: ta.Any,
|
161
|
-
) -> Result:
|
162
|
-
out_file = make_temp_file()
|
163
|
-
with defer(lambda: os.unlink(out_file)):
|
164
|
-
run_cmd = dc.replace(cmd, s=f"{cmd.s} -o {out_file} -w '%{{json}}'")
|
165
|
-
|
166
|
-
out_json_bytes = run_cmd.run(
|
167
|
-
subprocesses.check_output,
|
168
|
-
**subprocess_kwargs,
|
169
|
-
)
|
170
|
-
|
171
|
-
out_json = json.loads(out_json_bytes.decode())
|
172
|
-
status_code = check.isinstance(out_json['response_code'], int)
|
173
|
-
|
174
|
-
with open(out_file, 'rb') as f:
|
175
|
-
body = f.read()
|
176
|
-
|
177
|
-
result = self.Result(
|
178
|
-
status_code=status_code,
|
179
|
-
body=body,
|
180
|
-
)
|
181
|
-
|
182
|
-
if raise_ and (500 <= status_code <= 600):
|
183
|
-
raise result.as_error()
|
184
|
-
|
185
|
-
return result
|
186
|
-
|
187
|
-
def run_json_cmd(
|
188
|
-
self,
|
189
|
-
cmd: ShellCmd,
|
190
|
-
*,
|
191
|
-
success_status_codes: ta.Optional[ta.Container[int]] = None,
|
192
|
-
) -> ta.Optional[ta.Any]:
|
193
|
-
result = self.run_cmd(cmd, raise_=True)
|
194
|
-
|
195
|
-
if success_status_codes is not None:
|
196
|
-
is_success = result.status_code in success_status_codes
|
197
|
-
else:
|
198
|
-
is_success = 200 <= result.status_code < 300
|
199
|
-
|
200
|
-
if is_success:
|
201
|
-
if not (body := result.body):
|
202
|
-
return None
|
203
|
-
return json.loads(body.decode('utf-8-sig'))
|
204
|
-
|
205
|
-
elif result.status_code == 404:
|
206
|
-
return None
|
207
|
-
|
208
|
-
else:
|
209
|
-
raise result.as_error()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|