class NetcoreTransportConfig(Transport.CONFIG_CLASS): twisted_endpoint = ConfigServerEndpoint( 'The endpoint to listen on.', required=True, static=True, fallbacks=[ServerEndpointFallback()]) web_path = ConfigText("The path to serve this resource on.", default='/api/v1/netcore/', static=True) health_path = ConfigText("The path to serve the health resource on.", default='/health/', static=True) reject_none = ConfigBool( "Reject messages where the content parameter equals 'None'", required=False, default=True, static=True) # TODO: Deprecate these fields when confmodel#5 is done. host = ConfigText( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True) port = ConfigInt( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True)
class TruteqTransportConfig(Transport.CONFIG_CLASS): username = ConfigText( 'Username of the TruTeq account to connect to.', static=True) password = ConfigText( 'Password for the TruTeq account.', static=True) twisted_endpoint = ConfigClientEndpoint( 'The endpoint to connect to.', default='tcp:host=sms.truteq.com:port=50008', static=True, fallbacks=[ClientEndpointFallback()]) link_check_period = ConfigInt( 'Number of seconds between link checks sent to the server.', default=60, static=True) ussd_session_lifetime = ConfigInt( 'Maximum number of seconds to retain USSD session information.', default=300, static=True) debug = ConfigBool( 'Print verbose log output.', default=False, static=True) redis_manager = ConfigDict( 'How to connect to Redis.', default={}, static=True) # TODO: Deprecate these fields when confmodel#5 is done. host = ConfigText( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True) port = ConfigInt( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True)
class HttpApiConfig(HttpRpcTransport.CONFIG_CLASS): "HTTP API configuration." reply_expected = ConfigBool( "True if a reply message is expected.", default=False, static=True) allowed_fields = ConfigList( "The list of fields a request is allowed to contain. Defaults to the" " DEFAULT_ALLOWED_FIELDS class attribute.", static=True) field_defaults = ConfigDict( "Default values for fields not sent by the client.", default={}, static=True)
class SubmitShortMessageProcessorConfig(Config): submit_sm_encoding = ConfigText( 'How to encode the SMS before putting on the wire', static=True, default='utf-8') submit_sm_data_coding = ConfigInt( 'What data_coding value to tell the SMSC we\'re using when putting' 'an SMS on the wire', static=True, default=0) send_long_messages = ConfigBool( "If `True`, messages longer than 254 characters will be sent in the " "`message_payload` optional field instead of the `short_message` " "field. Default is `False`, simply because that maintains previous " "behaviour.", default=False, static=True) send_multipart_sar = ConfigBool( "If `True`, messages longer than 140 bytes will be sent as a series " "of smaller messages with the sar_* parameters set. Default is " "`False`.", default=False, static=True) send_multipart_udh = ConfigBool( "If `True`, messages longer than 140 bytes will be sent as a series " "of smaller messages with the user data headers. Default is `False`.", default=False, static=True) multipart_sar_reference_rollover = ConfigInt( "The value at which the reference number of a multi part SMS will " "roll over. eg. a value of 2 will result in a series 0, 1, 0, 1 ...", default=0x10000, static=True) def post_validate(self): long_message_params = ('send_long_messages', 'send_multipart_sar', 'send_multipart_udh') set_params = [p for p in long_message_params if getattr(self, p)] if len(set_params) > 1: params = ', '.join(set_params) self.raise_config_error( "The following parameters are mutually exclusive: %s" % params)
class TransportConfig(BaseWorker.CONFIG_CLASS): """Base config definition for transports. You should subclass this and add transport-specific fields. """ transport_name = ConfigText( "The name this transport instance will use to create its queues.", required=True, static=True) publish_status = ConfigBool( "Whether status messages should be published by the transport", default=False, static=True)
class DeliveryReportProcessorConfig(Config): DELIVERY_REPORT_REGEX = ('id:(?P<id>[^ ]{,65})' '(?: +sub:(?P<sub>[^ ]+))?' '(?: +dlvrd:(?P<dlvrd>[^ ]+))?' '(?: +submit date:(?P<submit_date>\d*))?' '(?: +done date:(?P<done_date>\d*))?' ' +stat:(?P<stat>[A-Z]{5,7})' '(?: +err:(?P<err>[^ ]+))?' ' +[Tt]ext:(?P<text>.{,20})' '.*') DELIVERY_REPORT_STATUS_MAPPING = { # Output values should map to themselves: 'delivered': 'delivered', 'failed': 'failed', 'pending': 'pending', # SMPP `message_state` values: 'ENROUTE': 'pending', 'DELIVERED': 'delivered', 'EXPIRED': 'failed', 'DELETED': 'failed', 'UNDELIVERABLE': 'failed', 'ACCEPTED': 'delivered', 'UNKNOWN': 'pending', 'REJECTED': 'failed', # From the most common regex-extracted format: 'DELIVRD': 'delivered', 'REJECTD': 'failed', 'FAILED': 'failed', # Currently we will accept this for Yo! TODO: investigate '0': 'delivered', } delivery_report_regex = ConfigRegex( 'Regex to use for matching delivery reports', default=DELIVERY_REPORT_REGEX, static=True) delivery_report_status_mapping = ConfigDict( "Mapping from delivery report message state to" " (`delivered`, `failed`, `pending`)", default=DELIVERY_REPORT_STATUS_MAPPING, static=True) delivery_report_use_esm_class = ConfigBool( "Use `esm_class` PDU parameter to determine whether a message is a" " delivery report.", default=True, static=True)
class RapidSMSRelayConfig(ApplicationWorker.CONFIG_CLASS): """RapidSMS relay configuration.""" web_path = ConfigText( "Path to listen for outbound messages from RapidSMS on.", static=True) web_port = ConfigInt( "Port to listen for outbound messages from RapidSMS on.", static=True) redis_manager = ConfigDict( "Redis manager configuration (only required if" " `allow_replies` is true)", default={}, static=True) allow_replies = ConfigBool( "Whether to support replies via the `in_reply_to` argument" " from RapidSMS.", default=True, static=True) vumi_username = ConfigText( "Username required when calling `web_path` (default: no" " authentication)", default=None) vumi_password = ConfigText("Password required when calling `web_path`", default=None) vumi_auth_method = ConfigText( "Authentication method required when calling `web_path`." "The 'basic' method is currently the only available method", default='basic') vumi_reply_timeout = ConfigInt( "Number of seconds to keep original messages in redis so that" " replies may be sent via `in_reply_to`.", default=10 * 60) allowed_endpoints = ConfigList('List of allowed endpoints to send from.', required=True, default=("default", )) rapidsms_url = ConfigUrl("URL of the rapidsms http backend.") rapidsms_username = ConfigText( "Username to use for the `rapidsms_url` (default: no authentication)", default=None) rapidsms_password = ConfigText("Password to use for the `rapidsms_url`", default=None) rapidsms_auth_method = ConfigText( "Authentication method to use with `rapidsms_url`." " The 'basic' method is currently the only available method.", default='basic') rapidsms_http_method = ConfigText( "HTTP request method to use for the `rapidsms_url`", default='POST')
class DeliverShortMessageProcessorConfig(Config): data_coding_overrides = ConfigDict( "Overrides for data_coding character set mapping. This is useful for " "setting the default encoding (0), adding additional undefined " "encodings (such as 4 or 8) or overriding encodings in cases where " "the SMSC is violating the spec (which happens a lot). Keys should " "be something that can be cast to an integer, values should be strings" "containing valid Python character encoding names.", default={}, static=True) allow_empty_messages = ConfigBool( "If True, send on empty messages as an empty unicode string. " "If False, reject empty messages as invalid.", default=False, static=True)
class DmarkUssdTransportConfig(HttpRpcTransport.CONFIG_CLASS): """Config for Dmark USSD transport.""" ussd_session_timeout = ConfigInt( "Number of seconds before USSD session information stored in Redis" " expires.", default=600, static=True) fix_to_addr = ConfigBool( "Whether or not to ensure that the to_addr is always starting with a " "* and ending with a #", default=False, static=True) redis_manager = ConfigDict("Redis client configuration.", default={}, static=True)
class MessengerTransportConfig(HttpRpcTransport.CONFIG_CLASS): access_token = ConfigText( "The access_token for the Messenger API", required=True) page_id = ConfigText( "The page id for the Messenger API", required=False, fallbacks=[SingleFieldFallback("app_id")]) app_id = ConfigText( "DEPRECATED The page app id for the Messenger API", required=False) welcome_message = ConfigDict( ("The payload for setting up a welcome message. " "Requires a page_id to be set"), required=False) retrieve_profile = ConfigBool( "Set to true to include the user profile details in " "the helper_metadata", required=False, default=False)
class AirtelUSSDTransportConfig(HttpRpcTransport.CONFIG_CLASS): airtel_username = ConfigText('The username for this transport', default=None, static=True) airtel_password = ConfigText('The password for this transport', default=None, static=True) airtel_charge = ConfigBool( 'Whether or not to charge for the responses sent.', required=False, default=False, static=True) airtel_charge_amount = ConfigInt('How much to charge', default=0, required=False, static=True) redis_manager = ConfigDict('Parameters to connect to Redis with.', default={}, required=False, static=True) session_key_prefix = ConfigText( 'The prefix to use for session key management. Specify this' 'if you are using more than 1 worker in a load-balanced' 'fashion.', default=None, static=True) ussd_session_timeout = ConfigInt('Max length of a USSD session', default=60 * 10, required=False, static=True) to_addr_pattern = ConfigText( 'A regular expression that to_addr values in messages that start a' ' new USSD session must match. Initial messages with invalid' ' to_addr values are rejected.', default=None, required=False, static=True, )
class ParlayXTransportConfig(Transport.CONFIG_CLASS): web_notification_path = ConfigText( 'Path to listen for delivery and receipt notifications on', static=True) web_notification_port = ConfigInt( 'Port to listen for delivery and receipt notifications on', default=0, static=True) notification_endpoint_uri = ConfigText( 'URI of the ParlayX SmsNotificationService in Vumi', static=True) short_code = ConfigText( 'Service activation number or short code to receive deliveries for', static=True) remote_send_uri = ConfigText( 'URI of the remote ParlayX SendSmsService', static=True) remote_notification_uri = ConfigText( 'URI of the remote ParlayX SmsNotificationService', static=True) start_notifications = ConfigBool( 'Start (and stop) the ParlayX notification service?', static=True) service_provider_service_id = ConfigText( 'Provisioned service provider service identifier', static=True) service_provider_id = ConfigText( 'Provisioned service provider identifier/username', static=True) service_provider_password = ConfigText( 'Provisioned service provider password', static=True)
class WeChatConfig(Transport.CONFIG_CLASS): api_url = ConfigText('The URL the WeChat API is accessible at.', default='https://api.wechat.com/cgi-bin/', required=False, static=True) auth_token = ConfigText( 'This WeChat app\'s auth token. ' 'Used for initial message authentication.', required=True, static=True) twisted_endpoint = ConfigServerEndpoint( 'The endpoint to listen on.', required=True, static=True, fallbacks=[ServerEndpointFallback()]) web_path = ConfigText("The path to serve this resource on.", default='/api/v1/wechat/', static=True) health_path = ConfigText("The path to serve the health resource on.", default='/health/', static=True) redis_manager = ConfigDict('Parameters to connect to Redis with.', default={}, required=False, static=True) wechat_appid = ConfigText( 'The WeChat app_id. Issued by WeChat for developer accounts ' 'to allow push API access.', required=True, static=True) wechat_secret = ConfigText( 'The WeChat secret. Issued by WeChat for developer accounts ' 'to allow push API access.', required=True, static=True) wechat_menu = ConfigDict('The menu structure to create at boot.', required=False, static=True) wechat_mask_lifetime = ConfigInt( 'How long, in seconds, to maintain an address mask for. ' '(default 1 hour)', default=60 * 60 * 1, static=True) embed_user_profile = ConfigBool( 'Whether or not to embed the WeChat User Profile info in ' 'messages received.', required=True, default=False, static=True) embed_user_profile_lang = ConfigText( 'What language to request User Profile as.', required=False, default='en', static=True) embed_user_profile_lifetime = ConfigInt( 'How long to cache User Profiles for.', default=(60 * 60), required=False, static=True) double_delivery_lifetime = ConfigInt( 'How long to keep track of Message IDs and responses for double ' 'delivery tracking.', default=(60 * 60), required=False, static=True) # TODO: Deprecate these fields when confmodel#5 is done. host = ConfigText( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True) port = ConfigInt( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True)
class SmppTransportConfig(Transport.CONFIG_CLASS): DELIVERY_REPORT_REGEX = ( 'id:(?P<id>\S{,65})' ' +sub:(?P<sub>...)' ' +dlvrd:(?P<dlvrd>...)' ' +submit date:(?P<submit_date>\d*)' ' +done date:(?P<done_date>\d*)' ' +stat:(?P<stat>[A-Z]{7})' ' +err:(?P<err>...)' ' +[Tt]ext:(?P<text>.{,20})' '.*' ) DELIVERY_REPORT_STATUS_MAPPING = { # Output values should map to themselves: 'delivered': 'delivered', 'failed': 'failed', 'pending': 'pending', # SMPP `message_state` values: 'ENROUTE': 'pending', 'DELIVERED': 'delivered', 'EXPIRED': 'failed', 'DELETED': 'failed', 'UNDELIVERABLE': 'failed', 'ACCEPTED': 'delivered', 'UNKNOWN': 'pending', 'REJECTED': 'failed', # From the most common regex-extracted format: 'DELIVRD': 'delivered', 'REJECTD': 'failed', # Currently we will accept this for Yo! TODO: investigate '0': 'delivered', } twisted_endpoint = ConfigClientEndpoint( 'The SMPP endpoint to connect to.', required=True, static=True, fallbacks=[ClientEndpointFallback()]) system_id = ConfigText( 'User id used to connect to the SMPP server.', required=True, static=True) password = ConfigText( 'Password for the system id.', required=True, static=True) system_type = ConfigText( "Additional system metadata that is passed through to the SMPP " "server on connect.", default="", static=True) interface_version = ConfigText( "SMPP protocol version. Default is '34' (i.e. version 3.4).", default="34", static=True) service_type = ConfigText( 'The SMPP service type', default="", static=True) dest_addr_ton = ConfigInt( 'Destination TON (type of number)', default=0, static=True) dest_addr_npi = ConfigInt( 'Destination NPI (number plan identifier). ' 'Default 1 (ISDN/E.164/E.163)', default=1, static=True) source_addr_ton = ConfigInt( 'Source TON (type of number)', default=0, static=True) source_addr_npi = ConfigInt( 'Source NPI (number plan identifier)', default=0, static=True) registered_delivery = ConfigBool( 'Whether or not to request delivery reports', default=True, static=True) smpp_bind_timeout = ConfigInt( 'How long to wait for a succesful bind', default=30, static=True) smpp_enquire_link_interval = ConfigInt( "Number of seconds to delay before reconnecting to the server after " "being disconnected. Default is 5s. Some WASPs, e.g. Clickatell " "require a 30s delay before reconnecting. In these cases a 45s " "initial_reconnect_delay is recommended.", default=55, static=True) initial_reconnect_delay = ConfigInt( 'How long to wait between reconnecting attempts', default=5, static=True) third_party_id_expiry = ConfigInt( 'How long (seconds) to keep 3rd party message IDs around to allow for ' 'matching submit_sm_resp and delivery report messages. Defaults to ' '1 week', default=(60 * 60 * 24 * 7), static=True) delivery_report_regex = ConfigRegex( 'What regex to use for matching delivery reports', default=DELIVERY_REPORT_REGEX, static=True) delivery_report_status_mapping = ConfigDict( "Mapping from delivery report message state to " "(`delivered`, `failed`, `pending`)", static=True, default=DELIVERY_REPORT_STATUS_MAPPING) submit_sm_expiry = ConfigInt( 'How long (seconds) to wait for the SMSC to return with a ' '`submit_sm_resp`. Defaults to 24 hours', default=(60 * 60 * 24), static=True) submit_sm_encoding = ConfigText( 'How to encode the SMS before putting on the wire', static=True, default='utf-8') submit_sm_data_coding = ConfigInt( 'What data_coding value to tell the SMSC we\'re using when putting' 'an SMS on the wire', static=True, default=0) data_coding_overrides = ConfigDict( "Overrides for data_coding character set mapping. This is useful for " "setting the default encoding (0), adding additional undefined " "encodings (such as 4 or 8) or overriding encodings in cases where " "the SMSC is violating the spec (which happens a lot). Keys should " "be integers, values should be strings containing valid Python " "character encoding names.", default={}, static=True) send_long_messages = ConfigBool( "If `True`, messages longer than 254 characters will be sent in the " "`message_payload` optional field instead of the `short_message` " "field. Default is `False`, simply because that maintains previous " "behaviour.", default=False, static=True) send_multipart_sar = ConfigBool( "If `True`, messages longer than 140 bytes will be sent as a series " "of smaller messages with the sar_* parameters set. Default is " "`False`.", default=False, static=True) send_multipart_udh = ConfigBool( "If `True`, messages longer than 140 bytes will be sent as a series " "of smaller messages with the user data headers. Default is `False`.", default=False, static=True) split_bind_prefix = ConfigText( "This is the Redis prefix to use for storing things like sequence " "numbers and message ids for delivery report handling. It defaults " "to `<system_id>@<host>:<port>`. " "*ONLY* if the connection is split into two separate binds for RX " "and TX then make sure this is the same value for both binds. " "This _only_ needs to be done for TX & RX since messages sent via " "the TX bind are handled by the RX bind and they need to share the " "same prefix for the lookup for message ids in delivery reports to " "work.", default='', static=True) throttle_delay = ConfigFloat( "Delay (in seconds) before retrying a message after receiving " "`ESME_RTHROTTLED` or `ESME_RMSGQFUL`.", default=0.1, static=True) COUNTRY_CODE = ConfigText( "Used to translate a leading zero in a destination MSISDN into a " "country code. Default ''", default="", static=True) OPERATOR_PREFIX = ConfigDict( "Nested dictionary of prefix to network name mappings. Default {} " "(set network to 'UNKNOWN'). E.g. { '27': { '27761': 'NETWORK1' }} ", default={}, static=True) OPERATOR_NUMBER = ConfigDict( "Dictionary of source MSISDN to use for each network listed in " "OPERATOR_PREFIX. If a network is not listed, the source MSISDN " "specified by the message sender is used. Default {} (always used the " "from address specified by the message sender). " "E.g. { 'NETWORK1': '27761234567'}", default={}, static=True) redis_manager = ConfigDict( 'How to connect to Redis', default={}, static=True) # TODO: Deprecate these fields when confmodel#5 is done. host = ConfigText( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True) port = ConfigInt( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True) def post_validate(self): long_message_params = ( 'send_long_messages', 'send_multipart_sar', 'send_multipart_udh') set_params = [p for p in long_message_params if getattr(self, p)] if len(set_params) > 1: params = ', '.join(set_params) self.raise_config_error( "The following parameters are mutually exclusive: %s" % params)
class SmppTransportConfig(Transport.CONFIG_CLASS): twisted_endpoint = ConfigClientEndpoint( 'The SMPP endpoint to connect to.', required=True, static=True, fallbacks=[ClientEndpointFallback()]) initial_reconnect_delay = ConfigInt( 'How long (in seconds) to wait between reconnecting attempts. ' 'Defaults to 5 seconds.', default=5, static=True) throttle_delay = ConfigFloat( "Delay (in seconds) before retrying a message after receiving " "`ESME_RTHROTTLED` or `ESME_RMSGQFUL`.", default=0.1, static=True) deliver_sm_decoding_error = ConfigText( 'The error to respond with when we were unable to decode all parts ' 'of a PDU.', default='ESME_RDELIVERYFAILURE', static=True) submit_sm_expiry = ConfigInt( 'How long (in seconds) to wait for the SMSC to return with a ' '`submit_sm_resp`. Defaults to 24 hours.', default=(60 * 60 * 24), static=True) disable_ack = ConfigBool( 'Disable publishing of `ack` events. In some cases this event ' 'causes more noise than signal. It can optionally be turned off. ' 'Defaults to False.', default=False, static=True) third_party_id_expiry = ConfigInt( 'How long (in seconds) to keep 3rd party message IDs around to allow ' 'for matching submit_sm_resp and delivery report messages. Defaults ' 'to 1 week.', default=(60 * 60 * 24 * 7), static=True) final_dr_third_party_id_expiry = ConfigInt( 'How long (in seconds) to keep 3rd party message IDs around after ' 'receiving a success or failure delivery report for the message.', default=(60 * 60), static=True) completed_multipart_info_expiry = ConfigInt( 'How long (in seconds) to keep multipart message info for completed ' 'multipart messages around to avoid pending operations accidentally ' 'recreating them without an expiry time. Defaults to 1 hour.', default=(60 * 60), static=True) redis_manager = ConfigDict('How to connect to Redis.', default={}, static=True) split_bind_prefix = ConfigText( "This is the Redis prefix to use for storing things like sequence " "numbers and message ids for delivery report handling. It defaults " "to `<system_id>@<transport_name>`. " "This should *ONLY* be done for TX & RX since messages sent via " "the TX bind are handled by the RX bind and they need to share the " "same prefix for the lookup for message ids in delivery reports to " "work.", default='', static=True) codec_class = ConfigClassName( 'Which class should be used to handle character encoding/decoding. ' 'MUST implement `IVumiCodec`.', default='vumi.codecs.VumiCodec', static=True, implements=IVumiCodec) delivery_report_processor = ConfigClassName( 'Which delivery report processor to use. ' 'MUST implement `IDeliveryReportProcessor`.', default=('vumi.transports.smpp.processors.' 'DeliveryReportProcessor'), static=True, implements=IDeliveryReportProcessor) delivery_report_processor_config = ConfigDict( 'The configuration for the `delivery_report_processor`.', default={}, static=True) deliver_short_message_processor = ConfigClassName( 'Which deliver short message processor to use. ' 'MUST implement `IDeliverShortMessageProcessor`.', default='vumi.transports.smpp.processors.DeliverShortMessageProcessor', static=True, implements=IDeliverShortMessageProcessor) deliver_short_message_processor_config = ConfigDict( 'The configuration for the `deliver_short_message_processor`.', default={}, static=True) submit_short_message_processor = ConfigClassName( 'Which submit short message processor to use. ' 'Should implements `ISubmitShortMessageProcessor`.', default='vumi.transports.smpp.processors.SubmitShortMessageProcessor', static=True, implements=ISubmitShortMessageProcessor) submit_short_message_processor_config = ConfigDict( 'The configuration for the `submit_short_message_processor`.', default={}, static=True) system_id = ConfigText('User id used to connect to the SMPP server.', required=True, static=True) password = ConfigText('Password for the system id.', required=True, static=True) system_type = ConfigText( "Additional system metadata that is passed through to the SMPP " "server on connect.", default="", static=True) interface_version = ConfigText( "SMPP protocol version. Default is '34' (i.e. version 3.4).", default="34", static=True) service_type = ConfigText('The SMPP service type.', default="", static=True) address_range = ConfigText( "Address range to receive. (SMSC-specific format, default empty.)", default="", static=True) dest_addr_ton = ConfigInt('Destination TON (type of number).', default=0, static=True) dest_addr_npi = ConfigInt( 'Destination NPI (number plan identifier). ' 'Default 1 (ISDN/E.164/E.163).', default=1, static=True) source_addr_ton = ConfigInt('Source TON (type of number).', default=0, static=True) source_addr_npi = ConfigInt('Source NPI (number plan identifier).', default=0, static=True) registered_delivery = ConfigBool( 'Whether or not to request delivery reports. Default True.', default=True, static=True) smpp_bind_timeout = ConfigInt( 'How long (in seconds) to wait for a succesful bind. Default 30.', default=30, static=True) smpp_enquire_link_interval = ConfigInt( "How long (in seconds) to delay before reconnecting to the server " "after being disconnected. Some WASPs, e.g. Clickatell require a 30s " "delay before reconnecting. In these cases a 45s " "`initial_reconnect_delay` is recommended. Default 55.", default=55, static=True) mt_tps = ConfigInt( 'Mobile Terminated Transactions per Second. The Maximum Vumi ' 'messages per second to attempt to put on the wire. ' 'Defaults to 0 which means no throttling is applied. ' '(NOTE: 1 Vumi message may result in multiple PDUs)', default=0, static=True, required=False) # TODO: Deprecate these fields when confmodel#5 is done. host = ConfigText( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True) port = ConfigInt( "*DEPRECATED* 'host' and 'port' fields may be used in place of the" " 'twisted_endpoint' field.", static=True)
class WikipediaConfig(ApplicationWorker.CONFIG_CLASS): api_url = ConfigUrl( "URL for the MediaWiki API to query. This defaults to the English" " Wikipedia. Any recent enough MediaWiki installation should be fine," " although certain assumptions are made about the structure of" " articles that may not hold outside of Wikipedia.", default='https://en.wikipedia.org/w/api.php') api_timeout = ConfigInt("API call timeout in seconds.", default=5) include_url_in_sms = ConfigBool( "Include url in the first SMS", default=False ) mobi_url_host = ConfigText( "The full mobi host url that will be used instead of the fullurl", default=None ) shortening_api_url = ConfigUrl( "URL for the Praekelt URL Shortening Service", default=None ) search_backend = ConfigText( "The Wikimedia search backend to use.", default=None, required=False, static=True) accept_gzip = ConfigBool( "If `True`, the HTTP client will request gzipped responses. This is" " generally beneficial, although it requires Twisted 11.1 or later.", default=False) user_agent = ConfigText( "Value of the `User-Agent` header on API requests.", default=('vumi-wikipedia/1.0 (https://github.com/praekelt/vumi-' 'wikipedia; [email protected])')) max_session_length = ConfigInt( "Lifetime of query session in seconds. This includes the lifetime of" " the content kept for further SMS deliveries.", default=600) max_ussd_content_length = ConfigInt( "Maximum character length of ASCII USSD content.", default=160) max_ussd_unicode_length = ConfigInt( "Maximum character length of unicode USSD content.", default=70) max_sms_content_length = ConfigInt( "Maximum character length of ASCII SMS content.", default=160) max_sms_unicode_length = ConfigInt( "Maximum character length of unicode SMS content.", default=70) sentence_break_threshold = ConfigInt( "If a sentence break is found within this many characters of the end" " of the truncated message, truncate at the sentence break instead of" " a word break.", default=10) transliterate_unicode = ConfigBool( "Set this to `True` to transliterate any non-ASCII chars. Requires" " unidecode lib.", default=False) minimize_text = ConfigBool( "Set this to `True` to attempt to shorten text by removing unnecessary" " chars.", default=False) send_sms_content = ConfigBool( "Set this to `False` to suppress the sending of content via SMS.", default=True) send_more_sms_content = ConfigBool( "Set this to `False` to ignore requests for more content via SMS.", default=True) metrics_prefix = ConfigText( "Prefix for metrics names. If unset, no metrics will be collected.", static=True) content_cache_time = ConfigInt( "Lifetime of cached article content in seconds. If unset, no caching" " will be done.", static=True, default=0) redis_manager = ConfigDict( "Redis connection configuration.", static=True, default={}) msg_prompt = ConfigText( 'Initial prompt shown to the users', default=u'What would you like to search Wikipedia for?') msg_no_results = ConfigText( 'No results found message, with one string parameter', default=u'Sorry, no Wikipedia results for %s') msg_error = ConfigText( 'Generic internal error message', default=u'Sorry, there was an error processing your request.' ' Please try again later.') msg_invalid_section = ConfigText( 'User picked incorrect section', default=u'Sorry, invalid selection. Please restart and try again') msg_more_content_suffix = ConfigText( "Suffix for SMS content that can be continued. An empty string" " should be specified if there is no incoming SMS connection.", default=' (reply for more)') msg_no_more_content_suffix = ConfigText( "Suffix for SMS content that is complete. An empty string should be " " specified if there is no incoming SMS connection.", default=' (end of section)') msg_ussd_suffix = ConfigText( 'Message to add at the end of the truncated USSD result', default=u'\n(Full content sent by SMS.)') secret_key = ConfigText( 'Secret key to use when hashing the user-ids before logging.', static=True) hash_algorithm = ConfigText( 'hashlib algorithm to use for hashing the user-ids', static=True, default='sha256') user_hash_char_limit = ConfigInt( 'Limit the user-hash to how many characters. ' 'Defaults to -1 (leave as is)', static=True, default=-1)
class HttpRpcTransportConfig(Transport.CONFIG_CLASS): """Base config definition for transports. You should subclass this and add transport-specific fields. """ web_path = ConfigText("The path to listen for requests on.", static=True) web_port = ConfigInt( "The port to listen for requests on, defaults to `0`.", default=0, static=True) web_username = ConfigText( "The username to require callers to authenticate with. If ``None``" " then no authentication is required. Currently only HTTP Basic" " authentication is supported.", default=None, static=True) web_password = ConfigText( "The password to go with ``web_username``. Must be ``None`` if and" " only if ``web_username`` is ``None``.", default=None, static=True) web_auth_domain = ConfigText("The name of authentication domain.", default="Vumi HTTP RPC transport", static=True) health_path = ConfigText( "The path to listen for downstream health checks on" " (useful with HAProxy)", default='health', static=True) request_cleanup_interval = ConfigInt( "How often should we actively look for old connections that should" " manually be timed out. Anything less than `1` disables the request" " cleanup meaning that all request objects will be kept in memory" " until the server is restarted, regardless if the remote side has" " dropped the connection or not. Defaults to 5 seconds.", default=5, static=True) request_timeout = ConfigInt( "How long should we wait for the remote side generating the response" " for this synchronous operation to come back. Any connection that has" " waited longer than `request_timeout` seconds will manually be" " closed. Defaults to 4 minutes.", default=(4 * 60), static=True) request_timeout_status_code = ConfigInt( "What HTTP status code should be generated when a timeout occurs." " Defaults to `504 Gateway Timeout`.", default=504, static=True) request_timeout_body = ConfigText( "What HTTP body should be returned when a timeout occurs." " Defaults to ''.", default='', static=True) noisy = ConfigBool( "Defaults to `False` set to `True` to make this transport log" " verbosely.", default=False, static=True) validation_mode = ConfigText( "The mode to operate in. Can be 'strict' or 'permissive'. If 'strict'" " then any parameter received that is not listed in EXPECTED_FIELDS" " nor in IGNORED_FIELDS will raise an error. If 'permissive' then no" " error is raised as long as all the EXPECTED_FIELDS are present.", default='strict', static=True) def post_validate(self): auth_supplied = (self.web_username is None, self.web_password is None) if any(auth_supplied) and not all(auth_supplied): raise ConfigError("If either web_username or web_password is" " specified, both must be specified")