Skip to main content

Marshmallow-like schematization of a directory structure

Project description

fschema

Marshmallow-like schematization of a directory structure

Quickstart Example

Let's say you have the following directory/file structure:

config/
  + plugins/
  |   + java/
  |   |   + plugin.yaml
  |   + python/
  |   |   + plugin.yaml
  + profiles/
  |   + new.yaml
  |   + old.yaml
  + env
  + config.yaml

You can describe it as a Python model and load everything into a single structure. Schemas describe the structure, fields describe how each node is loaded, and filesystem access goes through an FSInterface. FSLoader uses LocalFSInterface by default, but custom filesystem-like backends can be provided with FSLoader(schema=..., fs=...).

from fschema.fields import meta, node
from fschema.schema import Schema
from fschema.fs_loader import FSLoader

class PluginConfigSchema(Schema):
    name = meta.NodeName()
    config = node.File(fs_name="plugin.yaml")

class ProfileConfigSchema(Schema):
    name = meta.NodeName()
    config = meta.Content()

class ServiceConfigSchema(Schema):
    config = node.File(fs_name="config.yaml")
    env = node.File(fs_name="env")
    plugins = node.ListDirectory(node.SchematizedDirectory(PluginConfigSchema()))
    profiles = node.ListDirectory(node.SchematizedFile(ProfileConfigSchema()))

data = FSLoader(schema=ServiceConfigSchema()).load("/path/to/config")
print(data)

This will load the following data:

{
  "config": "<file-content>",
  "env": "<file-content>",
  "plugins": [
    {"name": "java", "config":  "<file-content>"},
    {"name": "python", "config":  "<file-content>"}
  ],
  "profiles": [
    {"name": "new.yaml", "config":  "<file-content>"},
    {"name": "old.yaml", "config":  "<file-content>"}
  ]
}

If you want to add post-processing of the data to your schema (e.g. validate it or convert it to an object), you can define a __fschema_post_load__ method:

class ServiceConfigSchema(Schema):
    ...
    def __fschema_post_load__(self, data: dict) -> ServiceConfiguration:
        return ServiceConfiguration(**data)

Reference

Fields

Meta Fields

Meta fields are the fields that use the metadata of the respective filesystem node (directory/file) and provide access to its various properties. All meta fields inherit from MetaField.

Meta field types:

  • NodeName() - special type of field that loads the name of the current node (directory or file)
  • Content(reader: Reader, data_transformer: DataTransformer) - for use inside a sub-schema of a SchematizedFile; reader parses content provided by FSLoader to JSON-like data; data_transformer loads it into an object and/or validates the data

Node Fields

Node fields correspond to actual filesystem nodes (directories/fields). All node fields inherit from NodeField.

All node fields have the optional argument fs_name - this is the name of the filesystem node the field corresponds to - useful if the filename has a period (.) in it, and, therefore cannot be used as the field's attribute name.

Exposed properties:

  • effective_fs_name - the resolved filesystem name: the explicit fs_name when provided, otherwise the schema attribute name.

Node field types:

  • SchematizedDirectory(directory_schema: Schema, fs_name: str | None) - load directory as a key-value mapping and apply the given sub-schema to the directory itself; this means nested files and directories must have fixed names
  • DictDirectory(nested_field: Field, fs_name: str | None) - load directory as a free mapping, without fixed key values; the given field instance is applied to all nested nodes
  • ListDirectory(nested_field: Field, fs_name: str | None) - load directory as a list of nodes; the given field instance is applied to all nested nodes
  • File(fs_name: str | None, reader: Reader, data_transformer: DataTransformer) - load file content; reader parses content provided by FSLoader to JSON-like data; data_transformer loads it into an object and/or validates the data
  • SchematizedFile(file_schema: Schema, fs_name: str | None) - load the file as a schematized mapping instead of a single flat object; this is useful if you need access to its metadata (e.g. via NodeName);

Content Readers

Available content readers:

  • JSONReader - parses content as JSON (as a dict)
  • YamlReader - parses content as YAML (as a dict)
  • TextReader - returns content as text (str); this is the default reader

Filesystem Interface

Filesystem access is abstracted behind FSInterface, available from fschema.fs. The default LocalFSInterface, also available from fschema.fs, supports local paths via pathlib. Custom backends can implement:

  • node_name(path: Path) -> str
  • child_path(path: Path, fs_name: str) -> Path
  • list_directory(path: Path) -> list[Path]
  • require_file(path: Path) -> None
  • require_directory(path: Path) -> None
  • read_file(path: Path, encoding="utf-8") -> str

Data Transformers

Available data transformers:

  • MarshmallowLoader(schema: Any) - loads the file data via a marshmallow schema

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

fschema-0.1.1.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

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

fschema-0.1.1-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file fschema-0.1.1.tar.gz.

File metadata

  • Download URL: fschema-0.1.1.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for fschema-0.1.1.tar.gz
Algorithm Hash digest
SHA256 542d36e36e86d5503deb78f1bcc0cc5b0054bb5080a724b267b840d905a9223d
MD5 c23e457cad7844db3337fdc19ca47669
BLAKE2b-256 df9fa9c149c989e31c9bea0a5e3a9121c5592389db064c663e4ebda7a13b8d91

See more details on using hashes here.

File details

Details for the file fschema-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: fschema-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for fschema-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8ee62057f27c1d2c9a084ee67c441874d23138ca94bbf362cafea05c4078825e
MD5 d83bb0099f6a437f1e0530db988ed266
BLAKE2b-256 0860bb7b77234578154486de5c4ea9efdfda2785a558c3e3cb4a76799e479943

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