Skip to main content

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 interface — ServiceClient (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

Release files for macss-service-client 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for macss-service-client 0.2.1
File Size Uploaded
macss_service_client-0.2.1.tar.gz 9.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for macss-service-client 0.2.1
File Interpreter ABI Platform
macss_service_client-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 20.5 kB

Release files / macss_service_client-0.2.1.tar.gz

Download URL macss_service_client-0.2.1.tar.gz
Size 9.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4c29f8093585f98c1d332a9c247448fb3134a6ea2de827760932a9b9f31e14be
BLAKE2b-256 checksum
How to use checksums
289b34de89f21bc7b75c0306f3dbef94c1a855e5415e1acd1ba08b273ab0604f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Release files / macss_service_client-0.2.1-py3-none-any.whl

Download URL macss_service_client-0.2.1-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0728139b98c7974e45af96e180c3136143507f1ea700ba878239cf7966db732a
BLAKE2b-256 checksum
How to use checksums
c5031166dead86c3c8b6e1c36ca0e1d7a39b95b51bba5ba031e4fa74ce2ae371
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.0

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page