Skip to content

Reference

Cookidoo API package.

Cookidoo

Unofficial Cookidoo API interface.

Init function for Cookidoo API.

Parameters:

Name Type Description Default
session ClientSession

The client session for aiohttp requests. Must use a CookieJar(unsafe=True) to support cross-domain cookies during the OAuth2 login flow.

required
cfg CookidooConfig

Cookidoo config

CookidooConfig()
Source code in cookidoo_api/cookidoo.py
def __init__(
    self,
    session: ClientSession,
    cfg: CookidooConfig = CookidooConfig(),
) -> None:
    """Init function for Cookidoo API.

    Parameters
    ----------
    session
        The client session for aiohttp requests.
        Must use a ``CookieJar(unsafe=True)`` to support cross-domain
        cookies during the OAuth2 login flow.
    cfg
        Cookidoo config

    """
    self._session = session
    self._cfg = cfg
    self._api_headers = DEFAULT_API_HEADERS.copy()
    self._logged_in = False

localization property

Localization.

api_endpoint property

Get the api endpoint.

Returns the cookidoo domain derived from the localization URL, e.g. https://cookidoo.ch or https://cookidoo.co.uk.

login async

Perform browser-based OAuth2 login.

Follows the same redirect chain as the Cookidoo web app: 1. Initiate login at cookidoo.{tld}/profile/{lang}/login 2. Follow redirects through OAuth2/PKCE to the CIAM login page 3. POST credentials to the CIAM login service 4. Follow callback redirects to capture session cookies

After login, the session's cookie jar contains the authentication cookies and all subsequent API calls are authenticated automatically.

Raises:

Type Description
CookidooRequestException

If the request fails.

CookidooParseException

If the login page cannot be parsed.

CookidooAuthException

If the login fails due to invalid credentials.

Source code in cookidoo_api/cookidoo.py
async def login(self) -> None:
    """Perform browser-based OAuth2 login.

    Follows the same redirect chain as the Cookidoo web app:
    1. Initiate login at ``cookidoo.{tld}/profile/{lang}/login``
    2. Follow redirects through OAuth2/PKCE to the CIAM login page
    3. POST credentials to the CIAM login service
    4. Follow callback redirects to capture session cookies

    After login, the session's cookie jar contains the authentication
    cookies and all subsequent API calls are authenticated automatically.

    Raises
    ------
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the login page cannot be parsed.
    CookidooAuthException
        If the login fails due to invalid credentials.

    """
    language = self._cfg.localization.language
    login_path = LOGIN_PATH.format(language=language)
    redirect = LOGIN_REDIRECT.format(language=language)
    login_url = URL(
        str(self.api_endpoint / login_path) + f"?redirectAfterLogin={redirect}",
        encoded=True,
    )

    try:
        # Step 1: Follow redirect chain to reach the CIAM login page
        async with self._session.get(login_url, allow_redirects=True) as resp:
            self._check_login_page_status(resp.status)
            login_html = await resp.text()

        # Step 2: Extract requestId from the login form
        request_id = self._extract_request_id(login_html)

        # Step 3: POST credentials to CIAM login service
        login_data = {
            "requestId": request_id,
            "username": self._cfg.email,
            "password": self._cfg.password,
        }
        async with self._session.post(
            CIAM_LOGIN_SRV_URL,
            data=login_data,
            allow_redirects=True,
        ) as resp:
            _LOGGER.debug(
                "Login POST completed, final URL: %s (status: %s)",
                resp.url,
                resp.status,
            )

        # Step 4: Verify authentication cookies were set
        self._verify_auth_cookies()
        self._logged_in = True

    except CookidooAuthException:
        raise
    except CookidooParseException:
        raise
    except TimeoutError as e:
        _LOGGER.debug("Exception: Login failed:\n %s", traceback.format_exc())
        raise CookidooRequestException(
            "Authentication failed due to connection timeout."
        ) from e
    except ClientError as e:
        _LOGGER.debug("Exception: Login failed:\n %s", traceback.format_exc())
        raise CookidooRequestException(
            "Authentication failed due to request exception."
        ) from e

save_cookies

Save session cookies to a file for later reuse.

Parameters:

Name Type Description Default
path str | Path

Path to the file where cookies will be saved.

required
Source code in cookidoo_api/cookidoo.py
def save_cookies(self, path: str | Path) -> None:
    """Save session cookies to a file for later reuse.

    Parameters
    ----------
    path
        Path to the file where cookies will be saved.

    """
    cookies: list[dict[str, str]] = []
    for cookie in self._session.cookie_jar:
        cookies.append(
            {
                "key": cookie.key,
                "value": cookie.value,
                "domain": cookie["domain"],
                "path": cookie["path"],
            }
        )
    Path(path).write_text(json.dumps(cookies), encoding="utf-8")

load_cookies

Load session cookies from a file to restore a previous session.

Parameters:

Name Type Description Default
path str | Path

Path to the file containing saved cookies.

required

Raises:

Type Description
CookidooConfigException

If the cookie file cannot be read or parsed.

Source code in cookidoo_api/cookidoo.py
def load_cookies(self, path: str | Path) -> None:
    """Load session cookies from a file to restore a previous session.

    Parameters
    ----------
    path
        Path to the file containing saved cookies.

    Raises
    ------
    CookidooConfigException
        If the cookie file cannot be read or parsed.

    """
    try:
        data = json.loads(Path(path).read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError) as e:
        raise CookidooConfigException(f"Cannot load cookies from {path}.") from e

    for entry in data:
        cookie: SimpleCookie = SimpleCookie()
        cookie[entry["key"]] = entry["value"]
        cookie[entry["key"]]["domain"] = entry.get("domain", "")
        cookie[entry["key"]]["path"] = entry.get("path", "/")
        self._session.cookie_jar.update_cookies(
            cookie, URL(f"https://{entry.get('domain', '')}")
        )

    # Check if required auth cookies are present
    cookie_names = {c.key for c in self._session.cookie_jar}
    required_cookies = {"_oauth2_proxy", "v-authenticated"}
    if required_cookies.issubset(cookie_names):
        self._logged_in = True

get_user_info async

Get user info.

Returns:

Type Description
CookidooUserInfo

The user info

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_user_info(
    self,
) -> CookidooUserInfo:
    """Get user info.

    Returns
    -------
    CookidooUserInfo
        The user info

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / COMMUNITY_PROFILE_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading user info"),
        "loading user info",
    )
    return self._parse_result(
        "loading user info",
        lambda: cookidoo_user_info_from_json(cast(CommunityProfileJSON, result)),
    )

get_active_subscription async

Get active subscription if any.

Returns:

Type Description
CookidooSubscription

The active subscription

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_active_subscription(
    self,
) -> CookidooSubscription | None:
    """Get active subscription if any.

    Returns
    -------
    CookidooSubscription
        The active subscription

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / SUBSCRIPTIONS_PATH.format(
        **self._cfg.localization.__dict__
    )
    subscriptions = self._ensure_sequence(
        await self._request_json("get", url, "loading active subscription"),
        "loading active subscription",
    )
    try:
        if subscription := next(
            (
                subscription
                for subscription in subscriptions
                if isinstance(subscription, Mapping) and subscription["active"]
            ),
            None,
        ):
            return self._parse_result(
                "loading active subscription",
                lambda: cookidoo_subscription_from_json(
                    cast(SubscriptionJSON, subscription)
                ),
            )
    except KeyError as e:
        raise CookidooParseException(
            "Loading active subscription failed during parsing of request response."
        ) from e
    return None

get_recipe_details async

Get recipe details.

Parameters:

Name Type Description Default
id str

The id of the recipe

required

Returns:

Type Description
CookidooShoppingRecipeDetails

The recipe details

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_recipe_details(self, id: str) -> CookidooShoppingRecipeDetails:
    """Get recipe details.

    Parameters
    ----------
    id
        The id of the recipe

    Returns
    -------
    CookidooShoppingRecipeDetails
        The recipe details

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / RECIPE_PATH.format(
        **self._cfg.localization.__dict__, id=id
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading recipe details"),
        "loading recipe details",
    )
    return self._parse_result(
        "loading recipe details",
        lambda: cookidoo_recipe_details_from_json(
            cast(RecipeDetailsJSON, result),
            self._cfg.localization,
        ),
    )

search_recipes async

Search recipes in Cookidoo (GET).

Uses the same API base as the rest of the client (api_endpoint): {api_endpoint}/search/{locale}

Parameters:

Name Type Description Default
query str | None

Optional search query (e.g. "chicken", "pasta").

None
locale str | None

Locale for the search path (e.g. "es", "en", "de"). Defaults to the first part of the configured language (e.g. "de-CH" -> "de").

None
accessories str | list[str] | None

Optional comma-separated accessory filters (e.g. "includingFriend,includingBladeCover,includingBladeCoverWithPeeler,includingCutter,includingSensor").

None
languages str | list[str] | None

Optional comma-separated language codes (e.g. "en,es").

None
categories str | list[str] | None

Optional comma-separated category IDs.

None
countries str | list[str] | None

Optional comma-separated country codes (e.g. "ar").

None
ingredients str | list[str] | None

Optional comma-separated ingredients.

None
exclude_ingredients str | list[str] | None

Optional comma-separated excluded ingredients.

None
tags str | list[str] | None

Optional comma-separated tags.

None
ratings str | list[str] | None

Optional comma-separated ratings (e.g. "5,4").

None
difficulty str | None

Optional difficulty (e.g. "easy", "medium", "hard").

None
preparation_time int | None

Optional preparation time in seconds.

None
total_time int | None

Optional total time in seconds.

None
portions int | None

Optional portions count.

None
page int | None

Optional page number (API-dependent, often 0- or 1-based).

None
page_size int | None

Optional page size (API-dependent; common keys: pageSize).

None
tmv ThermomixMachineType | str | list[ThermomixMachineType | str] | None

Optional Thermomix machine version. Use ThermomixMachineType (e.g. ThermomixMachineType.TM7) or a string ("TM7", "TM6", "TM5").

None

Returns:

Type Description
CookidooSearchResult

Search result with recipes and total count.

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore.

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def search_recipes(
    self,
    query: str | None = None,
    locale: str | None = None,
    accessories: str | list[str] | None = None,
    languages: str | list[str] | None = None,
    categories: str | list[str] | None = None,
    countries: str | list[str] | None = None,
    ingredients: str | list[str] | None = None,
    exclude_ingredients: str | list[str] | None = None,
    tags: str | list[str] | None = None,
    ratings: str | list[str] | None = None,
    difficulty: str | None = None,
    preparation_time: int | None = None,
    total_time: int | None = None,
    portions: int | None = None,
    page: int | None = None,
    page_size: int | None = None,
    tmv: ThermomixMachineType
    | str
    | list[ThermomixMachineType | str]
    | None = None,
) -> CookidooSearchResult:
    """Search recipes in Cookidoo (GET).

    Uses the same API base as the rest of the client (api_endpoint):
    {api_endpoint}/search/{locale}

    Parameters
    ----------
    query
        Optional search query (e.g. "chicken", "pasta").
    locale
        Locale for the search path (e.g. "es", "en", "de").
        Defaults to the first part of the configured language (e.g. "de-CH" -> "de").
    accessories
        Optional comma-separated accessory filters
        (e.g. "includingFriend,includingBladeCover,includingBladeCoverWithPeeler,includingCutter,includingSensor").
    languages
        Optional comma-separated language codes (e.g. "en,es").
    categories
        Optional comma-separated category IDs.
    countries
        Optional comma-separated country codes (e.g. "ar").
    ingredients
        Optional comma-separated ingredients.
    exclude_ingredients
        Optional comma-separated excluded ingredients.
    tags
        Optional comma-separated tags.
    ratings
        Optional comma-separated ratings (e.g. "5,4").
    difficulty
        Optional difficulty (e.g. "easy", "medium", "hard").
    preparation_time
        Optional preparation time in seconds.
    total_time
        Optional total time in seconds.
    portions
        Optional portions count.
    page
        Optional page number (API-dependent, often 0- or 1-based).
    page_size
        Optional page size (API-dependent; common keys: pageSize).
    tmv
        Optional Thermomix machine version. Use ``ThermomixMachineType``
        (e.g. ``ThermomixMachineType.TM7``) or a string ("TM7", "TM6", "TM5").

    Returns
    -------
    CookidooSearchResult
        Search result with recipes and total count.

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore.
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    if locale is None:
        locale = self._cfg.localization.language.split("-")[0]
    url = self.api_endpoint / "search" / locale
    params: dict[str, str] = {}
    if query is not None:
        params["query"] = query
    if accessories is not None and (
        normalized := normalize_list_param(accessories)
    ):
        params["accessories"] = normalized
    if languages is not None and (normalized := normalize_list_param(languages)):
        params["languages"] = normalized
    if categories is not None and (normalized := normalize_list_param(categories)):
        params["categories"] = normalized
    if countries is not None and (normalized := normalize_list_param(countries)):
        params["countries"] = normalized
    if ingredients is not None and (
        normalized := normalize_list_param(ingredients)
    ):
        params["ingredients"] = normalized
    if exclude_ingredients is not None and (
        normalized := normalize_list_param(exclude_ingredients)
    ):
        params["excludeIngredients"] = normalized
    if tags is not None and (normalized := normalize_list_param(tags)):
        params["tags"] = normalized
    if ratings is not None and (normalized := normalize_list_param(ratings)):
        params["ratings"] = normalized
    if difficulty is not None:
        params["difficulty"] = difficulty
    if preparation_time is not None:
        params["preparationTime"] = str(preparation_time)
    if total_time is not None:
        params["totalTime"] = str(total_time)
    if portions is not None:
        params["portions"] = str(portions)
    if page is not None:
        params["page"] = str(page)
    if page_size is not None:
        params["pageSize"] = str(page_size)
    if tmv is not None and (normalized := normalize_tmv_param(tmv)):
        params["tmv"] = normalized
    result = await self._request_json("get", url, "search recipes", params=params)
    if result is None:
        return CookidooSearchResult(recipes=[], total=0)
    if not isinstance(result, dict):
        raise CookidooParseException(
            "Search recipes failed during parsing of request response."
        )
    return cookidoo_search_result_from_json(
        cast(SearchResultJSON, result), self._cfg.localization
    )

get_custom_recipe async

Get custom recipe.

Parameters:

Name Type Description Default
id str

The id of the custom recipe

required

Returns:

Type Description
CookidooCustomRecipe

The custom recipe

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_custom_recipe(self, id: str) -> CookidooCustomRecipe:
    """Get custom recipe.

    Parameters
    ----------
    id
        The id of the custom recipe

    Returns
    -------
    CookidooCustomRecipe
        The custom recipe

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / CUSTOM_RECIPE_PATH.format(
        **self._cfg.localization.__dict__, id=id
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading custom recipe"),
        "loading custom recipe",
    )
    return self._parse_result(
        "loading custom recipe",
        lambda: cookidoo_custom_recipe_from_json(
            cast(CustomRecipeJSON, result),
            self._cfg.localization,
        ),
    )

list_custom_recipes async

List custom recipes.

Source code in cookidoo_api/cookidoo.py
async def list_custom_recipes(self) -> list[CookidooCustomRecipe]:
    """List custom recipes."""
    url = self.api_endpoint / CUSTOM_RECIPES_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "get",
            url,
            "listing custom recipes",
            headers={"ACCEPT": CUSTOM_RECIPES_PATH_ACCEPT},
        ),
        "listing custom recipes",
    )
    if not isinstance(result.get("items"), list):
        raise CookidooParseException(
            "Listing custom recipes failed during parsing of request response."
        )

    custom_recipes = cast(CustomRecipesJSON, result)
    return self._parse_result(
        "listing custom recipes",
        lambda: [
            cookidoo_custom_recipe_from_json(recipe, self._cfg.localization)
            for recipe in custom_recipes["items"]
        ],
    )

add_custom_recipe_from async

Add custom recipe.

Parameters:

Name Type Description Default
recipeId str

The base recipe to copy

required
servingSize int

The serving size of the custom recipe

required

Returns:

Type Description
CookidooCustomRecipe

The added custom recipe

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_custom_recipe_from(
    self, recipeId: str, servingSize: int
) -> CookidooCustomRecipe:
    """Add custom recipe.

    Parameters
    ----------
    recipeId
        The base recipe to copy
    servingSize
        The serving size of the custom recipe

    Returns
    -------
    CookidooCustomRecipe
        The added custom recipe

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {
        "recipeUrl": str(
            self.api_endpoint
            / RECIPE_PATH.format(**self._cfg.localization.__dict__, id=recipeId)
        ),
        "servingSize": servingSize,
    }
    url = self.api_endpoint / ADD_CUSTOM_RECIPE_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json("post", url, "add custom recipe", json=json_data),
        "add custom recipe",
    )
    return self._parse_result(
        "add custom recipe",
        lambda: cookidoo_custom_recipe_from_json(
            cast(CustomRecipeJSON, result),
            self._cfg.localization,
        ),
    )

remove_custom_recipe async

Remove custom recipe.

Parameters:

Name Type Description Default
custom_recipe_id str

The custom recipe id to remove

required

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_custom_recipe(
    self,
    custom_recipe_id: str,
) -> None:
    """Remove custom recipe.

    Parameters
    ----------
    custom_recipe_id
        The custom recipe id to remove

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / REMOVE_CUSTOM_RECIPE_PATH.format(
        **self._cfg.localization.__dict__, id=custom_recipe_id
    )
    await self._request_json(
        "delete", url, "remove custom recipe", parse_response=False
    )

get_shopping_list_recipes async

Get recipes.

Returns:

Type Description
list[CookidooShoppingRecipe]

The list of the recipes

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_shopping_list_recipes(
    self,
) -> list[CookidooShoppingRecipe]:
    """Get recipes.

    Returns
    -------
    list[CookidooShoppingRecipe]
        The list of the recipes

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / SHOPPING_LIST_RECIPES_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading recipes"),
        "loading recipes",
    )
    return self._parse_result(
        "loading recipes",
        lambda: [
            cookidoo_recipe_from_json(
                cast(RecipeJSON, recipe), self._cfg.localization
            )
            for recipe in [
                *cast(Sequence[object], result["recipes"]),
                *cast(Sequence[object], result["customerRecipes"]),
            ]
        ],
    )

get_ingredient_items async

Get ingredient items.

Returns:

Type Description
list[CookidooIngredientItem]

The list of the ingredient items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_ingredient_items(
    self,
) -> list[CookidooIngredientItem]:
    """Get ingredient items.

    Returns
    -------
    list[CookidooIngredientItem]
        The list of the ingredient items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / INGREDIENT_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading ingredient items"),
        "loading ingredient items",
    )
    return self._parse_result(
        "loading ingredient items",
        lambda: [
            cookidoo_ingredient_item_from_json(cast(ItemJSON, ingredient))
            for recipe in [
                *cast(Sequence[Mapping[str, object]], result["recipes"]),
                *cast(Sequence[Mapping[str, object]], result["customerRecipes"]),
            ]
            for ingredient in cast(
                Sequence[object], recipe["recipeIngredientGroups"]
            )
        ],
    )

add_ingredient_items_for_recipes async

Add ingredient items for recipes.

Parameters:

Name Type Description Default
recipe_ids list[str]

The recipe ids for the ingredient items to add to the shopping list

required

Returns:

Type Description
list[CookidooIngredientItem]

The list of the added ingredient items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_ingredient_items_for_recipes(
    self,
    recipe_ids: list[str],
) -> list[CookidooIngredientItem]:
    """Add ingredient items for recipes.

    Parameters
    ----------
    recipe_ids
        The recipe ids for the ingredient items to add to the shopping list

    Returns
    -------
    list[CookidooIngredientItem]
        The list of the added ingredient items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"recipeIDs": recipe_ids}
    url = self.api_endpoint / ADD_INGREDIENT_ITEMS_FOR_RECIPES_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post", url, "add ingredient items for recipes", json=json_data
        ),
        "add ingredient items for recipes",
    )
    return self._parse_result(
        "loading added ingredient items",
        lambda: [
            cookidoo_ingredient_item_from_json(cast(ItemJSON, ingredient))
            for recipe in cast(Sequence[Mapping[str, object]], result["data"])
            for ingredient in cast(
                Sequence[object], recipe["recipeIngredientGroups"]
            )
        ],
    )

remove_ingredient_items_for_recipes async

Remove ingredient items for recipes.

Parameters:

Name Type Description Default
recipe_ids list[str]

The recipe ids for the ingredient items to remove to the shopping list

required

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_ingredient_items_for_recipes(
    self,
    recipe_ids: list[str],
) -> None:
    """Remove ingredient items for recipes.

    Parameters
    ----------
    recipe_ids
        The recipe ids for the ingredient items to remove to the shopping list

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"recipeIDs": recipe_ids}
    url = self.api_endpoint / REMOVE_INGREDIENT_ITEMS_FOR_RECIPES_PATH.format(
        **self._cfg.localization.__dict__
    )
    await self._request_json(
        "post",
        url,
        "remove ingredient items for recipes",
        json=json_data,
        parse_response=False,
    )

edit_ingredient_items_ownership async

Edit ownership ingredient items.

Parameters:

Name Type Description Default
ingredient_items list[CookidooIngredientItem]

The ingredient items to change the the is_owned value for

required

Returns:

Type Description
list[CookidooIngredientItem]

The list of the edited ingredient items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def edit_ingredient_items_ownership(
    self,
    ingredient_items: list[CookidooIngredientItem],
) -> list[CookidooIngredientItem]:
    """Edit ownership ingredient items.

    Parameters
    ----------
    ingredient_items
        The ingredient items to change the the `is_owned` value for

    Returns
    -------
    list[CookidooIngredientItem]
        The list of the edited ingredient items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {
        "ingredients": [
            {
                "id": ingredient_item.id,
                "isOwned": ingredient_item.is_owned,
                "ownedTimestamp": int(time.time()),
            }
            for ingredient_item in ingredient_items
        ]
    }
    url = self.api_endpoint / EDIT_OWNERSHIP_INGREDIENT_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post", url, "edit ingredient items ownership", json=json_data
        ),
        "edit ingredient items ownership",
    )
    return self._parse_result(
        "loading edited ingredient items",
        lambda: [
            cookidoo_ingredient_item_from_json(cast(ItemJSON, ingredient))
            for ingredient in cast(Sequence[object], result["data"])
        ],
    )

add_ingredient_items_for_custom_recipes async

Add ingredient items for custom recipes.

Parameters:

Name Type Description Default
recipe_ids list[str]

The recipe ids for the ingredient items to add to the shopping list

required

Returns:

Type Description
list[CookidooIngredientItem]

The list of the added ingredient items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_ingredient_items_for_custom_recipes(
    self,
    recipe_ids: list[str],
) -> list[CookidooIngredientItem]:
    """Add ingredient items for custom recipes.

    Parameters
    ----------
    recipe_ids
        The recipe ids for the ingredient items to add to the shopping list

    Returns
    -------
    list[CookidooIngredientItem]
        The list of the added ingredient items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {
        "recipeIDs": [
            {"id": recipe_id, "source": "CUSTOMER"} for recipe_id in recipe_ids
        ]
    }
    url = self.api_endpoint / ADD_INGREDIENT_ITEMS_FOR_RECIPES_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post", url, "add ingredient items for custom recipes", json=json_data
        ),
        "add ingredient items for custom recipes",
    )
    return self._parse_result(
        "loading added ingredient items",
        lambda: [
            cookidoo_ingredient_item_from_json(cast(ItemJSON, ingredient))
            for recipe in cast(Sequence[Mapping[str, object]], result["data"])
            for ingredient in cast(
                Sequence[object], recipe["recipeIngredientGroups"]
            )
        ],
    )

remove_ingredient_items_for_custom_recipes async

Remove ingredient items for custom recipes.

Parameters:

Name Type Description Default
recipe_ids list[str]

The custom recipe ids for the ingredient items to remove to the shopping list

required

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_ingredient_items_for_custom_recipes(
    self,
    recipe_ids: list[str],
) -> None:
    """Remove ingredient items for custom recipes.

    Parameters
    ----------
    recipe_ids
        The custom recipe ids for the ingredient items to remove to the shopping list

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"recipeIDs": recipe_ids}
    url = self.api_endpoint / REMOVE_INGREDIENT_ITEMS_FOR_RECIPES_PATH.format(
        **self._cfg.localization.__dict__
    )
    await self._request_json(
        "post",
        url,
        "remove ingredient items for custom recipes",
        json=json_data,
        parse_response=False,
    )

get_additional_items async

Get additional items.

Returns:

Type Description
list[CookidooAdditionalItem]

The list of the additional items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_additional_items(
    self,
) -> list[CookidooAdditionalItem]:
    """Get additional items.

    Returns
    -------
    list[CookidooAdditionalItem]
        The list of the additional items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / ADDITIONAL_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading additional items"),
        "loading additional items",
    )
    return self._parse_result(
        "loading additional items",
        lambda: [
            cookidoo_additional_item_from_json(
                cast(AdditionalItemJSON, additional_item)
            )
            for additional_item in cast(Sequence[object], result["additionalItems"])
        ],
    )

add_additional_items async

Create additional items.

Parameters:

Name Type Description Default
additional_item_names list[str]

The additional item names to create, only the label can be set, as the default state is_owned=false is forced (chain with immediate update call for work-around)

required

Returns:

Type Description
list[CookidooAdditionalItem]

The list of the added additional items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_additional_items(
    self,
    additional_item_names: list[str],
) -> list[CookidooAdditionalItem]:
    """Create additional items.

    Parameters
    ----------
    additional_item_names
        The additional item names to create, only the label can be set, as the default state `is_owned=false` is forced (chain with immediate update call for work-around)

    Returns
    -------
    list[CookidooAdditionalItem]
        The list of the added additional items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"itemsValue": additional_item_names}
    url = self.api_endpoint / ADD_ADDITIONAL_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post", url, "add additional items", json=json_data
        ),
        "add additional items",
    )
    return self._parse_result(
        "loading added additional items",
        lambda: [
            cookidoo_additional_item_from_json(
                cast(AdditionalItemJSON, additional_item)
            )
            for additional_item in cast(Sequence[object], result["data"])
        ],
    )

edit_additional_items async

Edit additional items.

Parameters:

Name Type Description Default
additional_items list[CookidooAdditionalItem]

The additional items to change the the name value for

required

Returns:

Type Description
list[CookidooAdditionalItem]

The list of the edited additional items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def edit_additional_items(
    self,
    additional_items: list[CookidooAdditionalItem],
) -> list[CookidooAdditionalItem]:
    """Edit additional items.

    Parameters
    ----------
    additional_items
        The additional items to change the the `name` value for

    Returns
    -------
    list[CookidooAdditionalItem]
        The list of the edited additional items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {
        "additionalItems": [
            {
                "id": additional_item.id,
                "name": additional_item.name,
            }
            for additional_item in additional_items
        ]
    }
    url = self.api_endpoint / EDIT_ADDITIONAL_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post", url, "edit additional items", json=json_data
        ),
        "edit additional items",
    )
    return self._parse_result(
        "loading edited additional items",
        lambda: [
            cookidoo_additional_item_from_json(
                cast(AdditionalItemJSON, additional_item)
            )
            for additional_item in cast(Sequence[object], result["data"])
        ],
    )

edit_additional_items_ownership async

Edit ownership additional items.

Parameters:

Name Type Description Default
additional_items list[CookidooAdditionalItem]

The additional items to change the the is_owned value for

required

Returns:

Type Description
list[CookidooAdditionalItem]

The list of the edited additional items

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def edit_additional_items_ownership(
    self,
    additional_items: list[CookidooAdditionalItem],
) -> list[CookidooAdditionalItem]:
    """Edit ownership additional items.

    Parameters
    ----------
    additional_items
        The additional items to change the the `is_owned` value for

    Returns
    -------
    list[CookidooAdditionalItem]
        The list of the edited additional items

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {
        "additionalItems": [
            {
                "id": additional_item.id,
                "isOwned": additional_item.is_owned,
                "ownedTimestamp": int(time.time()),
            }
            for additional_item in additional_items
        ]
    }
    url = self.api_endpoint / EDIT_OWNERSHIP_ADDITIONAL_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post", url, "edit additional items ownership", json=json_data
        ),
        "edit additional items ownership",
    )
    return self._parse_result(
        "loading edited additional items",
        lambda: [
            cookidoo_additional_item_from_json(
                cast(AdditionalItemJSON, additional_item)
            )
            for additional_item in cast(Sequence[object], result["data"])
        ],
    )

remove_additional_items async

Remove additional items.

Parameters:

Name Type Description Default
additional_item_ids list[str]

The additional item ids to remove

required

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_additional_items(
    self,
    additional_item_ids: list[str],
) -> None:
    """Remove additional items.

    Parameters
    ----------
    additional_item_ids
        The additional item ids to remove

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"additionalItemIDs": additional_item_ids}
    url = self.api_endpoint / REMOVE_ADDITIONAL_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    await self._request_json(
        "post",
        url,
        "remove additional items",
        json=json_data,
        parse_response=False,
    )

clear_shopping_list async

Remove all additional items, ingredients and recipes.

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def clear_shopping_list(
    self,
) -> None:
    """Remove all additional items, ingredients and recipes.

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / INGREDIENT_ITEMS_PATH.format(
        **self._cfg.localization.__dict__
    )
    await self._request_json(
        "delete", url, "clear shopping list", parse_response=False
    )

count_managed_collections async

Get managed collections.

Returns:

Type Description
tuple[int, int]

The number of managed collections and the number of pages

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def count_managed_collections(self) -> tuple[int, int]:
    """Get managed collections.

    Returns
    -------
    tuple[int, int]
        The number of managed collections and the number of pages

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / MANAGED_COLLECTIONS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "get",
            url,
            "loading managed collections",
            headers={"ACCEPT": MANAGED_COLLECTIONS_PATH_ACCEPT},
        ),
        "loading managed collections",
    )
    return self._parse_result(
        "loading managed collections",
        lambda: (
            cast(PaginationJSON, result["page"])["totalElements"],
            cast(PaginationJSON, result["page"])["totalPages"],
        ),
    )

get_managed_collections async

Get managed collections.

Parameters:

Name Type Description Default
page int

The page of the managed collections

0

Returns:

Type Description
list[CookidooCollection]

The list of the managed collections

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_managed_collections(self, page: int = 0) -> list[CookidooCollection]:
    """Get managed collections.

    Parameters
    ----------
    page
        The page of the managed collections

    Returns
    -------
    list[CookidooCollection]
        The list of the managed collections

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / MANAGED_COLLECTIONS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "get",
            url,
            "loading managed collections",
            params={"page": str(page)},
            headers={"ACCEPT": MANAGED_COLLECTIONS_PATH_ACCEPT},
        ),
        "loading managed collections",
    )
    return self._parse_result(
        "loading managed collections",
        lambda: [
            cookidoo_collection_from_json(cast(ManagedCollectionJSON, item))
            for item in cast(Sequence[object], result["managedlists"])
        ],
    )

add_managed_collection async

Add managed collections.

Parameters:

Name Type Description Default
managed_collection_id str

The managed collection id to add

required

Returns:

Type Description
CookidooCollection

The added managed collection

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_managed_collection(
    self,
    managed_collection_id: str,
) -> CookidooCollection:
    """Add managed collections.

    Parameters
    ----------
    managed_collection_id
        The managed collection id to add

    Returns
    -------
    CookidooCollection
        The added managed collection

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"collectionId": managed_collection_id}
    url = self.api_endpoint / ADD_MANAGED_COLLECTION_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post",
            url,
            "add managed collection",
            json=json_data,
            headers={"ACCEPT": MANAGED_COLLECTIONS_PATH_ACCEPT},
        ),
        "add managed collection",
    )
    return self._parse_result(
        "loading added managed collection",
        lambda: cookidoo_collection_from_json(
            cast(ManagedCollectionJSON, result["content"])
        ),
    )

remove_managed_collection async

Remove managed collection.

Parameters:

Name Type Description Default
managed_collection_id str

The managed collection id to remove

required

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_managed_collection(
    self,
    managed_collection_id: str,
) -> None:
    """Remove managed collection.

    Parameters
    ----------
    managed_collection_id
        The managed collection id to remove

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / REMOVE_MANAGED_COLLECTION_PATH.format(
        **self._cfg.localization.__dict__, id=managed_collection_id
    )
    await self._request_json(
        "delete",
        url,
        "remove managed collection",
        headers={"ACCEPT": MANAGED_COLLECTIONS_PATH_ACCEPT},
        parse_response=False,
    )

count_custom_collections async

Get custom collections.

Returns:

Type Description
tuple[int, int]

The number of custom collections and the number of pages

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def count_custom_collections(self) -> tuple[int, int]:
    """Get custom collections.

    Returns
    -------
    tuple[int, int]
        The number of custom collections and the number of pages

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / CUSTOM_COLLECTIONS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "get",
            url,
            "loading custom collections",
            headers={"ACCEPT": CUSTOM_COLLECTIONS_PATH_ACCEPT},
        ),
        "loading custom collections",
    )
    return self._parse_result(
        "loading custom collections",
        lambda: (
            cast(PaginationJSON, result["page"])["totalElements"],
            cast(PaginationJSON, result["page"])["totalPages"],
        ),
    )

get_custom_collections async

Get custom collections.

Parameters:

Name Type Description Default
page int

The page of the custom collections

0

Returns:

Type Description
list[CookidooCollection]

The list of the custom collections

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_custom_collections(self, page: int = 0) -> list[CookidooCollection]:
    """Get custom collections.

    Parameters
    ----------
    page
        The page of the custom collections

    Returns
    -------
    list[CookidooCollection]
        The list of the custom collections

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / CUSTOM_COLLECTIONS_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "get",
            url,
            "loading custom collections",
            params={"page": str(page)},
            headers={"ACCEPT": CUSTOM_COLLECTIONS_PATH_ACCEPT},
        ),
        "loading custom collections",
    )
    return self._parse_result(
        "loading custom collections",
        lambda: [
            cookidoo_collection_from_json(cast(CustomCollectionJSON, item))
            for item in cast(Sequence[object], result["customlists"])
        ],
    )

add_custom_collection async

Add custom collections.

Parameters:

Name Type Description Default
custom_collection_name str

The custom collection name to add

required

Returns:

Type Description
CookidooCollection

The added custom collection

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_custom_collection(
    self,
    custom_collection_name: str,
) -> CookidooCollection:
    """Add custom collections.

    Parameters
    ----------
    custom_collection_name
        The custom collection name to add

    Returns
    -------
    CookidooCollection
        The added custom collection

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"title": custom_collection_name}
    url = self.api_endpoint / ADD_CUSTOM_COLLECTION_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "post",
            url,
            "add custom collection",
            json=json_data,
            headers={"ACCEPT": CUSTOM_COLLECTIONS_PATH_ACCEPT},
        ),
        "add custom collection",
    )
    return self._parse_result(
        "loading added custom collection",
        lambda: cookidoo_collection_from_json(
            cast(CustomCollectionJSON, result["content"])
        ),
    )

remove_custom_collection async

Remove custom collection.

Parameters:

Name Type Description Default
custom_collection_id str

The custom collection id to remove

required

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_custom_collection(
    self,
    custom_collection_id: str,
) -> None:
    """Remove custom collection.

    Parameters
    ----------
    custom_collection_id
        The custom collection id to remove

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / REMOVE_CUSTOM_COLLECTION_PATH.format(
        **self._cfg.localization.__dict__, id=custom_collection_id
    )
    await self._request_json(
        "delete",
        url,
        "remove custom collection",
        headers={"ACCEPT": CUSTOM_COLLECTIONS_PATH_ACCEPT},
        parse_response=False,
    )

add_recipes_to_custom_collection async

Add recipes to a custom collections.

Parameters:

Name Type Description Default
custom_collection_id str

The custom collection to add the recipes to

required
recipe_ids list[str]

The recipe ids to add to a custom collection

required

Returns:

Type Description
CookidooCollection

The changed custom collection

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_recipes_to_custom_collection(
    self,
    custom_collection_id: str,
    recipe_ids: list[str],
) -> CookidooCollection:
    """Add recipes to a custom collections.

    Parameters
    ----------
    custom_collection_id
        The custom collection to add the recipes to
    recipe_ids
        The recipe ids to add to a custom collection

    Returns
    -------
    CookidooCollection
        The changed custom collection

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"recipeIds": recipe_ids}
    url = self.api_endpoint / ADD_RECIPES_TO_CUSTOM_COLLECTION_PATH.format(
        **self._cfg.localization.__dict__, id=custom_collection_id
    )
    result = self._ensure_mapping(
        await self._request_json(
            "put", url, "add recipes to custom collection", json=json_data
        ),
        "add recipes to custom collection",
    )
    return self._parse_result(
        "loading added recipes",
        lambda: cookidoo_collection_from_json(
            cast(CustomCollectionJSON, result["content"])
        ),
    )

remove_recipe_from_custom_collection async

Remove recipe from a custom collections.

Parameters:

Name Type Description Default
custom_collection_id str

The custom collection to remove the recipe from

required
recipe_id str

The recipe id to remove from a custom collection

required

Returns:

Type Description
CookidooCollection

The changed custom collection

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_recipe_from_custom_collection(
    self,
    custom_collection_id: str,
    recipe_id: str,
) -> CookidooCollection:
    """Remove recipe from a custom collections.

    Parameters
    ----------
    custom_collection_id
        The custom collection to remove the recipe from
    recipe_id
        The recipe id to remove from a custom collection

    Returns
    -------
    CookidooCollection
        The changed custom collection

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / REMOVE_RECIPE_FROM_CUSTOM_COLLECTION_PATH.format(
        **self._cfg.localization.__dict__,
        id=custom_collection_id,
        recipe=recipe_id,
    )
    result = self._ensure_mapping(
        await self._request_json(
            "delete", url, "remove recipe from custom collection"
        ),
        "remove recipe from custom collection",
    )
    return self._parse_result(
        "loading removed recipe",
        lambda: cookidoo_collection_from_json(
            cast(CustomCollectionJSON, result["content"])
        ),
    )

get_recipes_in_calendar_week async

Get recipes in a calendar week.

Parameters:

Name Type Description Default
day date

The date specifying the calendar week

required

Returns:

Type Description
list[CookidooCalendarDay]

The list of the calendar days with recipes

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def get_recipes_in_calendar_week(
    self, day: date
) -> list[CookidooCalendarDay]:
    """Get recipes in a calendar week.

    Parameters
    ----------
    day
        The date specifying the calendar week

    Returns
    -------
    list[CookidooCalendarDay]
        The list of the calendar days with recipes

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """

    url = self.api_endpoint / RECIPES_IN_CALENDAR_WEEK_PATH.format(
        **self._cfg.localization.__dict__, day=day.isoformat()
    )
    result = self._ensure_mapping(
        await self._request_json("get", url, "loading recipes in calendar week"),
        "loading recipes in calendar week",
    )
    return self._parse_result(
        "loading recipes in calendar week",
        lambda: [
            cookidoo_calendar_day_from_json(
                cast(CalendarDayJSON, calendar_day), self._cfg.localization
            )
            for calendar_day in cast(Sequence[object], result["myDays"])
        ],
    )

add_recipes_to_calendar async

Add recipes to a calendar.

Parameters:

Name Type Description Default
day date

The date to add the recipes to in the calendar

required
recipe_ids list[str]

The recipe ids to add to the calendar

required

Returns:

Type Description
CookidooCalendarDay

The changed calendar day

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_recipes_to_calendar(
    self,
    day: date,
    recipe_ids: list[str],
) -> CookidooCalendarDay:
    """Add recipes to a calendar.

    Parameters
    ----------
    day
        The date to add the recipes to in the calendar
    recipe_ids
        The recipe ids to add to the calendar

    Returns
    -------
    CookidooCalendarDay
        The changed calendar day

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {"recipeIds": recipe_ids, "dayKey": day.isoformat()}
    url = self.api_endpoint / ADD_RECIPES_TO_CALENDER_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "put", url, "add recipes to calendar", json=json_data
        ),
        "add recipes to calendar",
    )
    return self._parse_result(
        "loading added recipes",
        lambda: cookidoo_calendar_day_from_json(
            cast(CalendarDayJSON, result["content"]),
            self._cfg.localization,
        ),
    )

remove_recipe_from_calendar async

Remove recipe from calendar.

Parameters:

Name Type Description Default
day date

The date to remove the recipe from in the calendar

required
recipe_id str

The recipe id to remove from the calendar

required

Returns:

Type Description
CookidooCalendarDay

The changed calendar day

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_recipe_from_calendar(
    self,
    day: date,
    recipe_id: str,
) -> CookidooCalendarDay:
    """Remove recipe from calendar.

    Parameters
    ----------
    day
        The date to remove the recipe from in the calendar
    recipe_id
        The recipe id to remove from the calendar

    Returns
    -------
    CookidooCalendarDay
        The changed calendar day

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / REMOVE_RECIPE_FROM_CALENDER_PATH.format(
        **self._cfg.localization.__dict__,
        day=day.isoformat(),
        recipe=recipe_id,
    )
    result = self._ensure_mapping(
        await self._request_json("delete", url, "remove recipe from calendar"),
        "remove recipe from calendar",
    )
    return self._parse_result(
        "loading removed recipe",
        lambda: cookidoo_calendar_day_from_json(
            cast(CalendarDayJSON, result["content"]),
            self._cfg.localization,
        ),
    )

add_custom_recipes_to_calendar async

Add custom recipes to a calendar.

Parameters:

Name Type Description Default
day date

The date to add the custom recipes to in the calendar

required
recipe_ids list[str]

The recipe ids to add to the calendar

required

Returns:

Type Description
CookidooCalendarDay

The changed calendar day

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def add_custom_recipes_to_calendar(
    self,
    day: date,
    recipe_ids: list[str],
) -> CookidooCalendarDay:
    """Add custom recipes to a calendar.

    Parameters
    ----------
    day
        The date to add the custom recipes to in the calendar
    recipe_ids
        The recipe ids to add to the calendar

    Returns
    -------
    CookidooCalendarDay
        The changed calendar day

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    json_data = {
        "recipeIds": recipe_ids,
        "dayKey": day.isoformat(),
        "recipeSource": "CUSTOMER",
    }
    url = self.api_endpoint / ADD_RECIPES_TO_CALENDER_PATH.format(
        **self._cfg.localization.__dict__
    )
    result = self._ensure_mapping(
        await self._request_json(
            "put", url, "add custom recipes to calendar", json=json_data
        ),
        "add custom recipes to calendar",
    )
    return self._parse_result(
        "loading added custom recipes",
        lambda: cookidoo_calendar_day_from_json(
            cast(CalendarDayJSON, result["content"]),
            self._cfg.localization,
        ),
    )

remove_custom_recipe_from_calendar async

Remove custom recipe from calendar.

Parameters:

Name Type Description Default
day date

The date to remove the custom recipe from in the calendar

required
recipe_id str

The custom recipe id to remove from the calendar

required

Returns:

Type Description
CookidooCalendarDay

The changed calendar day

Raises:

Type Description
CookidooAuthException

When the access token is not valid anymore

CookidooRequestException

If the request fails.

CookidooParseException

If the parsing of the request response fails.

Source code in cookidoo_api/cookidoo.py
async def remove_custom_recipe_from_calendar(
    self,
    day: date,
    recipe_id: str,
) -> CookidooCalendarDay:
    """Remove custom recipe from calendar.

    Parameters
    ----------
    day
        The date to remove the custom recipe from in the calendar
    recipe_id
        The custom recipe id to remove from the calendar

    Returns
    -------
    CookidooCalendarDay
        The changed calendar day

    Raises
    ------
    CookidooAuthException
        When the access token is not valid anymore
    CookidooRequestException
        If the request fails.
    CookidooParseException
        If the parsing of the request response fails.

    """
    url = self.api_endpoint / REMOVE_RECIPE_FROM_CALENDER_PATH.format(
        **self._cfg.localization.__dict__,
        day=day.isoformat(),
        recipe=recipe_id,
    )
    result = self._ensure_mapping(
        await self._request_json(
            "delete",
            url,
            "remove custom recipe from calendar",
            params={"recipeSource": "CUSTOMER"},
        ),
        "remove custom recipe from calendar",
    )
    return self._parse_result(
        "loading custom removed recipe",
        lambda: cookidoo_calendar_day_from_json(
            cast(CalendarDayJSON, result["content"]),
            self._cfg.localization,
        ),
    )

CookidooAuthException

Bases: CookidooException

When an authentication error is encountered.

CookidooConfigException

Bases: CookidooException

When the config is invalid.

CookidooException

Bases: Exception

General exception occurred.

CookidooParseException

Bases: CookidooException

When data could not be parsed.

CookidooRequestException

Bases: CookidooException

When a request returns an error.

CookidooResponseException

Bases: CookidooException

When a response could not be parsed.

CookidooUnavailableException

Bases: CookidooException

When the network or server is not available.

CookidooAdditionalItem dataclass

Bases: CookidooItem

Cookidoo additional item type.

CookidooCategory dataclass

Cookidoo category type.

Attributes:

Name Type Description
id str

The id of the category

name str

The label of the category

notes str

The additional information of the category

CookidooChapter dataclass

Cookidoo chapter type.

Attributes:

Name Type Description
title

The title of the chapter

recipes list[CookidooChapterRecipe]

The recipes in the chapter

CookidooChapterRecipe dataclass

Cookidoo chapter recipe type.

Attributes:

Name Type Description
id str

The id of the recipe

name str

The label of the recipe

total_time int

The time for the recipe

CookidooCollection dataclass

Cookidoo collection type.

Attributes:

Name Type Description
id str

The id of the collection

title

The title of the collection

description str | None

The description of the collection

chapters list[CookidooChapter]

The recipes in the collection

CookidooConfig dataclass

Cookidoo config type.

Attributes:

Name Type Description
localization CookidooLocalizationConfig

The localization for the api including country, language and url

email str

The email to login

password str

The password to login

CookidooIngredient dataclass

Cookidoo ingredient type.

Attributes:

Name Type Description
id str

The id of the ingredient

name str

The label of the ingredient

description str

The description of the item, including the quantity or other helpful information

CookidooIngredientItem dataclass

Bases: CookidooItem

Cookidoo ingredient item type.

Attributes:

Name Type Description
description str

The description of the item, including the quantity or other helpful information

CookidooItem dataclass

Cookidoo item type.

Attributes:

Name Type Description
id str

The id of the item

name str

The label of the item

CookidooLocalizationConfig dataclass

A localization config class.

CookidooRecipeCollection dataclass

Cookidoo recipe collection type.

Attributes:

Name Type Description
id str

The id of the collection

name str

The label of the collection

additional_information

The additional information of the collection

CookidooSearchRecipeHit dataclass

A single recipe hit from Cookidoo search.

Attributes:

Name Type Description
id str

The id of the recipe

name str

The title of the recipe

thumbnail str | None

The thumbnail image URL (small preview)

image str | None

The full-size image URL

url str

The URL of the recipe

CookidooSearchResult dataclass

Cookidoo search result type.

Attributes:

Name Type Description
recipes list[CookidooSearchRecipeHit]

List of recipe hits matching the search

total int

Total number of matching recipes

CookidooShoppingRecipe dataclass

Cookidoo shopping recipe type.

Attributes:

Name Type Description
id str

The id of the recipe

name str

The label of the recipe

ingredients list[CookidooIngredient]

The ingredients of the recipe

thumbnail str | None

The thumbnail image URL (small preview)

image str | None

The full-size image URL

url str

The URL of the recipe

CookidooShoppingRecipeDetails dataclass

Bases: CookidooShoppingRecipe

Cookidoo recipe details type.

Attributes:

Name Type Description
difficulty str

The difficulty of the recipe

notes list[str]

Hints and additional information about the recipe

categories list[CookidooCategory]

The categories of the recipe

collections list[CookidooRecipeCollection]

The collections of the recipe

utensils list[str]

The utensils needed for the recipe

serving_size int

The service size of the recipe

active_time int

The time needed preparing the recipe [in seconds]

total_time int

The time needed until the recipe is ready [in seconds]

nutrition_groups list[CookidooNutritionGroup]

The nutrition groups of the recipe (from API, may be empty)

CookidooSubscription dataclass

A subscription class.

CookidooUserInfo dataclass

A user info class.

ThermomixMachineType

Bases: StrEnum

Thermomix machine types.

get_country_options async

Get a list of possible country options.

Source code in cookidoo_api/helpers.py
async def get_country_options() -> list[str]:
    """Get a list of possible country options."""
    return list({option.country_code for option in await get_localization_options()})

get_language_options async

Get a list of possible language options.

Source code in cookidoo_api/helpers.py
async def get_language_options() -> list[str]:
    """Get a list of possible language options."""
    return list({option.language for option in await get_localization_options()})

get_localization_options async

Get a list of possible localization options.

Source code in cookidoo_api/helpers.py
async def get_localization_options(
    country: str | None = None,
    language: str | None = None,
) -> list[CookidooLocalizationConfig]:
    """Get a list of possible localization options."""
    return await __get_localization_options(country, language)