59 lines
1.6 KiB
Python
59 lines
1.6 KiB
Python
import requests
|
|
import dataclasses
|
|
from typing import Any
|
|
import functools
|
|
|
|
# Types
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
class SeqId:
|
|
raw_id: int
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
class CardId:
|
|
raw_id: str
|
|
|
|
# Endpoints
|
|
URL_API_ROOT = 'https://favro.com/api/v1'
|
|
URL_GET_ALL_CARDS = URL_API_ROOT+'/cards'
|
|
URL_UPDATE_CARD = URL_API_ROOT+'/cards/{card_id}'
|
|
|
|
class FavroClient:
|
|
|
|
def __init__(*, favro_org_id: str, favro_username: str, favro_password: str,
|
|
session: requests.Session | None = None):
|
|
# Setup session
|
|
self.session = session or requests.Session()
|
|
self.session.auth = (favro_username, favro_username)
|
|
self.session.headers.update({
|
|
'organizationId': favro_org_id,
|
|
'content-type': 'application/json',
|
|
})
|
|
|
|
|
|
def get_card_json(seqid: SeqId) -> dict[str, Any]:
|
|
# TODO: Return structured?
|
|
|
|
params = {'cardSequentialId': seqid.raw_id}
|
|
response = self.session.get(URL_GET_ALL_CARDS, params = params)
|
|
response.raise_for_status()
|
|
json = response.json()
|
|
assert json['pages'] == 1
|
|
assert len(json['entities']) == 1
|
|
return json['entities'][0]
|
|
|
|
@functools.cache
|
|
def get_card_id(seqid: SeqId) -> CardId:
|
|
json = get_card_json(seqid)
|
|
return CardId(json['cardId'])
|
|
|
|
def update_card_description(card_id: CardId, description: str):
|
|
json_body = {
|
|
'detailedDescription': description,
|
|
'descriptionFormat': 'markdown',
|
|
}
|
|
|
|
response = SESSION.put(URL_UPDATE_CARD.format(card_id=card_id.raw_id), json=json_body)
|
|
response.raise_for_status()
|
|
# TODO: Return updated?
|