Skip to main content

Service client abstraction with the Result pattern for Python. Transport-agnostic interface with an HTTP implementation.

Project description

macss-service-client

A service client abstraction for Python with the Result pattern for explicit success/failure handling.

Currently ships with an HTTP implementation using httpx. The architecture is designed to support additional transport layers in the future (see Roadmap).

Also available in Dart: service_client · TypeScript: @macss/service-client

Features

  • Transport-agnostic interfaceServiceClient (Protocol) defines the contract; HttpServiceClient implements it for HTTP
  • Result pattern with dataclass + Union — exhaustive checking via match/case
  • ServiceFailure base class for typed service errors (extensible via inheritance)
  • Configurable base URL, headers, and timeout
  • Fully async with httpx.AsyncClient
  • Typed with py.typed marker (PEP 561)

Installation

pip install macss-service-client

Usage

The example below follows an MVC structure: the View (main) delegates to a Controller, which calls the Service. The service returns a Result that the controller resolves via match/case.

Model

from dataclasses import dataclass
from typing import Any


@dataclass(frozen=True, slots=True)
class ToDo:
    id: int
    title: str
    is_completed: bool

    @staticmethod
    def from_json(json: dict[str, Any]) -> "ToDo":
        return ToDo(
            id=json["id"],
            title=json["title"],
            is_completed=json["completed"],
        )

Error

from service_client import ServiceFailure


class ToDoFailure(ServiceFailure):
    pass

Service

from service_client import (
    HttpClientException,
    HttpServiceClient,
    Result,
    ServiceClient,
    ServiceClientConfig,
    ServiceRequest,
    failure,
    success,
)

_config = ServiceClientConfig(
    base_url="https://jsonplaceholder.typicode.com",
    default_headers={"Content-Type": "application/json"},
    timeout=30.0,
)

_client: ServiceClient | None = None


def _get_service() -> ServiceClient:
    global _client
    if _client is None:
        _client = HttpServiceClient(_config)
    return _client


async def get_todo(todo_id: int) -> Result[ToDo, ToDoFailure]:
    request = ServiceRequest.http(
        method="GET",
        endpoint=f"todos/{todo_id}",
        error_message="Failed to fetch TODO",
    )

    try:
        response = await _get_service().send(request)
        return success(ToDo.from_json(response.data))
    except HttpClientException as exc:
        return failure(
            ToDoFailure(
                status_code=exc.status_code,
                message=str(exc.args[0]),
                response_body=exc.response,
            )
        )

Controller

The controller returns the Result directly — the view decides how to render each case:

from service_client import Result


class TodoController:
    async def fetch_todo(self, todo_id: int) -> Result[ToDo, ToDoFailure]:
        return await get_todo(todo_id)

View (main)

The view uses match/case to handle success and failure:

import asyncio
from service_client import Success, Failure


async def main() -> None:
    controller = TodoController()
    result = await controller.fetch_todo(1)

    match result:
        case Success(value=todo):
            print(f"{todo.id}: {todo.title}")
        case Failure(error=err):
            print(f"Error {err.status_code}: {err.message}")


asyncio.run(main())

License

MIT © ccisne.dev

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

macss_service_client-0.2.0.tar.gz (9.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

macss_service_client-0.2.0-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

Details for the file macss_service_client-0.2.0.tar.gz.

File metadata

  • Download URL: macss_service_client-0.2.0.tar.gz
  • Upload date:
  • Size: 9.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for macss_service_client-0.2.0.tar.gz
Algorithm Hash digest
SHA256 adcaa4d6a4ab9a190a04b8adf321517376634b1970929f007484f01031b0a1fd
MD5 d3cd1ef5b828998110268548b617469b
BLAKE2b-256 952f51c22a07005a817af3366120cd3ed47c6f93d05e3c0d0ff605db31b96085

See more details on using hashes here.

File details

Details for the file macss_service_client-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for macss_service_client-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ff750a8f79f82e24a1d7e79911242c1b68aa1eb22be8cbe426ec9e3df63cfc97
MD5 a935ce29aba17d01d0a0638a00faa6d6
BLAKE2b-256 4b802f1746ca730c36cc580a97944f4aa036e78dedd481bd86b6397063b6f071

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page