Add shroomdk readme.md

This commit is contained in:
Jim Myers 2022-07-25 16:18:19 -04:00
parent 6bf1e59b81
commit 5ec85751a3
6 changed files with 165 additions and 16 deletions

View File

@ -5,8 +5,8 @@ lint:
enabled:
- actionlint@1.6.15
- black@22.6.0
- git-diff-check@SYSTEM
- gitleaks@8.8.12
# - git-diff-check@SYSTEM
# - gitleaks@8.8.12
- isort@5.10.1
- markdownlint@0.32.0
# - markdownlint@0.32.0
- prettier@2.7.1

View File

@ -31,7 +31,7 @@ import { Flipside, Query, QueryResultSet } from "@flipsidecrypto/sdk";
// Initialize `Flipside` with your API key
const flipside = new Flipside(
"<YOUR_API_KEY>",
"https://node-api.flipsidecrypto.com"
"https://api.flipsidecrypto.com"
);
// Parameters can be passed into SQL statements via simple & native string interpolation

View File

@ -1,7 +1,150 @@
# Python SDK
[![Python Continuous Testing](https://github.com/FlipsideCrypto/sdk/actions/workflows/ci_python.yml/badge.svg)](https://github.com/FlipsideCrypto/sdk/actions/workflows/ci_python.yml)
Programmatic access to the most comprehensive blockchain data in Web3, for free. 🥳
<br>
<br>
```
[![Python Continuous Testing](https://github.com/FlipsideCrypto/sdk/actions/workflows/ci_python.yml/badge.svg)](https://github.com/FlipsideCrypto/sdk/actions/workflows/ci_python.yml)
<br>
<br>
GM frens, you've found yourself at the Python SDK for ShroomDK.
<br>
<br>
## 💾 Install the SDK
```bash
pip install shroomdk
```
## 🦾 Getting Started
```python
from shroomdk import ShroomDK
# Initialize `ShroomDK` with your API Key
sdk = ShroomDK(
"<YOUR_API_KEY>",
"https://api.flipsidecrypto.com"
)
# Parameters can be passed into SQL statements
# via native string interpolation
my_address = "0x...."
sql = f"""
SELECT
nft_address,
mint_price_eth,
mint_price_usd
FROM ethereum.core.ez_nft_mints
WHERE nft_to_address = LOWER('${my_address}')
"""
# Run the query against Flipside's query engine
# and await the results
query_result_set = sdk.query(sql)
# Iterate over the results
for record in query_result_set.records:
nft_address = record['nft_address']
mint_price_eth = record['mint_price_eth']
mint_price_usd = record['mint_price_usd']
print(f"${nft_address} minted for {mint_price_eth}E ({mint_price_usd})USD")
```
## The Details
### Executing a Query
When executing a query the following parameters can be passed in / overriden to the `query` method on the `ShroomDK` object:
| Argument | Description | Default Value |
|------------------------|------------------------------------------------------------------------------------|-----------------|
| sql | The sql string to execute | None (required) |
| ttl_minutes | The number of minutes to cache the query results | 60 |
| cached | An override on the query result cache. A value of false will re-execute the query. | True |
| timeout_minutes | The number of minutes until your query run times out | 20 |
| retry_interval_seconds | The number of second to wait between polls to the server | 1 |
| page_size | The number of rows/records to return | 100,000 |
| page_number | The page number to return (starts at 1) | 1 |
Let's create a query to retrieve all NFTs minted by an address:
```python
my_address = "0x...."
sql = f"""
SELECT
nft_address,
mint_price_eth,
mint_price_usd
FROM ethereum.core.ez_nft_mints
WHERE nft_to_address = LOWER('${my_address}')
LIMIT 100
"""
```
Now let's execute the query and retrieve the first 5 rows of the result set. Note we will set `page_size` to 5 and `page_number` to 1 to retrieve those first 5 rows.
```python
query_result_set = sdk.query(
sql,
ttl_minutes=60,
cached=True,
timeout_minutes=20,
retry_interval_seconds=1,
page_size=5,
page_number=1
)
```
The results of this query will be cached for 60 minutes, given the `ttl_minutes` parameter is set to 60. Let's examine the query result object that's returned.
### The `QueryResultSet` Object
After executing a query the results are stored in a `QueryResultSet` object:
```python
class QueryResultSet(BaseModel):
query_id: Union[str, None] = Field(None, description="The server id of the query")
status: str = Field(False, description="The status of the query (`PENDING`, `FINISHED`, `ERROR`)")
columns: Union[List[str], None] = Field(None, description="The names of the columns in the result set")
column_types: Union[List[str], None] = Field(None, description="The type of the columns in the result set")
rows: Union[List[Any], None] = Field(None, description="The results of the query")
run_stats: Union[QueryRunStats, None] = Field(
None,
description="Summary stats on the query run (i.e. the number of rows returned, the elapsed time, etc)",
)
records: Union[List[Any], None] = Field(None, description="The results of the query transformed as an array of objects")
error: Any
```
Let's iterate over the results from our query above.
<br>
<br>
Our query selected `nft_address`, `mint_price_eth`, and `mint_price_usd`. We can access the returned data via the `records` parameter. The column names in our query are assigned as keys in each record object.
```python
for record in query_result_set.records:
nft_address = record['nft_address']
mint_price_eth = record['mint_price_eth']
mint_price_usd = record['mint_price_usd']
print(f"${nft_address} minted for {mint_price_eth}E ({mint_price_usd})USD")
```
Other useful information can be accessed on the query result set object such as run stats, i.e. how long the query took to execute:
```python
started_at = query_result_set.run_stats.started_at
ended_at = query_result_set.run_stats.ended_at
elapsed_seconds = query_result_set.run_stats.elapsed_seconds
record_count = query_result_set.run_stats.record_count
print(f"This query took ${elapsed_seconds} seconds to run and returned {record_count} records from the database."")
```
### Rate Limits
Every API key is subject to a rate limit over a moving 5 minute window, as well as an aggregate daily limit.
<br>
<br>
If the limit is reach in a 5 minute period, the sdk will exponentially backoff and retry the query up to the `timeoutMinutes` parameter set on the `Query` object.
<br>
<br>
This feature is quite useful if leveraging the SDK client side and your web application sees a large spike in traffic. Rather than using up your daily limit all at once, requests will be smoothed out over the day.
<br>
<br>
Rate limits can be adjust per key/use-case.

View File

@ -14,11 +14,11 @@ with open("requirements.txt", "r") as fh:
setup(
install_requires=[req for req in requirements if req[:2] != "# "],
name="flipside_shroomdk",
name="shroomdk",
version=version,
author="dev@flipsidecrypto.com",
author_email="dev@flipsidecrypto.com",
description="ShroomDK by Flipside Crypto: Query the most comprehensive blockchain data in crypto",
description="ShroomDK (SDK) by Flipside Crypto: Query the most comprehensive blockchain data in crypto",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/FlipsideCrypto/sdk/python",
@ -35,5 +35,5 @@ setup(
"Programming Language :: Python :: 3.10",
],
dependency_links=[],
python_requires=">=3.6",
python_requires=">=3.7",
)

View File

@ -59,10 +59,14 @@ class API(object):
status_code=result.status_code,
status_msg=result.reason,
error_msg=data.get("errors") if data else None,
data=CreateQueryJson(**data) if data and data.get("errors") is None else None,
data=CreateQueryJson(**data)
if data and data.get("errors") is None
else None,
)
def get_query_result(self, query_id: str, page_number: int, page_size: int) -> QueryResultResp:
def get_query_result(
self, query_id: str, page_number: int, page_size: int
) -> QueryResultResp:
result = self._session.get(
self.get_url(f"queries/{query_id}"),
params={"pageNumber": page_number, "pageSize": page_size},
@ -78,7 +82,9 @@ class API(object):
status_code=result.status_code,
status_msg=result.reason,
error_msg=data.get("errors") if data else None,
data=QueryResultJson(**data) if data and data.get("errors") is None else None,
data=QueryResultJson(**data)
if data and data.get("errors") is None
else None,
)
@property

View File

@ -1,6 +1,6 @@
from .api import API
from .integrations import QueryIntegration
from .models import Query
from shroomdk.api import API
from shroomdk.integrations import QueryIntegration
from shroomdk.models import Query
API_BASE_URL = "https://api.flipsidecrypto.com"
@ -15,7 +15,7 @@ class ShroomDK(object):
ttl_minutes=60,
cached=True,
timeout_minutes=20,
retry_interval_seconds=0.5,
retry_interval_seconds=1,
page_size=100000,
page_number=1,
):