synmax-api-python-client 4.16.0__py3-none-any.whl → 4.16.1__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.
synmax/openapi/client.py CHANGED
@@ -10,7 +10,7 @@ import importlib
10
10
  from itertools import islice
11
11
  import pandas as pd
12
12
 
13
- from synmax.openapi.utils import change_signature, get_annotation, get_body_model, get_param_model
13
+ from synmax.openapi.utils import change_signature, get_annotation, get_body_model, get_param_model, PARAM_MODEL_SUFFIX, BODY_MODEL_SUFFIX
14
14
 
15
15
  class OpenAPIClient:
16
16
  def __init__(self,
@@ -100,16 +100,15 @@ class OpenAPIClient:
100
100
 
101
101
  def _create_request_function(self, method: str, full_url: str, param_model: Optional[Type[BaseModel]], body_model: Optional[Type[BaseModel]]):
102
102
  def request_func(self, **kwargs) -> Result:
103
+ param_dict = None
104
+ if param_model:
105
+ data = param_model(**kwargs).model_dump(mode='json')
106
+ param_dict = {k: v for k, v in data.dict().items() if v is not None}
107
+ body_dict = None
108
+ if body_model:
109
+ data = body_model(**kwargs).model_dump(mode='json')
110
+ body_dict = {k: v for k, v in data.items() if v is not None}
103
111
  def generator() -> Iterator[Dict[str, Any]]:
104
- param_dict = None
105
- if param_model:
106
- data = param_model(**kwargs).model_dump(mode='json')
107
- param_dict = {k: v for k, v in data.dict().items() if v is not None}
108
- body_dict = None
109
- if body_model:
110
- data = body_model(**kwargs).model_dump(mode='json')
111
-
112
- body_dict = {k: v for k, v in data.items() if v is not None}
113
112
  self._logger.info(f"Making request to {full_url}")
114
113
  retry_count = 0
115
114
  can_retry = True
synmax/openapi/utils.py CHANGED
@@ -1,8 +1,15 @@
1
1
  import inspect
2
- from pydantic import BaseModel, create_model, Extra
2
+ from pydantic import BaseModel, create_model, Extra, ValidationError
3
3
  from typing import Any, Dict, Optional, Type, Union, Literal
4
4
  from datetime import date
5
5
 
6
+ import traceback
7
+ import types
8
+ import typing
9
+
10
+ BODY_MODEL_SUFFIX = "BodyModel"
11
+ PARAM_MODEL_SUFFIX = "ParamsModel"
12
+
6
13
 
7
14
  def change_signature(func, signature: inspect.Signature):
8
15
  """
@@ -14,7 +21,105 @@ def change_signature(func, signature: inspect.Signature):
14
21
  def wrapped(*args, **kwargs):
15
22
  bound_arguments = inspect.signature(func).bind(*args, **kwargs)
16
23
  bound_arguments.apply_defaults()
17
- return func(*bound_arguments.args, **bound_arguments.kwargs)
24
+ try:
25
+ return func(*bound_arguments.args, **bound_arguments.kwargs)
26
+ except ValidationError as pydanticerror:
27
+ # strip user-irrelevant library guts from the error
28
+ tb = discard_traceback_frames(pydanticerror.__traceback__, 5)
29
+
30
+ # intercept familiar pydantic errors; replace them with user friendly ones
31
+ pretty = []
32
+ funcname = pydanticerror.title
33
+ funcname = funcname.removesuffix(BODY_MODEL_SUFFIX)
34
+ funcname = funcname.removesuffix(PARAM_MODEL_SUFFIX)
35
+ model = pydanticerror.model
36
+ fields = model.model_fields
37
+
38
+ errors_dict = {}
39
+ for e in pydanticerror.errors():
40
+ key = e['loc'][0]
41
+ if key not in errors_dict:
42
+ errors_dict[key] = []
43
+ errors_dict[key].append(e)
44
+
45
+ pretty = []
46
+ for param,errors in errors_dict.items():
47
+ # case: spurious param
48
+ if param not in fields:
49
+ pe = f"{funcname}:\n unexpected parameter '{param}'"
50
+ pretty.append(pe)
51
+ continue
52
+
53
+ annotation = fields[param].annotation
54
+ # handle unions as follows:
55
+ # if any arm of the union shallowly matches, its "the" relevant arm
56
+ # if no arm shallowly matches and there is one simple branch, its that one
57
+ # otherwise, we keep the whole union i guess
58
+ num_simple = 0
59
+ paramtype = None
60
+ if typing.get_origin(annotation) == typing.Union:
61
+ for e in errors:
62
+ if len(e['loc']) == 2:
63
+ input_value = e['input']
64
+ args = list(typing.get_args(annotation))
65
+ for arg in args:
66
+ shallow = typing.get_origin(arg)
67
+ if shallow is not None:
68
+ if isinstance(input_value, shallow):
69
+ paramtype = arg
70
+ break
71
+ else:
72
+ num_simple += 1
73
+ simple = arg
74
+ if isinstance(input_value, arg):
75
+ paramtype = arg
76
+ break
77
+ if paramtype is None:
78
+ if num_simple == 1:
79
+ paramtype = simple
80
+ else:
81
+ paramtype = annotation
82
+ else:
83
+ paramtype = annotation
84
+
85
+ if paramtype in [date, str, int, bool, float]:
86
+ input = errors[0]['input']
87
+ pe = f"{funcname}:\n '{param}' is expecting type '{paramtype.__name__}'"
88
+ pe += f"\n Got '{input}'"
89
+ pretty.append(pe)
90
+ continue
91
+ if typing.get_origin(paramtype) is list:
92
+ bad_inputs = []
93
+ not_list = False
94
+ arg = typing.get_args(paramtype)[0]
95
+ is_enum_list = typing.get_origin(arg) is typing.Literal
96
+ expecting = str(paramtype)
97
+ if is_enum_list:
98
+ expecting = "list[enum]"
99
+ pe = f"{funcname}:\n '{param}' is expecting type '{expecting}'"
100
+ if is_enum_list:
101
+ enumvals = typing.get_args(arg)
102
+ pe += f"\n Accepted enum values are: {', '.join(enumvals)}"
103
+ for e in errors:
104
+ if len(e['loc']) == 3: # error in a list element (path depth 3)
105
+ bad_inputs.append(str(e['input']))
106
+ if len(e['loc']) == 2: # not giving a list where a list expected
107
+ not_list = True
108
+ if not_list:
109
+ pe += f"\n Got '{e['input']}'"
110
+ pretty.append(pe)
111
+ continue
112
+ if len(bad_inputs > 0):
113
+ pe += f"\n Got '{', '.join(bad_inputs)}'"
114
+ pretty.append(pe)
115
+ continue
116
+ # if there's an error our prettifier recognized, just print that
117
+ # otherwise, fall back to the raw pydantic error
118
+ if len(pretty) == 0:
119
+ raise pydanticerror.with_traceback(tb)
120
+ else:
121
+ raise ParamError(pretty).with_traceback(tb) from None
122
+
18
123
  sig = inspect.signature(func)
19
124
  new_params = [
20
125
  inspect.Parameter(
@@ -54,7 +159,7 @@ def get_param_model(parameters: list, operation_id: str) -> Optional[Type[BaseMo
54
159
  schema = param.get("schema", {"type": "string"})
55
160
  required = param.get("required", False)
56
161
  param_fields[name] = (map_openapi_type(schema, name), ... if required else None)
57
- return create_model(f"{operation_id}Params", **param_fields) if param_fields else None
162
+ return create_model_with_error_metadata(f"{operation_id}{PARAM_MODEL_SUFFIX}", **param_fields) if param_fields else None
58
163
 
59
164
 
60
165
  def get_body_model(request_body: dict, operation_id: str) -> Optional[Type[BaseModel]]:
@@ -69,7 +174,7 @@ def get_body_model(request_body: dict, operation_id: str) -> Optional[Type[BaseM
69
174
  body_fields[key] = (map_openapi_type(value, key), ... if is_required else None)
70
175
  if schema.get("additionalProperties") is False:
71
176
  body_extra = Extra.forbid
72
- return create_model(f"{operation_id}Body", **body_fields, __config__=type("Config", (), {"extra": body_extra})) if body_fields else None
177
+ return create_model_with_error_metadata(f"{operation_id}{BODY_MODEL_SUFFIX}", **body_fields, __config__=type("Config", (), {"extra": body_extra})) if body_fields else None
73
178
 
74
179
 
75
180
  def map_openapi_type(schema: Dict[str, Any], name: str) -> Type:
@@ -99,3 +204,59 @@ def map_openapi_type(schema: Dict[str, Any], name: str) -> Type:
99
204
 
100
205
  return type_map.get(schema.get("type"), Any)
101
206
 
207
+
208
+ def discard_traceback_frames(tb, discard):
209
+ frames = []
210
+ while tb:
211
+ frames.append(tb)
212
+ tb = tb.tb_next
213
+ keep = max(0, len(frames) - discard)
214
+ frames = frames[:keep]
215
+ head = None
216
+ current = None
217
+ for frame in frames:
218
+ new_tb = types.TracebackType(
219
+ tb_next=None,
220
+ tb_frame=frame.tb_frame,
221
+ tb_lasti=frame.tb_lasti,
222
+ tb_lineno=frame.tb_lineno
223
+ )
224
+ if head is None:
225
+ head = new_tb
226
+ current = head
227
+ else:
228
+ current.tb_next = new_tb
229
+ current = new_tb
230
+ return head
231
+
232
+
233
+ class ParamError(ValueError):
234
+ def __init__(self, lines):
235
+ self.lines = lines
236
+
237
+ def __str__(self):
238
+ out = ''
239
+ for line in self.lines:
240
+ out += "\n" + line
241
+ return out
242
+
243
+ def __repr__(self):
244
+ return f'ParamError(lines={self.lines!r})'
245
+
246
+
247
+ def create_model_with_error_metadata(name, **params):
248
+ base_model = create_model(name, **params)
249
+ def __init__(self, *args, **kwargs):
250
+ try:
251
+ super(base_model, self).__init__(*args, **kwargs)
252
+ except ValidationError as e:
253
+ e.model = base_model
254
+ raise e
255
+ enriched_model = type(
256
+ name,
257
+ (base_model,),
258
+ {'__init__': __init__}
259
+ )
260
+ return enriched_model
261
+
262
+
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: synmax-api-python-client
3
- Version: 4.16.0
3
+ Version: 4.16.1
4
4
  Summary: Synmax API client
5
5
  Home-page: https://github.com/SynMaxDev/synmax-api-python-client.git
6
6
  Author: SynMax Inc.
@@ -13,14 +13,23 @@ Requires-Dist: aioretry>=6.3.1
13
13
  Requires-Dist: packaging>=24.2
14
14
  Requires-Dist: pandas>=2.0.3
15
15
  Requires-Dist: pydantic>=2.10.6
16
- Requires-Dist: pydantic-core<2.32.0,>=2.27.2
16
+ Requires-Dist: pydantic_core<2.32.0,>=2.27.2
17
17
  Requires-Dist: requests>=2.32.3
18
18
  Requires-Dist: tenacity>=9.0.0
19
19
  Requires-Dist: tqdm>=4.67.1
20
20
  Requires-Dist: urllib3>=2.3.0
21
21
  Requires-Dist: prance>=25.4.8.0
22
- Requires-Dist: openapi-spec-validator>=0.7.1
22
+ Requires-Dist: openapi_spec_validator>=0.7.1
23
23
  Requires-Dist: httpx>=0.28.1
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: description
27
+ Dynamic: description-content-type
28
+ Dynamic: home-page
29
+ Dynamic: license-file
30
+ Dynamic: requires-dist
31
+ Dynamic: requires-python
32
+ Dynamic: summary
24
33
 
25
34
  # SynMax API Python Client
26
35
 
@@ -17,33 +17,27 @@ synmax/hyperion/v4/__init__.py,sha256=VpXU-_FP836dXUDcUFYr-0y0-ZrSM8aCtGE97Z2qbS
17
17
  synmax/hyperion/v4/hyperion_client.py,sha256=mhYL3QiOoD2viCI60grLMFvGdHx8iD8IF05NWC6-HS0,868
18
18
  synmax/hyperion/v4/hyperion_client.pyi,sha256=yNgEmWzZWKPeQ4Y-ilfBOr8e_lMD4GIMwWe3UCHu438,12039
19
19
  synmax/hyperion/v4/openapi.yaml,sha256=RU4mACjWtL3yNwN5tEyZHYcJ37-pg7F3Y84UyBDfveE,100266
20
- synmax/hyperion/v4/start_hyperion_client.py,sha256=0Cs6qgy8yYuhrVhSVZqa7TKKR9PHFkEomA26MTQUJlU,2495
21
20
  synmax/leviaton/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- synmax/leviaton/start_leviaton_client.py,sha256=XrgEHoYTsLgwyuBWkHxsCzeEGoj4C40RuDVD_0QZ_ks,4101
23
- synmax/leviaton/start_leviaton_client2.py,sha256=JdN0FJV67yqjptxw769CjRqgFdzqIdCvmpNclmnErzg,3107
24
21
  synmax/leviaton/v1/__init__.py,sha256=UgUccQqpTDS0qB20AyHb1ZCdoJvgjeWK1ZbEg2b2I6Y,93
25
22
  synmax/leviaton/v1/leviaton_client.py,sha256=rdASXkfD8V5ChNJMAUk2ZiptK-bgJpcBkdH812ih5jk,917
26
23
  synmax/leviaton/v1/leviaton_client.pyi,sha256=XwDR89SwF-Gc7YlGKxei0g0Z4e75qmFM5KzzmvMIHxo,14070
27
24
  synmax/leviaton/v1/openapi.yaml,sha256=0H4fJaVEfiDInHpY2yV03c5kZ4Bb_j_UiuMvO2Um03c,143378
28
25
  synmax/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- synmax/openapi/client.py,sha256=WC14WowLxt6hFOdA6WAKAYU9Uet7tXmQGbkkyIQf9eo,8698
30
- synmax/openapi/utils.py,sha256=q6PsmUT0D58_AdOCM0ZNw1CrveiYVF4IQN4J6ticZ4Q,3689
26
+ synmax/openapi/client.py,sha256=lwENevbQmapCLktpcPgEpsqwYOATGLWDSwkpOs_3-LY,8684
27
+ synmax/openapi/utils.py,sha256=UyNm2UJ1s3YuLnd0Cq5lWbC92OWUhguyRYyOqlFB4rk,9789
31
28
  synmax/theia/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
29
  synmax/vulcan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- synmax/vulcan/start_vulcan_python_client.py,sha256=cx4DQyrNpIR6UyzOdEFreZWVLCwHE1Z1II5dfN6SPMg,746
34
30
  synmax/vulcan/v2/__init__.py,sha256=AGMAxDs93mZ_9zF1fFAufUsu9w9Ep94lO1vbLGbD-LU,81
35
31
  synmax/vulcan/v2/openapi.yaml,sha256=NzIGFtgqH5fd7ekSjXoTl6aQAkt2Fjk2kDaqDj-0z9M,53272
36
- synmax/vulcan/v2/start_vulcan_client.py,sha256=KaCH0B71-d5Px1BUizgV5NEQk_zBmXl_3ejq79WaKcg,1708
37
- synmax/vulcan/v2/start_vulcan_client2.py,sha256=z59_ZLZ3NX7nO-50cEx7bqeuzYRj-pA4WEMlLf304qs,1833
38
32
  synmax/vulcan/v2/vulcan_client.py,sha256=aeCaISqNyJ0bezbvCcxVgdGmUPp2Lv0SFqDbFCt9TXQ,879
39
33
  synmax/vulcan/v2/vulcan_client.pyi,sha256=PwWS5qexlEWzwF3oK0N7_mgCP1ne8PFSwrlWyCd5b00,1263
34
+ synmax_api_python_client-4.16.1.dist-info/licenses/LICENSE,sha256=vKvn9cDVfJhNepCuIXLWaHnnUoDPX26KD-iWb7NAZ4M,44
40
35
  test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
36
  test/test_api_client.py,sha256=HFWCu_xBgqQXc9p6k6YmP2gVrdCFwuhoDVqlxpN1Yoc,4713
42
37
  test/test_hyperion_client.py,sha256=aCb4bMBXWofa82MInXoU9tJ5wWsg5sBRv7B_CHvkrcg,1380
43
38
  test/test_hyperion_e2e.py,sha256=BPhZH7eVQZSsFcvPdonKjmLahnfsLy37Z2DHp0LGeHc,6247
44
39
  test/test_hyperion_helpers.py,sha256=R0G7oqKaoz6jLRACODJ1Cf2gA0gaMPQhOZRjKp4a6-s,2006
45
- synmax_api_python_client-4.16.0.dist-info/LICENSE,sha256=vKvn9cDVfJhNepCuIXLWaHnnUoDPX26KD-iWb7NAZ4M,44
46
- synmax_api_python_client-4.16.0.dist-info/METADATA,sha256=8mwiRFK5IHJfXhnkIXJ2FT0JzTYeuPohhSQQBIKax_M,4994
47
- synmax_api_python_client-4.16.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
48
- synmax_api_python_client-4.16.0.dist-info/top_level.txt,sha256=SAjmDfHlJzUmjoGCT1SnS4qGSLN_ZF-p58UN1yW5kB0,17
49
- synmax_api_python_client-4.16.0.dist-info/RECORD,,
40
+ synmax_api_python_client-4.16.1.dist-info/METADATA,sha256=vkM0VHFRBA6soiZDcZSq-XyppOIUq-78ZGXfg4LfTxE,5193
41
+ synmax_api_python_client-4.16.1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
42
+ synmax_api_python_client-4.16.1.dist-info/top_level.txt,sha256=SAjmDfHlJzUmjoGCT1SnS4qGSLN_ZF-p58UN1yW5kB0,17
43
+ synmax_api_python_client-4.16.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.45.1)
2
+ Generator: setuptools (79.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,27 +0,0 @@
1
- # from synmax.hyperion.v4.hyperion_client import HyperionApiClient
2
-
3
- # access_token = "eyJwcm9qZWN0X2lkIjogIlN5bm1heCBjb21tZXJjaWFsIEFQSSIsICJwcml2YXRlX2tleSI6ICIwQndzX0ExMFpkdVQyaWlNLS1lbXh3Mk5BNUkxa09kdFNVai04RjVvNzU4IiwgImNsaWVudF9pZCI6ICJGZWxpeCBLZXkiLCAidHlwZSI6ICJvbmVfeWVhcl9saWNlbnNlZF9jdXN0b21lciIsICJzdGFydF9kYXRlIjogIjAzLzE5LzIwMjQiLCAiZW5kX2RhdGUiOiAiMDMvMTkvMjAyNSIsICJ0cmlhbF9saWNlbnNlIjogZmFsc2UsICJpc3N1ZV9kYXRldGltZSI6ICIxOS0wMy0yMDI0IDE0OjI0OjA4IiwgImFkbWluX3VzZXIiOiBmYWxzZSwgInVzZXJfcm9sZXMiOiBbImh5cGVyaW9uIiwgInZ1bGNhbiJdfQ=="
4
-
5
- # client = HyperionApiClient(access_token=access_token)
6
-
7
- # res = client.wells(response_fields=["county", "date_completion", "date_first_production", "date_permit", "date_spud", "depth_measured", "depth_tvd", "horizontal_length", "lat_bottomhole", "lon_bottomhole", "lat_surface", "lon_surface", "operator", "region_natgas", "state_code", "sub_region_natgas", "well_id", "wellbore_type", "wellpad_id", "produced_formation", "produced_basin"], date_first_production_min="2023-01-31", date_first_production_max="2024-09-01")
8
- # # res = client.daily_production()
9
- # df = res.df()
10
- # print(df)
11
-
12
- # from synmax.hyperion.v4 import HyperionApiClient
13
-
14
- from synmax.hyperion.v4 import HyperionApiClient
15
-
16
- SYNMAX_ACCESS_TOKEN = "eyJwcm9qZWN0X2lkIjogIlN5bm1heCBjb21tZXJjaWFsIEFQSSIsICJwcml2YXRlX2tleSI6ICIwQndzX0ExMFpkdVQyaWlNLS1lbXh3Mk5BNUkxa09kdFNVai04RjVvNzU4IiwgImNsaWVudF9pZCI6ICJGZWxpeCBLZXkiLCAidHlwZSI6ICJvbmVfeWVhcl9saWNlbnNlZF9jdXN0b21lciIsICJzdGFydF9kYXRlIjogIjAzLzE5LzIwMjQiLCAiZW5kX2RhdGUiOiAiMDMvMTkvMjAyNSIsICJ0cmlhbF9saWNlbnNlIjogZmFsc2UsICJpc3N1ZV9kYXRldGltZSI6ICIxOS0wMy0yMDI0IDE0OjI0OjA4IiwgImFkbWluX3VzZXIiOiBmYWxzZSwgInVzZXJfcm9sZXMiOiBbImh5cGVyaW9uIiwgInZ1bGNhbiJdfQ=="
17
- hyperion_api_client = HyperionApiClient(access_token=SYNMAX_ACCESS_TOKEN)
18
- hyperion_api_client._write_stub()
19
-
20
- # wells_resp = hyperion_api_client.wells(response_fields=["county", "date_completion", "date_first_production", "date_permit", "date_spud", "depth_measured", "depth_tvd", "horizontal_length", "lat_bottomhole", "lon_bottomhole", "lat_surface", "lon_surface", "operator", "region_natgas", "state_code", "sub_region_natgas", "well_id", "wellbore_type", "wellpad_id", "produced_formation", "produced_basin"], date_first_production_min="2023-01-31", date_first_production_max="2024-09-01")
21
- results = hyperion_api_client.fetch_tils_expanded()
22
- results_df = results.df()
23
- results_df.head()
24
- print(results_df)
25
- # wells_df = wells_resp.df()
26
- # wells_df.head()
27
- # print(wells_df)
@@ -1,105 +0,0 @@
1
- from synmax.leviaton.v1.leviaton_client import LeviatonApiClient
2
- import requests
3
- headers={'x-api-key': '36b5ee11-c0c8-4af2-a1d1-ffdd5447597b', "Accept": "application/json"}
4
- key = '36b5ee11-c0c8-4af2-a1d1-ffdd5447597b'
5
- # client = LeviatonApiClient(access_token=headers['x-api-key'])
6
- import json
7
-
8
- # claims = {
9
- # "claims": [
10
- # {"claim_name": "leviaton_volume_flows", "claim_json": {"name": "leviaton_countries", "type": "api", "filters": {}}},
11
- # {"claim_name": "leviaton_terminals", "claim_json": {"name": "leviaton_terminals", "type": "api", "filters": {}}},
12
- # {"claim_name": "leviaton_transactions", "claim_json": {"name": "leviaton_transactions", "type": "api", "filters": {}}},
13
- # {"claim_name": "leviaton_vessels", "claim_json": {"name": "leviaton_volume_flows", "type": "api", "filters": {}}},
14
- # ]
15
- # }
16
- # url = f"https://leviaton.api.synmax.com/v1/openapi.yaml"
17
- # url = "http://127.0.0.1:8080/v1/openapi.yaml"
18
- # client = LeviatonApiClient(access_token=key)
19
-
20
- # response = requests.get(url, headers=headers, verify=False)
21
- # response.raise_for_status()
22
-
23
- # with open(client._spec, "wb") as f:
24
- # f.write(response.content)
25
- # client._write_stub()
26
-
27
- # payload = {
28
- # "destination_polygons": [
29
- # [
30
- # [-125.0, 24.5],
31
- # [-125.0, 49.5],
32
- # [-66.9, 49.5],
33
- # [-66.9, 24.5],
34
- # [-125.0, 24.5]
35
- # ],
36
- # [
37
- # [122.9, 24.0],
38
- # [122.9, 45.5],
39
- # [146.0, 45.5],
40
- # [146.0, 24.0],
41
- # [122.9, 24.0]
42
- # ]
43
- # ],
44
- # "from_timestamp": "2025-05-11T12:55:47.957167",
45
- # "to_timestamp": "2025-05-21T12:55:47.957167",
46
-
47
- # }
48
- # results = client.volume_flows_history(transaction_type='loading')
49
- # # results = client.volume_flows(**payload)
50
- # print(results.df())
51
-
52
- # res = client.transactions(destination_country_codes=["US"])
53
- # print(res.df())
54
-
55
- # for result in results:
56
- # print(result)
57
-
58
- # breakpoint()
59
-
60
- # from synmax.leviaton.v1.leviaton_client import LeviatonApiClient
61
-
62
- # API Key - Replace with your actual API key
63
- # api_key = "36b5ee11-c0c8-4af2-a1d1-ffdd5447597b"
64
-
65
- # Initialize the client
66
- # client = LeviatonApiClient(access_token=key)
67
- # client._write_stub()
68
-
69
- # Fetch transactions for USA terminals
70
- # result = client.vessels_history(from_timestamp="2025-01-01T00:00:00Z", to_timestamp="2025-01-22T00:00:00Z")
71
-
72
- # Fetch transactions from specific terminals
73
- # result = client.transactions_history(
74
- # destination_terminals=["LNG Canada", "Altamira", "Freeport", "Corpus Christi"]
75
- # )
76
-
77
- # result = client.terminals(countries=["USA"])
78
- # result = client.transactions()
79
- # result = client.vessels()
80
- # result = client.vessels_details()
81
- # result = client.volume_flows_history(transaction_type='loading')
82
- # result = client.volume_flows(transaction_type='loading')
83
- # result = client.countries()
84
- # result = client.transactions_details()
85
- # result = client.transactions_forecast()
86
- # result = client.transactions_forecast_details()
87
- # result = client.transactions_forecast_history()
88
- # result = client.transactions_forecast_history_details()
89
- # result = client.vessels_history()
90
-
91
-
92
- # print(result.df())for record in result:
93
- # print(record)
94
- access_token = "eyJwcm9qZWN0X2lkIjogIlN5bm1heCBjb21tZXJjaWFsIEFQSSIsICJwcml2YXRlX2tleSI6ICI5V2lYYUZqdXl1ZkdERXBRSUFhWWd6NG4wZlZLajktVjJocHRaM0RoSWdVIiwgImNsaWVudF9pZCI6ICJzeWRuZWVfZHRpbCIsICJ0eXBlIjogImxvbmdfdGVybV9saWNlbnNlZF9jdXN0b21lciIsICJzdGFydF9kYXRlIjogIjA5LzEyLzIwMjUiLCAiZW5kX2RhdGUiOiAiMTIvMzEvOTk5OSIsICJ0cmlhbF9saWNlbnNlIjogZmFsc2UsICJpc3N1ZV9kYXRldGltZSI6ICIxMi0wOS0yMDI1IDE5OjI5OjQ1IiwgImFkbWluX3VzZXIiOiBmYWxzZSwgInVzZXJfcm9sZXMiOiBbImR0aWxfZXhwYW5zaW9uIiwgImh5cGVyaW9uIiwgInZ1bGNhbiJdfQ=="
95
-
96
- from synmax.leviaton.v1 import LeviatonApiClient
97
- LeviatonApiClient._write_stub()
98
- leviaton_client = LeviatonApiClient(access_token=access_token)
99
-
100
- # Method name:
101
-
102
- result =leviaton_client.transactions_history(loading_origin_terminals=["Corpus Christi"], from_timestamp="2025-07-15T22:43:41.371622+00:00", to_timestamp="2025-07-27T22:43:41.371622+00:00")
103
-
104
- for record in result:
105
- print(record)
@@ -1,81 +0,0 @@
1
- from synmax.leviaton.v1.leviaton_client import LeviatonApiClient
2
-
3
-
4
- # API Key - Replace with your actual API key
5
- api_key = "36b5ee11-c0c8-4af2-a1d1-ffdd5447597b"
6
-
7
- # Initialize the client
8
- client = LeviatonApiClient(access_token=api_key)
9
-
10
- # Fetch transactions for USA terminals
11
- # print('starting')
12
- # result = client.transac
13
-
14
- # print(result.df())
15
-
16
- import os
17
- import unittest
18
- from synmax.leviaton.v1.leviaton_client import LeviatonApiClient
19
- import json
20
-
21
- class TestLeviatonApiMethods(unittest.TestCase):
22
- @classmethod
23
- def setUpClass(cls):
24
- api_key = "36b5ee11-c0c8-4af2-a1d1-ffdd5447597b"
25
- # x_auth_data = json.dumps({"claims": [{"claim_name":"leviaton_countries","claim_json":{"name":"leviaton_countries","type":"api","filters":{}}},{"claim_name":"leviaton_terminals","claim_json":{"name":"leviaton_terminals","type":"api","filters":{}}},{"claim_name":"leviaton_transactions","claim_json":{"name":"leviaton_transactions","type":"api","filters":{}}},{"claim_name":"leviaton_vessels","claim_json":{"name":"leviaton_vessels","type":"api","filters":{}}},{"claim_name":"leviaton_volume_flows","claim_json":{"name":"leviaton_volume_flows","type":"api","filters":{}}}]})
26
- cls.client = LeviatonApiClient(access_token=api_key)
27
-
28
- def test_all_api_methods(self):
29
- api_methods = [
30
- "countries",
31
- "healthcheck",
32
- "terminals",
33
- "vessels",
34
- # "vessels_history",
35
- "vessels_details",
36
- "volume_flows",
37
- "volume_flows/history",
38
- "transactions",
39
- "transactions_details",
40
- "transactions_forecast",
41
- "transactions_forecast_details",
42
- "transactions_forecast_history",
43
- "transactions_forecast_history_details",
44
- "transactions_history",
45
- ]
46
-
47
- for method_name in api_methods:
48
- with self.subTest(method=method_name):
49
- print(f"Testing {method_name}...")
50
- method = getattr(self.client, method_name, None)
51
- self.assertIsNotNone(method, f"Method '{method_name}' not found on client")
52
-
53
- try:
54
- result = method()
55
- df = result.df()
56
- self.assertIsNotNone(df, f"{method_name} returned None")
57
- self.assertFalse(df.empty, f"{method_name} returned an empty dataframe")
58
- except Exception as e:
59
- self.fail(f"{method_name} raised an exception: {e}")
60
-
61
- if __name__ == "__main__":
62
- unittest.main()
63
-
64
-
65
- # from synmax.leviaton.v1.leviaton_client import LeviatonApiClient
66
-
67
- # # API Key - Replace with your actual API key
68
- # api_key = "36b5ee11-c0c8-4af2-a1d1-ffdd5447597b"
69
-
70
- # # Initialize the client
71
- # client = LeviatonApiClient(access_token=api_key)
72
-
73
- # # Fetch transactions for USA terminals
74
- # result = client.transactions_history(destination_country_codes=["US"])
75
-
76
- # # Fetch transactions from specific terminals
77
- # result = client.transactions_history(
78
- # destination_terminals=["LNG Canada", "Altamira", "Freeport", "Corpus Christi"]
79
- # )
80
-
81
- # print(result.df())
@@ -1,14 +0,0 @@
1
-
2
-
3
-
4
- from synmax.vulcan.v2 import VulcanApiClient
5
-
6
- SYNMAX_ACCESS_TOKEN = "eyJwcm9qZWN0X2lkIjogIlN5bm1heCBjb21tZXJjaWFsIEFQSSIsICJwcml2YXRlX2tleSI6ICIwQndzX0ExMFpkdVQyaWlNLS1lbXh3Mk5BNUkxa09kdFNVai04RjVvNzU4IiwgImNsaWVudF9pZCI6ICJGZWxpeCBLZXkiLCAidHlwZSI6ICJvbmVfeWVhcl9saWNlbnNlZF9jdXN0b21lciIsICJzdGFydF9kYXRlIjogIjAzLzE5LzIwMjQiLCAiZW5kX2RhdGUiOiAiMDMvMTkvMjAyNSIsICJ0cmlhbF9saWNlbnNlIjogZmFsc2UsICJpc3N1ZV9kYXRldGltZSI6ICIxOS0wMy0yMDI0IDE0OjI0OjA4IiwgImFkbWluX3VzZXIiOiBmYWxzZSwgInVzZXJfcm9sZXMiOiBbImh5cGVyaW9uIiwgInZ1bGNhbiJdfQ=="
7
- vulcan_api_client = VulcanApiClient(access_token=SYNMAX_ACCESS_TOKEN)
8
- vulcan_api_client._write_stub()
9
-
10
- # wells_resp = vulcan_api_client.iir_data()
11
-
12
- # wells_df = wells_resp.df()
13
- # wells_df.head()
14
- # print(wells_df)
@@ -1,28 +0,0 @@
1
- from synmax.vulcan.v2.vulcan_client import VulcanApiClient
2
- import json
3
-
4
- VulcanApiClient._write_stub()
5
- # access_token = os.environ.get("ACCESS_TOKEN")
6
-
7
- claims_dict = {
8
- "claims": [
9
- {"claim_name": "vulcan_datacenters", "claim_json": {"name": "vulcan_datacenters", "type": "api", "filters": {}}},
10
- {"claim_name": "vulcan_underconstruction", "claim_json": {"name": "vulcan_underconstruction", "type": "api", "filters": {}}},
11
- {"claim_name": "vulcan_lng_projects", "claim_json": {"name": "vulcan_lng_projects", "type": "api", "filters": {}}},
12
- {"claim_name": "vulcan_metadata_history", "claim_json": {"name": "vulcan_metadata_history", "type": "api", "filters": {}}},
13
- {"claim_name": "vulcan_project_rankings", "claim_json": {"name": "vulcan_project_rankings", "type": "api", "filters": {}}},
14
- {"claim_name": "vulcan_iir_data", "claim_json": {"name": "vulcan_iir_data", "type": "api", "filters": {}}},
15
- {"claim_name": "vulcan_infrastructure_watch_extended", "claim_json": {"name": "vulcan_infrastructure_watch_extended", "type": "api", "filters": {}}},
16
- ]
17
- }
18
-
19
- client = VulcanApiClient(access_token='eyJwcm9qZWN0X2lkIjogIlN5bm1heCBjb21tZXJjaWFsIEFQSSIsICJwcml2YXRlX2tleSI6ICIwQndzX0ExMFpkdVQyaWlNLS1lbXh3Mk5BNUkxa09kdFNVai04RjVvNzU4IiwgImNsaWVudF9pZCI6ICJGZWxpeCBLZXkiLCAidHlwZSI6ICJvbmVfeWVhcl9saWNlbnNlZF9jdXN0b21lciIsICJzdGFydF9kYXRlIjogIjAzLzE5LzIwMjQiLCAiZW5kX2RhdGUiOiAiMDMvMTkvMjAyNSIsICJ0cmlhbF9saWNlbnNlIjogZmFsc2UsICJpc3N1ZV9kYXRldGltZSI6ICIxOS0wMy0yMDI0IDE0OjI0OjA4IiwgImFkbWluX3VzZXIiOiBmYWxzZSwgInVzZXJfcm9sZXMiOiBbImh5cGVyaW9uIiwgInZ1bGNhbiJdfQ==')
20
-
21
-
22
- payload = {}
23
-
24
- got = client.infrastructure_watch_extended()
25
- df = got.df()
26
- print(df)
27
-
28
- print(got)
@@ -1,43 +0,0 @@
1
- # result = client.transac
2
-
3
- # print(result.df())
4
-
5
- import os
6
- import unittest
7
- from synmax.vulcan.v2.vulcan_client import VulcanApiClient
8
- import json
9
-
10
- class TestVulcanApiMethods(unittest.TestCase):
11
- @classmethod
12
- def setUpClass(cls):
13
- api_key = "PSq8zWS3FgHnVGcE2Yz4ZNOBk4SRpUPI"
14
- x_auth_data = json.dumps({"claims": [{"claim_name":"vulcan_datacenters","claim_json":{"name":"vulcan_datacenters","type":"api","filters":{}}},{"claim_name":"vulcan_underconstruction","claim_json":{"name":"vulcan_underconstruction","type":"api","filters":{}}},{"claim_name":"vulcan_lng_projects","claim_json":{"name":"vulcan_lng_projects","type":"api","filters":{}}},{"claim_name":"vulcan_project_rankings","claim_json":{"name":"vulcan_project_rankings","type":"api","filters":{}}}]})
15
- cls.client = VulcanApiClient(access_token=api_key)
16
-
17
- def test_all_api_methods(self):
18
- api_methods = [
19
- "health",
20
- "datacenters",
21
- "underconstruction",
22
- "lng_projects",
23
- "project_rankings",
24
- "iir_data"
25
- ]
26
-
27
- for method_name in api_methods:
28
- with self.subTest(method=method_name):
29
- print(f"Testing {method_name}...")
30
- method = getattr(self.client, method_name, None)
31
- self.assertIsNotNone(method, f"Method '{method_name}' not found on client")
32
-
33
- try:
34
- result = method()
35
- df = result.df()
36
- print(df)
37
- self.assertIsNotNone(df, f"{method_name} returned None")
38
- self.assertFalse(df.empty, f"{method_name} returned an empty dataframe")
39
- except Exception as e:
40
- self.fail(f"{method_name} raised an exception: {e}")
41
-
42
- if __name__ == "__main__":
43
- unittest.main()