.. image:: https://img.shields.io/pypi/v/asynctelnet.svg
    :alt: Latest Version
    :target: https://pypi.python.org/pypi/asynctelnet

.. image:: https://img.shields.io/pypi/dm/asynctelnet.svg
    :alt: Downloads
    :target: https://pypi.python.org/pypi/asynctelnet


Introduction
============

asynctelnet is an asynchronous Telnet Client and Server library for python.
This project requires python 3.6 and later, using the anyio_ module.

.. _anyio: https://anyio.readthedocs.io/

asynctelnet is a heavily modified anyio-ization of the telnetlib3_ module.

.. _telnetlib3: https://telnetlib3.readthedocs.io/


Quick Example
-------------

Authoring a Telnet Server using Streams interface that offers a basic war game:

.. code-block:: python

    import anyio, asynctelnet

    async def shell(tcp):
        async with asynctelnet.TelnetServer(tcp) as stream:
            # this will fail if no charset has been negotiated
            await stream.send('\r\nWould you like to play a game? ')
            inp = await reader.receive(1)
            if inp:
                await stream.echo(inp)
                await stream.send('\r\nThey say the only way to win '
                                  'is to not play at all.\r\n')

    async def main():
        listener = await anyio.create_tcp_listener(local_port=56023)
        await listener.serve(shell)
    anyio.run(main)

Authoring a Telnet Client that plays the war game with this server:

.. code-block:: python

    import anyio, asynctelnet

    async def shell(tcp):
        async with asynctelnet.TelnetClient(tcp, client=True) as stream:
            while True:
                # read stream until '?' mark is found
                outp = await stream.receive(1024)
                if not outp:
                    # End of File
                    break
                elif '?' in outp:
                    # reply all questions with 'y'.
                    await stream.send('y')
    
                # display all server output
                print(outp, flush=True)
     
        # EOF
        print()
    
    async def main():
        async with await connect_tcp('localhost', 56023) as client:
            await shell(client)
    anyio.run(main)


Command Line
------------

Two command line scripts are distributed with this package.

``asynctelnet-client``

  Small terminal telnet client.  Some example destinations and options::

    asynctelnet-client nethack.alt.org
    asynctelnet-client --encoding=cp437 --force-binary blackflag.acid.org
    asynctelnet-client htc.zapto.org


``asynctelnet-server``

  Telnet server providing the default debugging shell.  This provides a simple
  shell server that allows introspection of the session's values, for example::

     tel:sh> help
     quit, writer, slc, toggle [option|all], reader, proto

     tel:sh> writer
     <TelnetWriter server mode:kludge +lineflow -xon_any +slc_sim server-will:BINARY,ECHO,SGA client-will:BINARY,NAWS,NEW_ENVIRON,TTYPE>

     tel:sh> reader
     <TelnetReaderUnicode encoding='utf8' limit=65536 buflen=0 eof=False>

     tel:sh> toggle all
     wont echo.
     wont suppress go-ahead.
     wont outbinary.
     dont inbinary.
     xon-any enabled.
     lineflow disabled.

     tel:sh> reader
     <TelnetReaderUnicode encoding='US-ASCII' limit=65536 buflen=1 eof=False>

     tel:sh> writer
     <TelnetWriter server mode:local -lineflow +xon_any +slc_sim client-will:NAWS,NEW_ENVIRON,TTYPE>


Both command-line scripts accept argument ``--shell=my_module.fn_shell``
describing a python module path to a coroutine of signature
``shell(reader, writer)``, just as the above examples.

Features
--------

The following RFC specifications are implemented:

* `rfc-727`_, "Telnet Logout Option," Apr 1977.
* `rfc-779`_, "Telnet Send-Location Option", Apr 1981.
* `rfc-854`_, "Telnet Protocol Specification", May 1983.
* `rfc-855`_, "Telnet Option Specifications", May 1983.
* `rfc-856`_, "Telnet Binary Transmission", May 1983.
* `rfc-857`_, "Telnet Echo Option", May 1983.
* `rfc-858`_, "Telnet Suppress Go Ahead Option", May 1983.
* `rfc-859`_, "Telnet Status Option", May 1983.
* `rfc-860`_, "Telnet Timing mark Option", May 1983.
* `rfc-885`_, "Telnet End of Record Option", Dec 1983.
* `rfc-1073`_, "Telnet Window Size Option", Oct 1988.
* `rfc-1079`_, "Telnet Terminal Speed Option", Dec 1988.
* `rfc-1091`_, "Telnet Terminal-Type Option", Feb 1989.
* `rfc-1096`_, "Telnet X Display Location Option", Mar 1989.
* `rfc-1123`_, "Requirements for Internet Hosts", Oct 1989.
* `rfc-1184`_, "Telnet Linemode Option (extended options)", Oct 1990.
* `rfc-1372`_, "Telnet Remote Flow Control Option", Oct 1992.
* `rfc-1408`_, "Telnet Environment Option", Jan 1993.
* `rfc-1571`_, "Telnet Environment Option Interoperability Issues", Jan 1994.
* `rfc-1572`_, "Telnet Environment Option", Jan 1994.
* `rfc-2066`_, "Telnet Charset Option", Jan 1997.

.. _rfc-727: https://www.rfc-editor.org/rfc/rfc727.txt
.. _rfc-779: https://www.rfc-editor.org/rfc/rfc779.txt
.. _rfc-854: https://www.rfc-editor.org/rfc/rfc854.txt
.. _rfc-855: https://www.rfc-editor.org/rfc/rfc855.txt
.. _rfc-856: https://www.rfc-editor.org/rfc/rfc856.txt
.. _rfc-857: https://www.rfc-editor.org/rfc/rfc857.txt
.. _rfc-858: https://www.rfc-editor.org/rfc/rfc858.txt
.. _rfc-859: https://www.rfc-editor.org/rfc/rfc859.txt
.. _rfc-860: https://www.rfc-editor.org/rfc/rfc860.txt
.. _rfc-885: https://www.rfc-editor.org/rfc/rfc885.txt
.. _rfc-1073: https://www.rfc-editor.org/rfc/rfc1073.txt
.. _rfc-1079: https://www.rfc-editor.org/rfc/rfc1079.txt
.. _rfc-1091: https://www.rfc-editor.org/rfc/rfc1091.txt
.. _rfc-1096: https://www.rfc-editor.org/rfc/rfc1096.txt
.. _rfc-1123: https://www.rfc-editor.org/rfc/rfc1123.txt
.. _rfc-1184: https://www.rfc-editor.org/rfc/rfc1184.txt
.. _rfc-1372: https://www.rfc-editor.org/rfc/rfc1372.txt
.. _rfc-1408: https://www.rfc-editor.org/rfc/rfc1408.txt
.. _rfc-1571: https://www.rfc-editor.org/rfc/rfc1571.txt
.. _rfc-1572: https://www.rfc-editor.org/rfc/rfc1572.txt
.. _rfc-2066: https://www.rfc-editor.org/rfc/rfc2066.txt

Further Reading
---------------

Further documentation available at https://asynctelnet.readthedocs.org/
