Skip to main content

sysnet-pyutils

SYSNET Python Utilities Library

Knihovna obsahuje základní, v aplikacích hojně používané, utility pro Python projekty.

Python License Verze Tests Coverage


📋 Obsah


🚀 Instalace

Základní instalace

pip install sysnet-pyutils

S volitelnými závislostmi

# Podpora AWS SES
pip install sysnet-pyutils[aws]

# Podpora MongoDB
pip install sysnet-pyutils[mongodb]

# Podpora cron validace
pip install sysnet-pyutils[cron]

# Vše najednou
pip install sysnet-pyutils[all]

Instalace z repository

git clone https://github.com/SYSNET-CZ/pyutils.git
cd pyutils
pip install -e .

Požadavky

  • Python 3.10+
  • Hlavní závislosti (automaticky nainstalovány):
    • pydantic[email]>=2.10.6
    • pytz>=2023.3
    • python-dateutil>=2.8.2
    • PyYAML>=6.0.1
    • xmltodict>=1.0.0
    • typing-extensions>=4.12.0

⚡ Rychlý start

import sysnet_pyutils as pu

# Generování identifikátorů
pid = pu.pid_next()
uuid = pu.uuid_next()

# Validace
is_valid = pu.is_valid_email("test@example.com")
is_valid_ico = pu.is_valid_ico("27074358")

# Datum a čas
today = pu.today()
now = pu.local_now()

# Hash
sha256 = pu.hash_sha256("text")

# Konfigurace
config = pu.Config(config_path='config.yml', config_dict={'key': 'value'})

📦 Moduly

utils.py — Hlavní modul

Obsahuje nejčastěji používané utility funkce, třídy a vzory.

Singleton pattern

from sysnet_pyutils import Singleton

class MyClass(metaclass=Singleton):
    def __init__(self):
        self.value = 42

instance1 = MyClass()
instance2 = MyClass()
assert instance1 is instance2  # Vždy stejná instance

Konfigurace

from sysnet_pyutils import Config

config = Config(
    config_path='app_config.yml',
    config_dict={'database': 'mongodb://localhost'}
)

if config.loaded:
    db_url = config.config['database']

Chování Config:

  • Soubor: ukládá se atomicky (dočasný soubor + přejmenování), čitelně (diakritika bez \u escape) a v pořadí klíčů z paměti. Nový soubor má práva 600 a chybějící adresáře se vytvoří s právy 700; práva existujícího souboru se nemění a volnější než 600 se při načtení zalogují jako varování.
  • Výchozí cesta: nezadáte-li config_path, použije se proměnná prostředí PYUTILS_CONFIG_PATH. Bez ní platí dosavadní umístění conf/config.yml vedle modulu (s varováním); není-li zapisovatelné, vyhodí se ConfigError s radou.
  • Chyby: poškozený YAML vyhodí ConfigParseError (podtřída ConfigError i yaml.YAMLError) s cestou, popisem a řádkem, nikdy s obsahem souboru; soubor zůstane nepřepsaný.
  • Nové výchozí hodnoty: s existujícím souborem se config_dict ignoruje. Chcete-li po upgradu aplikace doplnit chybějící klíče, použijte Config(config_path=..., config_dict=..., merge_defaults=True): doplní se jen to, co v souboru chybí (vnořené slovníky do hloubky, seznamy ne) a hodnoty ze souboru se nikdy nepřepíšou.
  • Secrets: hodnotu v YAML lze zadat odkazem ${env:NAZEV} nebo ${file:/absolutni/cesta} (i uvnitř textu, např. mongodb://u:${env:MONGO_PASSWORD}@h); rozliší se při načtení na Secret (podtřída str, repr a log maskované, reveal() vrací čistý str). Chybějící zdroj je ConfigError, nikdy tichý prázdný řetězec. store() zapisuje zpět odkaz, nikdy hodnotu. config.redacted() vrací kopii pro health a debug, config.audit() cesty k heslům v otevřené podobě. Doslovné ${ zapište jako $${. Viz docs/adr/0001-config-secrets.md.
  • Vstup: config_dict se při inicializaci zkopíruje; pozdější změny config neovlivní slovník volajícího a naopak.
  • Opakované volání: Config(...) vrací stále tutéž instanci; odlišná cesta nebo config_dict se ignoruje a zaloguje se varování.

Context a autentizace

from sysnet_pyutils import Context, api_keys_init

# Generování API klíčů
keys = api_keys_init(agenda='my_app', amount=3)

config = {'my_app': {'api_keys': keys}}

ctx = Context(config=config)
if ctx.check_api_key('some_key'):
    print(f"Přihlášen jako: {ctx.user_name}")

Context je singleton se sdíleným stavem. check_api_key() ukládá identitu do jediné instance, kterou sdílejí všechny souběžné požadavky. Ve webové službě (FastAPI) může jeden požadavek po await vidět identitu jiného. Pokus se dvěma souběžnými požadavky to potvrdil: Context vrátil první osobě jméno druhé. Ověřování API klíčů patří knihovně sysnet-apikeys (standard CML api-keys.md); check_api_key() a Ověřování API klíčů patří knihovně sysnet-apikeys (standard CML api-keys.md); check_api_key(), check_user() a api_keys_init() jsou zastaralé (DeprecationWarning) a zůstávají jen kvůli stávajícím službám. Tajemství (config, api_key, cert_pass) se čtou jako dřív, ale nejsou ve vars(), v repr ani v pickle/copy; pro diagnostiku slouží ctx.safe_dict().

Per-request kontext (RequestContext)

RequestContext jen nese identitu ověřenou jinde, v ContextVar, takže ji každý požadavek vidí jen svou. Ověřuje sysnet-apikeys; služba převede jeho Principal na kontext:

from fastapi import Depends
from sysnet_apikeys.fastapi import ApiKeyAuth
from sysnet_pyutils import RequestContext, current_request_context, set_request_context

auth = ApiKeyAuth(service)  # sysnet-apikeys


async def authenticated(principal=Depends(auth)) -> RequestContext:
    ctx = RequestContext(user_name=principal.client, agenda=principal.agenda)
    set_request_context(ctx)
    return ctx


# kdekoli později ve stejném požadavku:
agenda = current_request_context().agenda
  • RequestContext je neměnný (frozen); api_key a cert_pass jsou typu Secret (repr a log skrývají hodnotu).
  • authenticated je True, nese-li kontext identitu (user_name nebo api_key); samotná agenda ji nedělá.
  • Kontext nastavujte v async def závislosti. ContextVar nastavený v synchronní závislosti (def, běží ve vlákně) se do endpointu nepřenese; ověřeno pokusem s FastAPI 0.150. Případně použijte hodnotu vrácenou z Depends.
  • Pro dočasné nastavení v bloku: with use_request_context(ctx): ... (vždy vrátí předchozí hodnotu).

Identifikátory a validace

from sysnet_pyutils import pid_next, pid_check, pid_correct
from sysnet_pyutils import is_valid_uuid, is_valid_ico, is_valid_email, repair_ico

# PID — 12místný identifikátor s kontrolním součtem
pid = pid_next()
is_valid = pid_check(pid)
corrected = pid_correct("SNT12345678X")

# Validace
is_valid_ico("27074358")           # True
is_valid_email("user@example.com") # True
repair_ico("2707435X")             # Opraví kontrolní součet

Hash funkce

from sysnet_pyutils import hash_md5, hash_sha1, hash_sha256, hash_sha384

sha256 = hash_sha256("Hello World")

Datum a čas

from sysnet_pyutils import local_now, gmt_now, today, tomorrow
from sysnet_pyutils import date_to_datetime, date_to_datetime_utc, date_to_iso
from datetime import date

dt = date_to_datetime(date(2023, 5, 15))      # datetime v lokální TZ
dt_utc = date_to_datetime_utc(date(2023, 5, 15))  # datetime v UTC
iso = date_to_iso(date(2023, 5, 15))          # "2023-05-15"

Base64

from sysnet_pyutils import encode_string_b64, decode_b64_string
from sysnet_pyutils import encode_file_b64, decode_b64_to_file

encoded = encode_string_b64("Hello")
decoded = decode_b64_string(encoded)

Konverze case a XML

from sysnet_pyutils import to_snake, to_camel, to_snake_dict, to_camel_dict
from sysnet_pyutils import xml_to_dict, dict_to_xml

snake = to_snake("camelCase")        # "camel_case"
camel = to_camel("snake_case")       # "snakeCase"
data = xml_to_dict("<root><n>X</n></root>")

CITES utility

from sysnet_pyutils import order_to_cites, cites_to_order

letters = order_to_cites(1458)  # "BDB"
number = cites_to_order("BDB")  # 1458

data_utils.py

Utility pro práci se slovníky, konverzi typů a stránkování MongoDB.

from sysnet_pyutils import (
    get_dict_value_string, get_dict_value_int, get_dict_value_float,
    get_dict_value_bool, get_dict_value_date, get_dict_value_datetime,
    get_dict_value_email, get_dict_value_code, get_dict_value_uuid,
    convert_iso_to_date, convert_cz_to_date,
    paging_to_mongo, address_to_string,
    normalize_datetime, localize_datetime,
)

data = {'name': 'John', 'age': '30', 'email': 'john@example.com'}

name = get_dict_value_string(data, 'name')   # "John"
age = get_dict_value_int(data, 'age')         # 30
email = get_dict_value_email(data, 'email')   # "john@example.com"

# Konverze datumů
d = convert_iso_to_date('2023-05-15')
d_cz = convert_cz_to_date('15.05.2023')

# Stránkování pro MongoDB
paging = paging_to_mongo(start=20, page_size=10)
# {'start': 0, 'page': 2, 'skip': 20, 'limit': 10}

# Adresa na string
address = {'street': 'Main St 123', 'city': 'Prague', 'zip': '110 00'}
addr_str = address_to_string(address)

# Normalizace datetime na UTC
# Naivní datetime dostane zónu dle env TZ (výchozí: Europe/Prague), pak se převede na UTC.
# Čistý date → půlnoc v lokální zóně → UTC.
from datetime import date, datetime
utc_dt = normalize_datetime(datetime(2024, 7, 1, 12, 0, 0))   # naive → Prague → UTC
utc_dt = normalize_datetime(date(2024, 7, 1))                  # půlnoc Prague → UTC
utc_dt = normalize_datetime(None)                              # None → None

# Lokalizace datetime do lokální zóny (env TZ)
# Naivní datetime se považuje za UTC a převede do lokální zóny.
# Čistý date → půlnoc UTC → lokální zóna.
local_dt = localize_datetime(datetime(2024, 7, 1, 10, 0, 0))  # naive UTC → Prague
local_dt = localize_datetime(date(2024, 7, 1))                 # půlnoc UTC → Prague
local_dt = localize_datetime(None)                             # None → None

domino.py

Práce s HCL Domino Data Service (DDS).

from sysnet_pyutils import DdsDictionaryFactory

dds_data = {
    'Title': 'Test Document',
    'DateCreated': '2023-05-15T10:00:00',
    'IsActive': '1',
    'Amount': '99.99'
}

factory = DdsDictionaryFactory(dds_data)

title = factory.get_value_string('Title')
is_active = factory.get_value_bool('IsActive')
amount = factory.get_value_float('Amount')
date_created = factory.get_value_datetime('DateCreated')

factory.set_value_string('Status', 'Approved')
factory.set_value_bool('Published', True)

geo.py

Geografické transformace — konverze mezi WGS84 a S-JTSK.

from sysnet_pyutils import Wgs84, JTSK

wgs = Wgs84(latitude=50.0755, longitude=14.4378, altitude=200.0)

jtsk = JTSK(0, 0)
jtsk.from_wgs84(lon=wgs.longitude, lat=wgs.latitude, alt=wgs.altitude)

print(f"JTSK X: {jtsk.x:.2f}, Y: {jtsk.y:.2f}")

cron_utils

Validace cron výrazů (syntaktická i sémantická).

Vyžaduje volitelnou závislost: pip install sysnet-pyutils[cron]

from sysnet_pyutils.cron_utils.validation import (
    is_cron_syntax_valid,
    has_next_occurrence,
    validate_cron,
    summarize_cron,
)

# Syntaktická validace
is_cron_syntax_valid("0 9 * * 1-5")   # True
is_cron_syntax_valid("60 * * * *")    # False — minuta mimo rozsah

# Sémantická validace
has_next_occurrence("0 0 31 2 *")     # False — 31.2. nikdy nenastane

# Kompletní validace
is_valid, errors = validate_cron("0 9 * * 1-5")

# Sumarizace s dalším výskytem
summary = summarize_cron("0 9 * * 1-5")
if summary.syntax_ok and summary.has_occurrence:
    print(f"Další spuštění: {summary.next_run}")

globalmodel

Pydantic BaseModel s automatickou normalizací datetime do UTC.

from sysnet_pyutils import GlobalModel, PRAGUE_TZ
from datetime import datetime

class MyModel(GlobalModel):
    created_at: datetime | None = None

# Naivní datetime je považován za Europe/Prague a převeden na UTC
m = MyModel(created_at=datetime(2023, 5, 15, 10, 0, 0))
print(m.created_at)  # 2023-05-15 08:00:00+00:00 (UTC)

log.py

MongoDB logging handler.

Vyžaduje volitelnou závislost: pip install sysnet-pyutils[mongodb]

import logging
from sysnet_pyutils.log import MongoHandler

logger = logging.getLogger("myapp")
logger.addHandler(MongoHandler(
    host="localhost",
    port=27017,
    database="logging",
    collection="app_logs",
))

logger.error("Nastala chyba!")

ses.py

Odesílání e-mailů přes Amazon SES.

Vyžaduje volitelnou závislost: pip install sysnet-pyutils[aws]

from sysnet_pyutils.ses import SesFactory

ses = SesFactory(
    aws_region='eu-west-1',
    aws_access_key='KEY',
    aws_secret_access_key='SECRET',
    sender='noreply@example.com',
)

ses.send_email(
    recipient='user@example.com',
    subject='Test',
    body_text='Tělo zprávy v plain textu.',
    body_html='<p>Tělo zprávy v HTML.</p>',
)

syslog

Asynchronní odesílání zpráv na syslog server (UDP/TCP).

import asyncio
from sysnet_pyutils import SyslogFactory

syslog = SyslogFactory(server="192.168.1.10", port=514, tag="my-app")

async def main():
    await syslog.log_info("Aplikace spuštěna")
    await syslog.log_error("Nastala chyba")

asyncio.run(main())

models.general

Datové modely kompatibilní s FastAPI a Pydantic v2.

from sysnet_pyutils import (
    PersonBaseType, LocationType, GeoPointType,
    CodeValueType, MetadataType, PersonTypeEnum,
    LogItemType, WorkflowType,
)

# Osoba
person = PersonBaseType(
    name="Test Company s.r.o.",
    ico="27074358",
    email="info@test.com",
    location=LocationType(
        street="Main Street 123",
        city="Prague",
        zip="110 00",
        wgs=GeoPointType(lat=50.0755, lon=14.4378),
        country=CodeValueType(code="CZ", value="Czech Republic"),
    ),
)
person.unid = "3005277CB984B7FFC12587890060E2BF"
person.make_identifier()

# Metadata — default_factory zajistí aktuální čas při každém vytvoření
metadata = MetadataType(title="Important Document", form="certificate")
print(metadata.date_created)  # Aktuální čas

# Log položka
log_item = LogItemType(message="Dokument autorizován", originator="SYSTEM")
print(str(log_item))  # "2023-05-15 10:00:00 [SYSTEM] Dokument autorizován"

Info/Health modely

Sjednocený formát pro sledování zdraví služby (health check).

from sysnet_pyutils import InfoType, InfoComponentType, InfoStatusEnum, calculate_status

info = InfoType(name="My Service", version="1.0.0")

# Přidání komponenty (např. MongoDB)
info.components.append(InfoComponentType(
    name="mongo",
    status=InfoStatusEnum.GREEN,
    message="Connected to localhost:27017"
))

# Přidání další komponenty s chybou
info.components.append(InfoComponentType(
    name="storage",
    status=InfoStatusEnum.RED,
    message="Disk space low"
))

# Automatický výpočet celkového statusu (RED > YELLOW > GREEN)
info.status = calculate_status([component.status for component in info.components])
print(info.status)  # RED

🔌 Volitelné závislosti

Extra Balíčky Použití
[aws] boto3, botocore Modul ses.py — AWS SES
[mongodb] pymongo Modul log.py — MongoDB handler
[cron] croniter Modul cron_utils — validace cron výrazů
[all] vše výše Všechny volitelné funkce

Poznámka: Moduly ses.py a log.py lze importovat i bez příslušných závislostí. ImportError se vyhodí až při pokusu o instanciaci SesFactory / MongoHandler.


🧪 Testování

Knihovna obsahuje komplexní sadu testů s >90% pokrytím kódu.

Spuštění testů

# Z kořenového adresáře projektu
cd ~/projects/pyutils

# Všechny testy
.venv/bin/python -m pytest tests/

# S podrobným výstupem
.venv/bin/python -m pytest tests/ -v

# S pokrytím kódu
.venv/bin/python -m pytest tests/ --cov=sysnet_pyutils --cov-report=html

# Konkrétní modul
.venv/bin/python -m pytest tests/test_utils.py -v

Testovací soubory

Soubor Testovaný modul
test_utils.py utils.py
test_data_utils.py data_utils.py
test_domino.py domino.py
test_geo.py geo.py
test_cron_utils.py cron_utils/
test_ident_barcode.py ident.py, barcode.py
test_models_general.py models/general.py
test_global_model_recursive.py globalmodel/
test_global_model_timezone.py globalmodel/

👨‍💻 Vývoj

Struktura projektu

pyutils/
├── .github/workflows/       # GitHub Actions CI/CD
│   ├── ci.yml               # Syntax check, pytest, ruff
│   └── release.yml          # Ověření verze, testy, build a publikace na PyPI
├── sysnet_pyutils/          # Hlavní balíček
│   ├── __init__.py          # Veřejné API
│   ├── utils.py             # Hlavní utility modul
│   ├── data_utils.py        # Utility pro slovníky a typy
│   ├── domino.py            # HCL Domino DDS
│   ├── geo.py               # Geografické transformace (WGS84 ↔ JTSK)
│   ├── ident.py             # Identifikátory (PID, ID12)
│   ├── barcode.py           # Code39 čárové kódy
│   ├── constants.py         # Konfigurační konstanty
│   ├── log.py               # MongoDB logging handler
│   ├── ses.py               # AWS SES e-mail
│   ├── tools.py             # Singleton dekorátor
│   ├── cron_utils/          # Validace cron výrazů
│   │   └── validation.py
│   ├── globalmodel/         # GlobalModel s UTC normalizací
│   │   ├── global_model.py
│   │   ├── timeutils.py
│   │   └── models.py
│   ├── models/              # Pydantic datové modely
│   │   └── general.py
│   └── syslog/              # Syslog UDP/TCP klient
│       └── factory.py
├── tests/                   # Pytest testy
│   ├── conftest.py
│   └── test_*.py
├── conf/                    # Výchozí konfigurace
├── logs/                    # Adresář pro logy
├── pyproject.toml           # Build a nástroje
├── requirements.txt         # Závislosti (legacy)
├── CHANGELOG.md             # Přehled změn a vydání
└── LICENSE

Přidání nové funkcionality

  1. Implementujte funkci v příslušném modulu
  2. Exportujte ji v sysnet_pyutils/__init__.py
  3. Napište testy v tests/test_<modul>.py
  4. Spusťte testy: .venv/bin/python -m pytest tests/
  5. Aktualizujte README.md a CHANGELOG.md

CI/CD

Automatizaci zajišťují GitHub Actions na self-hosted runneru s Pythonem 3.11:

Workflow Spuštění Kroky
.github/workflows/ci.yml Každý push na main a pull request do main Kontrola syntaxe (compileall), testy (pytest) a lint (ruff)
.github/workflows/release.yml Push tagu v* Ověření verze, kontrola syntaxe a testy, build balíčku a publikace na PyPI

Obě workflow používají čistý checkout, před instalací mažou pip cache a pro testy instalují .[dev,cron,mongodb], včetně potřebných volitelných závislostí. Ruff je v CI zatím informativní (ruff check sysnet_pyutils/ || true); chyby syntaxe a testů naopak workflow zastaví.

Release workflow porovnává tag bez prefixu v s verzí v pyproject.toml. Při nesouladu nebo selhání testů se nepublikuje. Po úspěšných kontrolách vytvoří distribuční balíčky pomocí python -m build a nahraje je přes twine. GitHub secret PYPI_API_TOKEN je nastaven v repozitáři a poskytuje token pro PyPI; token nepatří do zdrojového kódu.

Vydání nové verze

  1. Změňte version v pyproject.toml (například na 1.8.0) a aktualizujte dokumentaci včetně changelogu a badge.

  2. Commitněte změny a dostaňte je na main; před vytvořením tagu ověřte úspěšné CI a správný release commit.

  3. Na tomto commitu vytvořte a odešlete odpovídající tag:

    git tag v1.8.0 && git push origin v1.8.0
    
  4. GitHub Actions automaticky provedou kontroly, build a publikaci. Výsledek sledujte v Release workflow.

Původní ruční postup (python -m build a twine upload, dříve i Windows skripty upload.ps1 a upload.cmd, odstraněné ve verzi 1.7.12) je nahrazen touto pipeline; při běžném vydání již lokálně nic nenahrávejte na PyPI.


🛠 Systémové proměnné

Proměnná Popis Výchozí hodnota
TZ Časová zóna 'Europe/Prague'
DEBUG Debug režim 'True'
LOG_FORMAT Formát logování '%(asctime)s - %(levelname)s in %(module)s: %(message)s'
LOG_DATE_FORMAT Formát data v logu '%d.%m.%Y %H:%M:%S'
LOG_FILE Soubor pro logování None
PID_PREFIX Prefix pro PID 'SNT'

📚 Changelog

Podrobnosti nových změn jsou v CHANGELOG.md.

Verze 1.9.0 (2026-10-28)

  • 🧭 RequestContext: nosič identity jednoho požadavku v ContextVar (set_request_context, current_request_context, use_request_context); souběžné požadavky se nevidí. Ověřování API klíčů záměrně neobsahuje, patří knihovně sysnet-apikeys.
  • ⚠️ Context.check_api_key(), Context.check_user() a api_keys_init() jsou zastaralé (DeprecationWarning jednou za proces); chování pro platné konfigurace se nemění.
  • 🛡️ Context: vadná konfigurace nebo klíč jiného typu než neprázdný řetězec vrací False místo výjimky.
  • 🔐 Context: tajemství (config, api_key, cert_pass) nejsou ve vars(), v repr ani v pickle/copy; čtení atributů beze změny, nová metoda safe_dict().

Podrobnosti a dopady na stávající aplikace jsou v CHANGELOG.md.

Verze 1.8.0 (2026-10-27)

  • 🔐 Config: ochrana secrets. Hodnotu v YAML lze zadat odkazem ${env:NAZEV} nebo ${file:/absolutni/cesta}; rozlišuje se při načtení na nový typ Secret (maskovaný repr, str a log), store() zapisuje zpět odkaz, nikdy hodnotu. Nově Config.redacted() a Config.audit(). Viz docs/adr/0001-config-secrets.md.
  • 💾 Config.store() a replace() zapisují atomicky (dočasný soubor + přejmenování); nový soubor má práva 600, chybějící adresáře se vytvoří s právy 700.
  • ⚠️ Config bez config_dict má config == {} místo None a nezapisuje null; config_dict se při inicializaci kopíruje; YAML se ukládá čitelně (diakritika) a v pořadí klíčů z paměti. První store() po upgradu přepíše soubor v novém formátu.
  • ✅ ConfigParseError pro poškozený YAML (i yaml.YAMLError), výchozí cesta z PYUTILS_CONFIG_PATH, opt-in merge_defaults=True, varování při ignorovaných parametrech opakovaného Config(...).

Podrobnosti a dopady na stávající aplikace jsou v CHANGELOG.md.

Verze 1.7.12 (2026-10-27)

  • ✅ GitHub Actions CI/CD: kontrola syntaxe, pytest a ruff při push/PR na main; ověření verze, testy, build a publikace na PyPI při tagu v*.

  • ✅ Opraveny starší chyby v tests/test_models_general.py: InfoComponentType(code=...) → name=..., neexistující update_status() → funkce calculate_status().

  • ✅ Doplněny veřejné exporty InfoComponentType, InfoStatusEnum, InfoType a calculate_status v sysnet_pyutils/__init__.py.

  • ✅ Ukázka Info/Health výše odpovídá aktuálnímu API (name, message, calculate_status).

  • 🧹 Odstraněny sledované pomocné soubory (mypy_*.txt, upload.cmd, upload.ps1, run_pytest.py, REVIZE_PROJEKTU.md); Windows cesty v README a CLAUDE.md nahrazeny linuxovými.

Verze 1.7.11 (2026-09-25)

  • ✅ MetadataEssentialType.creator: str | None — sjednocení s MetadataTypeBase, výchozí hodnota None (#10229).

Verze 1.7.10 (2026-09-25)

  • ✅ MetadataEssentialType.creator_organization: LinkedType | None — organizace tvůrce i v základních metadatech, výchozí hodnota None (#10229).

Verze 1.7.9 (2026-09-25)

  • ✅ MetadataTypeBase.creator_organization: LinkedType | None — organizace tvůrce dokumentu, výchozí hodnota None (#10229).

Verze 1.7.6 (2026-06-19)

Nové funkce:

  • ✅ models/general.py — přidán InfoType, InfoComponentType a InfoStatusEnum pro sjednocené health checky napříč mikroslužbami (#9991)
  • ✅ tests/test_models_general.py — doplněny testy pro výpočet statusu v InfoType

Verze 1.7.5 (2026-04-07)

Nové funkce:

  • ✅ data_utils.py — přidána normalize_datetime(date | datetime | None) -> datetime | None: naivní vstup dostane zónu dle TZ, výstup vždy UTC
  • ✅ data_utils.py — přidána localize_datetime(date | datetime | None) -> datetime | None: naivní vstup se považuje za UTC, výstup v lokální zóně dle TZ
  • ✅ Obě funkce exportovány z sysnet_pyutils/__init__.py
  • ✅ 22 nových testů v tests/test_data_utils_datetime.py (včetně DST hraničních případů a roundtrip testů)

Verze 1.7.1 (2026-03-02)

Opravy:

  • ✅ constants.py — doplněna chybějící konstanta CONFIG_PASSWORD
  • ✅ ses.py — import boto3 přesunut do lazy guardu (try/except ImportError)
  • ✅ log.py — import pymongo přesunut do lazy guardu (try/except ImportError)
  • ✅ data_utils.py — opraven zahozený výsledek datetime.replace() v adjust_datetime_to_utc()
  • ✅ models/general.py — Field(default=local_now()) nahrazeno Field(default_factory=local_now) na 4 místech
  • ✅ utils.py — email regex rozšířen na subdomény a TLD libovolné délky
  • ✅ tests/conftest.py — bare except: nahrazeno except Exception:
  • ✅ pyproject.toml — ruff konfigurace aktualizována na [tool.ruff.lint]
  • ✅ sysnet_pyutils/__init__.py — doplněno kompletní veřejné API balíčku
  • ✅ sysnet_pyutils/syslog/__init__.py — doplněn export SyslogFactory
  • ✅ Odstraněno 21 dočasných/analytických souborů z kořenového adresáře

Verze 1.6.1

  • ✅ Kompletní testovací pokrytí (251 testů, >90% coverage)
  • ✅ Modernizace pyproject.toml
  • ✅ Opravy singleton konfliktů v testech

Verze 1.6.0

  • Přidán balíček cron_utils pro validaci cron výrazů

Verze 1.5.0

  • Nový SyslogFactory pro asynchronní odesílání logů

Verze 1.4.9

  • Atribut authorized přesunut do MetadataTypeBase

Verze 1.4.8

  • Přidána funkce get_dict_value_as_person_type()

Verze 1.4.4

  • Přidána funkce address_to_string()

Verze 1.4.0

  • Do PersonBaseType přidána strukturovaná adresa location

Verze 1.3.10

  • Do MetadataTypeBase přidán atribut comment

Verze 1.3.5

  • Do PersonBaseType přidán atribut person_printable

Verze 1.3.1

  • Přidán modul constants.py

Verze 1.3.0

  • Přidána třída Context pro ověřování API klíčů

Verze 1.2.0

  • UUID → str v modelech (pro MongoDB)
  • Přidán BaseEnum s metodou has_value

Verze 1.1.0

  • Přidán datový slovník models.general (Pydantic)

Verze 1.0.8

  • Nové utility data_utils

Verze 1.0.5

  • Přidána třída DdsDictionaryFactory
  • Funkce local_now(), is_valid_unid()

Verze 1.0.4

  • CITES utility: order_to_cites(), cites_to_order()

Verze 1.0.3

  • Case konverze: to_camel(), to_snake()
  • XML utility: xml_to_dict(), dict_to_xml()

📞 Podpora

Našli jste bug?

  1. Zkontrolujte existující issues
  2. Vytvořte nový issue s:
    • Popisem problému
    • Kroky k reprodukci
    • Očekávané a skutečné chování
    • Verze Python a sysnet-pyutils

Chcete přispět?

  1. Forkněte repository
  2. Vytvořte feature branch
  3. Přidejte testy pro novou funkcionalitu
  4. Ověřte, že všechny testy procházejí
  5. Vytvořte pull request

📄 Licence

Tento projekt je licencován pod MIT licencí — viz LICENSE soubor.


Vytvořeno s ❤️ týmem SYSNET

Verze: 1.9.0

Datum: 2026-10-27

Metadata

Release files for sysnet-pyutils 1.9.0

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

Source distribution (sdist)

Source distribution for sysnet-pyutils 1.9.0
File Size Uploaded Provenance Actions
sysnet_pyutils-1.9.0.tar.gz 155.7 kB Without provenance Details for sysnet_pyutils-1.9.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sysnet-pyutils 1.9.0
File Interpreter ABI Platform Actions
sysnet_pyutils-1.9.0-py3-none-any.whl Python 3 none any Details for sysnet_pyutils-1.9.0-py3-none-any.whl

Total release size: 235.1 kB

Release files / sysnet_pyutils-1.9.0.tar.gz

Download URL sysnet_pyutils-1.9.0.tar.gz
Size 155.7 kB
Tags Source
SHA-256 checksum
How to use checksums
91d969debe35155eeebb791712901246902032a9c12529ffad0f55b3ff4fe59d
BLAKE2b-256 checksum
How to use checksums
324b56ff87e6f18dfa7794a4cad3960999eacfb4156ba2380251294a69e399ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / sysnet_pyutils-1.9.0-py3-none-any.whl

Download URL sysnet_pyutils-1.9.0-py3-none-any.whl
Size 79.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14ece8f882ccfb3e1d83d048c6887b5e3e247058ab5d191b1fdf75bec319d4f2
BLAKE2b-256 checksum
How to use checksums
d6511ecb08f7ab3921ac3a573232a676469703fd40fa78d5e3b2948a08929471
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Security for sysnet-pyutils 1.9.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.9.0 This release

2 release files No provenance

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