Skip to main content

Fractal Core

Fractal Core is the bottom layer of the Fractal stack: settings, exceptions, a service base class, and the utilities every layer above reaches for.

PyPI Version Build Status

Installation

pip install fractal-core

Background

Every layer of an application needs a few of the same things: somewhere to read configuration, a way to say a rule was broken, a shape for the adapters the application installs. Left unowned, those get re-invented per layer, or they end up in whichever module happened to need them first — and then that module becomes a dependency of everything.

This package owns them instead, and it owns nothing else. Nothing here imports another Fractal library. That constraint is the point: it is what lets fractal-commands, events, processes and the application context all build on this without importing each other.

Settings

Settings is a singleton, loaded once from the environment:

import os

from fractal_core import Settings


class AppSettings(Settings):
    ROOT_DIR = "/srv/app"          # optional: where to look for .env

    def load(self):
        self.DEBUG = os.getenv("DEBUG", "false") == "true"
        self.DATABASE_URL = os.getenv("DATABASE_URL")


settings = AppSettings()           # loads .env, then calls load()
AppSettings() is settings          # True — same instance from here on

Reading the environment exactly once is deliberate: configuration that can change under a running process is configuration you cannot reason about. Use settings.reload({...}) when you do want to replace it, typically in tests.

get_parameters reads several at once and fails on the first one missing, naming it:

url, debug = settings.get_parameters(["DATABASE_URL", "DEBUG"])
# FractalException: Settings does not provide 'DATABSE_URL'

Exceptions

Two hierarchies, kept apart on purpose:

  • DomainException — a business rule was violated. It carries the shape an HTTP layer needs (code, status_code, payload, headers) so the domain can stay ignorant of HTTP while still saying enough to be rendered. Ships with ObjectNotFoundException (404) and AggregateRootError (405).
  • FractalException — the application was assembled wrong: a setting that was never defined, a context missing a service. Not something to hand a caller.

The split matters at the edge. An HTTP layer can map every DomainException onto a response and let anything else become a 500, which is exactly right: a broken rule is an answer, a broken wiring is a bug.

Services

from fractal_core import Service


class Mailer(Service):
    @classmethod
    def install(cls, context):
        mailer = cls()
        yield mailer
        mailer.close()          # anything after the yield runs on teardown

    def is_healthy(self) -> bool:
        return self.connection.ping()

install is a generator so an adapter can hold a resource open for the lifetime of the application. is_healthy is what the application context checks on startup.

Utilities

from fractal_core import (
    EnhancedEncoder,     # json.JSONEncoder that also handles datetime, UUID, Decimal, set, objects
    all_subclasses,      # transitive subclasses of a class
    camel_to_snake, snake_to_camel, camel_case_to_spaces,
    slugify, slug_is_valid,
    init_logging,
)

json.dumps({"at": datetime.now(), "id": uuid4()}, cls=EnhancedEncoder)

EnhancedEncoder falls back to an object's __dict__, which is broad but not universal — something without one still raises TypeError rather than encoding as nothing.

Development

make dev-install
make test
make lint
make format

Download files

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

Source Distribution

fractal_core-1.1.0.tar.gz (14.2 kB view details)

Uploaded Source

Built Distribution

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

fractal_core-1.1.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file fractal_core-1.1.0.tar.gz.

File metadata

  • Download URL: fractal_core-1.1.0.tar.gz
  • Upload date:
  • Size: 14.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.34.2

File hashes

Hashes for fractal_core-1.1.0.tar.gz
Algorithm Hash digest
SHA256 58688bcf642f846858bd64c49f869d5a40e4f705d9891af40b29104dfce59688
MD5 fb318af846db7c9999a0d3232d80313d
BLAKE2b-256 94fa763c082ec6ffbc81a098c9bf95e3d3809c93b6b68f1f88048d21636a661b

See more details on using hashes here.

File details

Details for the file fractal_core-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: fractal_core-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.34.2

File hashes

Hashes for fractal_core-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b6012a377e9af96a16673f3724b72c8525b1d626d2ffa9cb0cd307f770c894c3
MD5 b0bc8235d6d152f242929c09c0b6e817
BLAKE2b-256 d4e12ff055b0d0bb95f61948e5e90ae5c4662058968aa3cbec7cb410d60e8b29

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 files

1.0.0

2 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