Skip to main content
Glama

propublica-mcp

_path.py4.64 kB
import pathlib from typing import Any, Iterable, Sequence, Union from attrs import field from cyclopts.utils import frozen, to_tuple_converter def ext_converter(value: Union[None, Any, Iterable[Any]]) -> tuple[str, ...]: return tuple(e.lower().lstrip(".") for e in to_tuple_converter(value)) @frozen(kw_only=True) class Path: """Assertions on properties of :class:`pathlib.Path`. Example Usage: .. code-block:: python from cyclopts import App, Parameter, validators from pathlib import Path from typing import Annotated app = App() @app.default def main( # ``src`` must be a file that exists. src: Annotated[Path, Parameter(validator=validators.Path(exists=True, dir_okay=False))], # ``dst`` must be a path that does **not** exist. dst: Annotated[Path, Parameter(validator=validators.Path(dir_okay=False, file_okay=False))], ): "Copies src->dst." dst.write_bytes(src.read_bytes()) app() .. code-block:: console $ my-script foo.bin bar.bin # if foo.bin does not exist ╭─ Error ───────────────────────────────────────────────────────╮ │ Invalid value "foo.bin" for "SRC". "foo.bin" does not exist. │ ╰───────────────────────────────────────────────────────────────╯ $ my-script foo.bin bar.bin # if bar.bin exists ╭─ Error ───────────────────────────────────────────────────────╮ │ Invalid value "bar.bin" for "DST". "bar.bin" already exists. │ ╰───────────────────────────────────────────────────────────────╯ """ exists: bool = False """If :obj:`True`, specified path **must** exist. Defaults to :obj:`False`.""" file_okay: bool = True """ If path exists, check it's type: * If :obj:`True`, specified path may be an **existing** file. * If :obj:`False`, then **existing** files are not allowed. Defaults to :obj:`True`. """ dir_okay: bool = True """ If path exists, check it's type: * If :obj:`True`, specified path may be an **existing** directory. * If :obj:`False`, then **existing** directories are not allowed. Defaults to :obj:`True`. """ # Can only ever really be a tuple[str, ...] ext: Union[str, Sequence[str]] = field(default=None, converter=ext_converter) """ Supplied path must have this extension (case insensitive). May or may not include the ".". """ def __attrs_post_init__(self): if self.exists and not self.file_okay and not self.dir_okay: raise ValueError("(exists=True, file_okay=False, dir_okay=False) is an invalid configuration.") def __call__(self, type_: Any, path: Any): if isinstance(path, Sequence): if isinstance(path, str): raise TypeError for p in path: self(type_, p) else: if not isinstance(path, pathlib.Path): return if self.ext and path.suffix.lower().lstrip(".") not in self.ext: if len(self.ext) == 1: raise ValueError(f'"{path}" must have extension "{self.ext[0]}".') else: pretty_ext = "{" + ", ".join(f'"{x}"' for x in self.ext) + "}" raise ValueError(f'"{path}" does not match one of supported extensions {pretty_ext}.') if path.exists(): if not self.file_okay and path.is_file(): if self.dir_okay: raise ValueError(f'Only directory is allowed, but "{path}" is a file.') else: raise ValueError(f'"{path}" already exists.') if not self.dir_okay and path.is_dir(): if self.file_okay: raise ValueError(f'Only file is allowed, but "{path}" is a directory.') else: raise ValueError(f'"{path}" already exists.') elif self.exists: raise ValueError(f'"{path}" does not exist.')

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/asachs01/propublica-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server