Skip to main content

General utilities for EO4EU

Project description

Base utilities for EO4EU

This package serves as a common base of utilities used in other eo4eu-[...]-utils packages. You may find it generally useful.

General

  • The if_none function helps with the writing of optional parameters. For example:
def validate(input: str, accepted: list[str]|None = None):
    accepted = if_none(accepted, ["yes", "definitely", "absolutely"])
    if input not in accepted:
        raise ValueError(f"Input \"{input}\" not in {accepted}")

Typing

The eo4eu_base_utils.typing submodule provides some of the types found in the standard library typing module. The difference is, for versions below 3.10, this module will pull them from typing_extensions instead.

Unify

The eo4eu_base_utils.unify submodule provides functions for working with dictionaries. Namely:

  • overlay combines two dictionaries recursively, preserving nested keys if possible. In the case of conflicts, overlay will prefer the second dictionary provided. Example:
from pprint import pprint
from eo4eu_base_utils.unify import overlay

h0 = {
    "name": "bobby.png",
    "dataset": "hamster images",
    "date": None,
    "metadata": {
        "size": "3TB",
        "color": "brown",
    },
}
h1 = {
    "path": "/usr/hamsters/bobby.png",
    "date": "2025-14-01",
    "metadata": {
        "color": "brown and white, actually",
        "type": "chubby",
    },
}

pprint(overlay(h0, h1))

Output:

{'dataset': 'hamster images',
 'date': '2025-14-01',
 'metadata': {'color': 'brown and white, actually',
              'size': '3TB',
              'type': 'chubby'},
 'name': 'bobby.png',
 'path': '/usr/hamsters/bobby.png'}
  • unify is similar to overlay, but raises a eo4eu_base_utils.unify.UnifyError in the case of conflicts. This function has a more general notion of values being "compatible"; one or both of the dictionaries might have types as values, thus serving as more of a schema. An example:
from pprint import pprint
from eo4eu_base_utils.unify import overlay

schema = {
    "service": "elasticsearch",
    "auth": {
        "username": str,
        "password": str,
    },
    "port": int,
}

good_data = {
    "service": "elasticsearch",
    "mood": "good",
    "auth": {
        "username": "buddy",
        "password": "pasword",
    },
    "port": 6868,
}

also_good_data = {  # doesn't matter if keys are missing
    "auth": {
        "username": "buddy",
    },
}

bad_data = {
    "auth": {
        "username": 007,  # not a string
    },
}

pprint(unify(schema, good_data))
pprint(unify(schema, also_good_data))
pprint(unify(schema, bad_data))  # this will raise an error

unify is commutative, therefore unify(d0, d1) == unify(d1, d0).

Result

The Result type is a hacky attempt to get something like rust's Result type, and have errors as values instead of exceptions. It has several constructors:

def parse_num(num_str: str) -> Result[float]:
    try:
        return Result.ok(float(num_str))
    except Exception as e:
        return Result.err(str(e))

The above function may also be written as:

def parse_num(num_str: str) -> Result[float]:
    return Result.wrap(float, num_str)

The Result type allows you to do a few neat things. For example, instead of this pattern:

config = None
try:
    config = read_from_file(config_file)
except Exception as e:
    logger.error(f"Failed to read config: {e}")

You can do this:

config = read_from_file(config_file)  # returns Result
if config.is_err():
    logger.error(f"Failed to read config: {config.fmt_err()}")

There is also result.is_ok() which is the opposite of result.is_err(). Also, things like:

some_num = (Result.wrap(get_user_input)
                  .default("7")
                  .map_ok(lambda num_str: float(num_str))
                  .map_ok(lambda num: num if num > 0 else 0)
                  .unwrap())  # this raises an exception if the result is an error

Which would normally be written as:

def get_some_num():
    user_input = "7"
    try:
        user_input = get_user_input()
    except Exception:
        pass

    num = float(user_input)
    if num < 0:
        num = 0
    return num

Possibly a bad example, but anyway...

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

eo4eu_base_utils-0.4.3.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

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

eo4eu_base_utils-0.4.3-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file eo4eu_base_utils-0.4.3.tar.gz.

File metadata

  • Download URL: eo4eu_base_utils-0.4.3.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.11.11

File hashes

Hashes for eo4eu_base_utils-0.4.3.tar.gz
Algorithm Hash digest
SHA256 03f64f6573ce587b869d125b09ca2209d7755158056d3163092b4d58017fb08a
MD5 5dd7ffde3b04609c33fa9fe44dc55bee
BLAKE2b-256 11e21d766b7b8ecc4ddecbffae9e3834d3710ed44f3ce15875bdeb05c3184f8e

See more details on using hashes here.

File details

Details for the file eo4eu_base_utils-0.4.3-py3-none-any.whl.

File metadata

File hashes

Hashes for eo4eu_base_utils-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b9841fd7d9d8cdf26aac585e82da69982b89afa849c8b735d120f9fd3298f2cd
MD5 c309f991b60e5b3201daf4a710940d8d
BLAKE2b-256 521c1b47ccc9f6894d6e43f692c332eea424a715e5a45699d8dc11fe755708bc

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