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.1.tar.gz (9.4 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.1-py3-none-any.whl (11.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: macss_service_client-0.2.1.tar.gz
  • Upload date:
  • Size: 9.4 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.1.tar.gz
Algorithm Hash digest
SHA256 4c29f8093585f98c1d332a9c247448fb3134a6ea2de827760932a9b9f31e14be
MD5 2343ca93618f7aade4653c5389f163a2
BLAKE2b-256 289b34de89f21bc7b75c0306f3dbef94c1a855e5415e1acd1ba08b273ab0604f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for macss_service_client-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0728139b98c7974e45af96e180c3136143507f1ea700ba878239cf7966db732a
MD5 77578923c09eeab06a27f27ac662cd11
BLAKE2b-256 c5031166dead86c3c8b6e1c36ca0e1d7a39b95b51bba5ba031e4fa74ce2ae371

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