docs: def create_session(self, location=None, media_mode=MediaModes.relayed, archive_mode=ArchiveModes.manual):
          """
          Creates a new OpenTok session and returns the session ID, which uniquely identifies
          the session.
  
          For example, when using the OpenTok JavaScript library, use the session ID when calling the
          OT.initSession() method (to initialize an OpenTok session).
  
          OpenTok sessions do not expire. However, authentication tokens do expire (see the
          generateToken() method). Also note that sessions cannot explicitly be destroyed.
  
          A session ID string can be up to 255 characters long.
  
          Calling this method results in an OpenTokException in the event of an error.
          Check the error message for details.
  
          You can also create a session using the OpenTok
          `REST API <https://tokbox.com/opentok/api/#session_id_production>`_ or
          `the OpenTok dashboard <https://dashboard.tokbox.com/projects>`_.
  
          :param String media_mode: Determines whether the session will transmit streams using the
               OpenTok Media Router (MediaMode.routed) or not (MediaMode.relayed). By default,
               the setting is MediaMode.relayed.
  
               With the media_mode property set to MediaMode.relayed, the session
               will attempt to transmit streams directly between clients. If clients cannot connect
               due to firewall restrictions, the session uses the OpenTok TURN server to relay
               audio-video streams.
  
               The `OpenTok Media
               Router <https://tokbox.com/opentok/tutorials/create-session/#media-mode>`_
               provides the following benefits:
  
                 * The OpenTok Media Router can decrease bandwidth usage in multiparty sessions.
                     (When the mediaMode property is set to  MediaMode.relayed, each client must send
                     a separate audio-video stream to each client subscribing to it.)
  
                 * The OpenTok Media Router can improve the quality of the user experience through
                   audio fallback and video recovery (see https://tokbox.com/platform/fallback). With
                   these features, if a client's connectivity degrades to a degree that
                   it does not support video for a stream it's subscribing to, the video is dropped on
                   that client (without affecting other clients), and the client receives audio only.
                   If the client's connectivity improves, the video returns.
  
                 * The OpenTok Media Router supports the archiving feature, which lets
                   you record, save, and retrieve OpenTok sessions (see http://tokbox.com/platform/archiving).
  
          :param String archive_mode: Whether the session is automatically archived
              (ArchiveModes.always) or not (ArchiveModes.manual). By default,
              the setting is ArchiveModes.manual, and you must call the
              start_archive() method of the OpenTok object to start archiving. To archive the session
              (either automatically or not), you must set the media_mode parameter to
              MediaModes.routed.
  
          :param String location: An IP address that the OpenTok servers will use to
              situate the session in its global network. If you do not set a location hint,
              the OpenTok servers will be based on the first client connecting to the session.
  
          :rtype: The Session object. The session_id property of the object is the session ID.
          """
  
          # build options
          options = {}
          if not isinstance(media_mode, MediaModes):
              raise OpenTokException(u('Cannot create session, {0} is not a valid media mode').format(media_mode))
          if not isinstance(archive_mode, ArchiveModes):
              raise OpenTokException(u('Cannot create session, {0} is not a valid archive mode').format(archive_mode))
          if archive_mode == ArchiveModes.always and media_mode != MediaModes.routed:
              raise OpenTokException(u('A session with always archive mode must also have the routed media mode.'))
          options[u('p2p.preference')] = media_mode.value
          options[u('archiveMode')] = archive_mode.value
          if location:
              # validate IP address
              try:
                  inet_aton(location)
              except:
                  raise OpenTokException(u('Cannot create session. Location must be either None or a valid IPv4 address {0}').format(location))
              options[u('location')] = location
  
          try:
              response = requests.post(self.endpoints.session_url(), data=options, headers=self.headers(), proxies=self.proxies, timeout=self.timeout)
              response.encoding = 'utf-8'
  
              if response.status_code == 403:
                  raise AuthError('Failed to create session, invalid credentials')
              if not response.content:
                  raise RequestError()
              dom = xmldom.parseString(response.content)
          except Exception as e:
              raise RequestError('Failed to create session: %s' % str(e))
  
          try:
              error = dom.getElementsByTagName('error')
              if error:
                  error = error[0]
                  raise AuthError('Failed to create session (code=%s): %s' % (error.attributes['code'].value, error.firstChild.attributes['message'].value))
  
              session_id = dom.getElementsByTagName('session_id')[0].childNodes[0].nodeValue
              return Session(self, session_id, location=location, media_mode=media_mode, archive_mode=archive_mode)
          except Exception as e:
              raise OpenTokException('Failed to generate session: %s' % str(e))