async def read_source(
    *,
    db: AsyncSession = Depends(deps.get_db),
    short_name: str,
    user: schemas.User = Depends(deps.get_user),
) -> schemas.Source:
    """Get source by id.

    Args:
    ----
        db (AsyncSession): The database session.
        short_name (str): The short name of the source.
        user (schemas.User): The current user.

    Returns:
    -------
        schemas.Source: The source object.

    Raises:
        HTTPException:
            - 404 if source not found
            - 400 if source missing required configuration classes
            - 500 if there's an error retrieving auth configuration
    """
    try:
        source = await crud.source.get_by_short_name(db, short_name)
        if not source:
            raise HTTPException(status_code=404, detail=f"Source not found: {short_name}")

        # Validate auth_config_class
        if not source.auth_config_class:
            raise HTTPException(
                status_code=400,
                detail=f"Source {short_name} does not have authentication configuration",
            )

        # Validate config_class
        if not source.config_class:
            raise HTTPException(
                status_code=400,
                detail=f"Source {short_name} does not have a configuration class",
            )

        # Get auth fields
        try:
            auth_config_class = resource_locator.get_auth_config(source.auth_config_class)
            auth_fields = Fields.from_config_class(auth_config_class)
        except Exception as e:
            logger.error(f"Failed to get auth config for {short_name}: {str(e)}")
            raise HTTPException(
                status_code=500, detail=f"Invalid auth configuration for source {short_name}"
            ) from e

        # Get config fields
        try:
            config_class = resource_locator.get_config(source.config_class)
            config_fields = Fields.from_config_class(config_class)
        except Exception as e:
            logger.error(f"Failed to get config for {short_name}: {str(e)}")
            raise HTTPException(
                status_code=500, detail=f"Invalid configuration for source {short_name}"
            ) from e

        # Create a dictionary with all required fields including auth_fields and config_fields
        source_dict = {
            **{key: getattr(source, key) for key in source.__dict__ if not key.startswith("_")},
            "auth_fields": auth_fields,
            "config_fields": config_fields,
        }

        # Validate in one step with all fields present
        source_model = schemas.Source.model_validate(source_dict)
        return source_model

    except HTTPException:
        # Re-raise HTTP exceptions as is
        raise
    except Exception as e:
        logger.exception(f"Error retrieving source {short_name}: {str(e)}")
        raise HTTPException(
            status_code=500, detail=f"Failed to retrieve source details for {short_name}"
        ) from e
Get source by id.

    Args:
    ----
        db (AsyncSession): The database session.
        short_name (str): The short name of the source.
        user (schemas.User): The current user.

    Returns:
    -------
        schemas.Source: The source object.

    Raises:
        HTTPException:
            - 404 if source not found
            - 400 if source missing required configuration classes
            - 500 if there's an error retrieving auth configuration
    
backend/airweave/api/v1/endpoints/sources.py