Skip to main content
Glama
validators.py4.79 kB
"""Validation helpers for IDS facets and specifications. This module provides early validation functions to catch IDS 1.0 schema violations and IfcTester requirements before export time. """ from typing import List, Optional from fastmcp.exceptions import ToolError from ifctester import ids def validate_single_entity_in_applicability( spec: ids.Specification, location: str ) -> None: """ Validate that applicability section has at most one entity facet. IDS 1.0 XSD constraint: Only ONE entity facet allowed per applicability. This constraint does not apply to requirements sections. Args: spec: Specification to validate location: "applicability" or "requirements" Raises: ToolError: If trying to add second entity facet to applicability Example: >>> spec = ids.Specification(name="Test", ifcVersion=["IFC4"]) >>> validate_single_entity_in_applicability(spec, "applicability") >>> # First call succeeds >>> spec.applicability.append(ids.Entity(name="IFCWALL")) >>> validate_single_entity_in_applicability(spec, "applicability") >>> # Second call raises ToolError """ if location != "applicability": return # Constraint only applies to applicability # Count existing entity facets entity_count = sum( 1 for facet in spec.applicability if isinstance(facet, ids.Entity) ) if entity_count >= 1: raise ToolError( "IDS 1.0 XSD constraint violation: Only ONE entity facet is allowed " "per specification's applicability section.\n\n" "WORKAROUND: Create a separate specification for each entity type.\n" "Example:\n" " - Specification 1: Applicability = IFCWALL\n" " - Specification 2: Applicability = IFCDOOR\n\n" f"Current specification '{spec.name}' already has an entity facet.\n\n" "See CLAUDE.md for more details on this IDS 1.0 limitation." ) def validate_property_set_required( property_set: Optional[str], property_name: str ) -> None: """ Validate that property_set is provided for property facets. IfcTester requirement: property_set must be specified for valid XML export. While the IDS schema technically allows property_set to be optional, IfcTester's XML generation requires it for successful validation. Args: property_set: Property set name (can be None) property_name: Property name (for error message) Raises: ToolError: If property_set is None or empty Example: >>> validate_property_set_required("Pset_WallCommon", "FireRating") >>> # Succeeds >>> validate_property_set_required(None, "FireRating") >>> # Raises ToolError """ if not property_set or property_set.strip() == "": raise ToolError( f"Property facet validation error: 'property_set' parameter is required.\n\n" f"Property '{property_name}' must belong to a property set for valid IDS export.\n\n" "COMMON PROPERTY SETS:\n" " - Pset_WallCommon (for walls)\n" " - Pset_DoorCommon (for doors)\n" " - Pset_WindowCommon (for windows)\n" " - Pset_SpaceCommon (for spaces)\n" " - Pset_SlabCommon (for slabs)\n" " - Pset_BeamCommon (for beams)\n" " - Pset_ColumnCommon (for columns)\n\n" "CUSTOM PROPERTY SETS:\n" " - Pset_Common (generic custom properties)\n" " - Pset_CustomProperties (organization-specific)\n\n" "This requirement ensures valid XML export via IfcTester.\n" "See CLAUDE.md for more details on this IfcTester requirement." ) def count_facets_by_type( facets: List, facet_type: type ) -> int: """ Count facets of a specific type in a list. Utility function for validation and inspection of facets in applicability or requirements sections. Args: facets: List of facets (applicability or requirements) facet_type: IfcTester facet class (e.g., ids.Entity, ids.Property) Returns: Count of facets matching the type Example: >>> from ifctester import ids >>> facets = [ ... ids.Entity(name="IFCWALL"), ... ids.Property(baseName="FireRating", propertySet="Pset_WallCommon"), ... ids.Attribute(name="Name") ... ] >>> count_facets_by_type(facets, ids.Entity) 1 >>> count_facets_by_type(facets, ids.Property) 1 >>> count_facets_by_type(facets, ids.Classification) 0 """ return sum(1 for facet in facets if isinstance(facet, facet_type))

Latest Blog Posts

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/vinnividivicci/ifc-ids-mcp'

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