@voxgig/sdkgen 1.5.1 → 2.0.0
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.
- package/dist/cmp/AgentGuideContent.js +5 -0
- package/dist/cmp/AgentGuideContent.js.map +1 -1
- package/dist/cmp/Feature.js +13 -0
- package/dist/cmp/Feature.js.map +1 -1
- package/dist/helpers/canonType.d.ts +3 -1
- package/dist/helpers/canonType.js +44 -1
- package/dist/helpers/canonType.js.map +1 -1
- package/dist/helpers/packageMeta.js +7 -0
- package/dist/helpers/packageMeta.js.map +1 -1
- package/dist/sdkgen.d.ts +3 -3
- package/dist/sdkgen.js +4 -1
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/project/.sdk/model/feature/paging.aontu +7 -0
- package/project/.sdk/model/target/py-data.aontu +64 -0
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +89 -1
- package/project/.sdk/src/cmp/clojure/Main_clojure.ts +1 -0
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +97 -0
- package/project/.sdk/src/cmp/dart/fragment/Main.fragment.dart +78 -0
- package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +84 -0
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +87 -0
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +75 -0
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +85 -0
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +4 -0
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +80 -0
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +86 -0
- package/project/.sdk/src/cmp/py/Entity_py.ts +9 -2
- package/project/.sdk/src/cmp/py/MainEntity_py.ts +1 -1
- package/project/.sdk/src/cmp/py/Main_py.ts +34 -6
- package/project/.sdk/src/cmp/py/Package_py.ts +6 -9
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +2 -2
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +3 -3
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityCreateOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityLoadOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityRemoveOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityUpdateOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +75 -8
- package/project/.sdk/src/cmp/py-data/Main_py-data.ts +987 -0
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +71 -0
- package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +95 -0
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +86 -0
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +75 -0
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +95 -0
- package/project/.sdk/tm/c/core/sdk.h +7 -0
- package/project/.sdk/tm/c/feature/paging.c +141 -2
- package/project/.sdk/tm/c/utility/graphql.c +178 -0
- package/project/.sdk/tm/c/utility/make_options.c +1 -1
- package/project/.sdk/tm/c/utility/make_response.c +6 -0
- package/project/.sdk/tm/c/utility/make_spec.c +23 -3
- package/project/.sdk/tm/clojure/src/sdk/client.clj +64 -1
- package/project/.sdk/tm/clojure/src/sdk/core.clj +126 -3
- package/project/.sdk/tm/clojure/src/sdk/features.clj +80 -14
- package/project/.sdk/tm/cpp/core/types.hpp +83 -0
- package/project/.sdk/tm/cpp/feature/paging.hpp +103 -1
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +152 -3
- package/project/.sdk/tm/csharp/core/Utility.cs +4 -0
- package/project/.sdk/tm/csharp/feature/PagingFeature.cs +118 -1
- package/project/.sdk/tm/csharp/utility/Graphql.cs +190 -0
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +1 -1
- package/project/.sdk/tm/csharp/utility/MakeResponse.cs +7 -0
- package/project/.sdk/tm/csharp/utility/MakeSpec.cs +21 -2
- package/project/.sdk/tm/csharp/utility/Register.cs +2 -0
- package/project/.sdk/tm/dart/lib/Point.dart +7 -0
- package/project/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +99 -4
- package/project/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +162 -0
- package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +1 -1
- package/project/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +5 -0
- package/project/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +18 -2
- package/project/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +6 -1
- package/project/.sdk/tm/dart/lib/utility/Utility.dart +9 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/paging.ex +136 -13
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +187 -3
- package/project/.sdk/tm/go/core/utility_type.go +2 -0
- package/project/.sdk/tm/go/feature/paging_feature.go +87 -1
- package/project/.sdk/tm/go/utility/graphql.go +168 -0
- package/project/.sdk/tm/go/utility/make_options.go +1 -1
- package/project/.sdk/tm/go/utility/make_response.go +6 -0
- package/project/.sdk/tm/go/utility/make_spec.go +19 -2
- package/project/.sdk/tm/go/utility/register.go +2 -0
- package/project/.sdk/tm/haskell/src/SdkFeatures.hs +146 -7
- package/project/.sdk/tm/haskell/src/SdkRuntime.hs +153 -3
- package/project/.sdk/tm/java/core/SdkClient.java +93 -0
- package/project/.sdk/tm/java/core/Utility.java +4 -0
- package/project/.sdk/tm/java/feature/PagingFeature.java +100 -1
- package/project/.sdk/tm/java/utility/Graphql.java +191 -0
- package/project/.sdk/tm/java/utility/MakeOptions.java +1 -1
- package/project/.sdk/tm/java/utility/MakeResponse.java +6 -0
- package/project/.sdk/tm/java/utility/MakeSpec.java +17 -2
- package/project/.sdk/tm/java/utility/Register.java +2 -0
- package/project/.sdk/tm/js/src/Point.js +5 -0
- package/project/.sdk/tm/js/src/feature/paging/PagingFeature.js +82 -3
- package/project/.sdk/tm/js/src/feature/test/TestFeature.js +14 -2
- package/project/.sdk/tm/js/src/utility/GraphqlUtility.js +148 -0
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +1 -1
- package/project/.sdk/tm/js/src/utility/MakeResponseUtility.js +7 -0
- package/project/.sdk/tm/js/src/utility/MakeSpecUtility.js +19 -2
- package/project/.sdk/tm/js/src/utility/Utility.js +4 -0
- package/project/.sdk/tm/kotlin/core/SdkClient.kt +84 -0
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/feature/PagingFeature.kt +92 -1
- package/project/.sdk/tm/kotlin/utility/Graphql.kt +145 -0
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +1 -1
- package/project/.sdk/tm/kotlin/utility/MakeReqRes.kt +6 -0
- package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +17 -2
- package/project/.sdk/tm/kotlin/utility/Register.kt +2 -0
- package/project/.sdk/tm/lean/src/SdkUtility.lean +134 -1
- package/project/.sdk/tm/lua/feature/paging_feature.lua +97 -2
- package/project/.sdk/tm/lua/utility/graphql.lua +163 -0
- package/project/.sdk/tm/lua/utility/make_options.lua +1 -1
- package/project/.sdk/tm/lua/utility/make_response.lua +6 -0
- package/project/.sdk/tm/lua/utility/make_spec.lua +18 -2
- package/project/.sdk/tm/lua/utility/register.lua +3 -0
- package/project/.sdk/tm/ocaml/sdk_features.ml +164 -20
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +143 -4
- package/project/.sdk/tm/ocaml/sdk_types.ml +2 -0
- package/project/.sdk/tm/perl/feature/paging_feature.pm +91 -3
- package/project/.sdk/tm/perl/utility/graphql.pm +150 -0
- package/project/.sdk/tm/perl/utility/make_options.pm +1 -1
- package/project/.sdk/tm/perl/utility/make_response.pm +6 -0
- package/project/.sdk/tm/perl/utility/make_spec.pm +20 -2
- package/project/.sdk/tm/perl/utility/register.pm +1 -0
- package/project/.sdk/tm/php/core/UtilityType.php +2 -0
- package/project/.sdk/tm/php/feature/PagingFeature.php +106 -4
- package/project/.sdk/tm/php/utility/Graphql.php +176 -0
- package/project/.sdk/tm/php/utility/MakeOptions.php +1 -1
- package/project/.sdk/tm/php/utility/MakeResponse.php +7 -0
- package/project/.sdk/tm/php/utility/MakeSpec.php +20 -2
- package/project/.sdk/tm/php/utility/Register.php +3 -0
- package/project/.sdk/tm/py/pkg/core/__init__.py +0 -0
- package/project/.sdk/tm/py/{core → pkg/core}/context.py +8 -8
- package/project/.sdk/tm/py/{core → pkg/core}/operation.py +1 -1
- package/project/.sdk/tm/py/{core → pkg/core}/response.py +1 -1
- package/project/.sdk/tm/py/{core → pkg/core}/result.py +1 -1
- package/project/.sdk/tm/py/{core → pkg/core}/utility_type.py +2 -0
- package/project/.sdk/tm/py/pkg/entity/__init__.py +0 -0
- package/project/.sdk/tm/py/pkg/feature/__init__.py +0 -0
- package/project/.sdk/tm/py/{feature → pkg/feature}/audit_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/cache_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/clienttrack_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/debug_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/idempotency_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/log_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/metrics_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/netsim_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/paging_feature.py +87 -6
- package/project/.sdk/tm/py/{feature → pkg/feature}/proxy_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/ratelimit_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/rbac_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/retry_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/streaming_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/telemetry_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/test_feature.py +2 -2
- package/project/.sdk/tm/py/{feature → pkg/feature}/timeout_feature.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/__init__.py +0 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/feature_init.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/fetcher.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/graphql.py +145 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_context.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_error.py +5 -5
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_fetch_def.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_options.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_point.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_request.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_response.py +6 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_spec.py +19 -4
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_url.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/param.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_auth.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_headers.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_method.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_params.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_path.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_query.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/register.py +71 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/transform_request.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/transform_response.py +2 -2
- package/project/.sdk/tm/py/test/feature_harness.py +6 -6
- package/project/.sdk/tm/py/test/runner.py +1 -1
- package/project/.sdk/tm/py/test/struct_runner.py +1 -1
- package/project/.sdk/tm/py/test/test_pipeline.py +5 -5
- package/project/.sdk/tm/py/test/test_primary_utility.py +8 -8
- package/project/.sdk/tm/py/test/test_struct_utility.py +3 -3
- package/project/.sdk/tm/py-data/LICENSE +22 -0
- package/project/.sdk/tm/py-data/Makefile +57 -0
- package/project/.sdk/tm/py-data/pkg/auth.py +131 -0
- package/project/.sdk/tm/py-data/pkg/fetch.py +178 -0
- package/project/.sdk/tm/py-data/pkg/frames.py +236 -0
- package/project/.sdk/tm/py-data/src/feature/README.md +8 -0
- package/project/.sdk/tm/py-data/src/feature/debug/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/idempotency/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/metrics/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/netsim/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/paging/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/streaming/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/test/__init__.py +0 -0
- package/project/.sdk/tm/py-data/test/test_auth.py +95 -0
- package/project/.sdk/tm/py-data/test/test_fetch.py +152 -0
- package/project/.sdk/tm/py-data/test/test_frames.py +250 -0
- package/project/.sdk/tm/rb/core/utility_type.rb +1 -0
- package/project/.sdk/tm/rb/feature/paging_feature.rb +89 -3
- package/project/.sdk/tm/rb/utility/graphql.rb +131 -0
- package/project/.sdk/tm/rb/utility/make_options.rb +1 -1
- package/project/.sdk/tm/rb/utility/make_response.rb +6 -0
- package/project/.sdk/tm/rb/utility/make_spec.rb +18 -2
- package/project/.sdk/tm/rb/utility/register.rb +3 -0
- package/project/.sdk/tm/rust/feature/paging.rs +124 -2
- package/project/.sdk/tm/rust/utility/graphql.rs +193 -0
- package/project/.sdk/tm/rust/utility/make_options.rs +1 -1
- package/project/.sdk/tm/rust/utility/make_response.rs +6 -0
- package/project/.sdk/tm/rust/utility/make_spec.rs +32 -4
- package/project/.sdk/tm/rust/utility/mod.rs +1 -0
- package/project/.sdk/tm/scala/core/SdkClient.scala +90 -0
- package/project/.sdk/tm/scala/core/Utility.scala +4 -0
- package/project/.sdk/tm/scala/feature/PagingFeature.scala +104 -3
- package/project/.sdk/tm/scala/utility/Graphql.scala +160 -0
- package/project/.sdk/tm/scala/utility/Make.scala +7 -1
- package/project/.sdk/tm/scala/utility/MakeSpec.scala +22 -2
- package/project/.sdk/tm/scala/utility/Register.scala +2 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +4 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/PagingFeature.swift +86 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Graphql.swift +142 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Make.swift +24 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +1 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +2 -0
- package/project/.sdk/tm/ts/src/Point.ts +7 -0
- package/project/.sdk/tm/ts/src/feature/paging/PagingFeature.ts +82 -3
- package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +14 -2
- package/project/.sdk/tm/ts/src/utility/GraphqlUtility.ts +152 -0
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +1 -1
- package/project/.sdk/tm/ts/src/utility/MakeResponseUtility.ts +7 -0
- package/project/.sdk/tm/ts/src/utility/MakeSpecUtility.ts +19 -2
- package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -0
- package/project/.sdk/tm/zig/core/utility.zig +198 -3
- package/project/.sdk/tm/zig/feature/paging.zig +128 -1
- package/src/cmp/AgentGuideContent.ts +5 -0
- package/src/cmp/Feature.ts +13 -0
- package/src/helpers/canonType.ts +46 -0
- package/src/helpers/packageMeta.ts +7 -0
- package/src/sdkgen.ts +6 -1
- package/project/.sdk/tm/py/utility/register.py +0 -68
- /package/project/.sdk/tm/py/{core → pkg/core}/control.py +0 -0
- /package/project/.sdk/tm/py/{core → pkg/core}/error.py +0 -0
- /package/project/.sdk/tm/py/{core → pkg/core}/helpers.py +0 -0
- /package/project/.sdk/tm/py/{core → pkg/core}/spec.py +0 -0
- /package/project/.sdk/tm/py/{feature → pkg/feature}/base_feature.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/clean.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/done.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/feature_add.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/feature_hook.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/make_result.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_body.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/result_basic.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/result_body.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/result_headers.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/voxgig_struct/__init__.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/voxgig_struct/voxgig_struct.py +0 -0
- /package/project/.sdk/tm/{py/core/__init__.py → py-data/src/feature/audit/.gitkeep} +0 -0
- /package/project/.sdk/tm/{py/entity/__init__.py → py-data/src/feature/base/.gitkeep} +0 -0
- /package/project/.sdk/tm/{py/feature/__init__.py → py-data/src/feature/cache/.gitkeep} +0 -0
- /package/project/.sdk/tm/{py/utility/__init__.py → py-data/src/feature/clienttrack/.gitkeep} +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# ProjectName SDK utility registration
|
|
2
|
+
|
|
3
|
+
from projectname_sdk.core.utility_type import ProjectNameUtility
|
|
4
|
+
|
|
5
|
+
from projectname_sdk.utility.clean import clean_util
|
|
6
|
+
from projectname_sdk.utility.done import done_util
|
|
7
|
+
from projectname_sdk.utility.make_error import make_error_util
|
|
8
|
+
from projectname_sdk.utility.feature_add import feature_add_util
|
|
9
|
+
from projectname_sdk.utility.feature_hook import feature_hook_util
|
|
10
|
+
from projectname_sdk.utility.feature_init import feature_init_util
|
|
11
|
+
from projectname_sdk.utility.fetcher import fetcher_util
|
|
12
|
+
from projectname_sdk.utility.make_fetch_def import make_fetch_def_util
|
|
13
|
+
from projectname_sdk.utility.make_context import make_context_util
|
|
14
|
+
from projectname_sdk.utility.make_options import make_options_util
|
|
15
|
+
from projectname_sdk.utility.make_request import make_request_util
|
|
16
|
+
from projectname_sdk.utility.make_response import make_response_util
|
|
17
|
+
from projectname_sdk.utility.make_result import make_result_util
|
|
18
|
+
from projectname_sdk.utility.make_point import make_point_util
|
|
19
|
+
from projectname_sdk.utility.make_spec import make_spec_util
|
|
20
|
+
from projectname_sdk.utility.make_url import make_url_util
|
|
21
|
+
from projectname_sdk.utility.param import param_util
|
|
22
|
+
from projectname_sdk.utility.prepare_auth import prepare_auth_util
|
|
23
|
+
from projectname_sdk.utility.prepare_body import prepare_body_util
|
|
24
|
+
from projectname_sdk.utility.prepare_headers import prepare_headers_util
|
|
25
|
+
from projectname_sdk.utility.prepare_method import prepare_method_util
|
|
26
|
+
from projectname_sdk.utility.prepare_params import prepare_params_util
|
|
27
|
+
from projectname_sdk.utility.prepare_path import prepare_path_util
|
|
28
|
+
from projectname_sdk.utility.prepare_query import prepare_query_util
|
|
29
|
+
from projectname_sdk.utility.graphql import graphql_body_util, graphql_errors_util
|
|
30
|
+
from projectname_sdk.utility.result_basic import result_basic_util
|
|
31
|
+
from projectname_sdk.utility.result_body import result_body_util
|
|
32
|
+
from projectname_sdk.utility.result_headers import result_headers_util
|
|
33
|
+
from projectname_sdk.utility.transform_request import transform_request_util
|
|
34
|
+
from projectname_sdk.utility.transform_response import transform_response_util
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def register_all(u):
|
|
38
|
+
u.clean = clean_util
|
|
39
|
+
u.done = done_util
|
|
40
|
+
u.make_error = make_error_util
|
|
41
|
+
u.feature_add = feature_add_util
|
|
42
|
+
u.feature_hook = feature_hook_util
|
|
43
|
+
u.feature_init = feature_init_util
|
|
44
|
+
u.fetcher = fetcher_util
|
|
45
|
+
u.make_fetch_def = make_fetch_def_util
|
|
46
|
+
u.make_context = make_context_util
|
|
47
|
+
u.make_options = make_options_util
|
|
48
|
+
u.make_request = make_request_util
|
|
49
|
+
u.make_response = make_response_util
|
|
50
|
+
u.make_result = make_result_util
|
|
51
|
+
u.make_point = make_point_util
|
|
52
|
+
u.make_spec = make_spec_util
|
|
53
|
+
u.make_url = make_url_util
|
|
54
|
+
u.param = param_util
|
|
55
|
+
u.prepare_auth = prepare_auth_util
|
|
56
|
+
u.prepare_body = prepare_body_util
|
|
57
|
+
u.prepare_headers = prepare_headers_util
|
|
58
|
+
u.prepare_method = prepare_method_util
|
|
59
|
+
u.prepare_params = prepare_params_util
|
|
60
|
+
u.prepare_path = prepare_path_util
|
|
61
|
+
u.prepare_query = prepare_query_util
|
|
62
|
+
u.graphql_body = graphql_body_util
|
|
63
|
+
u.graphql_errors = graphql_errors_util
|
|
64
|
+
u.result_basic = result_basic_util
|
|
65
|
+
u.result_body = result_body_util
|
|
66
|
+
u.result_headers = result_headers_util
|
|
67
|
+
u.transform_request = transform_request_util
|
|
68
|
+
u.transform_response = transform_response_util
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
ProjectNameUtility._registrar = register_all
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# ProjectName SDK utility: transform_request
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from utility.voxgig_struct import voxgig_struct as vs
|
|
5
|
-
from core.helpers import to_map
|
|
4
|
+
from projectname_sdk.utility.voxgig_struct import voxgig_struct as vs
|
|
5
|
+
from projectname_sdk.core.helpers import to_map
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def transform_request_util(ctx):
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# ProjectName SDK utility: transform_response
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from utility.voxgig_struct import voxgig_struct as vs
|
|
5
|
-
from core.helpers import to_map
|
|
4
|
+
from projectname_sdk.utility.voxgig_struct import voxgig_struct as vs
|
|
5
|
+
from projectname_sdk.core.helpers import to_map
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def transform_response_util(ctx):
|
|
@@ -14,12 +14,12 @@ from __future__ import annotations
|
|
|
14
14
|
|
|
15
15
|
from urllib.parse import quote
|
|
16
16
|
|
|
17
|
-
from config import make_config
|
|
18
|
-
from features import _make_feature
|
|
19
|
-
from core.control import ProjectNameControl
|
|
20
|
-
from core.error import ProjectNameError
|
|
21
|
-
from core.result import ProjectNameResult
|
|
22
|
-
from core.spec import ProjectNameSpec
|
|
17
|
+
from projectname_sdk.config import make_config
|
|
18
|
+
from projectname_sdk.features import _make_feature
|
|
19
|
+
from projectname_sdk.core.control import ProjectNameControl
|
|
20
|
+
from projectname_sdk.core.error import ProjectNameError
|
|
21
|
+
from projectname_sdk.core.result import ProjectNameResult
|
|
22
|
+
from projectname_sdk.core.spec import ProjectNameSpec
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
# True when this SDK was generated with the named feature.
|
|
@@ -6,7 +6,7 @@ import json
|
|
|
6
6
|
import re
|
|
7
7
|
from typing import Any, Dict, List, Callable, TypedDict, Optional, Union
|
|
8
8
|
|
|
9
|
-
from utility.voxgig_struct import voxgig_struct as vs
|
|
9
|
+
from projectname_sdk.utility.voxgig_struct import voxgig_struct as vs
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
NULLMARK = '__NULL__' # Value is JSON null
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
import pytest
|
|
17
17
|
|
|
18
18
|
from projectname_sdk import ProjectNameSDK
|
|
19
|
-
from core.error import ProjectNameError
|
|
20
|
-
from core.result import ProjectNameResult
|
|
21
|
-
from core.response import ProjectNameResponse
|
|
22
|
-
from core.spec import ProjectNameSpec
|
|
23
|
-
from feature.base_feature import ProjectNameBaseFeature
|
|
19
|
+
from projectname_sdk.core.error import ProjectNameError
|
|
20
|
+
from projectname_sdk.core.result import ProjectNameResult
|
|
21
|
+
from projectname_sdk.core.response import ProjectNameResponse
|
|
22
|
+
from projectname_sdk.core.spec import ProjectNameSpec
|
|
23
|
+
from projectname_sdk.feature.base_feature import ProjectNameBaseFeature
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def _client():
|
|
@@ -6,15 +6,15 @@ import re
|
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
8
|
|
|
9
|
-
from utility.voxgig_struct import voxgig_struct as vs
|
|
9
|
+
from projectname_sdk.utility.voxgig_struct import voxgig_struct as vs
|
|
10
10
|
from projectname_sdk import ProjectNameSDK
|
|
11
|
-
from core.spec import ProjectNameSpec
|
|
12
|
-
from core.result import ProjectNameResult
|
|
13
|
-
from core.response import ProjectNameResponse
|
|
14
|
-
from core.operation import ProjectNameOperation
|
|
15
|
-
from core.error import ProjectNameError
|
|
16
|
-
from core import helpers
|
|
17
|
-
from feature.base_feature import ProjectNameBaseFeature
|
|
11
|
+
from projectname_sdk.core.spec import ProjectNameSpec
|
|
12
|
+
from projectname_sdk.core.result import ProjectNameResult
|
|
13
|
+
from projectname_sdk.core.response import ProjectNameResponse
|
|
14
|
+
from projectname_sdk.core.operation import ProjectNameOperation
|
|
15
|
+
from projectname_sdk.core.error import ProjectNameError
|
|
16
|
+
from projectname_sdk.core import helpers
|
|
17
|
+
from projectname_sdk.feature.base_feature import ProjectNameBaseFeature
|
|
18
18
|
|
|
19
19
|
_TEST_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
20
20
|
|
|
@@ -13,8 +13,8 @@ from test.struct_runner import (
|
|
|
13
13
|
StructTestClient,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
from utility.voxgig_struct import voxgig_struct as vs
|
|
17
|
-
from utility.voxgig_struct.voxgig_struct import (
|
|
16
|
+
from projectname_sdk.utility.voxgig_struct import voxgig_struct as vs
|
|
17
|
+
from projectname_sdk.utility.voxgig_struct.voxgig_struct import (
|
|
18
18
|
T_noval, T_scalar, T_function, T_symbol, T_any, T_node, T_instance, T_null,
|
|
19
19
|
)
|
|
20
20
|
|
|
@@ -308,7 +308,7 @@ class TestStructUtility(unittest.TestCase):
|
|
|
308
308
|
|
|
309
309
|
|
|
310
310
|
def test_minor_joinurl(self):
|
|
311
|
-
from utility.voxgig_struct.voxgig_struct import join as struct_join
|
|
311
|
+
from projectname_sdk.utility.voxgig_struct.voxgig_struct import join as struct_join
|
|
312
312
|
runsetflags(minorSpec["join"], {"null": False},
|
|
313
313
|
lambda vin: struct_join(vin.get("val"), vin.get("sep"), vin.get("url")))
|
|
314
314
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) $$const.year$$ Voxgig
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
.PHONY: test build clean publish dev notebook
|
|
2
|
+
|
|
3
|
+
# Install the sibling ProjectName SDK from the same repo (../py) plus this
|
|
4
|
+
# package, both editable, so a working copy tests against the SDK it was
|
|
5
|
+
# generated alongside rather than whatever is on PyPI.
|
|
6
|
+
dev:
|
|
7
|
+
python3 -m pip install -e ../py
|
|
8
|
+
python3 -m pip install -e .
|
|
9
|
+
|
|
10
|
+
test:
|
|
11
|
+
python3 -m pytest test/
|
|
12
|
+
|
|
13
|
+
# Execute the generated quickstart notebook end to end. A quickstart that
|
|
14
|
+
# does not run is a broken product, so this is part of `make test` in CI.
|
|
15
|
+
notebook:
|
|
16
|
+
python3 -m jupyter nbconvert --to notebook --execute \
|
|
17
|
+
--stdout notebooks/quickstart.ipynb > /dev/null && echo "quickstart.ipynb OK"
|
|
18
|
+
|
|
19
|
+
build:
|
|
20
|
+
@echo "No build step for Python"
|
|
21
|
+
|
|
22
|
+
clean:
|
|
23
|
+
find . -name __pycache__ -exec rm -rf {} + 2>/dev/null; true
|
|
24
|
+
rm -rf dist .pytest_cache
|
|
25
|
+
|
|
26
|
+
# --- Release: publish to PyPI ---------------------------------------------
|
|
27
|
+
# Publish this package to PyPI, then tag py-data/vX.Y.Z. Run headless under the
|
|
28
|
+
# boru key vault, which injects the PyPI + GitHub tokens as environment
|
|
29
|
+
# variables (never written to disk or argv):
|
|
30
|
+
# boru vault exec --for=pypi=<alias> --for=github=<alias> -- make publish
|
|
31
|
+
# boru `--dry-run` injects a filler token we detect to rehearse: builds the dist
|
|
32
|
+
# but performs no upload, tag, or push. set -e + tag-last: a failed upload never
|
|
33
|
+
# leaves a tag behind. Needs python `build` + `twine` (pip install build twine).
|
|
34
|
+
VERSION := $(shell sed -nE 's/^version *= *"([^"]+)".*/\1/p' pyproject.toml | head -1)
|
|
35
|
+
TAG := py-data/v$(VERSION)
|
|
36
|
+
BORU_DRY_RUN_FILLER := BORU-DRY-RUN-FILLER-NOT-A-REAL-SECRET
|
|
37
|
+
publish: test
|
|
38
|
+
@if git rev-parse -q --verify "refs/tags/$(TAG)" >/dev/null; then \
|
|
39
|
+
echo "tag $(TAG) already exists — bump pyproject.toml version first"; exit 1; fi
|
|
40
|
+
@set -e; \
|
|
41
|
+
token="$${GITHUB_TOKEN:-$$GH_TOKEN}"; \
|
|
42
|
+
rm -rf dist; \
|
|
43
|
+
python3 -m build; \
|
|
44
|
+
if [ "$$token" = "$(BORU_DRY_RUN_FILLER)" ] || [ "$$TWINE_PASSWORD" = "$(BORU_DRY_RUN_FILLER)" ]; then \
|
|
45
|
+
echo "[dry-run] boru filler token detected: built the dist; would upload to PyPI and tag $(TAG); nothing pushed."; \
|
|
46
|
+
exit 0; \
|
|
47
|
+
fi; \
|
|
48
|
+
python3 -m twine upload dist/*; \
|
|
49
|
+
git tag -a "$(TAG)" -m "py-data v$(VERSION)"; \
|
|
50
|
+
url=$$(git remote get-url origin | sed -E 's#^git@github.com:#https://github.com/#'); \
|
|
51
|
+
if [ -n "$$token" ] && printf '%s' "$$url" | grep -q '^https://github.com/'; then \
|
|
52
|
+
hdr="AUTHORIZATION: basic $$(printf 'x-access-token:%s' "$$token" | base64 | tr -d '\n')"; \
|
|
53
|
+
git -c http.extraheader="$$hdr" push "$$url" "$(TAG)"; \
|
|
54
|
+
else \
|
|
55
|
+
git push origin "$(TAG)"; \
|
|
56
|
+
fi; \
|
|
57
|
+
echo "Published to PyPI + tag $(TAG)."
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# ProjectName Data — credential discovery.
|
|
2
|
+
#
|
|
3
|
+
# `data()` must work in a fresh Colab cell with no arguments. Analysts do not
|
|
4
|
+
# want to construct a client; they want a DataFrame. So the token and base
|
|
5
|
+
# URL are looked up through a short, predictable chain and the failure
|
|
6
|
+
# message TEACHES rather than merely reports.
|
|
7
|
+
#
|
|
8
|
+
# Kept generic (the SDK's env-var prefix is passed in) because this file is
|
|
9
|
+
# copied verbatim per SDK — only `ProjectName` is substituted at generation
|
|
10
|
+
# time, so nothing here may hardcode a per-API name.
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
NOT_FOUND = object()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def from_colab(key: str) -> Any:
|
|
22
|
+
"""Read a Colab secret, or NOT_FOUND.
|
|
23
|
+
|
|
24
|
+
Guarded three ways because every one of them bites in practice:
|
|
25
|
+
the import fails outside Colab; `userdata` raises SecretNotFoundError for
|
|
26
|
+
a key that was never set; and it raises NotebookAccessError when the
|
|
27
|
+
secret exists but the notebook has not been granted access to it (the
|
|
28
|
+
toggle in Colab's key panel). None of those are errors HERE — they just
|
|
29
|
+
mean "try the next source".
|
|
30
|
+
"""
|
|
31
|
+
try:
|
|
32
|
+
from google.colab import userdata # type: ignore
|
|
33
|
+
except Exception:
|
|
34
|
+
return NOT_FOUND
|
|
35
|
+
try:
|
|
36
|
+
val = userdata.get(key)
|
|
37
|
+
except Exception:
|
|
38
|
+
return NOT_FOUND
|
|
39
|
+
return val if val else NOT_FOUND
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def from_env(key: str) -> Any:
|
|
43
|
+
val = os.environ.get(key)
|
|
44
|
+
return val if val else NOT_FOUND
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def resolve(
|
|
48
|
+
prefix: str,
|
|
49
|
+
token: str | None = None,
|
|
50
|
+
base_url: str | None = None,
|
|
51
|
+
*,
|
|
52
|
+
token_key: str | None = None,
|
|
53
|
+
base_key: str | None = None,
|
|
54
|
+
) -> tuple:
|
|
55
|
+
"""(token, base_url, source) from args, then Colab secrets, then env.
|
|
56
|
+
|
|
57
|
+
`prefix` is the SDK's upper-snake name, e.g. ACME -> ACME_APIKEY /
|
|
58
|
+
ACME_BASE. Returns the raw values; validation is the caller's job so it
|
|
59
|
+
can decide whether a missing base_url is fatal (multi-tenant APIs) or
|
|
60
|
+
fine (the model's default applies).
|
|
61
|
+
"""
|
|
62
|
+
tkey = token_key or f"{prefix}_APIKEY"
|
|
63
|
+
bkey = base_key or f"{prefix}_BASE"
|
|
64
|
+
|
|
65
|
+
source = "argument"
|
|
66
|
+
tok: Any = token if token else NOT_FOUND
|
|
67
|
+
|
|
68
|
+
if tok is NOT_FOUND:
|
|
69
|
+
tok = from_colab(tkey)
|
|
70
|
+
source = "colab"
|
|
71
|
+
if tok is NOT_FOUND:
|
|
72
|
+
tok = from_env(tkey)
|
|
73
|
+
source = "env"
|
|
74
|
+
|
|
75
|
+
base: Any = base_url if base_url else NOT_FOUND
|
|
76
|
+
if base is NOT_FOUND:
|
|
77
|
+
base = from_colab(bkey)
|
|
78
|
+
if base is NOT_FOUND:
|
|
79
|
+
base = from_env(bkey)
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
None if tok is NOT_FOUND else tok,
|
|
83
|
+
None if base is NOT_FOUND else base,
|
|
84
|
+
None if tok is NOT_FOUND else source,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def missing_token_message(prefix: str, token_key: str | None = None) -> str:
|
|
89
|
+
"""The error an analyst sees when no credential was found.
|
|
90
|
+
|
|
91
|
+
Shows the exact lines to run for THIS SDK in both environments. A generic
|
|
92
|
+
"credentials not found" costs the reader a trip to the README; this costs
|
|
93
|
+
them a copy-paste.
|
|
94
|
+
"""
|
|
95
|
+
tkey = token_key or f"{prefix}_APIKEY"
|
|
96
|
+
return (
|
|
97
|
+
f"No API credential found for ProjectName.\n"
|
|
98
|
+
f"\n"
|
|
99
|
+
f"In Google Colab — open the key panel (left sidebar), add a secret\n"
|
|
100
|
+
f"named {tkey}, and enable notebook access for it. Or set it in code:\n"
|
|
101
|
+
f"\n"
|
|
102
|
+
f" from google.colab import userdata\n"
|
|
103
|
+
f" userdata.set('{tkey}', 'your-api-key')\n"
|
|
104
|
+
f"\n"
|
|
105
|
+
f"Elsewhere (Jupyter, a script, a terminal):\n"
|
|
106
|
+
f"\n"
|
|
107
|
+
f" import os\n"
|
|
108
|
+
f" os.environ['{tkey}'] = 'your-api-key'\n"
|
|
109
|
+
f"\n"
|
|
110
|
+
f"Or pass it directly:\n"
|
|
111
|
+
f"\n"
|
|
112
|
+
f" data(token='your-api-key')\n"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def missing_base_message(prefix: str, base_key: str | None = None) -> str:
|
|
117
|
+
"""The error for a multi-tenant API with no base URL.
|
|
118
|
+
|
|
119
|
+
Only raised when the model's server URL carries an unresolved
|
|
120
|
+
placeholder, i.e. the API genuinely has no single host and every customer
|
|
121
|
+
has their own instance. Guessing one would produce confusing 404s.
|
|
122
|
+
"""
|
|
123
|
+
bkey = base_key or f"{prefix}_BASE"
|
|
124
|
+
return (
|
|
125
|
+
f"ProjectName is multi-tenant: it has no single API host, so the base\n"
|
|
126
|
+
f"URL for YOUR instance is required.\n"
|
|
127
|
+
f"\n"
|
|
128
|
+
f" data(base_url='https://your-instance.example.com')\n"
|
|
129
|
+
f"\n"
|
|
130
|
+
f"or set {bkey} as a Colab secret / environment variable.\n"
|
|
131
|
+
)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# ProjectName Data — eager paging drain.
|
|
2
|
+
#
|
|
3
|
+
# Analysts want the whole table now. Lazy iterators are application
|
|
4
|
+
# ergonomics: correct for a service processing a stream, wrong for someone
|
|
5
|
+
# who typed `df = ad.things()` and wants to run a groupby on the next line.
|
|
6
|
+
#
|
|
7
|
+
# This module owns NO pagination knowledge. The sibling SDK's `paging`
|
|
8
|
+
# feature already normalises every server dialect it understands — a
|
|
9
|
+
# `Link: rel="next"` header, X-Page / X-Next-Page / X-Total-Count, or body
|
|
10
|
+
# `next` / `cursor` / `nextCursor` / `hasMore` — onto `result.paging`, and
|
|
11
|
+
# records the last one on the client. All we do is drive it to exhaustion by
|
|
12
|
+
# feeding the cursor/page back in through the per-call `ctrl.paging` hook,
|
|
13
|
+
# which exists for exactly this purpose.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import sys
|
|
18
|
+
from typing import Any, Callable
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Safety backstop. A server that always reports "more" (or a cursor that
|
|
22
|
+
# never advances) would otherwise loop forever inside a notebook cell with
|
|
23
|
+
# no output. Hitting this is always reported, never silent.
|
|
24
|
+
MAX_PAGES_DEFAULT = 1000
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def in_notebook() -> bool:
|
|
28
|
+
"""True when running under IPython/Jupyter/Colab with a display."""
|
|
29
|
+
try:
|
|
30
|
+
from IPython import get_ipython # type: ignore
|
|
31
|
+
except Exception:
|
|
32
|
+
return False
|
|
33
|
+
ip = get_ipython()
|
|
34
|
+
if ip is None:
|
|
35
|
+
return False
|
|
36
|
+
return hasattr(ip, "kernel")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _progress(count: int, pages: int, quiet: bool) -> None:
|
|
40
|
+
if quiet:
|
|
41
|
+
return
|
|
42
|
+
# Deliberately not tqdm: an extra hard dependency for a progress bar is a
|
|
43
|
+
# bad trade in an environment that reinstalls every dependency on every
|
|
44
|
+
# session start. A rewritten stderr line costs nothing and works in both
|
|
45
|
+
# notebooks and plain terminals.
|
|
46
|
+
sys.stderr.write(f"\r fetched {count} rows ({pages} pages)…")
|
|
47
|
+
sys.stderr.flush()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _progress_done(count: int, pages: int, quiet: bool) -> None:
|
|
51
|
+
if quiet:
|
|
52
|
+
return
|
|
53
|
+
sys.stderr.write(f"\r fetched {count} rows ({pages} pages) \n")
|
|
54
|
+
sys.stderr.flush()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def drain(
|
|
58
|
+
call: Callable[[dict], Any],
|
|
59
|
+
client: Any,
|
|
60
|
+
*,
|
|
61
|
+
limit: int | None = None,
|
|
62
|
+
max_pages: int = MAX_PAGES_DEFAULT,
|
|
63
|
+
quiet: bool = False,
|
|
64
|
+
progress_after: int = 1,
|
|
65
|
+
) -> list:
|
|
66
|
+
"""Call `call(ctrl)` until the server stops offering more.
|
|
67
|
+
|
|
68
|
+
call — invoked with a ctrl dict; returns one page of records
|
|
69
|
+
client — the SDK client, read for `_paging` (set by the paging feature)
|
|
70
|
+
limit — stop once this many rows are collected (None = all)
|
|
71
|
+
max_pages — backstop; a warning is emitted if it is reached
|
|
72
|
+
quiet — suppress progress output
|
|
73
|
+
progress_after — only show progress once this many pages have been fetched,
|
|
74
|
+
so the common single-page case prints nothing at all
|
|
75
|
+
|
|
76
|
+
Returns the accumulated records.
|
|
77
|
+
|
|
78
|
+
When the SDK's paging feature is INACTIVE there is no `_paging` state, so
|
|
79
|
+
this makes exactly one call and returns it — the correct degradation, not
|
|
80
|
+
an error. An SDK without paging configured genuinely has one page.
|
|
81
|
+
"""
|
|
82
|
+
rows: list = []
|
|
83
|
+
ctrl: dict = {}
|
|
84
|
+
pages = 0
|
|
85
|
+
seen_cursors: set = set()
|
|
86
|
+
hit_max = False
|
|
87
|
+
|
|
88
|
+
while True:
|
|
89
|
+
page = call(ctrl)
|
|
90
|
+
pages += 1
|
|
91
|
+
|
|
92
|
+
if page is None:
|
|
93
|
+
batch = []
|
|
94
|
+
elif isinstance(page, (list, tuple)):
|
|
95
|
+
batch = list(page)
|
|
96
|
+
else:
|
|
97
|
+
batch = [page]
|
|
98
|
+
|
|
99
|
+
rows.extend(batch)
|
|
100
|
+
|
|
101
|
+
if pages >= progress_after + 1:
|
|
102
|
+
_progress(len(rows), pages, quiet)
|
|
103
|
+
|
|
104
|
+
if limit is not None and len(rows) >= limit:
|
|
105
|
+
rows = rows[:limit]
|
|
106
|
+
break
|
|
107
|
+
|
|
108
|
+
paging = _last_paging(client)
|
|
109
|
+
if not paging or not paging.get("hasMore"):
|
|
110
|
+
break
|
|
111
|
+
|
|
112
|
+
# An empty page that still claims more would spin forever.
|
|
113
|
+
if len(batch) == 0:
|
|
114
|
+
break
|
|
115
|
+
|
|
116
|
+
nxt = _next_ctrl(paging)
|
|
117
|
+
if nxt is None:
|
|
118
|
+
break
|
|
119
|
+
|
|
120
|
+
# A cursor that repeats means the server is not advancing. Stopping
|
|
121
|
+
# beats looping: the analyst gets the rows fetched so far, plus a
|
|
122
|
+
# warning, instead of a hung cell.
|
|
123
|
+
token = repr(sorted(nxt.get("paging", {}).items()))
|
|
124
|
+
if token in seen_cursors:
|
|
125
|
+
_warn("pagination stopped advancing (repeated cursor) — "
|
|
126
|
+
f"returning the {len(rows)} rows fetched so far")
|
|
127
|
+
break
|
|
128
|
+
seen_cursors.add(token)
|
|
129
|
+
|
|
130
|
+
if pages >= max_pages:
|
|
131
|
+
hit_max = True
|
|
132
|
+
break
|
|
133
|
+
|
|
134
|
+
ctrl = nxt
|
|
135
|
+
|
|
136
|
+
if pages >= progress_after + 1:
|
|
137
|
+
_progress_done(len(rows), pages, quiet)
|
|
138
|
+
|
|
139
|
+
if hit_max:
|
|
140
|
+
_warn(f"stopped at max_pages={max_pages} with {len(rows)} rows; the "
|
|
141
|
+
"server still reported more. Pass max_pages= to raise the cap, "
|
|
142
|
+
"or limit= to take a defined slice.")
|
|
143
|
+
|
|
144
|
+
return rows
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _last_paging(client: Any) -> dict | None:
|
|
148
|
+
"""The paging state the SDK's paging feature recorded on the client."""
|
|
149
|
+
state = getattr(client, "_paging", None)
|
|
150
|
+
if not isinstance(state, dict):
|
|
151
|
+
return None
|
|
152
|
+
last = state.get("last")
|
|
153
|
+
return last if isinstance(last, dict) else None
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _next_ctrl(paging: dict) -> dict | None:
|
|
157
|
+
"""Build the ctrl for the next page from the recorded paging state.
|
|
158
|
+
|
|
159
|
+
Cursor wins over page number: when a server offers both, the cursor is
|
|
160
|
+
the one with consistency guarantees.
|
|
161
|
+
"""
|
|
162
|
+
cursor = paging.get("cursor")
|
|
163
|
+
if cursor is not None:
|
|
164
|
+
return {"paging": {"cursor": cursor}}
|
|
165
|
+
|
|
166
|
+
next_page = paging.get("nextPage")
|
|
167
|
+
if next_page is not None:
|
|
168
|
+
return {"paging": {"page": next_page}}
|
|
169
|
+
|
|
170
|
+
# A `Link: rel="next"` URL with no cursor/page extracted is not something
|
|
171
|
+
# we can turn into a ctrl — the SDK builds its own request URLs. Rather
|
|
172
|
+
# than guess at query parsing, stop and keep what we have.
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _warn(msg: str) -> None:
|
|
177
|
+
import warnings
|
|
178
|
+
warnings.warn(f"ProjectName data: {msg}", stacklevel=3)
|