API Documentation¶
TChannel¶
-
class
tchannel.
TChannel
(name, hostport=None, process_name=None, known_peers=None, trace=True, reuse_port=False, context_provider=None, tracer=None)[source]¶ Manages connections and requests to other TChannel services.
Usage for a JSON client/server:
tchannel = TChannel(name='foo') @tchannel.json.register def handler(request): return {'foo': 'bar'} response = yield tchannel.json( service='some-service', endpoint='endpoint', headers={'req': 'headers'}, body={'req': 'body'}, )
Variables: - thrift (ThriftArgScheme) – Make Thrift requests over TChannel and register Thrift handlers.
- json (JsonArgScheme) – Make JSON requests over TChannel and register JSON handlers.
- raw (RawArgScheme) – Make requests and register handles that pass raw bytes.
-
__init__
(name, hostport=None, process_name=None, known_peers=None, trace=True, reuse_port=False, context_provider=None, tracer=None)[source]¶ Note: In general only one
TChannel
instance should be used at a time. MultipleTChannel
instances are not advisable and could result in undefined behavior.Parameters: - name (string) – How this application identifies itself. This is the name callers will use to make contact, it is also what your downstream services will see in their metrics.
- hostport (string) – An optional host/port to serve on, e.g.,
"127.0.0.1:5555
. If not provided an ephemeral port will be used. When advertising on Hyperbahn you callers do not need to know your port.
-
call
(*args, **kwargs)[source]¶ Make low-level requests to TChannel services.
Note: Usually you would interact with a higher-level arg scheme like
tchannel.schemes.JsonArgScheme
ortchannel.schemes.ThriftArgScheme
.
-
advertise
(routers=None, name=None, timeout=None, router_file=None, jitter=None)[source]¶ Advertise with Hyperbahn.
After a successful advertisement, Hyperbahn will establish long-lived connections with your application. These connections are used to load balance inbound and outbound requests to other applications on the Hyperbahn network.
Re-advertisement happens periodically after calling this method (every minute). Hyperbahn will eject us from the network if it doesn’t get a re-advertise from us after 5 minutes.
This function may be called multiple times if it fails. If it succeeds, all consecutive calls are ignored.
Parameters: - routers (list) – A seed list of known Hyperbahn addresses to attempt contact with.
Entries should be of the form
"host:port"
. - name (string) – The name your application identifies itself as. This is usually
unneeded because in the common case it will match the
name
you initialized theTChannel
instance with. This is the identifier other services will use to make contact with you. - timeout – The timeout (in sec) for the initial advertise attempt. Defaults to 30 seconds.
- jitter – Variance allowed in the interval per request. Defaults to 5 seconds. The jitter applies to the initial advertise request as well.
- router_file – The host file that contains the routers information. The file should contain a JSON stringified format of the routers parameter. Either routers or router_file should be provided. If both provided, a ValueError will be raised.
Returns: A future that resolves to the remote server’s response after the first advertise finishes.
Raises: TimeoutError – When unable to make our first advertise request to Hyperbahn. Subsequent requests may fail but will be ignored.
- routers (list) – A seed list of known Hyperbahn addresses to attempt contact with.
Entries should be of the form
-
class
tchannel.singleton.
TChannel
[source]¶ Maintain a single TChannel instance per-thread.
-
tchannel_cls
¶ alias of
TChannel
-
classmethod
prepare
(*args, **kwargs)[source]¶ Set arguments to be used when instantiating a TChannel instance.
Arguments are the same as
tchannel.TChannel.__init__()
.
-
-
class
tchannel.
Request
(body=None, headers=None, transport=None, endpoint=None, service=None, timeout=None)[source]¶ A TChannel request.
This is sent by callers and received by registered handlers.
Variables: - body – The payload of this request. The type of this attribute depends on the scheme being used (e.g., JSON, Thrift, etc.).
- headers – A dictionary of application headers. This should be a mapping of strings to strings.
- transport –
Protocol-level transport headers. These are used for routing over Hyperbahn.
The most useful piece of information here is probably
request.transport.caller_name
, which is the identity of the application that created this request. - service – Name of the service being called. Inside request handlers, this is usually the name of “this” service itself. However, for services that simply forward requests to other services, this is the name of the target service.
- timeout – Amount of time (in seconds) within which this request is expected to finish.
-
class
tchannel.
Response
(body=None, headers=None, transport=None, status=None)[source]¶ A TChannel response.
This is sent by handlers and received by callers.
Variables: - body – The payload of this response. The type of this attribute depends on the scheme being used (e.g., JSON, Thrift, etc.).
- headers – A dictionary of application headers. This should be a mapping of strings to strings.
- transport – Protocol-level transport headers. These are used for routing over Hyperbahn.
Serialization Schemes¶
Thrift¶
-
class
tchannel.schemes.
ThriftArgScheme
(tchannel)[source]¶ Handler registration and serialization for Thrift.
Use
tchannel.thrift.load()
to parse your Thrift IDL and compile it into a module dynamically.from tchannel import thrift keyvalue = thrift.load('keyvalue.thrift', service='keyvalue')
To register a Thrift handler, use the
register()
decorator, providing a reference to the compiled service as an argument. The name of the service method should match the name of the decorated function.tchannel = TChannel(...) @tchannel.thrift.register(keyvalue.KeyValue) def setValue(request): data[request.body.key] = request.body.value
Use methods on the compiled service to generate requests to remote services and execute them via
TChannel.thrift()
.response = yield tchannel.thrift( keyvalue.KeyValue.setValue(key='foo', value='bar') )
-
__call__
(*args, **kwargs)[source]¶ Make a Thrift TChannel request.
Returns a
Response
containing the return value of the Thrift call (if any). If the remote server responded with a Thrift exception, that exception is raised.Parameters: - request (string) – Request obtained by calling a method on service objects generated
by
tchannel.thrift.load()
. - headers (dict) – Dictionary of header key-value pairs.
- timeout (float) – How long to wait (in seconds) before raising a
TimeoutError
- this defaults totchannel.glossary.DEFAULT_TIMEOUT
. - retry_on (string) – What events to retry on - valid values can be found in
tchannel.retry
. - retry_limit (int) –
How many attempts should be made (in addition to the initial attempt) to re-send this request when retryable error conditions (specified by
retry_on
) are encountered.Defaults to
tchannel.retry.DEFAULT_RETRY_LIMIT
(4).Note that the maximum possible time elapsed for a request is thus
(retry_limit + 1) * timeout
. - shard_key (string) – Set the
sk
transport header for Ringpop request routing. - trace (int) – Flags for tracing.
- hostport (string) – A ‘host:port’ value to use when making a request directly to a
TChannel service, bypassing Hyperbahn. This value takes precedence
over the
hostport
specified totchannel.thrift.load()
. - routing_delegate – Name of a service to which the request router should forward the request instead of the service specified in the call req.
- caller_name – Name of the service making the request. Defaults to the name provided when the TChannel was instantiated.
Return type: - request (string) – Request obtained by calling a method on service objects generated
by
-
-
tchannel.thrift.
load
(path, service=None, hostport=None, module_name=None)[source]¶ Loads the Thrift file at the specified path.
The file is compiled in-memory and a Python module containing the result is returned. It may be used with
TChannel.thrift
. For example,from tchannel import TChannel, thrift # Load our server's interface definition. donuts = thrift.load(path='donuts.thrift') # We need to specify a service name or hostport because this is a # downstream service we'll be calling. coffee = thrift.load(path='coffee.thrift', service='coffee') tchannel = TChannel('donuts') @tchannel.thrift.register(donuts.DonutsService) @tornado.gen.coroutine def submitOrder(request): args = request.body if args.coffee: yield tchannel.thrift( coffee.CoffeeService.order(args.coffee) ) # ...
The returned module contains, one top-level type for each struct, enum, union, exeption, and service defined in the Thrift file. For each service, the corresponding class contains a classmethod for each function defined in that service that accepts the arguments for that function and returns a
ThriftRequest
capable of being sent viaTChannel.thrift
.For more information on what gets generated by
load
, see thriftrw.Note that the
path
accepted byload
must be either an absolute path or a path relative to the the current directory. If you need to refer to Thrift files relative to the Python module in whichload
was called, use the__file__
magic variable.# Given, # # foo/ # myservice.thrift # bar/ # x.py # # Inside foo/bar/x.py, path = os.path.join( os.path.dirname(__file__), '../myservice.thrift' )
The returned value is a valid Python module. You can install the module by adding it to the
sys.modules
dictionary. This will allow importing items from this module directly. You can use the__name__
magic variable to make the generated module a submodule of the current module. For example,# foo/bar.py import sys from tchannel import thrift donuts = = thrift.load('donuts.thrift') sys.modules[__name__ + '.donuts'] = donuts
This installs the module generated for
donuts.thrift
as the modulefoo.bar.donuts
. Callers can then import items from that module directly. For example,# foo/baz.py from foo.bar.donuts import DonutsService, Order def baz(tchannel): return tchannel.thrift( DonutsService.submitOrder(Order(..)) )
Parameters: - service (str) – Name of the service that the Thrift file represents. This name will be used to route requests through Hyperbahn.
- path (str) – Path to the Thrift file. If this is a relative path, it must be relative to the current directory.
- hostport (str) – Clients can use this to specify the hostport at which the service can be found. If omitted, TChannel will route the requests through known peers. This value is ignored by servers.
- module_name (str) – Name used for the generated Python module. Defaults to the name of the Thrift file.
-
tchannel.
thrift_request_builder
(*args, **kwargs)[source]¶ Provide TChannel compatibility with Thrift-generated modules.
The service this creates is meant to be used with TChannel like so:
from tchannel import TChannel, thrift_request_builder from some_other_service_thrift import some_other_service tchannel = TChannel('my-service') some_service = thrift_request_builder( service='some-other-service', thrift_module=some_other_service ) resp = tchannel.thrift( some_service.fetchPotatoes() )
Deprecated since version 0.18.0: Please switch to
tchannel.thrift.load()
.Warning
This API is deprecated and will be removed in a future version.
Parameters: - service (string) – Name of Thrift service to call. This is used internally for grouping and stats, but also to route requests over Hyperbahn.
- thrift_module – The top-level module of the Apache Thrift generated code for the service that will be called.
- hostport (string) – When calling the Thrift service directly, and not over Hyperbahn, this ‘host:port’ value should be provided.
- thrift_class_name (string) – When the Apache Thrift generated Iface class name does not match thrift_module, then this should be provided.
JSON¶
-
class
tchannel.schemes.
JsonArgScheme
(tchannel)[source]¶ Semantic params and serialization for json.
-
__call__
(*args, **kwargs)[source]¶ Make JSON TChannel Request.
Parameters: - service (string) – Name of the service to call.
- endpoint (string) – Endpoint to call on service.
- body (string) – A raw body to provide to the endpoint.
- headers (dict) – Dictionary of header key-value pairs.
- timeout (float) – How long to wait (in seconds) before raising a
TimeoutError
- this defaults totchannel.glossary.DEFAULT_TIMEOUT
. - retry_on (string) – What events to retry on - valid values can be found in
tchannel.retry
. - retry_limit (int) –
How many attempts should be made (in addition to the initial attempt) to re-send this request when retryable error conditions (specified by
retry_on
) are encountered.Defaults to
tchannel.retry.DEFAULT_RETRY_LIMIT
(4).Note that the maximum possible time elapsed for a request is thus
(retry_limit + 1) * timeout
. - hostport (string) – A ‘host:port’ value to use when making a request directly to a TChannel service, bypassing Hyperbahn.
- routing_delegate – Name of a service to which the request router should forward the request instead of the service specified in the call req.
- caller_name – Name of the service making the request. Defaults to the name provided when the TChannel was instantiated.
Return type:
-
Raw¶
-
class
tchannel.schemes.
RawArgScheme
(tchannel)[source]¶ Semantic params and serialization for raw.
-
__call__
(*args, **kwargs)[source]¶ Make a raw TChannel request.
The request’s headers and body are treated as raw bytes and not serialized/deserialized.
The request’s headers and body are treated as raw bytes and not serialized/deserialized.
Parameters: - service (string) – Name of the service to call.
- endpoint (string) – Endpoint to call on service.
- body (string) – A raw body to provide to the endpoint.
- headers (string) – A raw headers block to provide to the endpoint.
- timeout (float) – How long to wait (in seconds) before raising a
TimeoutError
- this defaults totchannel.glossary.DEFAULT_TIMEOUT
. - retry_on (string) – What events to retry on - valid values can be found in
tchannel.retry
. - retry_limit (int) –
How many attempts should be made (in addition to the initial attempt) to re-send this request when retryable error conditions (specified by
retry_on
) are encountered.Defaults to
tchannel.retry.DEFAULT_RETRY_LIMIT
(4).Note that the maximum possible time elapsed for a request is thus
(retry_limit + 1) * timeout
. - hostport (string) – A ‘host:port’ value to use when making a request directly to a TChannel service, bypassing Hyperbahn.
- routing_delegate – Name of a service to which the request router should forward the request instead of the service specified in the call req.
- caller_name – Name of the service making the request. Defaults to the name provided when the TChannel was instantiated.
Return type:
-
Exception Handling¶
Errors¶
-
tchannel.errors.
TIMEOUT
= 1¶ The request timed out.
-
tchannel.errors.
CANCELED
= 2¶ The request was canceled.
-
tchannel.errors.
BUSY
= 3¶ The server was busy.
-
tchannel.errors.
BAD_REQUEST
= 6¶ The request was bad.
-
tchannel.errors.
NETWORK_ERROR
= 7¶ There was a network error when sending the request.
-
tchannel.errors.
UNHEALTHY
= 8¶ The server handling the request is unhealthy.
-
tchannel.errors.
FATAL
= 255¶ There was a fatal protocol-level error.
-
exception
tchannel.errors.
TChannelError
(description=None, id=None, tracing=None)[source]¶ Bases:
exceptions.Exception
A TChannel-generated exception.
Variables: code – The error code for this error. See the Specification for a description of these codes.
-
exception
tchannel.errors.
RetryableError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.TChannelError
An error where the original request is always safe to retry.
It is always safe to retry a request with this category of errors. The original request was never handled.
-
exception
tchannel.errors.
MaybeRetryableError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.TChannelError
An error where the original request may be safe to retry.
The original request may have reached the intended service. Hence, the request should only be retried if it is known to be idempotent.
-
exception
tchannel.errors.
NotRetryableError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.TChannelError
An error where the original request should not be re-sent.
Something was fundamentally wrong with the request and it should not be retried.
-
exception
tchannel.errors.
ReadError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.FatalProtocolError
Raised when there is an error while reading input.
-
exception
tchannel.errors.
InvalidChecksumError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.FatalProtocolError
Represent invalid checksum type in the message
-
exception
tchannel.errors.
NoAvailablePeerError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.RetryableError
Represents a failure to find any peers for a request.
-
exception
tchannel.errors.
AlreadyListeningError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.FatalProtocolError
Raised when attempting to listen multiple times.
-
exception
tchannel.errors.
OneWayNotSupportedError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.BadRequestError
Raised when a one-way Thrift procedure is called.
-
exception
tchannel.errors.
ValueExpectedError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.BadRequestError
Raised when a non-void Thrift response contains no value.
-
exception
tchannel.errors.
SingletonNotPreparedError
(description=None, id=None, tracing=None)[source]¶ Bases:
tchannel.errors.TChannelError
Raised when calling get_instance before calling prepare.
Retry Behavior¶
These values can be passed as the retry_on
behavior to
tchannel.TChannel.call()
.
-
tchannel.retry.
CONNECTION_ERROR
= u'c'¶ Retry the request on failures to connect to a remote host. This is the default retry behavior.
-
tchannel.retry.
NEVER
= u'n'¶ Never retry the request.
-
tchannel.retry.
TIMEOUT
= u't'¶ Retry the request on timeouts waiting for a response.
-
tchannel.retry.
CONNECTION_ERROR_AND_TIMEOUT
= u'ct'¶ Retry the request on failures to connect and timeouts after connecting.
-
tchannel.retry.
DEFAULT_RETRY_LIMIT
= 4¶ The default number of times to retry a request. This is in addition to the original request.
Synchronous Client¶
-
class
tchannel.sync.
TChannel
(name, hostport=None, process_name=None, known_peers=None, trace=False, threadloop=None)[source]¶ Make synchronous TChannel requests.
This client does not support incoming requests – it is a uni-directional client only.
The client is implemented on top of the Tornado-based implementation and offloads IO to a thread running an
IOLoop
next to your process.Usage mirrors the
TChannel
class.from tchannel.sync import TChannel tchannel = TChannel(name='my-synchronous-service') # Advertise with Hyperbahn. # This returns a future. You may want to block on its result, # particularly if you want you app to die on unsuccessful # advertisement. tchannel.advertise(routers) # keyvalue is the result of a call to ``tchannel.thrift.load``. future = tchannel.thrift( keyvalue.KeyValue.getItem('foo'), timeout=0.5, # 0.5 seconds ) result = future.result()
Fanout can be accomplished by using
as_completed
from theconcurrent.futures
module:from concurrent.futures import as_completed from tchannel.sync import TChannel tchannel = TChannel(name='my-synchronous-service') futures = [ tchannel.thrift(service.getItem(item)) for item in ('foo', 'bar') ] for future in as_completed(futures): print future.result()
(
concurrent.futures
is native to Python 3;pip install futures
if you’re using Python 2.x.)-
advertise
(routers=None, name=None, timeout=None, router_file=None, jitter=None)[source]¶ Advertise with Hyperbahn.
After a successful advertisement, Hyperbahn will establish long-lived connections with your application. These connections are used to load balance inbound and outbound requests to other applications on the Hyperbahn network.
Re-advertisement happens periodically after calling this method (every minute). Hyperbahn will eject us from the network if it doesn’t get a re-advertise from us after 5 minutes.
This function may be called multiple times if it fails. If it succeeds, all consecutive calls are ignored.
Parameters: - routers (list) – A seed list of known Hyperbahn addresses to attempt contact with.
Entries should be of the form
"host:port"
. - name (string) – The name your application identifies itself as. This is usually
unneeded because in the common case it will match the
name
you initialized theTChannel
instance with. This is the identifier other services will use to make contact with you. - timeout – The timeout (in sec) for the initial advertise attempt. Defaults to 30 seconds.
- jitter – Variance allowed in the interval per request. Defaults to 5 seconds. The jitter applies to the initial advertise request as well.
- router_file – The host file that contains the routers information. The file should contain a JSON stringified format of the routers parameter. Either routers or router_file should be provided. If both provided, a ValueError will be raised.
Returns: A future that resolves to the remote server’s response after the first advertise finishes.
Raises: TimeoutError – When unable to make our first advertise request to Hyperbahn. Subsequent requests may fail but will be ignored.
- routers (list) – A seed list of known Hyperbahn addresses to attempt contact with.
Entries should be of the form
-
call
(*args, **kwargs)[source]¶ Make low-level requests to TChannel services.
Note: Usually you would interact with a higher-level arg scheme like
tchannel.schemes.JsonArgScheme
ortchannel.schemes.ThriftArgScheme
.
-
-
class
tchannel.sync.singleton.
TChannel
[source]¶ -
tchannel_cls
¶ alias of
TChannel
-
classmethod
get_instance
()[source]¶ Get a configured, thread-safe, singleton TChannel instance.
Returns: tchannel.sync.TChannel
-
prepare
(*args, **kwargs)[source]¶ Set arguments to be used when instantiating a TChannel instance.
Arguments are the same as
tchannel.TChannel.__init__()
.
-