Skip to content
This repository was archived by the owner on Feb 18, 2026. It is now read-only.

Commit 71193d2

Browse files
committed
Add python client generator fixes
1 parent 1c35f87 commit 71193d2

10 files changed

Lines changed: 236 additions & 18 deletions

File tree

clients/python/graphsense/api/addresses_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
# Backward compatibility wrapper for @validate_call to accept async_req
3535
from functools import wraps
36+
from datetime import datetime as _dt_compat
3637
from pydantic import ConfigDict
3738
_validate_call_config = ConfigDict(arbitrary_types_allowed=True)
3839

@@ -64,10 +65,29 @@ def validate_call_compat(func):
6465
validated_func = _validate_call(config=_validate_call_config)(func)
6566
@wraps(func)
6667
def wrapper(*args, **kwargs):
67-
# Remove legacy v5 kwargs that v7 doesn't support
68+
# Capture async_req before removing it
6869
async_req = kwargs.pop('async_req', False)
6970
kwargs.pop('_preload_content', None)
7071
kwargs.pop('_return_http_data_only', None)
72+
# Convert datetime to date string for date parameters (backward compatibility)
73+
# Preserve full ISO 8601 format when datetime has time/timezone info
74+
for key in list(kwargs.keys()):
75+
if 'date' in key.lower() and isinstance(kwargs[key], _dt_compat):
76+
dt = kwargs[key]
77+
if dt.hour or dt.minute or dt.second or dt.tzinfo:
78+
# Preserve full datetime with timezone (ISO 8601)
79+
kwargs[key] = dt.isoformat()
80+
else:
81+
# Date-only (midnight, no timezone) - use simple format
82+
kwargs[key] = dt.strftime('%Y-%m-%d')
83+
# Also check positional args - var_date is typically arg[1]
84+
args = list(args)
85+
for i, arg in enumerate(args):
86+
if isinstance(arg, _dt_compat):
87+
if arg.hour or arg.minute or arg.second or arg.tzinfo:
88+
args[i] = arg.isoformat()
89+
else:
90+
args[i] = arg.strftime('%Y-%m-%d')
7191

7292
# Handle async_req: submit to thread pool if available
7393
if async_req:
@@ -78,6 +98,13 @@ def wrapper(*args, **kwargs):
7898
if thread_pool is not None:
7999
future = thread_pool.submit(validated_func, *args, **kwargs)
80100
return _AsyncResult(future)
101+
else:
102+
import warnings
103+
warnings.warn(
104+
"async_req=True but no thread pool available (pool_threads=0). "
105+
"Running synchronously. Set pool_threads >= 1 for async execution.",
106+
UserWarning
107+
)
81108
# No thread pool available, fall through to sync call
82109

83110
return validated_func(*args, **kwargs)

clients/python/graphsense/api/blocks_api.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import warnings
1313
from pydantic import Field, StrictFloat, StrictStr, StrictInt
14-
from datetime import datetime as _datetime
1514
from typing import Any, Dict, List, Optional, Tuple, Union
1615
from typing_extensions import Annotated
1716

@@ -60,7 +59,7 @@ def validate_call_compat(func):
6059
validated_func = _validate_call(config=_validate_call_config)(func)
6160
@wraps(func)
6261
def wrapper(*args, **kwargs):
63-
# Remove legacy v5 kwargs that v7 doesn't support
62+
# Capture async_req before removing it
6463
async_req = kwargs.pop('async_req', False)
6564
kwargs.pop('_preload_content', None)
6665
kwargs.pop('_return_http_data_only', None)
@@ -93,6 +92,13 @@ def wrapper(*args, **kwargs):
9392
if thread_pool is not None:
9493
future = thread_pool.submit(validated_func, *args, **kwargs)
9594
return _AsyncResult(future)
95+
else:
96+
import warnings
97+
warnings.warn(
98+
"async_req=True but no thread pool available (pool_threads=0). "
99+
"Running synchronously. Set pool_threads >= 1 for async execution.",
100+
UserWarning
101+
)
96102
# No thread pool available, fall through to sync call
97103

98104
return validated_func(*args, **kwargs)
@@ -395,7 +401,7 @@ def _get_block_serialize(
395401
def get_block_by_date(
396402
self,
397403
currency: Annotated[StrictStr, Field(description="The cryptocurrency code (e.g., btc)")],
398-
var_date: Annotated[Union[StrictStr, _datetime], Field(description="The date (YYYY-MM-DD)")],
404+
var_date: Annotated[StrictStr, Field(description="The date (YYYY-MM-DD)")],
399405
_request_timeout: Union[
400406
None,
401407
Annotated[StrictFloat, Field(gt=0)],
@@ -467,7 +473,7 @@ def get_block_by_date(
467473
def get_block_by_date_with_http_info(
468474
self,
469475
currency: Annotated[StrictStr, Field(description="The cryptocurrency code (e.g., btc)")],
470-
var_date: Annotated[Union[StrictStr, _datetime], Field(description="The date (YYYY-MM-DD)")],
476+
var_date: Annotated[StrictStr, Field(description="The date (YYYY-MM-DD)")],
471477
_request_timeout: Union[
472478
None,
473479
Annotated[StrictFloat, Field(gt=0)],
@@ -539,7 +545,7 @@ def get_block_by_date_with_http_info(
539545
def get_block_by_date_without_preload_content(
540546
self,
541547
currency: Annotated[StrictStr, Field(description="The cryptocurrency code (e.g., btc)")],
542-
var_date: Annotated[Union[StrictStr, _datetime], Field(description="The date (YYYY-MM-DD)")],
548+
var_date: Annotated[StrictStr, Field(description="The date (YYYY-MM-DD)")],
543549
_request_timeout: Union[
544550
None,
545551
Annotated[StrictFloat, Field(gt=0)],
@@ -613,10 +619,6 @@ def _get_block_by_date_serialize(
613619
_host_index,
614620
) -> RequestSerialized:
615621

616-
617-
# Convert datetime to string for backward compatibility
618-
if isinstance(var_date, _datetime):
619-
var_date = var_date.strftime('%Y-%m-%d')
620622
_host = None
621623

622624
_collection_formats: Dict[str, str] = {

clients/python/graphsense/api/bulk_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
# Backward compatibility wrapper for @validate_call to accept async_req
2626
from functools import wraps
27+
from datetime import datetime as _dt_compat
2728
from pydantic import ConfigDict
2829
_validate_call_config = ConfigDict(arbitrary_types_allowed=True)
2930

@@ -55,10 +56,29 @@ def validate_call_compat(func):
5556
validated_func = _validate_call(config=_validate_call_config)(func)
5657
@wraps(func)
5758
def wrapper(*args, **kwargs):
58-
# Remove legacy v5 kwargs that v7 doesn't support
59+
# Capture async_req before removing it
5960
async_req = kwargs.pop('async_req', False)
6061
kwargs.pop('_preload_content', None)
6162
kwargs.pop('_return_http_data_only', None)
63+
# Convert datetime to date string for date parameters (backward compatibility)
64+
# Preserve full ISO 8601 format when datetime has time/timezone info
65+
for key in list(kwargs.keys()):
66+
if 'date' in key.lower() and isinstance(kwargs[key], _dt_compat):
67+
dt = kwargs[key]
68+
if dt.hour or dt.minute or dt.second or dt.tzinfo:
69+
# Preserve full datetime with timezone (ISO 8601)
70+
kwargs[key] = dt.isoformat()
71+
else:
72+
# Date-only (midnight, no timezone) - use simple format
73+
kwargs[key] = dt.strftime('%Y-%m-%d')
74+
# Also check positional args - var_date is typically arg[1]
75+
args = list(args)
76+
for i, arg in enumerate(args):
77+
if isinstance(arg, _dt_compat):
78+
if arg.hour or arg.minute or arg.second or arg.tzinfo:
79+
args[i] = arg.isoformat()
80+
else:
81+
args[i] = arg.strftime('%Y-%m-%d')
6282

6383
# Handle async_req: submit to thread pool if available
6484
if async_req:
@@ -69,6 +89,13 @@ def wrapper(*args, **kwargs):
6989
if thread_pool is not None:
7090
future = thread_pool.submit(validated_func, *args, **kwargs)
7191
return _AsyncResult(future)
92+
else:
93+
import warnings
94+
warnings.warn(
95+
"async_req=True but no thread pool available (pool_threads=0). "
96+
"Running synchronously. Set pool_threads >= 1 for async execution.",
97+
UserWarning
98+
)
7299
# No thread pool available, fall through to sync call
73100

74101
return validated_func(*args, **kwargs)

clients/python/graphsense/api/entities_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
# Backward compatibility wrapper for @validate_call to accept async_req
3333
from functools import wraps
34+
from datetime import datetime as _dt_compat
3435
from pydantic import ConfigDict
3536
_validate_call_config = ConfigDict(arbitrary_types_allowed=True)
3637

@@ -62,10 +63,29 @@ def validate_call_compat(func):
6263
validated_func = _validate_call(config=_validate_call_config)(func)
6364
@wraps(func)
6465
def wrapper(*args, **kwargs):
65-
# Remove legacy v5 kwargs that v7 doesn't support
66+
# Capture async_req before removing it
6667
async_req = kwargs.pop('async_req', False)
6768
kwargs.pop('_preload_content', None)
6869
kwargs.pop('_return_http_data_only', None)
70+
# Convert datetime to date string for date parameters (backward compatibility)
71+
# Preserve full ISO 8601 format when datetime has time/timezone info
72+
for key in list(kwargs.keys()):
73+
if 'date' in key.lower() and isinstance(kwargs[key], _dt_compat):
74+
dt = kwargs[key]
75+
if dt.hour or dt.minute or dt.second or dt.tzinfo:
76+
# Preserve full datetime with timezone (ISO 8601)
77+
kwargs[key] = dt.isoformat()
78+
else:
79+
# Date-only (midnight, no timezone) - use simple format
80+
kwargs[key] = dt.strftime('%Y-%m-%d')
81+
# Also check positional args - var_date is typically arg[1]
82+
args = list(args)
83+
for i, arg in enumerate(args):
84+
if isinstance(arg, _dt_compat):
85+
if arg.hour or arg.minute or arg.second or arg.tzinfo:
86+
args[i] = arg.isoformat()
87+
else:
88+
args[i] = arg.strftime('%Y-%m-%d')
6989

7090
# Handle async_req: submit to thread pool if available
7191
if async_req:
@@ -76,6 +96,13 @@ def wrapper(*args, **kwargs):
7696
if thread_pool is not None:
7797
future = thread_pool.submit(validated_func, *args, **kwargs)
7898
return _AsyncResult(future)
99+
else:
100+
import warnings
101+
warnings.warn(
102+
"async_req=True but no thread pool available (pool_threads=0). "
103+
"Running synchronously. Set pool_threads >= 1 for async execution.",
104+
UserWarning
105+
)
79106
# No thread pool available, fall through to sync call
80107

81108
return validated_func(*args, **kwargs)

clients/python/graphsense/api/general_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
# Backward compatibility wrapper for @validate_call to accept async_req
2828
from functools import wraps
29+
from datetime import datetime as _dt_compat
2930
from pydantic import ConfigDict
3031
_validate_call_config = ConfigDict(arbitrary_types_allowed=True)
3132

@@ -57,10 +58,29 @@ def validate_call_compat(func):
5758
validated_func = _validate_call(config=_validate_call_config)(func)
5859
@wraps(func)
5960
def wrapper(*args, **kwargs):
60-
# Remove legacy v5 kwargs that v7 doesn't support
61+
# Capture async_req before removing it
6162
async_req = kwargs.pop('async_req', False)
6263
kwargs.pop('_preload_content', None)
6364
kwargs.pop('_return_http_data_only', None)
65+
# Convert datetime to date string for date parameters (backward compatibility)
66+
# Preserve full ISO 8601 format when datetime has time/timezone info
67+
for key in list(kwargs.keys()):
68+
if 'date' in key.lower() and isinstance(kwargs[key], _dt_compat):
69+
dt = kwargs[key]
70+
if dt.hour or dt.minute or dt.second or dt.tzinfo:
71+
# Preserve full datetime with timezone (ISO 8601)
72+
kwargs[key] = dt.isoformat()
73+
else:
74+
# Date-only (midnight, no timezone) - use simple format
75+
kwargs[key] = dt.strftime('%Y-%m-%d')
76+
# Also check positional args - var_date is typically arg[1]
77+
args = list(args)
78+
for i, arg in enumerate(args):
79+
if isinstance(arg, _dt_compat):
80+
if arg.hour or arg.minute or arg.second or arg.tzinfo:
81+
args[i] = arg.isoformat()
82+
else:
83+
args[i] = arg.strftime('%Y-%m-%d')
6484

6585
# Handle async_req: submit to thread pool if available
6686
if async_req:
@@ -71,6 +91,13 @@ def wrapper(*args, **kwargs):
7191
if thread_pool is not None:
7292
future = thread_pool.submit(validated_func, *args, **kwargs)
7393
return _AsyncResult(future)
94+
else:
95+
import warnings
96+
warnings.warn(
97+
"async_req=True but no thread pool available (pool_threads=0). "
98+
"Running synchronously. Set pool_threads >= 1 for async execution.",
99+
UserWarning
100+
)
74101
# No thread pool available, fall through to sync call
75102

76103
return validated_func(*args, **kwargs)

clients/python/graphsense/api/rates_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
# Backward compatibility wrapper for @validate_call to accept async_req
2626
from functools import wraps
27+
from datetime import datetime as _dt_compat
2728
from pydantic import ConfigDict
2829
_validate_call_config = ConfigDict(arbitrary_types_allowed=True)
2930

@@ -55,10 +56,29 @@ def validate_call_compat(func):
5556
validated_func = _validate_call(config=_validate_call_config)(func)
5657
@wraps(func)
5758
def wrapper(*args, **kwargs):
58-
# Remove legacy v5 kwargs that v7 doesn't support
59+
# Capture async_req before removing it
5960
async_req = kwargs.pop('async_req', False)
6061
kwargs.pop('_preload_content', None)
6162
kwargs.pop('_return_http_data_only', None)
63+
# Convert datetime to date string for date parameters (backward compatibility)
64+
# Preserve full ISO 8601 format when datetime has time/timezone info
65+
for key in list(kwargs.keys()):
66+
if 'date' in key.lower() and isinstance(kwargs[key], _dt_compat):
67+
dt = kwargs[key]
68+
if dt.hour or dt.minute or dt.second or dt.tzinfo:
69+
# Preserve full datetime with timezone (ISO 8601)
70+
kwargs[key] = dt.isoformat()
71+
else:
72+
# Date-only (midnight, no timezone) - use simple format
73+
kwargs[key] = dt.strftime('%Y-%m-%d')
74+
# Also check positional args - var_date is typically arg[1]
75+
args = list(args)
76+
for i, arg in enumerate(args):
77+
if isinstance(arg, _dt_compat):
78+
if arg.hour or arg.minute or arg.second or arg.tzinfo:
79+
args[i] = arg.isoformat()
80+
else:
81+
args[i] = arg.strftime('%Y-%m-%d')
6282

6383
# Handle async_req: submit to thread pool if available
6484
if async_req:
@@ -69,6 +89,13 @@ def wrapper(*args, **kwargs):
6989
if thread_pool is not None:
7090
future = thread_pool.submit(validated_func, *args, **kwargs)
7191
return _AsyncResult(future)
92+
else:
93+
import warnings
94+
warnings.warn(
95+
"async_req=True but no thread pool available (pool_threads=0). "
96+
"Running synchronously. Set pool_threads >= 1 for async execution.",
97+
UserWarning
98+
)
7299
# No thread pool available, fall through to sync call
73100

74101
return validated_func(*args, **kwargs)

clients/python/graphsense/api/tags_api.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
# Backward compatibility wrapper for @validate_call to accept async_req
3232
from functools import wraps
33+
from datetime import datetime as _dt_compat
3334
from pydantic import ConfigDict
3435
_validate_call_config = ConfigDict(arbitrary_types_allowed=True)
3536

@@ -61,10 +62,29 @@ def validate_call_compat(func):
6162
validated_func = _validate_call(config=_validate_call_config)(func)
6263
@wraps(func)
6364
def wrapper(*args, **kwargs):
64-
# Remove legacy v5 kwargs that v7 doesn't support
65+
# Capture async_req before removing it
6566
async_req = kwargs.pop('async_req', False)
6667
kwargs.pop('_preload_content', None)
6768
kwargs.pop('_return_http_data_only', None)
69+
# Convert datetime to date string for date parameters (backward compatibility)
70+
# Preserve full ISO 8601 format when datetime has time/timezone info
71+
for key in list(kwargs.keys()):
72+
if 'date' in key.lower() and isinstance(kwargs[key], _dt_compat):
73+
dt = kwargs[key]
74+
if dt.hour or dt.minute or dt.second or dt.tzinfo:
75+
# Preserve full datetime with timezone (ISO 8601)
76+
kwargs[key] = dt.isoformat()
77+
else:
78+
# Date-only (midnight, no timezone) - use simple format
79+
kwargs[key] = dt.strftime('%Y-%m-%d')
80+
# Also check positional args - var_date is typically arg[1]
81+
args = list(args)
82+
for i, arg in enumerate(args):
83+
if isinstance(arg, _dt_compat):
84+
if arg.hour or arg.minute or arg.second or arg.tzinfo:
85+
args[i] = arg.isoformat()
86+
else:
87+
args[i] = arg.strftime('%Y-%m-%d')
6888

6989
# Handle async_req: submit to thread pool if available
7090
if async_req:
@@ -75,6 +95,13 @@ def wrapper(*args, **kwargs):
7595
if thread_pool is not None:
7696
future = thread_pool.submit(validated_func, *args, **kwargs)
7797
return _AsyncResult(future)
98+
else:
99+
import warnings
100+
warnings.warn(
101+
"async_req=True but no thread pool available (pool_threads=0). "
102+
"Running synchronously. Set pool_threads >= 1 for async execution.",
103+
UserWarning
104+
)
78105
# No thread pool available, fall through to sync call
79106

80107
return validated_func(*args, **kwargs)

0 commit comments

Comments
 (0)