graphsense-python 2.11.0__tar.gz → 2.13.0__tar.gz
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.
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/PKG-INFO +31 -16
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/README.md +26 -15
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/__init__.py +1 -1
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/addresses_api.py +309 -6
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api_client.py +1 -1
- graphsense_python-2.13.0/graphsense/cli/__init__.py +1 -0
- graphsense_python-2.13.0/graphsense/cli/__main__.py +4 -0
- graphsense_python-2.13.0/graphsense/cli/bulk_cmd.py +95 -0
- graphsense_python-2.13.0/graphsense/cli/context.py +64 -0
- graphsense_python-2.13.0/graphsense/cli/convenience.py +444 -0
- graphsense_python-2.13.0/graphsense/cli/errors.py +74 -0
- graphsense_python-2.13.0/graphsense/cli/gs.py +139 -0
- graphsense_python-2.13.0/graphsense/cli/main.py +218 -0
- graphsense_python-2.13.0/graphsense/cli/raw.py +259 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/configuration.py +2 -2
- graphsense_python-2.13.0/graphsense/ext/__init__.py +6 -0
- graphsense_python-2.13.0/graphsense/ext/bulk.py +51 -0
- graphsense_python-2.13.0/graphsense/ext/client.py +520 -0
- graphsense_python-2.13.0/graphsense/ext/deprecation.py +81 -0
- graphsense_python-2.13.0/graphsense/ext/io.py +229 -0
- graphsense_python-2.13.0/graphsense/ext/output.py +245 -0
- graphsense_python-2.13.0/graphsense/ext/selectors.py +28 -0
- graphsense_python-2.13.0/graphsense/gs_files/__init__.py +69 -0
- graphsense_python-2.13.0/graphsense/gs_files/encoder.py +336 -0
- graphsense_python-2.13.0/graphsense/gs_files/parser.py +440 -0
- graphsense_python-2.13.0/graphsense/gs_files/summary.py +34 -0
- graphsense_python-2.13.0/graphsense/gs_files/writer.py +73 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address.py +3 -1
- graphsense_python-2.13.0/graphsense/models/cluster.py +140 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/entity.py +1 -1
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/neighbor_cluster.py +8 -2
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/neighbor_entity.py +9 -3
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense_python.egg-info/PKG-INFO +31 -16
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense_python.egg-info/SOURCES.txt +37 -1
- graphsense_python-2.13.0/graphsense_python.egg-info/entry_points.txt +2 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense_python.egg-info/requires.txt +5 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/pyproject.toml +19 -1
- graphsense_python-2.13.0/tests/test_cli_bulk.py +85 -0
- graphsense_python-2.13.0/tests/test_cli_convenience.py +295 -0
- graphsense_python-2.13.0/tests/test_cli_errors.py +118 -0
- graphsense_python-2.13.0/tests/test_cli_gs.py +80 -0
- graphsense_python-2.13.0/tests/test_cli_io_pipes.py +132 -0
- graphsense_python-2.13.0/tests/test_cli_raw_mirror.py +88 -0
- graphsense_python-2.13.0/tests/test_cli_tags_and_dates.py +360 -0
- graphsense_python-2.13.0/tests/test_ext_bulk.py +53 -0
- graphsense_python-2.13.0/tests/test_ext_client.py +217 -0
- graphsense_python-2.13.0/tests/test_ext_io.py +181 -0
- graphsense_python-2.13.0/tests/test_ext_output.py +168 -0
- graphsense_python-2.13.0/tests/test_ext_selectors.py +25 -0
- graphsense_python-2.13.0/tests/test_readme_template.py +45 -0
- graphsense_python-2.13.0/tests/test_regen_survives.py +60 -0
- graphsense_python-2.11.0/graphsense/models/cluster.py +0 -191
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/__init__.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/blocks_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/bulk_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/clusters_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/entities_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/general_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/rates_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/tags_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/tokens_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api/txs_api.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/api_response.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/compat.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/exceptions.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/__init__.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/actor.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/actor_context.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/address.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/address_tag.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/address_tags.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/address_tx.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/address_tx_utxo.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/address_txs.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/block.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/block_at_date.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/concept.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/currency_stats.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/entity.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/entity_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/external_conversion.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/http_validation_error.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/label_summary.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/labeled_item_ref.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/link.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/link_utxo.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/links.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/links_inner.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/location_inner.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/neighbor_address.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/neighbor_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/neighbor_entities.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/neighbor_entity.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/rate.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/rates.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/related_address.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/related_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_by_currency.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_level1.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_level2.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_level3.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_level4.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_level5.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/search_result_level6.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/stats.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tag.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tag_cloud_entry.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tag_summary.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/taxonomy.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/token_config.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/token_configs.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tx.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tx_account.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tx_ref.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tx_summary.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tx_utxo.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/tx_value.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/user_reported_tag.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/user_tag_report_response.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/validation_error.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/model/values.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/__init__.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/actor.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/actor_context.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address_output.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address_tag.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address_tags.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address_tx.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address_tx_utxo.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/address_txs.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/block.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/block_at_date.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/change_heuristics.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/cluster_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/coin_join_consensus.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/coin_join_heuristics.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/concept.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/consensus_entry.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/currency_stats.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/direct_change_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/entity_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/external_conversion.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/http_validation_error.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/join_market_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/label_summary.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/labeled_item_ref.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/link.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/link_utxo.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/links.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/links_inner.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/location_inner.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/multi_input_change_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/neighbor_address.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/neighbor_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/neighbor_clusters.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/neighbor_entities.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/one_time_change_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/rate.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/rates.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/related_address.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/related_addresses.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_by_currency.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_level1.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_level2.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_level3.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_level4.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_level5.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/search_result_level6.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/stats.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tag.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tag_cloud_entry.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tag_summary.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/taxonomy.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/token_config.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/token_configs.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tx.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tx_account.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tx_ref.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tx_summary.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tx_utxo.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/tx_value.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/user_reported_tag.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/user_tag_report_response.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/utxo_heuristics.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/validation_error.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/values.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/wasabi_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/whirlpool_coin_join_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/models/whirlpool_tx0_heuristic.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/py.typed +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense/rest.py +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense_python.egg-info/dependency_links.txt +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/graphsense_python.egg-info/top_level.txt +0 -0
- {graphsense_python-2.11.0 → graphsense_python-2.13.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphsense-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.13.0
|
|
4
4
|
Summary: GraphSense API
|
|
5
5
|
Author-email: Iknaio Cryptoasset Analytics GmbH <contact@iknaio.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,6 +15,10 @@ Requires-Dist: urllib3<3.0.0,>=2.1.0
|
|
|
15
15
|
Requires-Dist: python-dateutil>=2.8.2
|
|
16
16
|
Requires-Dist: pydantic>=2
|
|
17
17
|
Requires-Dist: typing-extensions>=4.7.1
|
|
18
|
+
Provides-Extra: cli
|
|
19
|
+
Requires-Dist: rich-click>=1.7; extra == "cli"
|
|
20
|
+
Requires-Dist: jmespath>=1.0; extra == "cli"
|
|
21
|
+
Requires-Dist: pygments>=2.15; extra == "cli"
|
|
18
22
|
|
|
19
23
|
# graphsense-python
|
|
20
24
|
GraphSense API provides programmatic access to blockchain analytics data across
|
|
@@ -41,8 +45,8 @@ for details.
|
|
|
41
45
|
|
|
42
46
|
This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
|
43
47
|
|
|
44
|
-
- API version: 2.
|
|
45
|
-
- Package version: 2.
|
|
48
|
+
- API version: 2.13.0
|
|
49
|
+
- Package version: 2.13.0
|
|
46
50
|
- Generator version: 7.19.0
|
|
47
51
|
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
|
48
52
|
For more information, please visit [https://www.iknaio.com/](https://www.iknaio.com/)
|
|
@@ -52,37 +56,39 @@ For more information, please visit [https://www.iknaio.com/](https://www.iknaio.
|
|
|
52
56
|
Python 3.9+
|
|
53
57
|
|
|
54
58
|
## Installation & Usage
|
|
55
|
-
### pip install
|
|
56
59
|
|
|
57
|
-
|
|
60
|
+
This project uses [uv](https://docs.astral.sh/uv/) for environment and
|
|
61
|
+
dependency management.
|
|
62
|
+
|
|
63
|
+
### Add to a uv project
|
|
58
64
|
|
|
59
65
|
```sh
|
|
60
|
-
|
|
66
|
+
uv add graphsense-python
|
|
67
|
+
# or, to include the optional `[cli]` extra (installs the `graphsense` CLI):
|
|
68
|
+
uv add 'graphsense-python[cli]'
|
|
61
69
|
```
|
|
62
|
-
(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`)
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
```python
|
|
66
|
-
import graphsense
|
|
67
|
-
```
|
|
71
|
+
### Install from git
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
```sh
|
|
74
|
+
uv add 'git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git'
|
|
75
|
+
```
|
|
70
76
|
|
|
71
|
-
|
|
77
|
+
### One-off script usage
|
|
72
78
|
|
|
73
79
|
```sh
|
|
74
|
-
python
|
|
80
|
+
uv run --with graphsense-python python my_script.py
|
|
75
81
|
```
|
|
76
|
-
(or `sudo python setup.py install` to install the package for all users)
|
|
77
82
|
|
|
78
83
|
Then import the package:
|
|
84
|
+
|
|
79
85
|
```python
|
|
80
86
|
import graphsense
|
|
81
87
|
```
|
|
82
88
|
|
|
83
89
|
### Tests
|
|
84
90
|
|
|
85
|
-
Execute `pytest` to run the tests.
|
|
91
|
+
Execute `uv run pytest` to run the tests.
|
|
86
92
|
|
|
87
93
|
## Getting Started
|
|
88
94
|
|
|
@@ -137,6 +143,7 @@ All URIs are relative to *https://api.iknaio.com*
|
|
|
137
143
|
Class | Method | HTTP request | Description
|
|
138
144
|
------------ | ------------- | ------------- | -------------
|
|
139
145
|
*AddressesApi* | [**get_address**](docs/AddressesApi.md#get_address) | **GET** /{currency}/addresses/{address} | Get an address
|
|
146
|
+
*AddressesApi* | [**get_address_cluster**](docs/AddressesApi.md#get_address_cluster) | **GET** /{currency}/addresses/{address}/cluster | Get the cluster for an address
|
|
140
147
|
*AddressesApi* | [**get_address_entity**](docs/AddressesApi.md#get_address_entity) | **GET** /{currency}/addresses/{address}/entity | Get the entity for an address
|
|
141
148
|
*AddressesApi* | [**get_tag_summary_by_address**](docs/AddressesApi.md#get_tag_summary_by_address) | **GET** /{currency}/addresses/{address}/tag_summary | Get address attribution tag summary
|
|
142
149
|
*AddressesApi* | [**list_address_links**](docs/AddressesApi.md#list_address_links) | **GET** /{currency}/addresses/{address}/links | List transactions between two addresses
|
|
@@ -277,3 +284,11 @@ Authentication schemes defined for the API:
|
|
|
277
284
|
contact@iknaio.com
|
|
278
285
|
|
|
279
286
|
|
|
287
|
+
## Using the high-level wrapper or CLI
|
|
288
|
+
|
|
289
|
+
- **Python** — [`README_EXT.md`](README_EXT.md) documents
|
|
290
|
+
`graphsense.ext.GraphSense`, a single facade that removes boilerplate and
|
|
291
|
+
bundles commonly-paired calls (ships with the base install).
|
|
292
|
+
- **Shell** — [`README_CLI.md`](README_CLI.md) documents the `graphsense` CLI
|
|
293
|
+
(installed via `uv add 'graphsense-python[cli]'`): pipe-friendly,
|
|
294
|
+
JSON/CSV I/O, auto-bulk.
|
|
@@ -23,8 +23,8 @@ for details.
|
|
|
23
23
|
|
|
24
24
|
This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
|
25
25
|
|
|
26
|
-
- API version: 2.
|
|
27
|
-
- Package version: 2.
|
|
26
|
+
- API version: 2.13.0
|
|
27
|
+
- Package version: 2.13.0
|
|
28
28
|
- Generator version: 7.19.0
|
|
29
29
|
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
|
30
30
|
For more information, please visit [https://www.iknaio.com/](https://www.iknaio.com/)
|
|
@@ -34,37 +34,39 @@ For more information, please visit [https://www.iknaio.com/](https://www.iknaio.
|
|
|
34
34
|
Python 3.9+
|
|
35
35
|
|
|
36
36
|
## Installation & Usage
|
|
37
|
-
### pip install
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
This project uses [uv](https://docs.astral.sh/uv/) for environment and
|
|
39
|
+
dependency management.
|
|
40
|
+
|
|
41
|
+
### Add to a uv project
|
|
40
42
|
|
|
41
43
|
```sh
|
|
42
|
-
|
|
44
|
+
uv add graphsense-python
|
|
45
|
+
# or, to include the optional `[cli]` extra (installs the `graphsense` CLI):
|
|
46
|
+
uv add 'graphsense-python[cli]'
|
|
43
47
|
```
|
|
44
|
-
(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`)
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
```python
|
|
48
|
-
import graphsense
|
|
49
|
-
```
|
|
49
|
+
### Install from git
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
```sh
|
|
52
|
+
uv add 'git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git'
|
|
53
|
+
```
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
### One-off script usage
|
|
54
56
|
|
|
55
57
|
```sh
|
|
56
|
-
python
|
|
58
|
+
uv run --with graphsense-python python my_script.py
|
|
57
59
|
```
|
|
58
|
-
(or `sudo python setup.py install` to install the package for all users)
|
|
59
60
|
|
|
60
61
|
Then import the package:
|
|
62
|
+
|
|
61
63
|
```python
|
|
62
64
|
import graphsense
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
### Tests
|
|
66
68
|
|
|
67
|
-
Execute `pytest` to run the tests.
|
|
69
|
+
Execute `uv run pytest` to run the tests.
|
|
68
70
|
|
|
69
71
|
## Getting Started
|
|
70
72
|
|
|
@@ -119,6 +121,7 @@ All URIs are relative to *https://api.iknaio.com*
|
|
|
119
121
|
Class | Method | HTTP request | Description
|
|
120
122
|
------------ | ------------- | ------------- | -------------
|
|
121
123
|
*AddressesApi* | [**get_address**](docs/AddressesApi.md#get_address) | **GET** /{currency}/addresses/{address} | Get an address
|
|
124
|
+
*AddressesApi* | [**get_address_cluster**](docs/AddressesApi.md#get_address_cluster) | **GET** /{currency}/addresses/{address}/cluster | Get the cluster for an address
|
|
122
125
|
*AddressesApi* | [**get_address_entity**](docs/AddressesApi.md#get_address_entity) | **GET** /{currency}/addresses/{address}/entity | Get the entity for an address
|
|
123
126
|
*AddressesApi* | [**get_tag_summary_by_address**](docs/AddressesApi.md#get_tag_summary_by_address) | **GET** /{currency}/addresses/{address}/tag_summary | Get address attribution tag summary
|
|
124
127
|
*AddressesApi* | [**list_address_links**](docs/AddressesApi.md#list_address_links) | **GET** /{currency}/addresses/{address}/links | List transactions between two addresses
|
|
@@ -259,3 +262,11 @@ Authentication schemes defined for the API:
|
|
|
259
262
|
contact@iknaio.com
|
|
260
263
|
|
|
261
264
|
|
|
265
|
+
## Using the high-level wrapper or CLI
|
|
266
|
+
|
|
267
|
+
- **Python** — [`README_EXT.md`](README_EXT.md) documents
|
|
268
|
+
`graphsense.ext.GraphSense`, a single facade that removes boilerplate and
|
|
269
|
+
bundles commonly-paired calls (ships with the base install).
|
|
270
|
+
- **Shell** — [`README_CLI.md`](README_CLI.md) documents the `graphsense` CLI
|
|
271
|
+
(installed via `uv add 'graphsense-python[cli]'`): pipe-friendly,
|
|
272
|
+
JSON/CSV I/O, auto-bulk.
|
|
@@ -20,6 +20,7 @@ from typing_extensions import Annotated
|
|
|
20
20
|
from graphsense.models.address import Address
|
|
21
21
|
from graphsense.models.address_tags import AddressTags
|
|
22
22
|
from graphsense.models.address_txs import AddressTxs
|
|
23
|
+
from graphsense.models.cluster import Cluster
|
|
23
24
|
from graphsense.models.entity import Entity
|
|
24
25
|
from graphsense.models.links import Links
|
|
25
26
|
from graphsense.models.neighbor_addresses import NeighborAddresses
|
|
@@ -433,6 +434,305 @@ class AddressesApi:
|
|
|
433
434
|
|
|
434
435
|
|
|
435
436
|
|
|
437
|
+
@validate_call_compat
|
|
438
|
+
def get_address_cluster(
|
|
439
|
+
self,
|
|
440
|
+
currency: Annotated[StrictStr, Field(description="The cryptocurrency code (e.g., btc)")],
|
|
441
|
+
address: Annotated[StrictStr, Field(description="The cryptocurrency address")],
|
|
442
|
+
include_actors: Annotated[Optional[StrictBool], Field(description="Whether to include actor information")] = None,
|
|
443
|
+
_request_timeout: Union[
|
|
444
|
+
None,
|
|
445
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
446
|
+
Tuple[
|
|
447
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
448
|
+
Annotated[StrictFloat, Field(gt=0)]
|
|
449
|
+
]
|
|
450
|
+
] = None,
|
|
451
|
+
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
|
452
|
+
_content_type: Optional[StrictStr] = None,
|
|
453
|
+
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
454
|
+
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
455
|
+
) -> Cluster:
|
|
456
|
+
"""Get the cluster for an address
|
|
457
|
+
|
|
458
|
+
Returns the address cluster that contains the given address.
|
|
459
|
+
|
|
460
|
+
:param currency: The cryptocurrency code (e.g., btc) (required)
|
|
461
|
+
:type currency: str
|
|
462
|
+
:param address: The cryptocurrency address (required)
|
|
463
|
+
:type address: str
|
|
464
|
+
:param include_actors: Whether to include actor information
|
|
465
|
+
:type include_actors: bool
|
|
466
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
467
|
+
number provided, it will be total request
|
|
468
|
+
timeout. It can also be a pair (tuple) of
|
|
469
|
+
(connection, read) timeouts.
|
|
470
|
+
:type _request_timeout: int, tuple(int, int), optional
|
|
471
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
472
|
+
request; this effectively ignores the
|
|
473
|
+
authentication in the spec for a single request.
|
|
474
|
+
:type _request_auth: dict, optional
|
|
475
|
+
:param _content_type: force content-type for the request.
|
|
476
|
+
:type _content_type: str, Optional
|
|
477
|
+
:param _headers: set to override the headers for a single
|
|
478
|
+
request; this effectively ignores the headers
|
|
479
|
+
in the spec for a single request.
|
|
480
|
+
:type _headers: dict, optional
|
|
481
|
+
:param _host_index: set to override the host_index for a single
|
|
482
|
+
request; this effectively ignores the host_index
|
|
483
|
+
in the spec for a single request.
|
|
484
|
+
:type _host_index: int, optional
|
|
485
|
+
:return: Returns the result object.
|
|
486
|
+
""" # noqa: E501
|
|
487
|
+
|
|
488
|
+
_param = self._get_address_cluster_serialize(
|
|
489
|
+
currency=currency,
|
|
490
|
+
address=address,
|
|
491
|
+
include_actors=include_actors,
|
|
492
|
+
_request_auth=_request_auth,
|
|
493
|
+
_content_type=_content_type,
|
|
494
|
+
_headers=_headers,
|
|
495
|
+
_host_index=_host_index
|
|
496
|
+
)
|
|
497
|
+
|
|
498
|
+
_response_types_map: Dict[str, Optional[str]] = {
|
|
499
|
+
'200': "Cluster",
|
|
500
|
+
'404': None,
|
|
501
|
+
'422': "HTTPValidationError",
|
|
502
|
+
}
|
|
503
|
+
response_data = self.api_client.call_api(
|
|
504
|
+
*_param,
|
|
505
|
+
_request_timeout=_request_timeout
|
|
506
|
+
)
|
|
507
|
+
response_data.read()
|
|
508
|
+
return self.api_client.response_deserialize(
|
|
509
|
+
response_data=response_data,
|
|
510
|
+
response_types_map=_response_types_map,
|
|
511
|
+
).data
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
@validate_call_compat
|
|
515
|
+
def get_address_cluster_with_http_info(
|
|
516
|
+
self,
|
|
517
|
+
currency: Annotated[StrictStr, Field(description="The cryptocurrency code (e.g., btc)")],
|
|
518
|
+
address: Annotated[StrictStr, Field(description="The cryptocurrency address")],
|
|
519
|
+
include_actors: Annotated[Optional[StrictBool], Field(description="Whether to include actor information")] = None,
|
|
520
|
+
_request_timeout: Union[
|
|
521
|
+
None,
|
|
522
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
523
|
+
Tuple[
|
|
524
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
525
|
+
Annotated[StrictFloat, Field(gt=0)]
|
|
526
|
+
]
|
|
527
|
+
] = None,
|
|
528
|
+
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
|
529
|
+
_content_type: Optional[StrictStr] = None,
|
|
530
|
+
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
531
|
+
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
532
|
+
) -> ApiResponse[Cluster]:
|
|
533
|
+
"""Get the cluster for an address
|
|
534
|
+
|
|
535
|
+
Returns the address cluster that contains the given address.
|
|
536
|
+
|
|
537
|
+
:param currency: The cryptocurrency code (e.g., btc) (required)
|
|
538
|
+
:type currency: str
|
|
539
|
+
:param address: The cryptocurrency address (required)
|
|
540
|
+
:type address: str
|
|
541
|
+
:param include_actors: Whether to include actor information
|
|
542
|
+
:type include_actors: bool
|
|
543
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
544
|
+
number provided, it will be total request
|
|
545
|
+
timeout. It can also be a pair (tuple) of
|
|
546
|
+
(connection, read) timeouts.
|
|
547
|
+
:type _request_timeout: int, tuple(int, int), optional
|
|
548
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
549
|
+
request; this effectively ignores the
|
|
550
|
+
authentication in the spec for a single request.
|
|
551
|
+
:type _request_auth: dict, optional
|
|
552
|
+
:param _content_type: force content-type for the request.
|
|
553
|
+
:type _content_type: str, Optional
|
|
554
|
+
:param _headers: set to override the headers for a single
|
|
555
|
+
request; this effectively ignores the headers
|
|
556
|
+
in the spec for a single request.
|
|
557
|
+
:type _headers: dict, optional
|
|
558
|
+
:param _host_index: set to override the host_index for a single
|
|
559
|
+
request; this effectively ignores the host_index
|
|
560
|
+
in the spec for a single request.
|
|
561
|
+
:type _host_index: int, optional
|
|
562
|
+
:return: Returns the result object.
|
|
563
|
+
""" # noqa: E501
|
|
564
|
+
|
|
565
|
+
_param = self._get_address_cluster_serialize(
|
|
566
|
+
currency=currency,
|
|
567
|
+
address=address,
|
|
568
|
+
include_actors=include_actors,
|
|
569
|
+
_request_auth=_request_auth,
|
|
570
|
+
_content_type=_content_type,
|
|
571
|
+
_headers=_headers,
|
|
572
|
+
_host_index=_host_index
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
_response_types_map: Dict[str, Optional[str]] = {
|
|
576
|
+
'200': "Cluster",
|
|
577
|
+
'404': None,
|
|
578
|
+
'422': "HTTPValidationError",
|
|
579
|
+
}
|
|
580
|
+
response_data = self.api_client.call_api(
|
|
581
|
+
*_param,
|
|
582
|
+
_request_timeout=_request_timeout
|
|
583
|
+
)
|
|
584
|
+
response_data.read()
|
|
585
|
+
return self.api_client.response_deserialize(
|
|
586
|
+
response_data=response_data,
|
|
587
|
+
response_types_map=_response_types_map,
|
|
588
|
+
)
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
@validate_call_compat
|
|
592
|
+
def get_address_cluster_without_preload_content(
|
|
593
|
+
self,
|
|
594
|
+
currency: Annotated[StrictStr, Field(description="The cryptocurrency code (e.g., btc)")],
|
|
595
|
+
address: Annotated[StrictStr, Field(description="The cryptocurrency address")],
|
|
596
|
+
include_actors: Annotated[Optional[StrictBool], Field(description="Whether to include actor information")] = None,
|
|
597
|
+
_request_timeout: Union[
|
|
598
|
+
None,
|
|
599
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
600
|
+
Tuple[
|
|
601
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
602
|
+
Annotated[StrictFloat, Field(gt=0)]
|
|
603
|
+
]
|
|
604
|
+
] = None,
|
|
605
|
+
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
|
606
|
+
_content_type: Optional[StrictStr] = None,
|
|
607
|
+
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
608
|
+
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
609
|
+
) -> RESTResponseType:
|
|
610
|
+
"""Get the cluster for an address
|
|
611
|
+
|
|
612
|
+
Returns the address cluster that contains the given address.
|
|
613
|
+
|
|
614
|
+
:param currency: The cryptocurrency code (e.g., btc) (required)
|
|
615
|
+
:type currency: str
|
|
616
|
+
:param address: The cryptocurrency address (required)
|
|
617
|
+
:type address: str
|
|
618
|
+
:param include_actors: Whether to include actor information
|
|
619
|
+
:type include_actors: bool
|
|
620
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
621
|
+
number provided, it will be total request
|
|
622
|
+
timeout. It can also be a pair (tuple) of
|
|
623
|
+
(connection, read) timeouts.
|
|
624
|
+
:type _request_timeout: int, tuple(int, int), optional
|
|
625
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
626
|
+
request; this effectively ignores the
|
|
627
|
+
authentication in the spec for a single request.
|
|
628
|
+
:type _request_auth: dict, optional
|
|
629
|
+
:param _content_type: force content-type for the request.
|
|
630
|
+
:type _content_type: str, Optional
|
|
631
|
+
:param _headers: set to override the headers for a single
|
|
632
|
+
request; this effectively ignores the headers
|
|
633
|
+
in the spec for a single request.
|
|
634
|
+
:type _headers: dict, optional
|
|
635
|
+
:param _host_index: set to override the host_index for a single
|
|
636
|
+
request; this effectively ignores the host_index
|
|
637
|
+
in the spec for a single request.
|
|
638
|
+
:type _host_index: int, optional
|
|
639
|
+
:return: Returns the result object.
|
|
640
|
+
""" # noqa: E501
|
|
641
|
+
|
|
642
|
+
_param = self._get_address_cluster_serialize(
|
|
643
|
+
currency=currency,
|
|
644
|
+
address=address,
|
|
645
|
+
include_actors=include_actors,
|
|
646
|
+
_request_auth=_request_auth,
|
|
647
|
+
_content_type=_content_type,
|
|
648
|
+
_headers=_headers,
|
|
649
|
+
_host_index=_host_index
|
|
650
|
+
)
|
|
651
|
+
|
|
652
|
+
_response_types_map: Dict[str, Optional[str]] = {
|
|
653
|
+
'200': "Cluster",
|
|
654
|
+
'404': None,
|
|
655
|
+
'422': "HTTPValidationError",
|
|
656
|
+
}
|
|
657
|
+
response_data = self.api_client.call_api(
|
|
658
|
+
*_param,
|
|
659
|
+
_request_timeout=_request_timeout
|
|
660
|
+
)
|
|
661
|
+
return response_data.response
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
def _get_address_cluster_serialize(
|
|
665
|
+
self,
|
|
666
|
+
currency,
|
|
667
|
+
address,
|
|
668
|
+
include_actors,
|
|
669
|
+
_request_auth,
|
|
670
|
+
_content_type,
|
|
671
|
+
_headers,
|
|
672
|
+
_host_index,
|
|
673
|
+
) -> RequestSerialized:
|
|
674
|
+
|
|
675
|
+
_host = None
|
|
676
|
+
|
|
677
|
+
_collection_formats: Dict[str, str] = {
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
_path_params: Dict[str, str] = {}
|
|
681
|
+
_query_params: List[Tuple[str, str]] = []
|
|
682
|
+
_header_params: Dict[str, Optional[str]] = _headers or {}
|
|
683
|
+
_form_params: List[Tuple[str, str]] = []
|
|
684
|
+
_files: Dict[
|
|
685
|
+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
|
|
686
|
+
] = {}
|
|
687
|
+
_body_params: Optional[bytes] = None
|
|
688
|
+
|
|
689
|
+
# process the path parameters
|
|
690
|
+
if currency is not None:
|
|
691
|
+
_path_params['currency'] = currency
|
|
692
|
+
if address is not None:
|
|
693
|
+
_path_params['address'] = address
|
|
694
|
+
# process the query parameters
|
|
695
|
+
if include_actors is not None:
|
|
696
|
+
|
|
697
|
+
_query_params.append(('include_actors', include_actors))
|
|
698
|
+
|
|
699
|
+
# process the header parameters
|
|
700
|
+
# process the form parameters
|
|
701
|
+
# process the body parameter
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
# set the HTTP header `Accept`
|
|
705
|
+
if 'Accept' not in _header_params:
|
|
706
|
+
_header_params['Accept'] = self.api_client.select_header_accept(
|
|
707
|
+
[
|
|
708
|
+
'application/json'
|
|
709
|
+
]
|
|
710
|
+
)
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
# authentication setting
|
|
714
|
+
_auth_settings: List[str] = [
|
|
715
|
+
'api_key'
|
|
716
|
+
]
|
|
717
|
+
|
|
718
|
+
return self.api_client.param_serialize(
|
|
719
|
+
method='GET',
|
|
720
|
+
resource_path='/{currency}/addresses/{address}/cluster',
|
|
721
|
+
path_params=_path_params,
|
|
722
|
+
query_params=_query_params,
|
|
723
|
+
header_params=_header_params,
|
|
724
|
+
body=_body_params,
|
|
725
|
+
post_params=_form_params,
|
|
726
|
+
files=_files,
|
|
727
|
+
auth_settings=_auth_settings,
|
|
728
|
+
collection_formats=_collection_formats,
|
|
729
|
+
_host=_host,
|
|
730
|
+
_request_auth=_request_auth
|
|
731
|
+
)
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
436
736
|
@validate_call_compat
|
|
437
737
|
def get_address_entity(
|
|
438
738
|
self,
|
|
@@ -452,9 +752,9 @@ class AddressesApi:
|
|
|
452
752
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
453
753
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
454
754
|
) -> Entity:
|
|
455
|
-
"""Get the entity for an address
|
|
755
|
+
"""(Deprecated) Get the entity for an address
|
|
456
756
|
|
|
457
|
-
Returns the
|
|
757
|
+
Deprecated alias for `GET /{currency}/addresses/{address}/cluster`. Returns the address cluster that contains the given address.
|
|
458
758
|
|
|
459
759
|
:param currency: The cryptocurrency code (e.g., btc) (required)
|
|
460
760
|
:type currency: str
|
|
@@ -483,6 +783,7 @@ class AddressesApi:
|
|
|
483
783
|
:type _host_index: int, optional
|
|
484
784
|
:return: Returns the result object.
|
|
485
785
|
""" # noqa: E501
|
|
786
|
+
warnings.warn("GET /{currency}/addresses/{address}/entity is deprecated.", DeprecationWarning)
|
|
486
787
|
|
|
487
788
|
_param = self._get_address_entity_serialize(
|
|
488
789
|
currency=currency,
|
|
@@ -529,9 +830,9 @@ class AddressesApi:
|
|
|
529
830
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
530
831
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
531
832
|
) -> ApiResponse[Entity]:
|
|
532
|
-
"""Get the entity for an address
|
|
833
|
+
"""(Deprecated) Get the entity for an address
|
|
533
834
|
|
|
534
|
-
Returns the
|
|
835
|
+
Deprecated alias for `GET /{currency}/addresses/{address}/cluster`. Returns the address cluster that contains the given address.
|
|
535
836
|
|
|
536
837
|
:param currency: The cryptocurrency code (e.g., btc) (required)
|
|
537
838
|
:type currency: str
|
|
@@ -560,6 +861,7 @@ class AddressesApi:
|
|
|
560
861
|
:type _host_index: int, optional
|
|
561
862
|
:return: Returns the result object.
|
|
562
863
|
""" # noqa: E501
|
|
864
|
+
warnings.warn("GET /{currency}/addresses/{address}/entity is deprecated.", DeprecationWarning)
|
|
563
865
|
|
|
564
866
|
_param = self._get_address_entity_serialize(
|
|
565
867
|
currency=currency,
|
|
@@ -606,9 +908,9 @@ class AddressesApi:
|
|
|
606
908
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
607
909
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
608
910
|
) -> RESTResponseType:
|
|
609
|
-
"""Get the entity for an address
|
|
911
|
+
"""(Deprecated) Get the entity for an address
|
|
610
912
|
|
|
611
|
-
Returns the
|
|
913
|
+
Deprecated alias for `GET /{currency}/addresses/{address}/cluster`. Returns the address cluster that contains the given address.
|
|
612
914
|
|
|
613
915
|
:param currency: The cryptocurrency code (e.g., btc) (required)
|
|
614
916
|
:type currency: str
|
|
@@ -637,6 +939,7 @@ class AddressesApi:
|
|
|
637
939
|
:type _host_index: int, optional
|
|
638
940
|
:return: Returns the result object.
|
|
639
941
|
""" # noqa: E501
|
|
942
|
+
warnings.warn("GET /{currency}/addresses/{address}/entity is deprecated.", DeprecationWarning)
|
|
640
943
|
|
|
641
944
|
_param = self._get_address_entity_serialize(
|
|
642
945
|
currency=currency,
|
|
@@ -95,7 +95,7 @@ class ApiClient:
|
|
|
95
95
|
self.default_headers[header_name] = header_value
|
|
96
96
|
self.cookie = cookie
|
|
97
97
|
# Set default User-Agent.
|
|
98
|
-
self.user_agent = 'OpenAPI-Generator/2.
|
|
98
|
+
self.user_agent = 'OpenAPI-Generator/2.13.0/python'
|
|
99
99
|
self.client_side_validation = configuration.client_side_validation
|
|
100
100
|
|
|
101
101
|
def __enter__(self):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""graphsense CLI — requires the [cli] extra (`pip install graphsense-python[cli]`)."""
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""`graphsense bulk <operation>` — direct access to /bulk.json / /bulk.csv."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import rich_click as click
|
|
8
|
+
|
|
9
|
+
from graphsense.cli.context import CliContext
|
|
10
|
+
from graphsense.ext import io as io_mod
|
|
11
|
+
from graphsense.ext import output as out_mod
|
|
12
|
+
|
|
13
|
+
pass_ctx = click.make_pass_decorator(CliContext)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.command(name="bulk")
|
|
17
|
+
@click.argument("operation")
|
|
18
|
+
@click.argument("currency")
|
|
19
|
+
@click.argument("keys", nargs=-1)
|
|
20
|
+
@click.option(
|
|
21
|
+
"--key-field",
|
|
22
|
+
default="address",
|
|
23
|
+
help="Field name the bulk operation expects (address, tx_hash, cluster, ...).",
|
|
24
|
+
)
|
|
25
|
+
@click.option("--num-pages", type=int, default=1)
|
|
26
|
+
@pass_ctx
|
|
27
|
+
def bulk_command(
|
|
28
|
+
ctx: CliContext,
|
|
29
|
+
operation: str,
|
|
30
|
+
currency: str,
|
|
31
|
+
keys: tuple[str, ...],
|
|
32
|
+
key_field: str,
|
|
33
|
+
num_pages: int,
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Call /bulk.json/<operation> or /bulk.csv/<operation> for a list of keys.
|
|
36
|
+
|
|
37
|
+
Keys come from positionals, --input, or stdin (JSON/CSV/lines, with
|
|
38
|
+
--address-jq / --address-col).
|
|
39
|
+
Output format follows --format (default json).
|
|
40
|
+
"""
|
|
41
|
+
ids = _collect_keys(ctx, keys)
|
|
42
|
+
if not ids:
|
|
43
|
+
raise click.UsageError("no keys provided for bulk")
|
|
44
|
+
|
|
45
|
+
fmt = (ctx.format or "json").lower()
|
|
46
|
+
gs = ctx.gs()
|
|
47
|
+
result = gs.bulk(
|
|
48
|
+
operation,
|
|
49
|
+
ids,
|
|
50
|
+
currency=currency,
|
|
51
|
+
format="csv" if fmt == "csv" else "json",
|
|
52
|
+
num_pages=num_pages,
|
|
53
|
+
key_field=key_field,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if fmt == "csv":
|
|
57
|
+
_write_raw(ctx, result)
|
|
58
|
+
else:
|
|
59
|
+
out_mod.write(
|
|
60
|
+
result,
|
|
61
|
+
output=ctx.output,
|
|
62
|
+
directory=ctx.directory,
|
|
63
|
+
format=ctx.format,
|
|
64
|
+
color=ctx.color,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _collect_keys(ctx: CliContext, positional: tuple[str, ...]) -> list[str]:
|
|
69
|
+
if positional:
|
|
70
|
+
return list(positional)
|
|
71
|
+
text = ctx.read_input_text()
|
|
72
|
+
if text is None:
|
|
73
|
+
return []
|
|
74
|
+
return io_mod.parse_input(
|
|
75
|
+
text,
|
|
76
|
+
input_format=ctx.input_format,
|
|
77
|
+
jq=ctx.address_jq,
|
|
78
|
+
col=ctx.address_col,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _write_raw(ctx: CliContext, payload) -> None:
|
|
83
|
+
"""For CSV bulk output, the server already returns flat rows; pass through."""
|
|
84
|
+
text: Optional[str]
|
|
85
|
+
if isinstance(payload, (bytes, bytearray)):
|
|
86
|
+
text = payload.decode("utf-8")
|
|
87
|
+
elif isinstance(payload, str):
|
|
88
|
+
text = payload
|
|
89
|
+
else:
|
|
90
|
+
# Some generated clients deserialize the CSV as {"value": "...raw..."}
|
|
91
|
+
text = str(payload)
|
|
92
|
+
with out_mod.open_out(ctx.output) as fh:
|
|
93
|
+
fh.write(text)
|
|
94
|
+
if not text.endswith("\n"):
|
|
95
|
+
fh.write("\n")
|