omlish 0.0.0.dev423__py3-none-any.whl → 0.0.0.dev484__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 omlish might be problematic. Click here for more details.
- omlish/{.manifests.json → .omlish-manifests.json} +12 -0
- omlish/__about__.py +21 -18
- omlish/argparse/all.py +17 -9
- omlish/argparse/cli.py +16 -3
- omlish/argparse/utils.py +21 -0
- omlish/asyncs/all.py +0 -13
- omlish/asyncs/asyncio/rlock.py +110 -0
- omlish/asyncs/asyncio/subprocesses.py +2 -2
- omlish/asyncs/asyncio/sync.py +43 -0
- omlish/asyncs/asyncio/utils.py +2 -0
- omlish/asyncs/ioproxy/proxy.py +1 -1
- omlish/asyncs/sync.py +25 -0
- omlish/bootstrap/_marshal.py +1 -1
- omlish/bootstrap/diag.py +12 -21
- omlish/bootstrap/main.py +2 -5
- omlish/bootstrap/sys.py +27 -28
- omlish/c3.py +4 -1
- omlish/cexts/include/omlish/omlish.hh +1 -0
- omlish/collections/__init__.py +13 -1
- omlish/collections/attrregistry.py +210 -0
- omlish/collections/cache/impl.py +3 -2
- omlish/collections/identity.py +1 -0
- omlish/collections/mappings.py +28 -0
- omlish/collections/trie.py +5 -1
- omlish/collections/utils.py +77 -0
- omlish/concurrent/__init__.py +0 -11
- omlish/concurrent/all.py +18 -0
- omlish/concurrent/futures.py +25 -0
- omlish/concurrent/threadlets.py +1 -1
- omlish/configs/processing/flattening.py +1 -1
- omlish/configs/processing/merging.py +8 -6
- omlish/configs/types.py +1 -1
- omlish/daemons/__init__.py +70 -0
- omlish/daemons/daemon.py +2 -2
- omlish/daemons/launching.py +2 -2
- omlish/daemons/reparent.py +2 -3
- omlish/daemons/spawning.py +2 -3
- omlish/dataclasses/__init__.py +5 -5
- omlish/dataclasses/errors.py +1 -1
- omlish/dataclasses/impl/api/classes/decorator.py +3 -0
- omlish/dataclasses/impl/api/classes/make.py +4 -1
- omlish/dataclasses/impl/concerns/doc.py +1 -1
- omlish/dataclasses/impl/concerns/repr.py +15 -2
- omlish/dataclasses/impl/configs.py +97 -36
- omlish/dataclasses/impl/generation/compilation.py +21 -19
- omlish/dataclasses/impl/generation/globals.py +1 -0
- omlish/dataclasses/impl/generation/ops.py +1 -0
- omlish/dataclasses/impl/generation/processor.py +105 -24
- omlish/dataclasses/impl/processing/base.py +8 -0
- omlish/dataclasses/impl/processing/driving.py +8 -8
- omlish/dataclasses/specs.py +34 -2
- omlish/dataclasses/tools/as_.py +0 -12
- omlish/dataclasses/tools/modifiers.py +5 -0
- omlish/dataclasses/tools/static.py +1 -1
- omlish/diag/_pycharm/runhack.py +1 -1
- omlish/diag/{lslocks.py → cmds/lslocks.py} +6 -6
- omlish/diag/{lsof.py → cmds/lsof.py} +6 -6
- omlish/diag/{ps.py → cmds/ps.py} +6 -6
- omlish/diag/procfs.py +4 -4
- omlish/diag/pycharm.py +16 -2
- omlish/diag/pydevd.py +58 -40
- omlish/diag/replserver/console.py +3 -3
- omlish/diag/replserver/server.py +2 -2
- omlish/dispatch/__init__.py +18 -12
- omlish/dispatch/methods.py +50 -140
- omlish/dom/rendering.py +1 -1
- omlish/formats/dotenv.py +8 -8
- omlish/formats/json/stream/__init__.py +18 -3
- omlish/formats/json/stream/building.py +2 -2
- omlish/formats/json/stream/lexing.py +401 -67
- omlish/formats/json/stream/parsing.py +32 -10
- omlish/formats/json/stream/rendering.py +6 -6
- omlish/formats/json/stream/utils.py +132 -30
- omlish/formats/json5/literals.py +7 -4
- omlish/formats/json5/parsing.py +33 -79
- omlish/formats/json5/stream.py +77 -0
- omlish/formats/logfmt.py +8 -2
- omlish/funcs/genmachine.py +2 -2
- omlish/funcs/guard.py +225 -0
- omlish/graphs/dot/rendering.py +1 -1
- omlish/http/all.py +122 -53
- omlish/http/asgi.py +2 -2
- omlish/http/clients/__init__.py +0 -34
- omlish/http/clients/asyncs.py +153 -0
- omlish/http/clients/base.py +63 -122
- omlish/http/clients/coro/sync.py +171 -0
- omlish/http/clients/default.py +209 -30
- omlish/http/clients/executor.py +56 -0
- omlish/http/clients/httpx.py +78 -13
- omlish/http/clients/middleware.py +181 -0
- omlish/http/clients/sync.py +151 -0
- omlish/http/clients/syncasync.py +49 -0
- omlish/http/clients/urllib.py +8 -5
- omlish/http/coro/client/{client.py → connection.py} +43 -37
- omlish/http/coro/client/headers.py +5 -5
- omlish/http/coro/client/response.py +37 -38
- omlish/http/coro/client/status.py +4 -4
- omlish/http/coro/{client/io.py → io.py} +19 -2
- omlish/http/coro/server/fdio.py +10 -9
- omlish/http/coro/server/server.py +14 -41
- omlish/http/coro/server/sockets.py +7 -6
- omlish/http/flasky/__init__.py +40 -0
- omlish/http/flasky/_compat.py +2 -0
- omlish/http/flasky/api.py +82 -0
- omlish/http/flasky/app.py +203 -0
- omlish/http/flasky/cvs.py +59 -0
- omlish/http/flasky/requests.py +20 -0
- omlish/http/flasky/responses.py +23 -0
- omlish/http/flasky/routes.py +23 -0
- omlish/http/flasky/types.py +15 -0
- omlish/http/handlers.py +3 -2
- omlish/http/headers.py +69 -35
- omlish/http/sse.py +1 -1
- omlish/http/urls.py +67 -0
- omlish/inject/__init__.py +173 -126
- omlish/inject/_dataclasses.py +4986 -0
- omlish/inject/binder.py +10 -49
- omlish/inject/elements.py +27 -0
- omlish/inject/{utils.py → helpers/constfn.py} +3 -3
- omlish/inject/{tags.py → helpers/id.py} +2 -2
- omlish/inject/helpers/multis.py +143 -0
- omlish/inject/helpers/wrappers.py +54 -0
- omlish/inject/impl/elements.py +52 -22
- omlish/inject/impl/injector.py +76 -49
- omlish/inject/impl/inspect.py +11 -1
- omlish/inject/impl/maysync.py +43 -0
- omlish/inject/impl/multis.py +10 -7
- omlish/inject/impl/privates.py +8 -8
- omlish/inject/impl/providers.py +23 -34
- omlish/inject/impl/providersmap.py +43 -0
- omlish/inject/impl/proxy.py +0 -2
- omlish/inject/impl/scopes.py +19 -23
- omlish/inject/impl/sync.py +41 -0
- omlish/inject/injector.py +37 -8
- omlish/inject/inspect.py +35 -0
- omlish/inject/listeners.py +4 -4
- omlish/inject/managed.py +54 -18
- omlish/inject/maysync.py +27 -0
- omlish/inject/multis.py +8 -0
- omlish/inject/overrides.py +3 -3
- omlish/inject/privates.py +6 -0
- omlish/inject/providers.py +8 -1
- omlish/inject/scopes.py +40 -12
- omlish/inject/sync.py +49 -0
- omlish/io/buffers.py +119 -1
- omlish/io/readers.py +29 -0
- omlish/iterators/__init__.py +28 -20
- omlish/iterators/transforms.py +204 -0
- omlish/lang/__init__.py +240 -129
- omlish/lang/_asyncs.cc +186 -0
- omlish/lang/asyncs.py +67 -43
- omlish/lang/{attrs.py → attrstorage.py} +15 -15
- omlish/lang/cached/property.py +2 -2
- omlish/lang/casing.py +11 -0
- omlish/lang/classes/bindable.py +2 -3
- omlish/lang/classes/restrict.py +8 -0
- omlish/lang/classes/simple.py +26 -4
- omlish/lang/collections.py +1 -1
- omlish/lang/contextmanagers.py +59 -9
- omlish/lang/functions.py +31 -33
- omlish/lang/imports/_capture.cc +103 -0
- omlish/lang/imports/capture.py +902 -0
- omlish/lang/imports/lazy.py +0 -25
- omlish/lang/imports/proxy.py +559 -0
- omlish/lang/iterables.py +2 -2
- omlish/lang/lazyglobals.py +49 -14
- omlish/lang/maybes.py +2 -1
- omlish/lang/maysync.py +2 -2
- omlish/lang/params.py +17 -0
- omlish/lang/recursion.py +0 -1
- omlish/lang/resources.py +1 -1
- omlish/lang/sequences.py +124 -0
- omlish/lifecycles/contextmanagers.py +1 -2
- omlish/lifecycles/controller.py +1 -2
- omlish/lite/abstract.py +54 -24
- omlish/lite/asyncs.py +146 -0
- omlish/lite/attrops.py +415 -0
- omlish/lite/cached.py +57 -1
- omlish/lite/contextmanagers.py +4 -4
- omlish/lite/dataclasses.py +55 -0
- omlish/lite/inject.py +5 -4
- omlish/lite/marshal.py +1 -0
- omlish/lite/maybes.py +10 -2
- omlish/lite/maysync.py +22 -5
- omlish/lite/pycharm.py +1 -1
- omlish/lite/strings.py +0 -7
- omlish/lite/timing.py +6 -3
- omlish/lite/typing.py +6 -0
- omlish/logs/_amalg.py +8 -0
- omlish/logs/all.py +59 -31
- omlish/logs/base.py +204 -0
- omlish/logs/contexts.py +171 -0
- omlish/logs/formatters.py +13 -0
- omlish/logs/infos.py +377 -0
- omlish/logs/levels.py +97 -0
- omlish/logs/modules.py +13 -0
- omlish/logs/protocols.py +32 -0
- omlish/logs/standard.py +20 -15
- omlish/logs/std/configs.py +29 -0
- omlish/logs/{filters.py → std/filters.py} +1 -1
- omlish/logs/std/formatters.py +25 -0
- omlish/logs/std/handlers.py +19 -0
- omlish/logs/{json.py → std/json.py} +2 -2
- omlish/logs/std/loggers.py +48 -0
- omlish/logs/{proxy.py → std/proxy.py} +3 -3
- omlish/logs/std/records.py +671 -0
- omlish/logs/typed/bindings.py +108 -37
- omlish/logs/typed/types.py +17 -1
- omlish/logs/typed/values.py +2 -2
- omlish/logs/utils.py +60 -4
- omlish/logs/warnings.py +8 -0
- omlish/manifests/loading.py +8 -1
- omlish/marshal/__init__.py +54 -22
- omlish/marshal/_dataclasses.py +2774 -0
- omlish/marshal/base/configs.py +12 -0
- omlish/marshal/base/contexts.py +36 -21
- omlish/marshal/base/funcs.py +8 -11
- omlish/marshal/base/options.py +8 -0
- omlish/marshal/base/registries.py +146 -44
- omlish/marshal/base/types.py +40 -16
- omlish/marshal/composite/iterables.py +33 -20
- omlish/marshal/composite/literals.py +20 -18
- omlish/marshal/composite/mappings.py +36 -23
- omlish/marshal/composite/maybes.py +29 -19
- omlish/marshal/composite/newtypes.py +16 -16
- omlish/marshal/composite/optionals.py +14 -14
- omlish/marshal/composite/special.py +15 -15
- omlish/marshal/composite/unions/literals.py +93 -0
- omlish/marshal/composite/unions/primitives.py +103 -0
- omlish/marshal/factories/invalidate.py +18 -68
- omlish/marshal/factories/method.py +26 -0
- omlish/marshal/factories/moduleimport/factories.py +22 -65
- omlish/marshal/factories/multi.py +13 -25
- omlish/marshal/factories/recursive.py +42 -56
- omlish/marshal/factories/typecache.py +29 -74
- omlish/marshal/factories/typemap.py +42 -43
- omlish/marshal/objects/dataclasses.py +129 -106
- omlish/marshal/objects/marshal.py +18 -14
- omlish/marshal/objects/namedtuples.py +48 -42
- omlish/marshal/objects/unmarshal.py +19 -15
- omlish/marshal/polymorphism/marshal.py +9 -11
- omlish/marshal/polymorphism/metadata.py +16 -5
- omlish/marshal/polymorphism/standard.py +13 -1
- omlish/marshal/polymorphism/unions.py +15 -105
- omlish/marshal/polymorphism/unmarshal.py +9 -10
- omlish/marshal/singular/enums.py +14 -18
- omlish/marshal/standard.py +10 -6
- omlish/marshal/trivial/any.py +1 -1
- omlish/marshal/trivial/forbidden.py +21 -26
- omlish/math/fixed.py +2 -2
- omlish/metadata.py +23 -1
- omlish/os/atomics.py +2 -2
- omlish/os/forkhooks.py +4 -0
- omlish/os/journald.py +3 -3
- omlish/os/pidfiles/pinning.py +2 -2
- omlish/reflect/ops.py +9 -0
- omlish/reflect/types.py +44 -8
- omlish/secrets/marshal.py +1 -1
- omlish/secrets/secrets.py +6 -3
- omlish/sockets/addresses.py +1 -1
- omlish/sockets/server/handlers.py +2 -2
- omlish/sockets/server/server.py +4 -3
- omlish/sockets/server/ssl.py +2 -2
- omlish/specs/jmespath/__init__.py +12 -3
- omlish/specs/jmespath/_dataclasses.py +2893 -0
- omlish/specs/jmespath/ast.py +1 -1
- omlish/specs/jsonrpc/__init__.py +13 -0
- omlish/specs/jsonrpc/_marshal.py +32 -23
- omlish/specs/jsonrpc/conns.py +10 -7
- omlish/specs/jsonschema/_marshal.py +1 -1
- omlish/specs/jsonschema/keywords/__init__.py +7 -0
- omlish/specs/jsonschema/keywords/_dataclasses.py +1644 -0
- omlish/specs/openapi/_marshal.py +31 -22
- omlish/sql/__init__.py +15 -20
- omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
- omlish/sql/queries/_marshal.py +3 -3
- omlish/sql/queries/params.py +1 -1
- omlish/sql/queries/rendering.py +1 -1
- omlish/sql/tabledefs/_marshal.py +1 -1
- omlish/subprocesses/all.py +135 -0
- omlish/subprocesses/base.py +8 -3
- omlish/subprocesses/editor.py +1 -1
- omlish/sync.py +181 -20
- omlish/term/alt.py +60 -0
- omlish/term/confirm.py +8 -8
- omlish/term/pager.py +235 -0
- omlish/term/terminfo.py +935 -0
- omlish/term/termstate.py +67 -0
- omlish/term/vt100/terminal.py +0 -3
- omlish/testing/pytest/plugins/asyncs/fixtures.py +4 -1
- omlish/testing/pytest/plugins/skips.py +2 -5
- omlish/testing/unittest/main.py +3 -3
- omlish/text/docwrap/__init__.py +3 -0
- omlish/text/docwrap/__main__.py +11 -0
- omlish/text/docwrap/api.py +83 -0
- omlish/text/docwrap/cli.py +86 -0
- omlish/text/docwrap/groups.py +84 -0
- omlish/text/docwrap/lists.py +167 -0
- omlish/text/docwrap/parts.py +146 -0
- omlish/text/docwrap/reflowing.py +106 -0
- omlish/text/docwrap/rendering.py +151 -0
- omlish/text/docwrap/utils.py +11 -0
- omlish/text/docwrap/wrapping.py +59 -0
- omlish/text/filecache.py +2 -2
- omlish/text/lorem.py +6 -0
- omlish/text/parts.py +2 -2
- omlish/text/textwrap.py +51 -0
- omlish/typedvalues/__init__.py +1 -1
- omlish/typedvalues/marshal.py +85 -59
- omlish/typedvalues/values.py +2 -1
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/METADATA +36 -38
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/RECORD +323 -385
- omlish/asyncs/bluelet/LICENSE +0 -6
- omlish/asyncs/bluelet/all.py +0 -67
- omlish/asyncs/bluelet/api.py +0 -23
- omlish/asyncs/bluelet/core.py +0 -178
- omlish/asyncs/bluelet/events.py +0 -79
- omlish/asyncs/bluelet/files.py +0 -80
- omlish/asyncs/bluelet/runner.py +0 -417
- omlish/asyncs/bluelet/sockets.py +0 -216
- omlish/asyncs/bridge.py +0 -359
- omlish/asyncs/utils.py +0 -18
- omlish/dataclasses/impl/generation/mangling.py +0 -18
- omlish/defs.py +0 -216
- omlish/dispatch/_dispatch2.py +0 -69
- omlish/dispatch/_dispatch3.py +0 -108
- omlish/dynamic.py +0 -219
- omlish/formats/json/Json.g4 +0 -77
- omlish/formats/json/_antlr/JsonLexer.py +0 -109
- omlish/formats/json/_antlr/JsonListener.py +0 -61
- omlish/formats/json/_antlr/JsonParser.py +0 -457
- omlish/formats/json/_antlr/JsonVisitor.py +0 -42
- omlish/formats/json5/Json5.g4 +0 -168
- omlish/formats/json5/_antlr/Json5Lexer.py +0 -354
- omlish/formats/json5/_antlr/Json5Listener.py +0 -79
- omlish/formats/json5/_antlr/Json5Parser.py +0 -617
- omlish/formats/json5/_antlr/Json5Visitor.py +0 -52
- omlish/funcs/match.py +0 -227
- omlish/io/trampoline.py +0 -289
- omlish/lang/imports/proxyinit.py +0 -665
- omlish/lite/logs.py +0 -4
- omlish/lite/reprs.py +0 -85
- omlish/logs/abc.py +0 -319
- omlish/logs/callers.py +0 -67
- omlish/logs/color.py +0 -27
- omlish/logs/configs.py +0 -29
- omlish/logs/handlers.py +0 -17
- omlish/logs/protocol.py +0 -218
- omlish/logs/timing.py +0 -58
- omlish/marshal/factories/match.py +0 -34
- omlish/marshal/factories/simple.py +0 -28
- omlish/specs/irc/messages/base.py +0 -49
- omlish/specs/irc/messages/formats.py +0 -92
- omlish/specs/irc/messages/messages.py +0 -774
- omlish/specs/irc/messages/parsing.py +0 -98
- omlish/specs/irc/numerics/formats.py +0 -97
- omlish/specs/irc/numerics/numerics.py +0 -865
- omlish/specs/irc/numerics/types.py +0 -59
- omlish/specs/irc/protocol/LICENSE +0 -11
- omlish/specs/irc/protocol/__init__.py +0 -61
- omlish/specs/irc/protocol/consts.py +0 -6
- omlish/specs/irc/protocol/errors.py +0 -30
- omlish/specs/irc/protocol/message.py +0 -21
- omlish/specs/irc/protocol/nuh.py +0 -55
- omlish/specs/irc/protocol/parsing.py +0 -158
- omlish/specs/irc/protocol/rendering.py +0 -153
- omlish/specs/irc/protocol/tags.py +0 -102
- omlish/specs/irc/protocol/utils.py +0 -30
- omlish/specs/proto/Protobuf3.g4 +0 -396
- omlish/specs/proto/__init__.py +0 -0
- omlish/specs/proto/_antlr/Protobuf3Lexer.py +0 -340
- omlish/specs/proto/_antlr/Protobuf3Listener.py +0 -448
- omlish/specs/proto/_antlr/Protobuf3Parser.py +0 -3909
- omlish/specs/proto/_antlr/Protobuf3Visitor.py +0 -257
- omlish/specs/proto/_antlr/__init__.py +0 -0
- omlish/specs/proto/nodes.py +0 -54
- omlish/specs/proto/parsing.py +0 -97
- omlish/sql/parsing/Minisql.g4 +0 -292
- omlish/sql/parsing/__init__.py +0 -0
- omlish/sql/parsing/_antlr/MinisqlLexer.py +0 -322
- omlish/sql/parsing/_antlr/MinisqlListener.py +0 -511
- omlish/sql/parsing/_antlr/MinisqlParser.py +0 -3763
- omlish/sql/parsing/_antlr/MinisqlVisitor.py +0 -292
- omlish/sql/parsing/_antlr/__init__.py +0 -0
- omlish/sql/parsing/parsing.py +0 -119
- omlish/text/antlr/__init__.py +0 -3
- omlish/text/antlr/_runtime/BufferedTokenStream.py +0 -305
- omlish/text/antlr/_runtime/CommonTokenFactory.py +0 -64
- omlish/text/antlr/_runtime/CommonTokenStream.py +0 -90
- omlish/text/antlr/_runtime/FileStream.py +0 -30
- omlish/text/antlr/_runtime/InputStream.py +0 -90
- omlish/text/antlr/_runtime/IntervalSet.py +0 -183
- omlish/text/antlr/_runtime/LICENSE.txt +0 -28
- omlish/text/antlr/_runtime/LL1Analyzer.py +0 -176
- omlish/text/antlr/_runtime/Lexer.py +0 -332
- omlish/text/antlr/_runtime/ListTokenSource.py +0 -147
- omlish/text/antlr/_runtime/Parser.py +0 -583
- omlish/text/antlr/_runtime/ParserInterpreter.py +0 -173
- omlish/text/antlr/_runtime/ParserRuleContext.py +0 -189
- omlish/text/antlr/_runtime/PredictionContext.py +0 -632
- omlish/text/antlr/_runtime/Recognizer.py +0 -150
- omlish/text/antlr/_runtime/RuleContext.py +0 -230
- omlish/text/antlr/_runtime/StdinStream.py +0 -14
- omlish/text/antlr/_runtime/Token.py +0 -158
- omlish/text/antlr/_runtime/TokenStreamRewriter.py +0 -258
- omlish/text/antlr/_runtime/Utils.py +0 -36
- omlish/text/antlr/_runtime/__init__.py +0 -2
- omlish/text/antlr/_runtime/_all.py +0 -24
- omlish/text/antlr/_runtime/_pygrun.py +0 -174
- omlish/text/antlr/_runtime/atn/ATN.py +0 -135
- omlish/text/antlr/_runtime/atn/ATNConfig.py +0 -162
- omlish/text/antlr/_runtime/atn/ATNConfigSet.py +0 -215
- omlish/text/antlr/_runtime/atn/ATNDeserializationOptions.py +0 -27
- omlish/text/antlr/_runtime/atn/ATNDeserializer.py +0 -449
- omlish/text/antlr/_runtime/atn/ATNSimulator.py +0 -50
- omlish/text/antlr/_runtime/atn/ATNState.py +0 -267
- omlish/text/antlr/_runtime/atn/ATNType.py +0 -20
- omlish/text/antlr/_runtime/atn/LexerATNSimulator.py +0 -573
- omlish/text/antlr/_runtime/atn/LexerAction.py +0 -301
- omlish/text/antlr/_runtime/atn/LexerActionExecutor.py +0 -146
- omlish/text/antlr/_runtime/atn/ParserATNSimulator.py +0 -1664
- omlish/text/antlr/_runtime/atn/PredictionMode.py +0 -502
- omlish/text/antlr/_runtime/atn/SemanticContext.py +0 -333
- omlish/text/antlr/_runtime/atn/Transition.py +0 -271
- omlish/text/antlr/_runtime/atn/__init__.py +0 -4
- omlish/text/antlr/_runtime/dfa/DFA.py +0 -136
- omlish/text/antlr/_runtime/dfa/DFASerializer.py +0 -76
- omlish/text/antlr/_runtime/dfa/DFAState.py +0 -129
- omlish/text/antlr/_runtime/dfa/__init__.py +0 -4
- omlish/text/antlr/_runtime/error/DiagnosticErrorListener.py +0 -111
- omlish/text/antlr/_runtime/error/ErrorListener.py +0 -75
- omlish/text/antlr/_runtime/error/ErrorStrategy.py +0 -712
- omlish/text/antlr/_runtime/error/Errors.py +0 -176
- omlish/text/antlr/_runtime/error/__init__.py +0 -4
- omlish/text/antlr/_runtime/tree/Chunk.py +0 -33
- omlish/text/antlr/_runtime/tree/ParseTreeMatch.py +0 -121
- omlish/text/antlr/_runtime/tree/ParseTreePattern.py +0 -75
- omlish/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +0 -377
- omlish/text/antlr/_runtime/tree/RuleTagToken.py +0 -53
- omlish/text/antlr/_runtime/tree/TokenTagToken.py +0 -50
- omlish/text/antlr/_runtime/tree/Tree.py +0 -194
- omlish/text/antlr/_runtime/tree/Trees.py +0 -114
- omlish/text/antlr/_runtime/tree/__init__.py +0 -2
- omlish/text/antlr/_runtime/xpath/XPath.py +0 -278
- omlish/text/antlr/_runtime/xpath/XPathLexer.py +0 -98
- omlish/text/antlr/_runtime/xpath/__init__.py +0 -4
- omlish/text/antlr/delimit.py +0 -109
- omlish/text/antlr/dot.py +0 -41
- omlish/text/antlr/errors.py +0 -14
- omlish/text/antlr/input.py +0 -96
- omlish/text/antlr/parsing.py +0 -54
- omlish/text/antlr/runtime.py +0 -102
- omlish/text/antlr/utils.py +0 -38
- /omlish/{asyncs/bluelet → cexts}/__init__.py +0 -0
- /omlish/{formats/json/_antlr → diag/cmds}/__init__.py +0 -0
- /omlish/{formats/json5/_antlr → http/clients/coro}/__init__.py +0 -0
- /omlish/{specs/irc → inject/helpers}/__init__.py +0 -0
- /omlish/{specs/irc/messages → logs/std}/__init__.py +0 -0
- /omlish/logs/{noisy.py → std/noisy.py} +0 -0
- /omlish/{specs/irc/numerics → marshal/composite/unions}/__init__.py +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/top_level.txt +0 -0
omlish/http/clients/base.py
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
# ruff: noqa: UP006 UP007 UP045
|
|
2
|
+
# @omlish-lite
|
|
1
3
|
"""
|
|
2
4
|
TODO:
|
|
5
|
+
- ?? lite ?? whole point is an async client in lite code
|
|
3
6
|
- stream
|
|
4
7
|
- chunk size - httpx interface is awful, punch through?
|
|
5
8
|
- httpx catch
|
|
6
9
|
- return non-200 HttpResponses
|
|
7
10
|
- async
|
|
8
11
|
"""
|
|
9
|
-
import
|
|
10
|
-
import contextlib
|
|
12
|
+
import dataclasses as dc
|
|
11
13
|
import typing as ta
|
|
12
14
|
|
|
13
|
-
from ... import
|
|
14
|
-
from ... import
|
|
15
|
-
from ... import
|
|
15
|
+
from ...lite.abstract import Abstract
|
|
16
|
+
from ...lite.attrops import AttrOps
|
|
17
|
+
from ...lite.cached import cached_property
|
|
16
18
|
from ..headers import CanHttpHeaders
|
|
17
19
|
from ..headers import HttpHeaders
|
|
18
20
|
|
|
@@ -33,17 +35,28 @@ def is_success_status(status: int) -> bool:
|
|
|
33
35
|
##
|
|
34
36
|
|
|
35
37
|
|
|
38
|
+
@ta.final
|
|
36
39
|
@dc.dataclass(frozen=True)
|
|
37
|
-
class HttpRequest
|
|
40
|
+
class HttpRequest:
|
|
38
41
|
url: str
|
|
39
|
-
method: str
|
|
42
|
+
method: ta.Optional[str] = None # noqa
|
|
40
43
|
|
|
41
|
-
_: dc.KW_ONLY
|
|
44
|
+
# _: dc.KW_ONLY
|
|
42
45
|
|
|
43
|
-
headers: CanHttpHeaders
|
|
44
|
-
data: bytes
|
|
46
|
+
headers: ta.Optional[CanHttpHeaders] = None
|
|
47
|
+
data: ta.Union[bytes, str, None] = None
|
|
45
48
|
|
|
46
|
-
timeout_s: float
|
|
49
|
+
timeout_s: ta.Optional[float] = None
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
|
|
53
|
+
__repr__ = AttrOps['HttpRequest'](lambda o: (
|
|
54
|
+
o.url,
|
|
55
|
+
o.method,
|
|
56
|
+
(o.headers, dict(repr_fn=AttrOps.truthy_repr)),
|
|
57
|
+
(o.data, dict(repr_fn=lambda v: '...' if v is not None else None)),
|
|
58
|
+
(o.timeout_s, dict(repr_fn=AttrOps.opt_repr)),
|
|
59
|
+
)).repr
|
|
47
60
|
|
|
48
61
|
#
|
|
49
62
|
|
|
@@ -55,151 +68,79 @@ class HttpRequest(lang.Final):
|
|
|
55
68
|
return 'POST'
|
|
56
69
|
return 'GET'
|
|
57
70
|
|
|
58
|
-
@
|
|
59
|
-
def headers_(self) -> HttpHeaders
|
|
71
|
+
@cached_property
|
|
72
|
+
def headers_(self) -> ta.Optional[HttpHeaders]:
|
|
60
73
|
return HttpHeaders(self.headers) if self.headers is not None else None
|
|
61
74
|
|
|
62
75
|
|
|
63
76
|
#
|
|
64
77
|
|
|
65
78
|
|
|
66
|
-
@dc.dataclass(frozen=True
|
|
67
|
-
class BaseHttpResponse(
|
|
68
|
-
status: int
|
|
69
|
-
|
|
70
|
-
headers: HttpHeaders | None = dc.xfield(None, repr=dc.truthy_repr)
|
|
71
|
-
|
|
79
|
+
@dc.dataclass(frozen=True) # kw_only=True
|
|
80
|
+
class BaseHttpResponse(Abstract):
|
|
72
81
|
request: HttpRequest
|
|
73
|
-
underlying: ta.Any = dc.field(default=None, repr=False)
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def is_success(self) -> bool:
|
|
77
|
-
return is_success_status(self.status)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
@dc.dataclass(frozen=True, kw_only=True)
|
|
81
|
-
class HttpResponse(BaseHttpResponse, lang.Final):
|
|
82
|
-
data: bytes | None = dc.xfield(None, repr_fn=lambda v: '...' if v is not None else None)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
@dc.dataclass(frozen=True, kw_only=True)
|
|
86
|
-
class StreamHttpResponse(BaseHttpResponse, lang.Final):
|
|
87
|
-
class Stream(ta.Protocol):
|
|
88
|
-
def read(self, /, n: int = -1) -> bytes: ...
|
|
89
|
-
|
|
90
|
-
stream: Stream
|
|
91
82
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def __enter__(self) -> ta.Self:
|
|
95
|
-
return self
|
|
83
|
+
status: int
|
|
96
84
|
|
|
97
|
-
|
|
98
|
-
self.close()
|
|
85
|
+
headers: ta.Optional[HttpHeaders] = None
|
|
99
86
|
|
|
100
|
-
|
|
101
|
-
if (c := self._closer) is not None:
|
|
102
|
-
c()
|
|
87
|
+
underlying: ta.Any = None
|
|
103
88
|
|
|
89
|
+
#
|
|
104
90
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
__repr__ = AttrOps['BaseHttpResponse'](lambda o: (
|
|
92
|
+
o.status,
|
|
93
|
+
(o.headers, dict(repr_fn=AttrOps.truthy_repr)),
|
|
94
|
+
o.request,
|
|
95
|
+
)).repr
|
|
108
96
|
|
|
109
|
-
|
|
110
|
-
resp.close()
|
|
97
|
+
#
|
|
111
98
|
|
|
112
|
-
|
|
113
|
-
|
|
99
|
+
@property
|
|
100
|
+
def is_success(self) -> bool:
|
|
101
|
+
return is_success_status(self.status)
|
|
114
102
|
|
|
115
103
|
|
|
116
|
-
@
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return
|
|
104
|
+
@ta.final
|
|
105
|
+
@dc.dataclass(frozen=True) # kw_only=True
|
|
106
|
+
class HttpResponse(BaseHttpResponse):
|
|
107
|
+
data: ta.Optional[bytes] = None
|
|
121
108
|
|
|
122
|
-
|
|
123
|
-
with contextlib.closing(resp):
|
|
124
|
-
yield resp
|
|
109
|
+
#
|
|
125
110
|
|
|
126
|
-
|
|
127
|
-
|
|
111
|
+
__repr__ = AttrOps['HttpResponse'](lambda o: (
|
|
112
|
+
o.status,
|
|
113
|
+
(o.headers, dict(repr_fn=AttrOps.truthy_repr)),
|
|
114
|
+
(o.data, dict(repr_fn=lambda v: '...' if v is not None else None)),
|
|
115
|
+
o.request,
|
|
116
|
+
)).repr
|
|
128
117
|
|
|
129
118
|
|
|
130
|
-
|
|
131
|
-
if isinstance(resp, HttpResponse):
|
|
132
|
-
return resp
|
|
119
|
+
##
|
|
133
120
|
|
|
134
|
-
elif isinstance(resp, StreamHttpResponse):
|
|
135
|
-
data = resp.stream.read()
|
|
136
|
-
return HttpResponse(**{
|
|
137
|
-
**{k: v for k, v in dc.shallow_asdict(resp).items() if k not in ('stream', '_closer')},
|
|
138
|
-
'data': data,
|
|
139
|
-
})
|
|
140
121
|
|
|
141
|
-
|
|
142
|
-
|
|
122
|
+
@ta.final
|
|
123
|
+
class HttpClientContext:
|
|
124
|
+
def __init__(self) -> None:
|
|
125
|
+
self._dct: dict = {}
|
|
143
126
|
|
|
144
127
|
|
|
145
|
-
|
|
128
|
+
##
|
|
146
129
|
|
|
147
130
|
|
|
148
131
|
class HttpClientError(Exception):
|
|
149
132
|
@property
|
|
150
|
-
def cause(self) -> BaseException
|
|
133
|
+
def cause(self) -> ta.Optional[BaseException]:
|
|
151
134
|
return self.__cause__
|
|
152
135
|
|
|
153
136
|
|
|
154
|
-
@dc.dataclass(
|
|
137
|
+
@dc.dataclass()
|
|
155
138
|
class HttpStatusError(HttpClientError):
|
|
156
139
|
response: HttpResponse
|
|
157
140
|
|
|
158
141
|
|
|
159
|
-
|
|
142
|
+
##
|
|
160
143
|
|
|
161
144
|
|
|
162
|
-
class
|
|
163
|
-
|
|
164
|
-
return self
|
|
165
|
-
|
|
166
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
167
|
-
pass
|
|
168
|
-
|
|
169
|
-
def request(
|
|
170
|
-
self,
|
|
171
|
-
req: HttpRequest,
|
|
172
|
-
*,
|
|
173
|
-
check: bool = False,
|
|
174
|
-
) -> HttpResponse:
|
|
175
|
-
with closing_response(self.stream_request(
|
|
176
|
-
req,
|
|
177
|
-
check=check,
|
|
178
|
-
)) as resp:
|
|
179
|
-
return read_response(resp)
|
|
180
|
-
|
|
181
|
-
def stream_request(
|
|
182
|
-
self,
|
|
183
|
-
req: HttpRequest,
|
|
184
|
-
*,
|
|
185
|
-
check: bool = False,
|
|
186
|
-
) -> StreamHttpResponse:
|
|
187
|
-
resp = self._stream_request(req)
|
|
188
|
-
|
|
189
|
-
try:
|
|
190
|
-
if check and not resp.is_success:
|
|
191
|
-
if isinstance(resp.underlying, Exception):
|
|
192
|
-
cause = resp.underlying
|
|
193
|
-
else:
|
|
194
|
-
cause = None
|
|
195
|
-
raise HttpStatusError(read_response(resp)) from cause # noqa
|
|
196
|
-
|
|
197
|
-
except Exception:
|
|
198
|
-
close_response(resp)
|
|
199
|
-
raise
|
|
200
|
-
|
|
201
|
-
return resp
|
|
202
|
-
|
|
203
|
-
@abc.abstractmethod
|
|
204
|
-
def _stream_request(self, req: HttpRequest) -> StreamHttpResponse:
|
|
205
|
-
raise NotImplementedError
|
|
145
|
+
class BaseHttpClient(Abstract):
|
|
146
|
+
pass
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# @omlish-lite
|
|
2
|
+
# ruff: noqa: UP045
|
|
3
|
+
import errno
|
|
4
|
+
import socket
|
|
5
|
+
import typing as ta
|
|
6
|
+
import urllib.parse
|
|
7
|
+
|
|
8
|
+
from ....io.buffers import ReadableListBuffer
|
|
9
|
+
from ....lite.check import check
|
|
10
|
+
from ...coro.client.connection import CoroHttpClientConnection
|
|
11
|
+
from ...coro.client.response import CoroHttpClientResponse
|
|
12
|
+
from ...coro.io import CoroHttpIo
|
|
13
|
+
from ...headers import HttpHeaders
|
|
14
|
+
from ...urls import unparse_url_request_path
|
|
15
|
+
from ..base import HttpClientContext
|
|
16
|
+
from ..base import HttpClientError
|
|
17
|
+
from ..base import HttpRequest
|
|
18
|
+
from ..sync import HttpClient
|
|
19
|
+
from ..sync import StreamHttpResponse
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
T = ta.TypeVar('T')
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CoroHttpClient(HttpClient):
|
|
29
|
+
class _Connection:
|
|
30
|
+
def __init__(self, req: HttpRequest) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
|
|
33
|
+
self._req = req
|
|
34
|
+
self._ups = urllib.parse.urlparse(req.url)
|
|
35
|
+
|
|
36
|
+
self._ssl = self._ups.scheme == 'https'
|
|
37
|
+
|
|
38
|
+
_cc: ta.Optional[CoroHttpClientConnection] = None
|
|
39
|
+
_resp: ta.Optional[CoroHttpClientResponse] = None
|
|
40
|
+
|
|
41
|
+
_sock: ta.Optional[socket.socket] = None
|
|
42
|
+
_sock_file: ta.Optional[ta.BinaryIO] = None
|
|
43
|
+
|
|
44
|
+
_ssl_context: ta.Any = None
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
|
|
48
|
+
def _create_https_context(self, http_version: int) -> ta.Any:
|
|
49
|
+
# https://github.com/python/cpython/blob/a7160912274003672dc116d918260c0a81551c21/Lib/http/client.py#L809
|
|
50
|
+
import ssl
|
|
51
|
+
|
|
52
|
+
# Function also used by urllib.request to be able to set the check_hostname attribute on a context object.
|
|
53
|
+
context = ssl.create_default_context()
|
|
54
|
+
|
|
55
|
+
# Send ALPN extension to indicate HTTP/1.1 protocol.
|
|
56
|
+
if http_version == 11:
|
|
57
|
+
context.set_alpn_protocols(['http/1.1'])
|
|
58
|
+
|
|
59
|
+
# Enable PHA for TLS 1.3 connections if available.
|
|
60
|
+
if context.post_handshake_auth is not None:
|
|
61
|
+
context.post_handshake_auth = True
|
|
62
|
+
|
|
63
|
+
return context
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
|
|
67
|
+
def setup(self) -> StreamHttpResponse:
|
|
68
|
+
check.none(self._sock)
|
|
69
|
+
check.none(self._ssl_context)
|
|
70
|
+
|
|
71
|
+
self._cc = cc = CoroHttpClientConnection(
|
|
72
|
+
check.not_none(self._ups.hostname),
|
|
73
|
+
default_port=CoroHttpClientConnection.HTTPS_PORT if self._ssl else CoroHttpClientConnection.HTTP_PORT,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if self._ssl:
|
|
77
|
+
self._ssl_context = self._create_https_context(self._cc.http_version)
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
self._run_coro(cc.connect())
|
|
81
|
+
|
|
82
|
+
self._run_coro(cc.request(
|
|
83
|
+
self._req.method or 'GET',
|
|
84
|
+
unparse_url_request_path(self._ups) or '/',
|
|
85
|
+
self._req.data,
|
|
86
|
+
hh.single_str_dct if (hh := self._req.headers_) is not None else {},
|
|
87
|
+
))
|
|
88
|
+
|
|
89
|
+
self._resp = resp = self._run_coro(cc.get_response())
|
|
90
|
+
|
|
91
|
+
return StreamHttpResponse(
|
|
92
|
+
status=resp._state.status, # noqa
|
|
93
|
+
headers=HttpHeaders(resp._state.headers.items()), # noqa
|
|
94
|
+
request=self._req,
|
|
95
|
+
underlying=self,
|
|
96
|
+
_stream=ReadableListBuffer().new_buffered_reader(self),
|
|
97
|
+
_closer=self.close,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
except Exception:
|
|
101
|
+
self.close()
|
|
102
|
+
raise
|
|
103
|
+
|
|
104
|
+
def _run_coro(self, g: ta.Generator[ta.Any, ta.Any, T]) -> T:
|
|
105
|
+
i = None
|
|
106
|
+
|
|
107
|
+
while True:
|
|
108
|
+
try:
|
|
109
|
+
o = g.send(i)
|
|
110
|
+
except StopIteration as e:
|
|
111
|
+
return e.value
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
i = self._handle_io(o)
|
|
115
|
+
except OSError as e:
|
|
116
|
+
raise HttpClientError from e
|
|
117
|
+
|
|
118
|
+
def _handle_io(self, o: CoroHttpIo.Io) -> ta.Any:
|
|
119
|
+
if isinstance(o, CoroHttpIo.ConnectIo):
|
|
120
|
+
check.none(self._sock)
|
|
121
|
+
self._sock = socket.create_connection(*o.args, **(o.kwargs or {}))
|
|
122
|
+
|
|
123
|
+
if self._ssl_context is not None:
|
|
124
|
+
self._sock = self._ssl_context.wrap_socket(
|
|
125
|
+
self._sock,
|
|
126
|
+
server_hostname=check.not_none(o.server_hostname),
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Might fail in OSs that don't implement TCP_NODELAY
|
|
130
|
+
try:
|
|
131
|
+
self._sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
132
|
+
except OSError as e:
|
|
133
|
+
if e.errno != errno.ENOPROTOOPT:
|
|
134
|
+
raise
|
|
135
|
+
|
|
136
|
+
self._sock_file = self._sock.makefile('rb')
|
|
137
|
+
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
elif isinstance(o, CoroHttpIo.CloseIo):
|
|
141
|
+
check.not_none(self._sock).close()
|
|
142
|
+
return None
|
|
143
|
+
|
|
144
|
+
elif isinstance(o, CoroHttpIo.WriteIo):
|
|
145
|
+
check.not_none(self._sock).sendall(o.data)
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
elif isinstance(o, CoroHttpIo.ReadIo):
|
|
149
|
+
if (sz := o.sz) is not None:
|
|
150
|
+
return check.not_none(self._sock_file).read(sz)
|
|
151
|
+
else:
|
|
152
|
+
return check.not_none(self._sock_file).read()
|
|
153
|
+
|
|
154
|
+
elif isinstance(o, CoroHttpIo.ReadLineIo):
|
|
155
|
+
return check.not_none(self._sock_file).readline(o.sz)
|
|
156
|
+
|
|
157
|
+
else:
|
|
158
|
+
raise TypeError(o)
|
|
159
|
+
|
|
160
|
+
def read1(self, n: int = -1, /) -> bytes:
|
|
161
|
+
return self._run_coro(check.not_none(self._resp).read(n if n >= 0 else None))
|
|
162
|
+
|
|
163
|
+
def close(self) -> None:
|
|
164
|
+
if self._resp is not None:
|
|
165
|
+
self._resp.close()
|
|
166
|
+
if self._sock is not None:
|
|
167
|
+
self._sock.close()
|
|
168
|
+
|
|
169
|
+
def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
|
|
170
|
+
conn = CoroHttpClient._Connection(req)
|
|
171
|
+
return conn.setup()
|
omlish/http/clients/default.py
CHANGED
|
@@ -1,60 +1,239 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import contextlib
|
|
1
3
|
import typing as ta
|
|
2
4
|
|
|
5
|
+
from ... import lang
|
|
3
6
|
from ..headers import CanHttpHeaders
|
|
4
|
-
from .
|
|
7
|
+
from .asyncs import AsyncHttpClient
|
|
8
|
+
from .base import HttpClientContext
|
|
5
9
|
from .base import HttpRequest
|
|
6
10
|
from .base import HttpResponse
|
|
7
|
-
from .
|
|
11
|
+
from .sync import HttpClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
with lang.auto_proxy_import(globals()):
|
|
15
|
+
from . import httpx as _httpx
|
|
16
|
+
from . import urllib as _urllib
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
C = ta.TypeVar('C')
|
|
20
|
+
R = ta.TypeVar('R')
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class _DefaultRequester(lang.Abstract, ta.Generic[C, R]):
|
|
27
|
+
def __call__(
|
|
28
|
+
self,
|
|
29
|
+
url: str,
|
|
30
|
+
method: str | None = None,
|
|
31
|
+
*,
|
|
32
|
+
headers: CanHttpHeaders | None = None,
|
|
33
|
+
data: bytes | str | None = None,
|
|
34
|
+
|
|
35
|
+
timeout_s: float | None = None,
|
|
36
|
+
|
|
37
|
+
context: HttpClientContext | None = None,
|
|
38
|
+
check: bool = False,
|
|
39
|
+
client: C | None = None, # noqa
|
|
40
|
+
|
|
41
|
+
**kwargs: ta.Any,
|
|
42
|
+
) -> R:
|
|
43
|
+
request = HttpRequest( # noqa
|
|
44
|
+
url,
|
|
45
|
+
method=method,
|
|
46
|
+
|
|
47
|
+
headers=headers,
|
|
48
|
+
data=data,
|
|
49
|
+
|
|
50
|
+
timeout_s=timeout_s,
|
|
51
|
+
|
|
52
|
+
**kwargs,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return self._do(
|
|
56
|
+
request,
|
|
57
|
+
context=context,
|
|
58
|
+
check=check,
|
|
59
|
+
client=client,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@abc.abstractmethod
|
|
63
|
+
def _do(
|
|
64
|
+
self,
|
|
65
|
+
request: HttpRequest, # noqa
|
|
66
|
+
*,
|
|
67
|
+
context: HttpClientContext | None = None,
|
|
68
|
+
check: bool = False,
|
|
69
|
+
client: C | None = None, # noqa
|
|
70
|
+
) -> R:
|
|
71
|
+
raise NotImplementedError
|
|
8
72
|
|
|
9
73
|
|
|
10
74
|
##
|
|
11
75
|
|
|
12
76
|
|
|
13
77
|
def _default_client() -> HttpClient:
|
|
14
|
-
return UrllibHttpClient()
|
|
78
|
+
return _urllib.UrllibHttpClient()
|
|
15
79
|
|
|
16
80
|
|
|
17
81
|
def client() -> HttpClient:
|
|
18
82
|
return _default_client()
|
|
19
83
|
|
|
20
84
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
85
|
+
@contextlib.contextmanager
|
|
86
|
+
def manage_client(client: HttpClient | None = None) -> ta.Generator[HttpClient]: # noqa
|
|
87
|
+
if client is not None:
|
|
88
|
+
yield client
|
|
89
|
+
|
|
90
|
+
else:
|
|
91
|
+
with _default_client() as client: # noqa
|
|
92
|
+
yield client
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class _BaseSyncDefaultRequester(_DefaultRequester[HttpClient, R], lang.Abstract, ta.Generic[R]):
|
|
99
|
+
def _do(
|
|
100
|
+
self,
|
|
101
|
+
request: HttpRequest, # noqa
|
|
102
|
+
*,
|
|
103
|
+
context: HttpClientContext | None = None,
|
|
104
|
+
check: bool = False,
|
|
105
|
+
client: HttpClient | None = None, # noqa
|
|
106
|
+
) -> R:
|
|
107
|
+
if context is None:
|
|
108
|
+
context = HttpClientContext()
|
|
109
|
+
|
|
110
|
+
if client is not None:
|
|
111
|
+
return self._do_(
|
|
112
|
+
client,
|
|
113
|
+
context,
|
|
114
|
+
request,
|
|
115
|
+
check=check,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
else:
|
|
119
|
+
with _default_client() as client: # noqa
|
|
120
|
+
return self._do_(
|
|
121
|
+
client,
|
|
122
|
+
context,
|
|
123
|
+
request,
|
|
124
|
+
check=check,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
@abc.abstractmethod
|
|
128
|
+
def _do_(
|
|
129
|
+
self,
|
|
130
|
+
client: HttpClient, # noqa
|
|
131
|
+
context: HttpClientContext,
|
|
132
|
+
request: HttpRequest, # noqa
|
|
133
|
+
*,
|
|
134
|
+
check: bool = False, # noqa
|
|
135
|
+
) -> R:
|
|
136
|
+
raise NotImplementedError
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class _SyncDefaultRequester(_BaseSyncDefaultRequester[HttpResponse]):
|
|
140
|
+
def _do_(
|
|
141
|
+
self,
|
|
142
|
+
client: HttpClient, # noqa
|
|
143
|
+
context: HttpClientContext,
|
|
144
|
+
request: HttpRequest, # noqa
|
|
145
|
+
*,
|
|
146
|
+
check: bool = False, # noqa
|
|
147
|
+
) -> HttpResponse:
|
|
148
|
+
return client.request(
|
|
149
|
+
request,
|
|
150
|
+
context=context,
|
|
151
|
+
check=check,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
request = _SyncDefaultRequester()
|
|
27
156
|
|
|
28
|
-
timeout_s: float | None = None,
|
|
29
157
|
|
|
30
|
-
|
|
158
|
+
##
|
|
31
159
|
|
|
32
|
-
client: HttpClient | None = None, # noqa
|
|
33
160
|
|
|
34
|
-
|
|
35
|
-
)
|
|
36
|
-
req = HttpRequest(
|
|
37
|
-
url,
|
|
38
|
-
method=method,
|
|
161
|
+
def _default_async_client() -> AsyncHttpClient:
|
|
162
|
+
return _httpx.HttpxAsyncHttpClient()
|
|
39
163
|
|
|
40
|
-
headers=headers,
|
|
41
|
-
data=data,
|
|
42
164
|
|
|
43
|
-
|
|
165
|
+
def async_client() -> AsyncHttpClient:
|
|
166
|
+
return _default_async_client()
|
|
44
167
|
|
|
45
|
-
**kwargs,
|
|
46
|
-
)
|
|
47
168
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
169
|
+
@contextlib.asynccontextmanager
|
|
170
|
+
async def manage_async_client(client: AsyncHttpClient | None = None) -> ta.AsyncGenerator[AsyncHttpClient]: # noqa
|
|
171
|
+
if client is not None:
|
|
172
|
+
yield client
|
|
51
173
|
|
|
174
|
+
else:
|
|
175
|
+
async with _default_async_client() as client: # noqa
|
|
176
|
+
yield client
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
#
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class _BaseAsyncDefaultRequester(_DefaultRequester[AsyncHttpClient, ta.Awaitable[R]], lang.Abstract, ta.Generic[R]):
|
|
183
|
+
async def _do(
|
|
184
|
+
self,
|
|
185
|
+
request: HttpRequest, # noqa
|
|
186
|
+
*,
|
|
187
|
+
context: HttpClientContext | None = None,
|
|
188
|
+
check: bool = False,
|
|
189
|
+
client: AsyncHttpClient | None = None, # noqa
|
|
190
|
+
) -> R:
|
|
191
|
+
if context is None:
|
|
192
|
+
context = HttpClientContext()
|
|
193
|
+
|
|
194
|
+
if client is not None:
|
|
195
|
+
return await self._do_(
|
|
196
|
+
client,
|
|
197
|
+
context,
|
|
198
|
+
request,
|
|
199
|
+
check=check,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
else:
|
|
203
|
+
async with _default_async_client() as client: # noqa
|
|
204
|
+
return await self._do_(
|
|
205
|
+
client,
|
|
206
|
+
context,
|
|
207
|
+
request,
|
|
208
|
+
check=check,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
@abc.abstractmethod
|
|
212
|
+
def _do_(
|
|
213
|
+
self,
|
|
214
|
+
client: AsyncHttpClient, # noqa
|
|
215
|
+
context: HttpClientContext,
|
|
216
|
+
request: HttpRequest, # noqa
|
|
217
|
+
*,
|
|
218
|
+
check: bool = False, # noqa
|
|
219
|
+
) -> ta.Awaitable[R]:
|
|
220
|
+
raise NotImplementedError
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class _AsyncDefaultRequester(_BaseAsyncDefaultRequester[HttpResponse]):
|
|
224
|
+
async def _do_(
|
|
225
|
+
self,
|
|
226
|
+
client: AsyncHttpClient, # noqa
|
|
227
|
+
context: HttpClientContext,
|
|
228
|
+
request: HttpRequest, # noqa
|
|
229
|
+
*,
|
|
230
|
+
check: bool = False,
|
|
231
|
+
) -> HttpResponse: # noqa
|
|
232
|
+
return await client.request(
|
|
233
|
+
request,
|
|
234
|
+
context=context,
|
|
52
235
|
check=check,
|
|
53
236
|
)
|
|
54
237
|
|
|
55
|
-
if client is not None:
|
|
56
|
-
return do(client)
|
|
57
238
|
|
|
58
|
-
|
|
59
|
-
with _default_client() as cli:
|
|
60
|
-
return do(cli)
|
|
239
|
+
async_request = _AsyncDefaultRequester()
|