API Reference¶
The Main ptadapter
Module¶
Python interface for Pluggable Transports
The main module exports the adapter classes, as well as several Named Tuple classes used as return values of adapter class methods.
Adapters¶
-
class
ptadapter.
ClientAdapter
(pt_exec, state, transports, proxy=None, *, exit_on_stdin_close=True)¶ Run a pluggable transport as client.
For each enabled transport, the PT will listen on a port, which can be looked up using
get_transport()
. Useopen_transport_connection()
to make a connection through a transport.This object can be used as an async context manager. On entering the context, the PT is started, and on exiting the PT is stopped. The adapter itself is returned as the “as” variable.
-
__init__
(pt_exec, state, transports, proxy=None, *, exit_on_stdin_close=True)¶ Create the adapter.
- Parameters
pt_exec (
Union
[List
[str
],List
[bytes
]]) – The pluggable transport command line to execute. This has to be a list of str / bytes, sinceasyncio.create_subprocess_exec()
does not accept an entire command line as a string. On non-Windows platformsshlex.split()
can be used to split a command line string into a list, while on Windows it’s a bit more complicated.state (
Union
[None
,str
,bytes
,PathLike
]) – The state directory. This is a directory where the PT is allowed to store state. Either specify an absolute path (which is not required to exist, in which case the PT will create the directory), or specifyNone
to use a temporary directory created usingtempfile
.transports (
List
[str
]) – a list of client transports the PT should initialize. PTs will ignore names they don’t recognize.proxy (
Optional
[str
]) – The upstream proxy to use. Must be specified in the URI format:<proxy_type>://[<user_name>[:<password>][@]<ip>:<port>
.exit_on_stdin_close (
bool
) – Whether closing the PT’s STDIN indicates the PT should gracefully exit.
-
await
open_transport_connection
(transport, host, port, args, **kwargs)¶ (async) Open a connection through a client transport.
This method uses
get_transport()
andasyncio.open_connection()
, and their exceptions will not be modified. Additional possible exceptions are listed below.- Parameters
transport (
str
) – Name of the transport.host (
Union
[str
,IPv4Address
,IPv6Address
]) – Destination IP address or host name. Depending on the PT, host names or IPv6 addresses may not be supported.port (
int
) – Destination port number.args (
Optional
[Dict
[str
,str
]]) – Per-connection arguments. Both keys and values should be strings. (Backslash, equal signs and semicolons will be automatically escaped before passing to PT.)kwargs – Any unrecognized keyword arguments are passed to
asyncio.open_connection()
. This can be useful for specifying limit and local_addr.
- Return type
Tuple
[StreamReader
,StreamWriter
]- Returns
A (
StreamReader
,StreamWriter
) tuple.- Raises
RuntimeError – If the PT violates PT-spec or SOCKS proxy protocols.
ValueError – If host, port or args are invalid.
exceptions.PTConnectError – If the PT reports an error while connecting to the destination.
-
get_transport
(transport)¶ Look up initialized client transport methods.
- Parameters
transport (
str
) – Name of the transport.- Return type
ClientTransport
- Returns
A
ClientTransport
NamedTuple for the specified transport.- Raises
KeyError – If the specified transport was not provided when calling
__init__()
.asyncio.InvalidStateError – If PT has not yet started, or if the transport is not yet initialized.
RuntimeError – If the PT returned an error while initializing the specified transport.
-
await
start
()¶ (async) Start the PT executable and wait until it’s ready.
“Ready” means that all transports have finished initializing.
- Return type
-
state
¶ The state directory.
If a temporary directory is used, this will be
None
before the adapter starts, and will be the actual path of the directory after the adapter has started. The temporary directory will be deleted once the adapter is stopped.
-
await
stop
()¶ (async) Stop the PT executable.
First try to signal a graceful exit by closing PT’s STDIN (if enabled) and wait, then call
terminate()
and wait, then callkill()
.- Return type
-
-
class
ptadapter.
ServerAdapter
(pt_exec, state, forward_host, forward_port, *, exit_on_stdin_close=True)¶ Run a pluggable transport as server.
For each enabled transport, the PT will listen on a port, which can be either specified or left auto-assigned, and looked up using
get_transport()
. The PT will forward unobfuscated traffic directly to forward_host:forward_port.This object can be used as an async context manager. On entering the context, the PT is started, and on exiting the PT is stopped. The adapter itself is returned as the “as” variable.
-
__init__
(pt_exec, state, forward_host, forward_port, *, exit_on_stdin_close=True)¶ Create the adapter.
- Parameters
pt_exec (
Union
[List
[str
],List
[bytes
]]) – The pluggable transport command line to execute. This has to be a list of str / bytes, sinceasyncio.create_subprocess_exec()
does not accept an entire command line as a string. On non-Windows platformsshlex.split()
can be used to split a command line string into a list, while on Windows it’s a bit more complicated.state (
Union
[None
,str
,bytes
,PathLike
]) – The state directory. This is a directory where the PT is allowed to store state. Either specify a path (which is not required to exist, in which case the PT will create the directory), or specifyNone
to use a temporary directory created usingtempfile
. For servers, using an actual persistent location is recommended.forward_host (
Union
[str
,IPv4Address
,IPv6Address
]) – IP address or host name to forward unobfuscated traffic to.forward_port (
int
) – Port number to forward unobfuscated traffic to.exit_on_stdin_close (
bool
) – Whether closing the PT’s STDIN indicates the PT should gracefully exit.
-
add_transport
(transport, host, port, options=None)¶ Add a server transport.
This can only be called before PT starts. Unlike when running as client, PTs only support one tunnel per transport when running as server. Calling this with the same transport again will overwrite the previous entry.
- Parameters
transport (
str
) – The transport name. PT will ignore names it does not recognize.host (
Union
[None
,str
,IPv4Address
,IPv6Address
]) – The IP address to listen on. This must not be a host name. host and port must be either specified at the same time, or set toNone
at the same time.
- Return type
-
get_transport
(transport)¶ Look up initialized server transport methods.
- Parameters
transport (
str
) – Name of the transport.- Return type
ServerTransport
- Returns
A
ServerTransport
NamedTuple for the specified transport.- Raises
KeyError – If the specified transport was not provided when calling
__init__()
.asyncio.InvalidStateError – If PT has not yet started, or if the transport is not yet initialized.
RuntimeError – If the PT returned an error while initializing the specified transport.
-
await
start
()¶ (async) Start the PT executable and wait until it’s ready.
“Ready” means that all transports have finished initializing.
- Return type
-
state
¶ The state directory.
If a temporary directory is used, this will be
None
before the adapter starts, and will be the actual path of the directory after the adapter has started. The temporary directory will be deleted once the adapter is stopped.
-
await
stop
()¶ (async) Stop the PT executable.
First try to signal a graceful exit by closing PT’s STDIN (if enabled) and wait, then call
terminate()
and wait, then callkill()
.- Return type
-
-
class
ptadapter.
ExtServerAdapter
(pt_exec, state, client_connected_cb, *, preconnect_cb=None, auth_cookie_file=None, ext_host='localhost', ext_port=0, ext_family=<AddressFamily.AF_UNSPEC: 0>, exit_on_stdin_close=True)¶ Run a pluggable transport as server.
For each enabled transport, the PT will listen on a port, which can be either specified or left auto-assigned, and looked up using
get_transport()
. The PT will connect to the adapter using the ExtOrPort protocol, and a callback will be invoked.This object can be used as an async context manager. On entering the context, the PT is started, and on exiting the PT is stopped. The adapter itself is returned as the “as” variable.
-
__init__
(pt_exec, state, client_connected_cb, *, preconnect_cb=None, auth_cookie_file=None, ext_host='localhost', ext_port=0, ext_family=<AddressFamily.AF_UNSPEC: 0>, exit_on_stdin_close=True)¶ Create the adapter.
- Parameters
pt_exec (
Union
[List
[str
],List
[bytes
]]) – The pluggable transport command line to execute. This has to be a list of str / bytes, sinceasyncio.create_subprocess_exec()
does not accept an entire command line as a string. On non-Windows platformsshlex.split()
can be used to split a command line string into a list, while on Windows it’s a bit more complicated.state (
Union
[None
,str
,bytes
,PathLike
]) – The state directory. This is a directory where the PT is allowed to store state. Either specify a path (which is not required to exist, in which case the PT will create the directory), or specifyNone
to use a temporary directory created usingtempfile
. For servers, using an actual persistent location is recommended.client_connected_cb (
Callable
[[StreamReader
,StreamWriter
,ExtOrPortClientConnection
],Awaitable
[None
]]) – Async callback function called to handle incoming client connections. It will be called with three arguments: (reader, writer, connection_info), where reader and writer are aStreamReader
,StreamWriter
pair, and connection_info is aExtOrPortClientConnection
containing information on the connecting client.preconnect_cb (
Optional
[Callable
[[ExtOrPortClientConnection
],Awaitable
[bool
]]]) – Optional async callback function called before client_connect_cb, where an incoming connection can be rejected. It will be called with a single argument ofExtOrPortClientConnection
containing information on the connecting client, and should return a boolean, whereTrue
means to allow the connection andFalse
means to reject.auth_cookie_file (
Union
[str
,bytes
,PathLike
,None
]) – Path to the ExtOrPort authentication cookie file. If specified, this should be a path + filename to a writable location that is not readable by other users. If unspecified, a temporary directory is created usingtempfile
, and the cookie file created inside.ext_host (
str
) – IP address / host name to bind ExtOrPort to. The ExtOrPort is used internally between the PT and the adapter, so this should be a loopback address.ext_port (
int
) – Port number to bind ExtOrPort to.0
means a random ephemeral port.ext_family (
int
) – Thefamily
flag passed while binding ExtOrPort.socket.AF_INET
orsocket.AF_INET6
can be passed to restrict ExtOrPort to IPv4 or IPv6 respectively.exit_on_stdin_close (
bool
) – Whether closing the PT’s STDIN indicates the PT should gracefully exit.
-
add_transport
(transport, host, port, options=None)¶ Add a server transport.
This can only be called before PT starts. Unlike when running as client, PTs only support one tunnel per transport when running as server. Calling this with the same transport again will overwrite the previous entry.
- Parameters
transport (
str
) – The transport name. PT will ignore names it does not recognize.host (
Union
[None
,str
,IPv4Address
,IPv6Address
]) – The IP address to listen on. This must not be a host name. host and port must be either specified at the same time, or set toNone
at the same time.
- Return type
-
get_transport
(transport)¶ Look up initialized server transport methods.
- Parameters
transport (
str
) – Name of the transport.- Return type
ServerTransport
- Returns
A
ServerTransport
NamedTuple for the specified transport.- Raises
KeyError – If the specified transport was not provided when calling
__init__()
.asyncio.InvalidStateError – If PT has not yet started, or if the transport is not yet initialized.
RuntimeError – If the PT returned an error while initializing the specified transport.
-
await
start
()¶ (async) Start the PT executable and wait until it’s ready.
“Ready” means that all transports have finished initializing.
- Return type
-
state
¶ The state directory.
If a temporary directory is used, this will be
None
before the adapter starts, and will be the actual path of the directory after the adapter has started. The temporary directory will be deleted once the adapter is stopped.
-
await
stop
()¶ (async) Stop the PT executable.
First try to signal a graceful exit by closing PT’s STDIN (if enabled) and wait, then call
terminate()
and wait, then callkill()
.- Return type
-
Supporting Classes¶
-
class
ptadapter.
ClientTransport
(scheme: str, host: str, port: int)¶ NamedTuple
describing an initialized client transport method.-
scheme
¶ The proxy scheme, either “socks4” or “socks5”.
-
host
¶ Proxy IP address.
-
port
¶ Proxy port.
-
-
class
ptadapter.
ServerTransport
(host: str, port: int, options: Optional[str])¶ NamedTuple
describing an initialized server transport method.-
host
¶ Reverse proxy IP address.
-
port
¶ Reverse proxy port.
-
options
¶ Per-transport option field returned by PT.
-
parse_args
()¶ Parse the “ARGS” option in the options field into a dict.
If the options field is not present, or it does not contain an “ARGS” option, return an empty dict.
- Raises
ValueError – if the “ARGS” option is not well-formed.
- Return type
-
-
class
ptadapter.
ExtOrPortClientConnection
(transport: Optional[str], host: Union[None, ipaddress.IPv4Address, ipaddress.IPv6Address], port: Optional[int])¶ NamedTuple
describing an incoming client connection.In practice, PTs should provide all the information represented here, but the ExtOrPort specs does not explicitly require PT to provide everything, so there still might be cases where some of the entries are
None
.-
transport
¶ Name of transport used by the client.
-
host
¶ IP address of the client.
Note: this is not a string, but an instance of either
ipaddress.IPv4Address
oripaddress.IPv6Address
. Callstr()
on it if you need a string.
-
port
¶ Port number of the client.
-
exceptions
Submodule¶
Exceptions raised by this package.
Two Enums used in these exceptions are also imported in this module for convenience.
-
exception
ptadapter.exceptions.
PTConnectError
¶ Bases:
ConnectionError
Error while PT tries to connect to destination.
This is the base class of some other connection errors. To make catching connectivity-related exceptions easier, this inherits from the built-in
ConnectionError
.
-
exception
ptadapter.exceptions.
PTSOCKS5ConnectError
¶ Bases:
ptadapter.exceptions.PTConnectError
Error reported by client PT using SOCKS5 connecting to destination.
The args of this exception contains the reason of failure returned by the PT, as an instance of
ptadapter.socks.SOCKS5Reply
. This may or may not be useful; do not be surprised if PTs only ever return GENERAL_FAILURE.
-
exception
ptadapter.exceptions.
PTSOCKS4ConnectError
¶ Bases:
ptadapter.exceptions.PTConnectError
Error reported by client PT using SOCKS4 connecting to destination.
The args of this exception contains the reason of failure returned by the PT, as an instance of
ptadapter.socks.SOCKS4Reply
. This is likely to be even less useful than a SOCKS5 reply, since the specific errors are all related toidentd
, which we are not using.
-
class
ptadapter.exceptions.
SOCKS5Reply
(value)¶ Bases:
ptadapter.enums.BytesEnum
Command reply from SOCKS5 server to client.
-
SUCCESS
= b'\x00'¶
-
GENERAL_FAILURE
= b'\x01'¶
-
CONNECTION_NOT_ALLOWED_BY_RULESET
= b'\x02'¶
-
NETWORK_UNREACHABLE
= b'\x03'¶
-
HOST_UNREACHABLE
= b'\x04'¶
-
CONNECTION_REFUSED
= b'\x05'¶
-
TTL_EXPIRED
= b'\x06'¶
-
COMMAND_NOT_SUPPORTED
= b'\x07'¶
-
ADDRESS_TYPE_NOT_SUPPORTED
= b'\x08'¶
-