{ "info": { "author": "BlockFacts Ltd.", "author_email": "marko@blockfacts.io", "bugtrack_url": null, "classifiers": [], "description": "![alt text](https://blockfacts.io/img/logo/bf-logo@2x.png \"BlockFacts official logo\")\n# BlockFacts Python SDK\nOfficial BlockFacts Python SDK including Rest and WebSocket API support.\n\n## Features\n\n- REST API client with a function wrapper for easy API access\n- WebSocket API client for real-time data gathering\n\n**Note**: In order to read more and get richer details regarding our REST and WebSocket APIs, please refer to our official docs: https://docs.blockfacts.io.\n\n* [Installation](#installation)\n* [Quick start](#quick-start)\n* [Using Rest API Client](#using-rest-api-client)\n* [Asset endpoints](#asset-endpoints)\n* [BlockFacts endpoints](#blockfacts-endpoints)\n* [Exchange endpoints](#exchange-endpoints)\n* [Using WebSocket API Client](#using-websocket-api-client)\n\n## Installation\n```bash\n$ pip install blockfacts-sdk\n```\n\n## Quick start\nTo start using our SDK just import the package and pass the `API-KEY` and `API-SECRET` in the constructor.\n\n```python\nfrom blockfacts import RestClient \nfrom blockfacts import WebsocketClient \n\nkey = 'your-api-key'\nsecret = 'your-api-secret'\n\nrestClient = RestClient(key, secret)\nwebsocketClient = WebsocketClient(key, secret)\n```\n\n## Using Rest API Client\nIn the examples below, you can see which method is mapped to call it's predefined endpoint. You can also read more about authorization and how to obtain an API Key here: https://docs.blockfacts.io/?python#authorization\n\n## Asset endpoints\n\n### List all assets\nGet all assets that we support.\n- [`listAllAssets()`](https://docs.blockfacts.io/?python#list-all-assets)\n\n```python\njsonResponse = restClient.assets.listAllAssets()\n```\n\n### Get specific asset\nGet specific asset by ticker ID.\n- [`getSpecificAsset(tickerId)`](https://docs.blockfacts.io/?python#specific-asset)\n\n```python\njsonResponse = restClient.assets.getSpecificAsset(\"BTC\")\n```\n\n## BlockFacts endpoints\n\n### Exchanges in normalization\nList exchanges that go into the normalization for specific asset-denominator pair.\n- [`getExchangesInNormalization(pairs)`](https://docs.blockfacts.io/?python#exchanges-in-normalization)\n\n```python\njsonResponse = restClient.blockfacts.getExchangesInNormalization([\"BTC-USD\", \"ETH-USD\"])\n\n# OR\n\njsonResponse = restClient.blockfacts.getExchangesInNormalization(\"BTC-USD, ETH-USD\")\n```\n\n### Current data\nGet current normalization data for specific asset-denominator pair.\n- [`getCurrentData(assets, denominators)`](https://docs.blockfacts.io/?python#current-data)\n\n```python\njsonResponse = restClient.blockfacts.getCurrentData([\"BTC\", \"ETH\"], [\"USD\", \"EUR\"])\n\n# OR\n\njsonResponse = restClient.blockfacts.getCurrentData(\"BTC, ETH\", \"USD, EUR\")\n```\n\n### Historical data\nGet historical normalization data by asset-denominator, date, time and interval.\n- [`getHistoricalData(asset, denominator, date, time, interval, page)`](https://docs.blockfacts.io/?python#historical-data)\n\n```python\njsonResponse = restClient.blockfacts.getHistoricalData(\"BTC\", \"USD\", \"2.9.2019\", \"14:00:00\", 20)\n\n# OR with page parameter (optional)\n\njsonResponse = restClient.blockfacts.getHistoricalData(\"BTC\", \"USD\", \"2.9.2019\", \"14:00:00\", 20, 3)\n```\n\n### Specific historical data\nGet historical normalized price by specific point in time.\n- [`getSpecificHistoricalData(asset, denominator, date, time)`](https://docs.blockfacts.io/?python#specific-historical-data)\n\n```python\njsonResponse = restClient.blockfacts.getSpecificHistoricalData(\"BTC\", \"USD\", \"2.9.2019\", \"14:00:00\")\n```\n\n### Normalization pairs\nGet all running normalization pairs. Resulting in which asset-denominator pairs are currently being normalized inside our internal system.\n- [`getNormalizationPairs()`](https://docs.blockfacts.io/?python#normalization-pairs)\n\n```python\njsonResponse = restClient.blockfacts.getNormalizationPairs()\n```\n\n### End of day data\nGet normalized end of day data for specific asset-denominator.\n- [`getEndOfDayData(asset, denominator, length)`](https://docs.blockfacts.io/?python#end-of-day-data)\n\n```python\njsonResponse = restClient.blockfacts.getEndOfDayData(\"BTC\", \"USD\", 1)\n```\n\n## Exchange endpoints\n\n### List all exchanges\nList all exchanges that we support.\n- [`listAllExchanges()`](https://docs.blockfacts.io/?python#all-exchanges)\n\n```python\njsonResponse = restClient.exchanges.listAllExchanges()\n```\n\n### Specific exchange data\nGet information about a specific exchange by its name. Returns information such as which assets are supported, asset ticker info, etc.\n- [`getSpecificExchangeData(exchange)`](https://docs.blockfacts.io/?python#specific-exchange-data)\n\n```python\njsonResponse = restClient.exchanges.getSpecificExchangeData(\"KRAKEN\")\n```\n\n### Current trade data\nGet current trade data for specific asset-denominator pair, from specific exchange(s).\n- [`getCurrentTradeData(assets, denominators, exchanges)`](https://docs.blockfacts.io/?python#current-trade-data)\n\n```python\njsonResponse = restClient.exchanges.getCurrentTradeData([\"BTC\", \"ETH\"], [\"USD\", \"GBP\"], [\"KRAKEN\", \"COINBASE\"])\n\n# OR\n\nrestClient.exchanges.getCurrentTradeData(\"BTC, ETH\", \"USD, GBP\", \"KRAKEN, COINBASE\")\n```\n\n### Historical trade data\nGet exchange historical price by asset-denominator, exchange, date, time and interval.\n- [`getHistoricalTradeData(asset, denominator, exchanges, date, time, interval, page)`](https://docs.blockfacts.io/?python#historical-trade-data)\n\n```python\njsonResponse = restClient.exchanges.getHistoricalTradeData(\"BTC\", \"USD\", [\"KRAKEN\", \"COINBASE\"], \"2.9.2019\", \"14:00:00\", 20)\n\n# OR with page parameter (optional)\n\njsonResponse = restClient.exchanges.getHistoricalTradeData(\"BTC\", \"USD\", \"KRAKEN, COINBASE\", \"2.9.2019\", \"14:00:00\", 20, 3)\n```\n\n### Specific trade data\nGet historical exchange trades in specific second.\n- [`getSpecificTradeData(asset, denominator, exchanges, date, time)`](https://docs.blockfacts.io/?python#specific-trade-data)\n\n```python\njsonResponse = restClient.exchanges.getSpecificTradeData(\"BTC\", \"USD\", [\"KRAKEN\", \"COINBASE\"], \"2.9.2019\", \"14:00:00\")\n\n# OR\n\njsonResponse = restClient.exchanges.getSpecificTradeData(\"BTC\", \"USD\", \"KRAKEN, COINBASE\", \"2.9.2019\", \"14:00:00\")\n```\n\n### End of day data\nGet exchange end of day data for specific asset-denominator and exchange\n- [`getEndOfDayData(asset, denominator, exchange, length)`](https://docs.blockfacts.io/?python#end-of-day-data-2)\n\n```python\njsonResponse = restClient.exchanges.getEndOfDayData(\"BTC\", \"USD\", \"KRAKEN\", 5)\n```\n\n## Using WebSocket API Client\nOur WebSocket feed provides real-time market data streams from multiple exchanges at once and the BlockFacts normalized price stream for each second. The WebSocket feed uses a bidirectional protocol, and all messages sent and received via websockets are encoded in a `JSON` format.\n\n### Getting started and connecting\nTo get started simply create a new instance of the WebsocketClient class, and create handler functions for websocket events. You can then call the `connect()` function and open a connection with the BlockFacts websocket server.\n\n```python\nfrom blockfacts import WebsocketClient\nimport json\n\nkey = 'your-api-key'\nsecret = 'your-api-secret'\n\ndef on_open():\n print(\"BlockFacts websocket server connection open\")\n\ndef on_message(message):\n data = json.loads(message)\n print(data) \n # Handle websocket server messages\n\ndef on_close():\n print(\"BlockFacts websocket server connection closed\")\n\ndef on_error(err):\n print(err)\n\nwebsocketClient = WebsocketClient(key, secret)\nwebsocketClient.onOpen = on_open\nwebsocketClient.onMessage = on_message\nwebsocketClient.onClose = on_close\nwebsocketClient.onError = on_error\nwebsocketClient.connect()\n```\n\n### Subscribing\nIn order to subscribe to specific channels or asset-pairs you must send out a `subscribe` type message. The subscribe message must be sent out after the connection with the websocket has been established. You can call the `subscribe()` function right after the `connect()` function, or in the `on_open()` event handler and pass it a list of channels: \n\n```python\nwebsocketClient.connect()\nwebsocketClient.subscribe([\n {\n \"name\":\"BLOCKFACTS\",\n \"pairs\": [\n \"BTC-USD\"\n ]\n },\n {\n \"name\":\"HEARTBEAT\"\n }\n])\n\n# OR\n\ndef on_open():\n print(\"BlockFacts websocket server connection open\")\n websocketClient.subscribe([\n {\n \"name\":\"BLOCKFACTS\",\n \"pairs\": [\n \"BTC-USD\"\n ]\n },\n {\n \"name\":\"HEARTBEAT\"\n }\n ])\n```\n\n### Unsubscribing\nIf you wish to unsubscribe from certain channels or pairs, you can do so by sending the `unsubscribe` type message.\n\n```python\nwebsocketClient.unsubscribe([\n {\n \"name\":\"BLOCKFACTS\",\n \"pairs\": [\n \"BTC-USD\",\n \"ETH-USD\"\n ]\n },\n {\n \"name\":\"HEARTBEAT\"\n },\n {\n \"name\":\"KRAKEN\"\n }\n])\n```\n\n### Ping\nClients can send `ping` type messages to determine if the server is online.\n\n```python\nwebsocketClient.ping()\n```\n\n### Pong\nClients must respond to `ping` type messages sent from the server with a `pong` type message.\n\n```python\ndef on_message(message):\n data = json.loads(message)\n\n if (data[\"type\"] == \"ping\"):\n websocketClient.pong()\n```\n\nThe `on_message()` event handler can also be used to handle all message types from the websocket, for example:\n\n```python\ndef on_msg(message):\n data = json.loads(message)\n\n if data[\"type\"] == 'subscribed':\n # Subscribed type message \n\n if data[\"type\"] == 'unsubscribed':\n # Unsubscribed type message \n\n if data[\"type\"] == 'exchangeTrade':\n # ExchangeTrade type message \n\n if data[\"type\"] == 'blockfactsPrice':\n # BlockfactsPrice type message \n\n if data[\"type\"] == 'ping':\n # Ping type message \n websocketClient.pong() \n\n if data[\"type\"] == 'pong':\n # Pong type message \n\n if data[\"type\"] == 'status':\n # Status type message \n\n if data[\"type\"] == 'heartbeat':\n # Heartbeat type message \n\n if data[\"type\"] == 'error':\n # Error type message \n```\n\n### Disconnect\nClients can disconnect from the BlockFacts websocket by calling the `disconnect()` function. The disconnect function will work only if the connection has already been established.\n\n```python\nwebsocketClient.disconnect()\n```\n\nIn order to have a better understanding of our server responses, please refer to: https://docs.blockfacts.io/?python#server-messages\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/blockfacts-io/blockfacts-python-sdk", "keywords": "BlockFacts,BlockFacts API,Crypto API,Crypto Assets API,Unified Cryptocurrency API,BlockFacts SDK,BlockFacts Python,Blockchain API", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "blockfacts-sdk", "package_url": "https://pypi.org/project/blockfacts-sdk/", "platform": "", "project_url": "https://pypi.org/project/blockfacts-sdk/", "project_urls": { "Homepage": "https://github.com/blockfacts-io/blockfacts-python-sdk" }, "release_url": "https://pypi.org/project/blockfacts-sdk/1.0.0/", "requires_dist": [ "requests", "websocket-client" ], "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4", "summary": "Official BlockFacts Python SDK including Rest and WebSocket API support", "version": "1.0.0" }, "last_serial": 5982082, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "8d2a7508bbe93042cc3c5489b26145cb", "sha256": "0c8e3f3f158088be71c90c32ff8e970db0b96e74d90c9226737de932d9320c99" }, "downloads": -1, "filename": "blockfacts_sdk-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8d2a7508bbe93042cc3c5489b26145cb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4", "size": 10270, "upload_time": "2019-10-16T09:00:05", "url": "https://files.pythonhosted.org/packages/ee/14/511c5d6e599997cb9f38186a46a9a6ed751f4a3c197fc4983b77968b49c6/blockfacts_sdk-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "78597ef260b4a31bab7f12499676a9be", "sha256": "b60e5b4caba22bac3ae9299ee9b18e4b9dbd76875551661c5fc846cccea54369" }, "downloads": -1, "filename": "blockfacts-sdk-1.0.0.tar.gz", "has_sig": false, "md5_digest": "78597ef260b4a31bab7f12499676a9be", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4", "size": 9529, "upload_time": "2019-10-16T09:00:09", "url": "https://files.pythonhosted.org/packages/d6/92/9e0ee63525bc87b0886f23cb4c9098b69b631bf52e44879f573e43c962cf/blockfacts-sdk-1.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "8d2a7508bbe93042cc3c5489b26145cb", "sha256": "0c8e3f3f158088be71c90c32ff8e970db0b96e74d90c9226737de932d9320c99" }, "downloads": -1, "filename": "blockfacts_sdk-1.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8d2a7508bbe93042cc3c5489b26145cb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4", "size": 10270, "upload_time": "2019-10-16T09:00:05", "url": "https://files.pythonhosted.org/packages/ee/14/511c5d6e599997cb9f38186a46a9a6ed751f4a3c197fc4983b77968b49c6/blockfacts_sdk-1.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "78597ef260b4a31bab7f12499676a9be", "sha256": "b60e5b4caba22bac3ae9299ee9b18e4b9dbd76875551661c5fc846cccea54369" }, "downloads": -1, "filename": "blockfacts-sdk-1.0.0.tar.gz", "has_sig": false, "md5_digest": "78597ef260b4a31bab7f12499676a9be", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4", "size": 9529, "upload_time": "2019-10-16T09:00:09", "url": "https://files.pythonhosted.org/packages/d6/92/9e0ee63525bc87b0886f23cb4c9098b69b631bf52e44879f573e43c962cf/blockfacts-sdk-1.0.0.tar.gz" } ] }