def connection_factory(requests: AsyncIterator[PublishRequest]):
     final_metadata = merge_metadata(
         metadata, topic_routing_metadata(topic, partition)
     )
     return client_cache.get().publish(
         requests, metadata=list(final_metadata.items())
     )
def make_async_subscriber(
    subscription: SubscriptionPath,
    transport: str,
    per_partition_flow_control_settings: FlowControlSettings,
    nack_handler: Optional[NackHandler] = None,
    message_transformer: Optional[MessageTransformer] = None,
    fixed_partitions: Optional[Set[Partition]] = None,
    credentials: Optional[Credentials] = None,
    client_options: Optional[ClientOptions] = None,
    metadata: Optional[Mapping[str, str]] = None,
) -> AsyncSingleSubscriber:
    """
    Make a Pub/Sub Lite AsyncSubscriber.

    Args:
      subscription: The subscription to subscribe to.
      transport: The transport type to use.
      per_partition_flow_control_settings: The flow control settings for each partition subscribed to. Note that these
        settings apply to each partition individually, not in aggregate.
      nack_handler: An optional handler for when nack() is called on a Message. The default will fail the client.
      message_transformer: An optional transformer from Pub/Sub Lite messages to Cloud Pub/Sub messages.
      fixed_partitions: A fixed set of partitions to subscribe to. If not present, will instead use auto-assignment.
      credentials: The credentials to use to connect. GOOGLE_DEFAULT_CREDENTIALS is used if None.
      client_options: Other options to pass to the client. Note that if you pass any you must set api_endpoint.
      metadata: Additional metadata to send with the RPC.

    Returns:
      A new AsyncSubscriber.
    """
    metadata = merge_metadata(pubsub_context(framework="CLOUD_PUBSUB_SHIM"), metadata)
    if client_options is None:
        client_options = ClientOptions(
            api_endpoint=regional_endpoint(subscription.location.region)
        )
    assigner_factory: Callable[[], Assigner]
    if fixed_partitions:
        assigner_factory = lambda: FixedSetAssigner(fixed_partitions)  # noqa: E731
    else:
        assigner_factory = lambda: _make_dynamic_assigner(  # noqa: E731
            subscription, transport, client_options, credentials, metadata,
        )

    if nack_handler is None:
        nack_handler = DefaultNackHandler()
    if message_transformer is None:
        message_transformer = MessageTransformer.of_callable(to_cps_subscribe_message)
    partition_subscriber_factory = _make_partition_subscriber_factory(
        subscription,
        transport,
        client_options,
        credentials,
        metadata,
        per_partition_flow_control_settings,
        nack_handler,
        message_transformer,
    )
    return AssigningSingleSubscriber(assigner_factory, partition_subscriber_factory)
    def factory(partition: Partition) -> AsyncSingleSubscriber:
        subscribe_client = SubscriberServiceAsyncClient(
            credentials=credentials,
            client_options=client_options,
            transport=transport)  # type: ignore
        cursor_client = CursorServiceAsyncClient(
            credentials=credentials,
            client_options=client_options,
            transport=transport)  # type: ignore
        final_metadata = merge_metadata(
            base_metadata,
            subscription_routing_metadata(subscription, partition))

        def subscribe_connection_factory(
                requests: AsyncIterator[SubscribeRequest]):
            return subscribe_client.subscribe(requests,
                                              metadata=list(
                                                  final_metadata.items()))

        def cursor_connection_factory(
            requests: AsyncIterator[StreamingCommitCursorRequest], ):
            return cursor_client.streaming_commit_cursor(
                requests, metadata=list(final_metadata.items()))

        subscriber = wire_subscriber.SubscriberImpl(
            InitialSubscribeRequest(subscription=str(subscription),
                                    partition=partition.value),
            _DEFAULT_FLUSH_SECONDS,
            GapicConnectionFactory(subscribe_connection_factory),
        )
        committer = CommitterImpl(
            InitialCommitCursorRequest(subscription=str(subscription),
                                       partition=partition.value),
            _DEFAULT_FLUSH_SECONDS,
            GapicConnectionFactory(cursor_connection_factory),
        )
        ack_set_tracker = AckSetTrackerImpl(committer)
        return SinglePartitionSingleSubscriber(
            subscriber,
            flow_control_settings,
            ack_set_tracker,
            nack_handler,
            add_id_to_cps_subscribe_transformer(partition,
                                                message_transformer),
        )
    def factory(partition: Partition) -> AsyncSingleSubscriber:
        final_metadata = merge_metadata(
            base_metadata, subscription_routing_metadata(subscription, partition)
        )

        def subscribe_connection_factory(requests: AsyncIterator[SubscribeRequest]):
            return subscribe_client_cache.get().subscribe(
                requests, metadata=list(final_metadata.items())
            )

        def cursor_connection_factory(
            requests: AsyncIterator[StreamingCommitCursorRequest],
        ):
            return cursor_client_cache.get().streaming_commit_cursor(
                requests, metadata=list(final_metadata.items())
            )

        def subscriber_factory(reset_handler: SubscriberResetHandler):
            return wire_subscriber.SubscriberImpl(
                InitialSubscribeRequest(
                    subscription=str(subscription), partition=partition.value
                ),
                _DEFAULT_FLUSH_SECONDS,
                GapicConnectionFactory(subscribe_connection_factory),
                reset_handler,
            )

        committer = CommitterImpl(
            InitialCommitCursorRequest(
                subscription=str(subscription), partition=partition.value
            ),
            _DEFAULT_FLUSH_SECONDS,
            GapicConnectionFactory(cursor_connection_factory),
        )
        ack_set_tracker = AckSetTrackerImpl(committer)
        return SinglePartitionSingleSubscriber(
            subscriber_factory,
            flow_control_settings,
            ack_set_tracker,
            nack_handler,
            add_id_to_cps_subscribe_transformer(partition, message_transformer),
        )
def make_async_publisher(
    topic: TopicPath,
    transport: str,
    per_partition_batching_settings: Optional[BatchSettings] = None,
    credentials: Optional[Credentials] = None,
    client_options: Optional[ClientOptions] = None,
    metadata: Optional[Mapping[str, str]] = None,
) -> AsyncSinglePublisher:
    """
    Make a new publisher for the given topic.

    Args:
      topic: The topic to publish to.
      transport: The transport type to use.
      per_partition_batching_settings: Settings for batching messages on each partition. The default is reasonable for most cases.
      credentials: The credentials to use to connect. GOOGLE_DEFAULT_CREDENTIALS is used if None.
      client_options: Other options to pass to the client. Note that if you pass any you must set api_endpoint.
      metadata: Additional metadata to send with the RPC.

    Returns:
      A new AsyncPublisher.

    Throws:
      GoogleApiCallException on any error determining topic structure.
    """
    metadata = merge_metadata(pubsub_context(framework="CLOUD_PUBSUB_SHIM"), metadata)

    def underlying_factory():
        return make_wire_publisher(
            topic=topic,
            transport=transport,
            per_partition_batching_settings=per_partition_batching_settings,
            credentials=credentials,
            client_options=client_options,
            metadata=metadata,
        )

    return AsyncSinglePublisherImpl(underlying_factory)