Refactors transaction retrieval to use Fava API
Replaces direct database queries for transactions with calls to the Fava API, centralizing transaction logic and improving data consistency. This change removes redundant code and simplifies the API by relying on Fava for querying transactions based on account patterns and other criteria. Specifically, the commit introduces new methods in the FavaClient class for querying transactions, retrieving account transactions, and retrieving user transactions. The API endpoints are updated to utilize these methods.
This commit is contained in:
parent
88ff3821ce
commit
de3e4e65af
2 changed files with 208 additions and 106 deletions
108
fava_client.py
108
fava_client.py
|
|
@ -401,6 +401,114 @@ class FavaClient:
|
|||
logger.warning(f"Fava health check failed: {e}")
|
||||
return False
|
||||
|
||||
async def query_transactions(
|
||||
self,
|
||||
account_pattern: Optional[str] = None,
|
||||
limit: int = 100,
|
||||
include_pending: bool = True
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Query transactions from Fava/Beancount.
|
||||
|
||||
Args:
|
||||
account_pattern: Optional regex pattern to filter accounts (e.g., "User-abc123")
|
||||
limit: Maximum number of transactions to return
|
||||
include_pending: Include pending transactions (flag='!')
|
||||
|
||||
Returns:
|
||||
List of transaction dictionaries with date, description, postings, etc.
|
||||
|
||||
Example:
|
||||
# All transactions
|
||||
txns = await fava.query_transactions()
|
||||
|
||||
# User's transactions
|
||||
txns = await fava.query_transactions(account_pattern="User-abc123")
|
||||
|
||||
# Account transactions
|
||||
txns = await fava.query_transactions(account_pattern="Assets:Receivable:User-abc")
|
||||
"""
|
||||
# Build Beancount query
|
||||
if account_pattern:
|
||||
query = f"SELECT * WHERE account ~ '{account_pattern}' ORDER BY date DESC LIMIT {limit}"
|
||||
else:
|
||||
query = f"SELECT * ORDER BY date DESC LIMIT {limit}"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
||||
response = await client.get(
|
||||
f"{self.base_url}/query",
|
||||
params={"query_string": query}
|
||||
)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
|
||||
# Fava query API returns: {"data": {"rows": [...], "columns": [...]}}
|
||||
data = result.get("data", {})
|
||||
rows = data.get("rows", [])
|
||||
|
||||
# Transform Fava's query result to transaction list
|
||||
transactions = []
|
||||
for row in rows:
|
||||
# Fava returns rows with various fields depending on the query
|
||||
# For "SELECT *", we get transaction details
|
||||
if isinstance(row, dict):
|
||||
# Filter by flag if needed
|
||||
flag = row.get("flag", "*")
|
||||
if not include_pending and flag == "!":
|
||||
continue
|
||||
|
||||
transactions.append(row)
|
||||
|
||||
return transactions[:limit]
|
||||
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(f"Fava query error: {e.response.status_code} - {e.response.text}")
|
||||
raise
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f"Fava connection error: {e}")
|
||||
raise
|
||||
|
||||
async def get_account_transactions(
|
||||
self,
|
||||
account_name: str,
|
||||
limit: int = 100
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Get all transactions affecting a specific account.
|
||||
|
||||
Args:
|
||||
account_name: Full account name (e.g., "Assets:Receivable:User-abc123")
|
||||
limit: Maximum number of transactions
|
||||
|
||||
Returns:
|
||||
List of transactions affecting this account
|
||||
"""
|
||||
return await self.query_transactions(
|
||||
account_pattern=account_name.replace(":", "\\:"), # Escape colons for regex
|
||||
limit=limit
|
||||
)
|
||||
|
||||
async def get_user_transactions(
|
||||
self,
|
||||
user_id: str,
|
||||
limit: int = 100
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Get all transactions affecting a user's accounts.
|
||||
|
||||
Args:
|
||||
user_id: User ID
|
||||
limit: Maximum number of transactions
|
||||
|
||||
Returns:
|
||||
List of transactions affecting user's accounts
|
||||
"""
|
||||
return await self.query_transactions(
|
||||
account_pattern=f"User-{user_id[:8]}",
|
||||
limit=limit
|
||||
)
|
||||
|
||||
|
||||
# Singleton instance (configured from settings)
|
||||
_fava_client: Optional[FavaClient] = None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue