mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-25 15:39:32 +00:00
feat: Add mypy to pre-commit.
This commit is contained in:
committed by
Elisiário Couto
parent
de3da84dff
commit
ec8ef8346a
0
leggen/__init__.py
Normal file
0
leggen/__init__.py
Normal file
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
import requests
|
||||
from typing import Dict, Any, Optional, List
|
||||
from typing import Dict, Any, Optional, List, Union
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from leggen.utils.text import error
|
||||
@@ -9,9 +9,13 @@ from leggen.utils.text import error
|
||||
class LeggendAPIClient:
|
||||
"""Client for communicating with the leggend FastAPI service"""
|
||||
|
||||
base_url: str
|
||||
|
||||
def __init__(self, base_url: Optional[str] = None):
|
||||
self.base_url = base_url or os.environ.get(
|
||||
"LEGGEND_API_URL", "http://localhost:8000"
|
||||
self.base_url = (
|
||||
base_url
|
||||
or os.environ.get("LEGGEND_API_URL", "http://localhost:8000")
|
||||
or "http://localhost:8000"
|
||||
)
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update(
|
||||
@@ -36,7 +40,7 @@ class LeggendAPIClient:
|
||||
try:
|
||||
error_data = response.json()
|
||||
error(f"Error details: {error_data.get('detail', 'Unknown error')}")
|
||||
except:
|
||||
except Exception:
|
||||
error(f"Response: {response.text}")
|
||||
raise
|
||||
except Exception as e:
|
||||
@@ -48,7 +52,7 @@ class LeggendAPIClient:
|
||||
try:
|
||||
response = self._make_request("GET", "/health")
|
||||
return response.get("status") == "healthy"
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
# Bank endpoints
|
||||
@@ -122,7 +126,7 @@ class LeggendAPIClient:
|
||||
self, days: int = 30, account_id: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Get transaction statistics"""
|
||||
params = {"days": days}
|
||||
params: Dict[str, Union[int, str]] = {"days": days}
|
||||
if account_id:
|
||||
params["account_id"] = account_id
|
||||
|
||||
@@ -141,7 +145,7 @@ class LeggendAPIClient:
|
||||
self, account_ids: Optional[List[str]] = None, force: bool = False
|
||||
) -> Dict[str, Any]:
|
||||
"""Trigger a sync"""
|
||||
data = {"force": force}
|
||||
data: Dict[str, Union[bool, List[str]]] = {"force": force}
|
||||
if account_ids:
|
||||
data["account_ids"] = account_ids
|
||||
|
||||
@@ -152,7 +156,7 @@ class LeggendAPIClient:
|
||||
self, account_ids: Optional[List[str]] = None, force: bool = False
|
||||
) -> Dict[str, Any]:
|
||||
"""Run sync synchronously"""
|
||||
data = {"force": force}
|
||||
data: Dict[str, Union[bool, List[str]]] = {"force": force}
|
||||
if account_ids:
|
||||
data["account_ids"] = account_ids
|
||||
|
||||
@@ -172,7 +176,11 @@ class LeggendAPIClient:
|
||||
cron: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Update scheduler configuration"""
|
||||
data = {"enabled": enabled, "hour": hour, "minute": minute}
|
||||
data: Dict[str, Union[bool, int, str]] = {
|
||||
"enabled": enabled,
|
||||
"hour": hour,
|
||||
"minute": minute,
|
||||
}
|
||||
if cron:
|
||||
data["cron"] = cron
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ def add(ctx):
|
||||
|
||||
success("Bank connection request created successfully!")
|
||||
warning(
|
||||
f"Please open the following URL in your browser to complete the authorization:"
|
||||
"Please open the following URL in your browser to complete the authorization:"
|
||||
)
|
||||
click.echo(f"\n{result['link']}\n")
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import click
|
||||
|
||||
from leggen.main import cli
|
||||
from leggen.utils.network import delete as http_delete
|
||||
from leggen.utils.text import info, success
|
||||
|
||||
|
||||
@@ -16,11 +15,12 @@ def delete(ctx, requisition_id: str):
|
||||
|
||||
Check `leggen status` to get the REQUISITION_ID
|
||||
"""
|
||||
import requests
|
||||
|
||||
info(f"Deleting Bank Requisition: {requisition_id}")
|
||||
|
||||
_ = http_delete(
|
||||
ctx,
|
||||
f"/requisitions/{requisition_id}",
|
||||
)
|
||||
api_url = ctx.obj.get("api_url", "http://localhost:8000")
|
||||
res = requests.delete(f"{api_url}/requisitions/{requisition_id}")
|
||||
res.raise_for_status()
|
||||
|
||||
success(f"Bank Requisition {requisition_id} deleted")
|
||||
|
||||
@@ -27,7 +27,7 @@ def sync(ctx: click.Context, wait: bool, force: bool):
|
||||
result = api_client.sync_now(force=force)
|
||||
|
||||
if result.get("success"):
|
||||
success(f"Sync completed successfully!")
|
||||
success("Sync completed successfully!")
|
||||
info(f"Accounts processed: {result.get('accounts_processed', 0)}")
|
||||
info(f"Transactions added: {result.get('transactions_added', 0)}")
|
||||
info(f"Balances updated: {result.get('balances_updated', 0)}")
|
||||
|
||||
@@ -5,7 +5,6 @@ from pathlib import Path
|
||||
|
||||
import click
|
||||
|
||||
from leggen.utils.auth import get_token
|
||||
from leggen.utils.config import load_config
|
||||
from leggen.utils.text import error
|
||||
|
||||
@@ -111,14 +110,4 @@ def cli(ctx: click.Context, api_url: str):
|
||||
return
|
||||
|
||||
# Store API URL in context for commands to use
|
||||
if api_url:
|
||||
ctx.obj["api_url"] = api_url
|
||||
|
||||
# For backwards compatibility, still support direct GoCardless calls
|
||||
# This will be used as fallback if leggend service is not available
|
||||
try:
|
||||
token = get_token(ctx)
|
||||
ctx.obj["headers"] = {"Authorization": f"Bearer {token}"}
|
||||
except Exception:
|
||||
# If we can't get token, commands will rely on API service
|
||||
pass
|
||||
ctx.obj["api_url"] = api_url
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
import requests
|
||||
|
||||
from leggen.utils.text import warning
|
||||
|
||||
|
||||
def create_token(ctx: click.Context) -> str:
|
||||
"""
|
||||
Create a new token
|
||||
"""
|
||||
res = requests.post(
|
||||
f"{ctx.obj['gocardless']['url']}/token/new/",
|
||||
json={
|
||||
"secret_id": ctx.obj["gocardless"]["key"],
|
||||
"secret_key": ctx.obj["gocardless"]["secret"],
|
||||
},
|
||||
)
|
||||
res.raise_for_status()
|
||||
auth = res.json()
|
||||
save_auth(auth)
|
||||
return auth["access"]
|
||||
|
||||
|
||||
def get_token(ctx: click.Context) -> str:
|
||||
"""
|
||||
Get the token from the auth file or request a new one
|
||||
"""
|
||||
auth_file = Path.home() / ".config" / "leggen" / "auth.json"
|
||||
if auth_file.exists():
|
||||
with click.open_file(str(auth_file), "r") as f:
|
||||
auth = json.load(f)
|
||||
if not auth.get("access"):
|
||||
return create_token(ctx)
|
||||
|
||||
res = requests.post(
|
||||
f"{ctx.obj['gocardless']['url']}/token/refresh/",
|
||||
json={"refresh": auth["refresh"]},
|
||||
)
|
||||
try:
|
||||
res.raise_for_status()
|
||||
auth.update(res.json())
|
||||
save_auth(auth)
|
||||
return auth["access"]
|
||||
except requests.exceptions.HTTPError:
|
||||
warning(
|
||||
f"Token probably expired, requesting a new one.\nResponse: {res.status_code}\n{res.text}"
|
||||
)
|
||||
return create_token(ctx)
|
||||
else:
|
||||
return create_token(ctx)
|
||||
|
||||
|
||||
def save_auth(d: dict):
|
||||
auth_dir = Path.home() / ".config" / "leggen"
|
||||
auth_dir.mkdir(parents=True, exist_ok=True)
|
||||
auth_file = auth_dir / "auth.json"
|
||||
|
||||
with click.open_file(str(auth_file), "w") as f:
|
||||
json.dump(d, f)
|
||||
@@ -3,7 +3,6 @@ from datetime import datetime
|
||||
import click
|
||||
|
||||
import leggen.database.sqlite as sqlite_engine
|
||||
from leggen.utils.network import get
|
||||
from leggen.utils.text import info, warning
|
||||
|
||||
|
||||
@@ -32,15 +31,21 @@ def persist_transactions(ctx: click.Context, account: str, transactions: list) -
|
||||
|
||||
|
||||
def save_transactions(ctx: click.Context, account: str) -> list:
|
||||
import requests
|
||||
|
||||
api_url = ctx.obj.get("api_url", "http://localhost:8000")
|
||||
|
||||
info(f"[{account}] Getting account details")
|
||||
account_info = get(ctx, f"/accounts/{account}")
|
||||
res = requests.get(f"{api_url}/accounts/{account}")
|
||||
res.raise_for_status()
|
||||
account_info = res.json()
|
||||
|
||||
info(f"[{account}] Getting transactions")
|
||||
transactions = []
|
||||
|
||||
account_transactions = get(ctx, f"/accounts/{account}/transactions/").get(
|
||||
"transactions", []
|
||||
)
|
||||
res = requests.get(f"{api_url}/accounts/{account}/transactions/")
|
||||
res.raise_for_status()
|
||||
account_transactions = res.json().get("transactions", [])
|
||||
|
||||
for transaction in account_transactions.get("booked", []):
|
||||
booked_date = transaction.get("bookingDateTime") or transaction.get(
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import click
|
||||
import requests
|
||||
|
||||
from leggen.utils.text import error
|
||||
|
||||
|
||||
def get(ctx: click.Context, path: str, params: dict = {}):
|
||||
"""
|
||||
GET request to the GoCardless API
|
||||
"""
|
||||
|
||||
url = f"{ctx.obj['gocardless']['url']}{path}"
|
||||
res = requests.get(url, headers=ctx.obj["headers"], params=params)
|
||||
try:
|
||||
res.raise_for_status()
|
||||
except Exception as e:
|
||||
error(f"Error: {e}\n{res.text}")
|
||||
ctx.abort()
|
||||
return res.json()
|
||||
|
||||
|
||||
def post(ctx: click.Context, path: str, data: dict = {}):
|
||||
"""
|
||||
POST request to the GoCardless API
|
||||
"""
|
||||
|
||||
url = f"{ctx.obj['gocardless']['url']}{path}"
|
||||
res = requests.post(url, headers=ctx.obj["headers"], json=data)
|
||||
try:
|
||||
res.raise_for_status()
|
||||
except Exception as e:
|
||||
error(f"Error: {e}\n{res.text}")
|
||||
ctx.abort()
|
||||
return res.json()
|
||||
|
||||
|
||||
def put(ctx: click.Context, path: str, data: dict = {}):
|
||||
"""
|
||||
PUT request to the GoCardless API
|
||||
"""
|
||||
|
||||
url = f"{ctx.obj['gocardless']['url']}{path}"
|
||||
res = requests.put(url, headers=ctx.obj["headers"], json=data)
|
||||
try:
|
||||
res.raise_for_status()
|
||||
except Exception as e:
|
||||
error(f"Error: {e}\n{res.text}")
|
||||
ctx.abort()
|
||||
return res.json()
|
||||
|
||||
|
||||
def delete(ctx: click.Context, path: str):
|
||||
"""
|
||||
DELETE request to the GoCardless API
|
||||
"""
|
||||
|
||||
url = f"{ctx.obj['gocardless']['url']}{path}"
|
||||
res = requests.delete(url, headers=ctx.obj["headers"])
|
||||
try:
|
||||
res.raise_for_status()
|
||||
except Exception as e:
|
||||
error(f"Error: {e}\n{res.text}")
|
||||
ctx.abort()
|
||||
return res.json()
|
||||
Reference in New Issue
Block a user