class_docstr: A channel to communicate with NNI manager.
  
  Each NNI experiment has a channel URL for tuner/assessor/strategy algorithm.
  The channel can only be connected once, so for each Python side :class:`~nni.experiment.Experiment` object,
  there should be exactly one corresponding ``TunerCommandChannel`` instance.
  
  :meth:`connect` must be invoked before sending or receiving data.
  
  The constructor does not have side effect so ``TunerCommandChannel`` can be created anywhere.
  But :meth:`connect` requires an initialized NNI manager, or otherwise the behavior is unpredictable.
  
  :meth:`_send` and :meth:`_receive` are underscore-prefixed because their signatures are scheduled to change by v3.0.
  
  Parameters
  ----------
  url
      The command channel URL.
      For now it must be like ``"ws://localhost:8080/tuner"`` or ``"ws://localhost:8080/url-prefix/tuner"``.
class_docstr_tok: ["A","channel","to","communicate","with","NNI","manager",".","Each","NNI","experiment","has","a","channel","URL","for","tuner\/assessor\/strategy","algorithm",".","The","channel","can","only","be","connected","once",",","so","for","each","Python","side",":","class",":","`","~nni.experiment.Experiment","`","object",",","there","should","be","exactly","one","corresponding","``","TunerCommandChannel","``","instance",".",":","meth",":","`","connect","`","must","be","invoked","before","sending","or","receiving","data",".","The","constructor","does","not","have","side","effect","so","``","TunerCommandChannel","``","can","be","created","anywhere",".","But",":","meth",":","`","connect","`","requires","an","initialized","NNI","manager",",","or","otherwise","the","behavior","is","unpredictable",".",":","meth",":","`","_send","`","and",":","meth",":","`","_receive","`","are","underscore-prefixed","because","their","signatures","are","scheduled","to","change","by","v3.0",".","Parameters","--","--","--","--","--","url","The","command","channel","URL",".","For","now","it","must","be","like","``","``","ws",":","\/\/localhost:8080\/tuner","''","``","or","``","``","ws",":","\/\/localhost:8080\/url-prefix\/tuner","''","``","."]
docstr: Send a new trial job to NNI manager.
  
  Without multi-phase in mind, one parameter = one trial.
  
  Parameters
  ----------
  parameter_id
      The ID of the current parameter.
      It's used by whoever calls the :meth:`send_trial` function to identify the parameters.
      In most cases, they are non-negative integers starting from 0.
  parameters
      The parameters.
  parameter_source
      The source of the parameters. ``algorithm`` means the parameters are generated by the algorithm.
      It should be left as default in most cases.
  parameter_index
      The index of the parameters. This is previously used in multi-phase, but now it's only kept for compatibility reasons.
  placement_constraint
      The placement constraint of the created trial job.
docstr_tok: ["Send","a","new","trial","job","to","NNI","manager",".","Without","multi-phase","in","mind",",","one","parameter","=","one","trial",".","Parameters","--","--","--","--","--","parameter_id","The","ID","of","the","current","parameter",".","It","'s","used","by","whoever","calls","the",":","meth",":","`","send_trial","`","function","to","identify","the","parameters",".","In","most","cases",",","they","are","non-negative","integers","starting","from","0.","parameters","The","parameters",".","parameter_source","The","source","of","the","parameters",".","``","algorithm","``","means","the","parameters","are","generated","by","the","algorithm",".","It","should","be","left","as","default","in","most","cases",".","parameter_index","The","index","of","the","parameters",".","This","is","previously","used","in","multi-phase",",","but","now","it","'s","only","kept","for","compatibility","reasons",".","placement_constraint","The","placement","constraint","of","the","created","trial","job","."]
code: def send_trial(
      self,
      parameter_id: int,
      parameters: Parameters,
      parameter_source: str = "algorithm",
      parameter_index: int = 0,
      placement_constraint: dict[str, Any]
      | None = None,  # TODO: Define PlacementConstraint class.
  ):
      """
      Send a new trial job to NNI manager.
  
      Without multi-phase in mind, one parameter = one trial.
  
      Parameters
      ----------
      parameter_id
          The ID of the current parameter.
          It's used by whoever calls the :meth:`send_trial` function to identify the parameters.
          In most cases, they are non-negative integers starting from 0.
      parameters
          The parameters.
      parameter_source
          The source of the parameters. ``algorithm`` means the parameters are generated by the algorithm.
          It should be left as default in most cases.
      parameter_index
          The index of the parameters. This is previously used in multi-phase, but now it's only kept for compatibility reasons.
      placement_constraint
          The placement constraint of the created trial job.
      """
      # Local import to reduce import delay.
      from nni.common.version import version_dump
  
      trial_dict = {
          "parameter_id": parameter_id,
          "parameters": parameters,
          "parameter_source": parameter_source,
          "parameter_index": parameter_index,
          "version_info": version_dump(),
      }
      if placement_constraint is not None:
          _validate_placement_constraint(placement_constraint)
          trial_dict["placement_constraint"] = placement_constraint
  
      try:
          send_payload = dump(
              trial_dict,
              pickle_size_limit=int(
                  os.getenv("PICKLE_SIZE_LIMIT", 64 * 1024)
              ),
          )
      except PayloadTooLarge:
          raise ValueError(
              "Serialization failed when trying to dump the model because payload too large (larger than 64 KB). "
              "This is usually caused by pickling large objects (like datasets) by mistake. "
              "See the full error traceback for details and https://nni.readthedocs.io/en/stable/NAS/Serialization.html "
              "for how to resolve such issue. "
          )
  
      self._send(CommandType.NewTrialJob, send_payload)
  
imports: from __future__ import annotations
  import logging
  import os
  from collections import defaultdict
  from threading import Event
  from typing import Any, Callable
  from nni.common.serializer import dump, load, PayloadTooLarge
  from nni.runtime.command_channel.websocket import WsChannelClient
  from nni.typehint import Parameters
  from .command_type import CommandType, TunerIncomingCommand, Initialize, RequestTrialJobs, UpdateSearchSpace, ReportMetricData, TrialEnd, Terminate
label_desc: Use image node_id 6 for calling the TunerCommandChannel obj's underlying member method code with example usage: obj.send_trial(parameter_id, parameters, parameter_source, parameter_index, placement_constraint) without return types