Skip to main content

Typed factory-aware base for service and repository components without a domain model.

Project description

servicePhilosophy

A small typed foundation for factory-aware repository-style components.

Python 3.12+
Runtime deps none
License MIT

Core idea

ServiceRepository[FactoryT]
= a neutral base class for objects that need factory access.
It does not require a model.
It does not know about SQL, HTTP, controllers, or frameworks.

ServiceRepository stores an optional factory and exposes it through:

  • factory — returns the factory, or raises FactoryRequiredError when missing
  • maybe_factory — returns the factory or None
  • has_factoryTrue when a factory was provided at construction

Use ServiceRepositoryProtocol when you want to type against that shape without inheriting from the base class. Use RepositoryFactoryProtocol as a minimal marker for factory types that downstream packages extend.

What this is (and is not)

  • ServiceRepository is not a SQL repository.
  • ServiceRepository is not an API client.
  • It is a shared factory-aware base.
  • sqlPhilosophy can extend it with model-bound persistence.
  • apiPhilosophy can extend it with HTTP/resource clients.
  • Application service repositories can extend it directly for business logic with no model at all.

This package has zero runtime dependencies. It does not include SQLAlchemy, HTTP clients, FastAPI, Pydantic, or Django.

Basic service repository

from servicephilosophy import ServiceRepository


class ServiceFactory:
    def greeting(self) -> str:
        return "hello"


class GreetingService(ServiceRepository[ServiceFactory]):
    def greet(self) -> str:
        return self.factory.greeting()

SQL specialization in another package

from typing import Generic, TypeVar

from servicephilosophy import ServiceRepository

ModelT = TypeVar("ModelT")
FactoryT = TypeVar("FactoryT")


class BaseRepository(ServiceRepository[FactoryT], Generic[ModelT, FactoryT]):
    model: type[ModelT]

API specialization in another package

from typing import Generic, TypeVar

from servicephilosophy import ServiceRepository

ResourceT = TypeVar("ResourceT")
FactoryT = TypeVar("FactoryT")


class BaseApiRepository(ServiceRepository[FactoryT], Generic[ResourceT, FactoryT]):
    pass

Business logic with no model

from servicephilosophy import ServiceRepository


class PermissionServiceRepository(ServiceRepository[ServiceFactory]):
    def has_permission(self, actor_id: int, permission: str) -> bool:
        return True

Recommended ecosystem

servicePhilosophy
  ServiceRepository[FactoryT]

sqlPhilosophy
  BaseRepository[ModelT, FactoryT]

apiPhilosophy
  BaseApiRepository[ResourceT, FactoryT]

application
  PermissionServiceRepository(ServiceRepository[ServiceFactory])

Each layer adds its own concern. servicePhilosophy only handles factory wiring; specialization lives in the package or application that needs it.

Install

pip install servicephilosophy

Development:

uv sync --extra dev
uv run pytest
uv run ruff check src tests
uv run mypy src

Public API

from servicephilosophy import (
    FactoryRequiredError,
    RepositoryFactoryProtocol,
    ServiceRepository,
    ServiceRepositoryProtocol,
)

Or import from submodules:

from servicephilosophy.repository import ServiceRepository
from servicephilosophy.protocols import RepositoryFactoryProtocol, ServiceRepositoryProtocol
from servicephilosophy.exceptions import FactoryRequiredError

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

servicephilosophy-0.1.0.tar.gz (5.3 kB view details)

Uploaded Source

Built Distribution

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

servicephilosophy-0.1.0-py3-none-any.whl (5.7 kB view details)

Uploaded Python 3

File details

Details for the file servicephilosophy-0.1.0.tar.gz.

File metadata

  • Download URL: servicephilosophy-0.1.0.tar.gz
  • Upload date:
  • Size: 5.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for servicephilosophy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c6fc92e5dcced8fbf2c3482644cea2b4074a7b7ce9f73883fd6788cad4aad938
MD5 18e1b92675f0ddb6d618a271c63dc813
BLAKE2b-256 d0f654f2196bd9909ce3217854ed89073971ef6e765591e134d6fc6ac6aefad4

See more details on using hashes here.

File details

Details for the file servicephilosophy-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for servicephilosophy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7e35b11afe06545182b8e65f0d09603c3953918d14311bc1a38aad3ee7c78578
MD5 3641b16654eea595e65dcfebfa4d71d9
BLAKE2b-256 3cbeb69cdbc5606e8ffcf507cae7535f5a690ea6d4afe618f6812c690d4be31c

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