docstr: Start the server programmatically.
  
  To get the client, use the context manager.
  
  .. note::
     ``blocking=True`` and using ``start()`` as a context manager is mutually exclusive.
  
  Args:
      blocking: If True, the server will block until it is stopped.
      env: A dictionary of environment variables to pass to the server. Default to ``None``.
      stdin: The stdin to pass to the server. Default to ``None``.
      stdout: The stdout to pass to the server. Default to ``None``.
      stderr: The stderr to pass to the server. Default to ``None``.
      text: Whether to output as text or bytes for stdout and stderr. Default to ``None``.
docstr_tok: ["Start","the","server","programmatically",".","To","get","the","client",",","use","the","context","manager",".","..","note",":",":","``","blocking=True","``","and","using","``","start","(",")","``","as","a","context","manager","is","mutually","exclusive",".","Args",":","blocking",":","If","True",",","the","server","will","block","until","it","is","stopped",".","env",":","A","dictionary","of","environment","variables","to","pass","to","the","server",".","Default","to","``","None","``",".","stdin",":","The","stdin","to","pass","to","the","server",".","Default","to","``","None","``",".","stdout",":","The","stdout","to","pass","to","the","server",".","Default","to","``","None","``",".","stderr",":","The","stderr","to","pass","to","the","server",".","Default","to","``","None","``",".","text",":","Whether","to","output","as","text","or","bytes","for","stdout","and","stderr",".","Default","to","``","None","``","."]
code: def start(
      self,
      blocking: bool = False,
      env: dict[str, str] | None = None,
      stdin: _FILE = None,
      stdout: _FILE = None,
      stderr: _FILE = None,
      text: bool | None = None,
  ) -> t.ContextManager[ClientType]:
      """Start the server programmatically.
  
      To get the client, use the context manager.
  
      .. note::
         ``blocking=True`` and using ``start()`` as a context manager is mutually exclusive.
  
      Args:
          blocking: If True, the server will block until it is stopped.
          env: A dictionary of environment variables to pass to the server. Default to ``None``.
          stdin: The stdin to pass to the server. Default to ``None``.
          stdout: The stdout to pass to the server. Default to ``None``.
          stderr: The stderr to pass to the server. Default to ``None``.
          text: Whether to output as text or bytes for stdout and stderr. Default to ``None``.
      """
      # NOTE: User shouldn't manually set this since this envvar will be managed by BentoML.
      os.environ[BENTOML_SERVE_FROM_SERVER_API] = str(True)
  
      if env is None:
          env = {}
      env.update(os.environ.copy())
  
      class _Manager:
          def __init__(__inner_self):
              logger.debug(
                  f"Starting server with arguments: {self.args}"
              )
              default_io_descriptor = (
                  None if blocking else subprocess.PIPE
              )
              if text is None:
                  warn(
                      "Setting text to True will be the default behavior for bentoml 2.x. Set it explicitly to avoid breaking changes.\n"
                      + "For Example: 'server.start(text=False, ...)'"
                  )
              self.process = subprocess.Popen(
                  self.args,
                  stdout=stdout
                  if stdout is not None
                  else default_io_descriptor,
                  stderr=stderr
                  if stderr is not None
                  else default_io_descriptor,
                  stdin=stdin
                  if stdin is not None
                  else default_io_descriptor,
                  env=env,
                  # TODO: Make this default to True in 2.x
                  text=text if text is not None else False,
              )
  
              if blocking:
                  try:
                      self.process.wait()
                  except KeyboardInterrupt:
                      pass
  
          def __enter__(__inner_self) -> ClientType:
              return self.get_client()
  
          def __exit__(
              __inner_self,
              _exc_type: type[BaseException] | None,
              _exc_value: BaseException | None,
              _traceback: TracebackType | None,
          ):
              self.stop()
  
      return _Manager()
  
imports: from __future__ import annotations
  import logging
  import os
  import signal
  import subprocess
  import sys
  import textwrap
  import typing
  from abc import ABC
  from abc import abstractmethod
  from typing import TYPE_CHECKING
  from warnings import warn
  from simple_di import Provide
  from simple_di import inject
  from ._internal.bento import Bento
  from ._internal.client import Client
  from ._internal.client.grpc import GrpcClient
  from ._internal.client.http import HTTPClient
  from ._internal.configuration.containers import BentoMLContainer
  from ._internal.service import Service
  from ._internal.tag import Tag
  from ._internal.utils.analytics.usage_stats import BENTOML_SERVE_FROM_SERVER_API
  from .exceptions import InvalidArgument
  from .exceptions import ServerStateException
  from .exceptions import UnservableException
label_desc: Use image node_id 2 for calling the Server obj's underlying member method code with example usage: obj.start(blocking, env, stdin, stdout, stderr, text) and returns: _Manager, self