The FaxSender property¶
- class CallFaxSender¶
A class that provides an API for transmitting a fax on a connected call.
This class exposes a public property called
Details
of typeFaxDetails
(see below) which provides details on the fax job in progress.The call channel object uses this class to provide fax transmit functionality. The CallChannel object has a public property called
FaxSender
of this type. Please see the tutorial for examples on how to use this class.- class Cause¶
Once a fax transmit job has ended and the transmit
State
has returned toIDLE
orERROR
, theCause
will be one of these.Fax transmit termination causes are:
- ERROR
Transmit has stopped due to an error.
- NORMAL
Transmit has stopped normally.
- ABORTED
Transmit has been aborted (probably because stop was called).
- HANGUP
Transmit ended because the receiver hung up.
- TIMEOUT
Transmit stopped because a timer has expired.
- NOTFAX
The receiving end has not sent any fax signals, it is probably not a fax machine.
- UNKNOWN_OPTION
An unknown fax option was supplied.
- UNKNOWN_VALUE
A known fax option value was supplied with an incorrect value.
- INCONSISTENT_OPTIONS
Inconsistent fax options were supplied.
- STANDARDMISMATCH
A T.30 - T.38 negotiation mismatch has occurred and the call has been abandoned.
- COMMSFAULT
A fax communication error has occurred. This could be due to the receiving end not being a fax machine or due to bad line conditions. Check that the receiving end is a compatible fax machine and then try again.
- PAGEQUALITY
The Fax has been abandoned because there have been too many errors. Try again.
- NONE
Transmit is in progress or transmit has not occurred.
When passing fax options to the
send
orstart
functions, the user will supply a dictionary of name - value pairs. These names, and their corresponding values can be found in the online fax documentation. If an invalid variable name or value is supplied, or if an invalid combination of variables is supplied, the action will fail and the cause will be one ofUNKNOWN_OPTION
,UNKNOWN_VALUE
orINCONSISTENT_OPTIONS
. It is a good idea to check for these causes as one of them would normally require a correction to the application. An example is given below.This combination would make faxing impossible:
fax_options = { 'v17':'NO', 'MinDataRate':'14400' } if channel.FaxSender.start(fax_to_send=fax_to_send, fax_options=fax_options) is False: cause = channel.FaxSender.cause() if cause == channel.FaxSender.Cause.INCONSISTENT_OPTIONS: raise Error("This combination of options is not allowed: {0}".format(repr(channel.FaxSender.Details.failed_option)))
Sometimes a fax session will fail because the other end is not a fax machine (for example, an outbound fax call is answered by a human); In this case the cause will be
NOTFAX
, for example:cause = channel.FaxSender.wait_until_finished() if cause == channel.FaxSender.Cause.NOTFAX: raise Hangup("Hang up because other end is not a fax machine")
A fax session can also fail because the line quality is simply too bad for a fax to succeed. For these cases we have the causes
COMMSFAULT
andPAGEQUALITY
. If a fax session fails and the cause isCOMMSFAULT
, it would be worthwhile checking the line before trying again. If the cause isPAGEQUALITY
, it may be worth waiting ten minutes or so and before trying again.
- class State¶
The fax transmit state can be checked to determine whether a fax is in progress. When a fax job ends and
State
has returned toIDLE
orERROR
, the terminationCause
can be checked to find the reason why.Fax transmit states are:
- SENDING
A transmit job is in progress.
- IDLE
No transmit job is in progress.
- ERROR
The most recent transmit job failed and none is currently in progress.
- cause()¶
This function will return a cause.
When a particular job terminates, the reason why can be requested by calling this function.
If this function is called while a job is still running, the cause will be
NONE
.
- send(fax_to_send, fax_options=None)¶
Send a fax on the current connected call channel.
- Required argument:
- fax_to_send
the fax document object to send.
- Optional arguments:
- fax_options
fax configuration options for this session.
fax_to_send
is an object that is used to configure the fax document for sending. A reference to the object is passed into this function. If you are not familiar with the fax document object, please read up on it before continuing.fax_options
is a dictionary of name - value pairs where the name is that of a fax option and the value is what that option should be set to. Fax options would normally be set on your inbound and outbound service pages. It is, however, possible to set options from within an application. For instance, to force a high resolution fax:cause = channel.FaxSender.send(my_fax, fax_options={'HighRes':'YES'})
The list of option names, and their possible values, can be found on the online fax documentation page.
If the call state is
IDLE
, this function will raise aHangup
exception. If the call state is notIDLE
but also notANSWERED
, this function will raise anError
exception.If the send state is already
SENDING
, this function will raise anError
exception. If the call channel already has an external audio source, e.g, it is connected to another call channel, this function will raise anError
exception.This function will block until the fax has been sent or a timeout has expired.
Upon return, this function will return a
cause
.Usage example:
my_fax = FaxToSend() my_fax.set_content('my_outbound_fax.tif') cause = channel.FaxSender.send(my_fax) if cause == channel.FaxSender.Cause.NORMAL: print("the fax job ended normally") elif cause == channel.FaxSender.Cause.NOTFAX: print("the receiver was not a fax machine") else: print("the fax job failed")
- start(fax_to_send, fax_options=None)¶
Start sending a fax on the current connected call channel.
- Required argument:
- fax_to_send
the fax document object to send.
- Optional arguments:
- fax_options
fax configuration options for this session.
fax_to_send
is an object that is used to configure the fax document for sending. A reference to the object is passed into this function. If you are not familiar with the fax document object, please read up on it before continuing.fax_options
is a dictionary of name - value pairs where the name is that of a fax option and the value is what that option should be set to. Fax options would normally be set on your inbound and outbound service pages. It is, however, possible to set options from within an application. For instance, to force a high resolution fax:cause = channel.FaxSender.start(my_fax, fax_options={'HighRes':'YES'})
The list of option names, and their possible values, can be found on the online fax documentation page.
If the call state is
IDLE
, this function will raise aHangup
exception. If the call state is notIDLE
but also notANSWERED
, this function will raise anError
exception.If the send state is already
SENDING
, this function will raise anError
exception. If the call channel already has an external audio source, e.g, it is connected to another call channel, this function will raise anError
exception.This function will block until fax transmission has begun or a timeout has expired.
Upon return, this method will return True for success, otherwise False.
Usage example:
my_fax = FaxToSend() my_fax.set_content('my_outbound_fax.tif') # Start sending a fax. if channel.FaxSender.start(my_fax) == True: # while the fax is being sent, we can do something else; # and then wait for it to finish. cause = channel.FaxSender.wait_until_finished() if cause == channel.FaxSender.Cause.NORMAL: print("the fax job ended normally") elif cause == channel.FaxSender.Cause.NOTFAX: print("the receiver was not a fax machine") else: print("the fax job failed") else: # The function returned False, this probably means that # the acknowledgement to indicate that fax sending has begun # did not arrive in time, and the function has timed out. pass
- state()¶
This function will return the current state.
When a particular job is busy, its state can be tracked by calling this function.
If this function is called while when no job is in progress, the state will be
IDLE
.
- stop()¶
Stop sending the fax. The current fax session will be aborted.
If the call state is
IDLE
, this function will raise aHangup
exception. If the call state is notIDLE
but also notANSWERED
, this function will raise anError
exception.If the send state is not
SENDING
, this function will simply return True. Otherwise, this call will block until fax sending has stopped or a timeout has expired.Upon return, this method will return True for success, otherwise False.
Usage example:
# Start sending a fax and then stop it. if channel.FaxSender.start(filename="my_fax.tif") == True: # while the file is transmitting we can do something else, # ... # then, for whatever reason, stop it. channel.FaxSender.stop()
- wait_for_negotiated_settings(seconds_timeout=None)¶
Wait for the fax endpoint negotiation to be completed.
- Optional argument:
- seconds_timeout
The maximum time, in seconds, to wait.
This function will wait until the negotiated settings are available.
If the channel associated with this fax session goes to
IDLE
, this function will raise aHangup
exception,If the fax session encounters an error, this function will raise an
Error
exception.Once the negotiated settings are available, this function will return the settings dictionary. If the negotiated settings dictionary is empty, this means that fax negotiation has failed.
Usage example:
negotiated_settings = channel.FaxSender.wait_for_negotiated_settings() if negotiated_settings == {}: # negotiation has failed, we should quit and hang up. cause = channel.FaxSender.cause() raise Hangup("fax receiver returned {0}".format(cause)) for setting, value in negotiated_settings.iteritems(): print("{0:>15.15} : {1}".format(setting, value))
- wait_for_next_page(seconds_timeout=None)¶
Wait for the next fax page to be completed.
- Optional argument:
- seconds_timeout
The maximum time, in seconds, to wait.
This function will wait for the next page to be completed.
If the channel associated with this fax session is
IDLE
, this function will raise aHangup
exception.If the fax session encounters an error, this function will raise an
Error
exception.Once the next page has completed, this function will return the number of pages completed so far.
Usage example:
# We can wait for each page to be sent, we do this until we've been told # that no more pages will be sent. It is important to note that the last_page # flag does not indicate success, it simply means that no more pages will be processed. while channel.FaxSender.Details.last_page is not True: pages = channel.FaxSender.wait_for_next_page() print("Sent {0} pages so far".format(pages)) # Now we need to wait until the fax session has finished. We need to do this even though # the last page flag has been set. Remember to check the cause, the last_page indicator # may have been set, but this does not mean that every page was sent. cause = channel.FaxSender.wait_until_finished() if cause != channel.FaxSender.Cause.NORMAL: raise Error("The fax sender failed with cause {0}".format(cause))
- wait_until_finished(seconds_timeout=None)¶
Wait for the fax session to complete.
- Optional argument:
- seconds_timeout
the amount of time allocated to wait for the fax session to complete. Default is to wait forever.
This function will block until the current fax session has finished or the timeout has expired. Giving a value of
None
forseconds_timeout
will enable an infinite wait. If the timeout does expire, this function will return a cause ofTIMEOUT
.Upon return, this function will return a
cause
.This function will not raise a
HANGUP
exception if the call state is alreadyIDLE
. It is possible for there to be a brief period during which the call can beIDLE
whilst the fax session is still terminating.Usage example:
# Start sending a fax and then wait for it to finish. if channel.FaxSender.start(filename="my_fax.tif") == True: # do something else for a bit cause = channel.FaxSender.wait_until_finished() if cause == channel.FaxSender.Cause.NORMAL: print("the fax job ended normally") elif cause == channel.FaxSender.Cause.NOTFAX: print("the receiver was not a fax machine") else: print("the fax job failed")
Fax Details¶
- class FaxDetails(channel, logger)¶
Holds details of the fax session. The details are filled in as the fax progresses.
- ID
The fax ID as returned by the cloud.
- line
The connected line associated with this fax.
- fax_standard
T.30 or T.38.
- options
The fax options, this is a dictionary in the form { option:value, … }.
- failed_option
The fax options that could not be set, this is a dictionary in the form { option:value, … }.
- pages
The number of fax pages sent or received so far.
- last_page
Will be True if no more pages are to be handled during this fax session. Note: this does not imply that the fax session was successful.
- negotiated
The fax parameters that have been negotiated, this is a dictionary in the form { option:value, … }.
- raw_cause
The fax error code returned when the cause is ERROR or NOTFAX.
Usage example:
# create the fax document object my_fax = FaxToSend('my_fax.tiff') # send the fax and check the termination cause if channel.FaxSender.send(fax_to_send=my_fax) != channel.FaxSender.Cause.NORMAL: # the fax did not terminate normally, look at the raw_cause print("Fax failed with raw cause {0}".format(channel.FaxSender.Details.raw_cause))