Skip to content

Commit

Permalink
cleanup flags, move transactions vector to dumper
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelsoup42 committed Oct 5, 2023
1 parent c50edfd commit 0dc40ff
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
28 changes: 6 additions & 22 deletions src/cardano_account_pandas_dumper/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from json import JSONDecodeError

import jstyleson
import pandas as pd
from blockfrost import ApiError, BlockFrostApi
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE

Expand Down Expand Up @@ -75,7 +74,7 @@ def _create_arg_parser():
)
result.add_argument(
"--unmute",
help="Do not mute policies in the mute list and numerical-only metadata.",
help="Do not auto-mute anything, do not use muted policies.",
action="store_true",
)
result.add_argument(
Expand All @@ -90,9 +89,10 @@ def _create_arg_parser():
action="store_true",
)
result.add_argument(
"--no_rewards",
"--with_rewards",
help="Do not add reward transactions.",
action="store_true",
default=True,
type=bool,
)
return result

Expand Down Expand Up @@ -149,7 +149,7 @@ def main():
api=api_instance,
staking_addresses=staking_addresses_set,
to_block=args.to_block,
include_rewards=not args.no_rewards,
include_rewards=not args.with_rewards,
)
except ApiError as api_exception:
parser.exit(
Expand Down Expand Up @@ -183,32 +183,16 @@ def main():
unmute=args.unmute,
detail_level=args.detail_level,
)
transactions = pd.concat(
[
data_from_api.transactions,
pd.Series(
[]
if args.no_rewards
else [reporter.reward_transaction(r) for r in data_from_api.rewards]
),
]
)

transactions.index = [reporter.extract_timestamp(t) for t in transactions]
transactions.sort_index(inplace=True)
if args.csv_output:
try:
reporter.make_transaction_frame(
transactions,
).to_csv(
reporter.make_transaction_frame().to_csv(
args.csv_output,
)
except OSError as exception:
warnings.warn(f"Failed to write CSV file: {exception}")
if args.xlsx_output:
try:
reporter.make_transaction_frame(
transactions,
text_cleaner=lambda x: ILLEGAL_CHARACTERS_RE.sub(
lambda y: "".join(
["\\x0" + hex(ord(y.group(0))).removeprefix("0x")]
Expand Down
49 changes: 36 additions & 13 deletions src/cardano_account_pandas_dumper/cardano_account_pandas_dumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,20 @@ def __init__(
self.pinned_policies = pd.Series(known_dict.get("pinned_policies", []))
self.scripts = pd.Series(known_dict.get("scripts", {}))
self.labels = pd.Series(known_dict.get("labels", {}))
transactions = pd.concat(
[
self.data.transactions,
pd.Series([self.reward_transaction(r) for r in self.data.rewards]),
]
)

transactions.index = pd.Index(
[self.extract_timestamp(t) for t in transactions],
dtype="datetime64[ns]",
)
transactions.sort_index(inplace=True)
assert len(transactions) == len(self.data.transactions) + len(self.data.rewards)
self.transactions = transactions

def _truncate(self, value: str) -> str:
return (
Expand Down Expand Up @@ -308,7 +322,9 @@ def _format_policy(self, policy: str) -> Optional[str]:
)

@classmethod
def extract_timestamp(cls, transaction: blockfrost.utils.Namespace) -> Any:
def extract_timestamp(
cls, transaction: blockfrost.utils.Namespace
) -> np.datetime64:
"""Returns timestamp of transaction."""
return np.datetime64(
datetime.datetime.fromtimestamp(transaction.block_time)
Expand Down Expand Up @@ -429,15 +445,20 @@ def _transaction_balance(self, transaction: blockfrost.utils.Namespace) -> Any:
lambda: np.longlong(0)
)
for key, value in result.items():
if key[0] == self.ADA_DECIMALS or not transaction.asset_mint_or_burn_count:
sum_by_asset[key[0]] += value

assert all([v == np.longlong(0) for v in sum_by_asset.values()]), (
sum_by_asset[key[0]] += value
sum_by_asset = {k: v for k, v in sum_by_asset.items() if v}
assert (
self.ADA_ASSET not in sum_by_asset
and len(sum_by_asset) == transaction.asset_mint_or_burn_count
), (
f"Unbalanced transaction: {transaction.hash if transaction.hash else '-'} : "
+ f"{self._format_message(transaction)} : "
+ str(
{
f"{self._format_policy(self.data.assets[k].policy_id)}@{self._decode_asset_name(self.data.assets[k])}": v
(
f"{self._format_policy(self.data.assets[k].policy_id)}@"
+ f"{self._decode_asset_name(self.data.assets[k])}"
): v
for k, v in sum_by_asset.items()
if v != np.longlong(0)
}
Expand All @@ -447,13 +468,12 @@ def _transaction_balance(self, transaction: blockfrost.utils.Namespace) -> Any:

def make_balance_frame(
self,
transactions: pd.Series,
text_cleaner: Callable = lambda x: x,
):
"""Make DataFrame with transaction balances."""
balance = pd.DataFrame(
data=[self._transaction_balance(x) for x in transactions],
index=transactions.index,
data=[self._transaction_balance(x) for x in self.transactions],
index=self.transactions.index,
dtype="Int64",
)
balance.columns = pd.MultiIndex.from_tuples(balance.columns)
Expand Down Expand Up @@ -485,7 +505,6 @@ def make_balance_frame(

def make_transaction_frame(
self,
transactions: pd.Series,
zero_is_nan: bool = True,
with_total: bool = True,
text_cleaner: Callable = lambda x: x,
Expand All @@ -495,18 +514,22 @@ def make_transaction_frame(
msg_frame = pd.DataFrame(
data=[
{"hash": x.hash, "message": text_cleaner(self._format_message(x))}
for x in transactions
for x in self.transactions
],
index=transactions.index,
index=self.transactions.index,
dtype="string",
)

balance_frame = self.make_balance_frame(transactions, text_cleaner=text_cleaner)
balance_frame = self.make_balance_frame(text_cleaner=text_cleaner)
msg_frame.columns = pd.MultiIndex.from_tuples(
[
("metadata", c) + (len(balance_frame.columns[0]) - 2) * ("",)
for c in msg_frame.columns
]
)
assert len(msg_frame) == len(
balance_frame
), f"Frame lengths do not match {msg_frame=!s} , {balance_frame=!s}"
joined_frame = pd.concat(objs=[msg_frame, balance_frame], axis=1)
# Add total line at the bottom
if with_total:
Expand Down

0 comments on commit 0dc40ff

Please sign in to comment.