def get_state(key, namespace=None, table_name=None, environment=None,
              layer=None, stage=None, shard_id=None, consistent=True,
              deserializer=json.loads, wait_exponential_multiplier=500,
              wait_exponential_max=5000, stop_max_delay=10000):
    """Get Lambda state value(s)."""
    if table_name is None:
        table_name = _state_table_name(environment=environment, layer=layer,
                                       stage=stage)

    if not table_name:
        msg = ("Can't produce state table name: unable to get state "
               "item '{}'".format(key))
        logger.error(msg)
        raise StateTableError(msg)
        return

    dynamodb = boto3.resource("dynamodb")
    table = dynamodb.Table(table_name)
    logger.info("Getting key '{}' from table '{}'".format(key, table_name))
    if namespace:
        key = "{}:{}".format(namespace, key)

    if shard_id:
        key = "{}:{}".format(shard_id, key)

    @retry(retry_on_exception=_is_critical_exception,
           wait_exponential_multiplier=wait_exponential_multiplier,
           wait_exponential_max=wait_exponential_max,
           stop_max_delay=stop_max_delay)
    def get_item():
        try:
            return table.get_item(
                Key={"id": key}, ConsistentRead=consistent).get(
                    "Item", {}).get("value")
        except Exception as err:
            if _is_dynamodb_critical_exception(err):
                raise CriticalError(err)
            else:
                raise

    value = get_item()

    if not value:
        return

    if deserializer:
        try:
            value = deserializer(value)
        except ValueError:
            # For backwards compatibility: plain strings are allowed
            logger.error("Unable to json-deserialize value '{}'".format(value))
            return value

    return value