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?