miio.updater module

class miio.updater.OneShotServer(file, interface=None)[source]

Bases: object

A simple HTTP server for serving an update file.

The server will be started in an ephemeral port, and will only accept a single request to keep it simple.

static find_local_ip()[source]
class miio.updater.SingleFileHandler(request, client_address, server)[source]

Bases: BaseHTTPRequestHandler

A simplified handler just returning the contents of a buffer.


alias of HTTPMessage


Return the client address.


Return the current date and time formatted for a message header.


Send the blank line ending the MIME headers.


Handle multiple requests if necessary.


Decide what to do with an “Expect: 100-continue” header.

If the client is expecting a 100 Continue response, we must respond with either a 100 Continue or a final response before waiting for the request body. The default is to always respond with a 100 Continue. You can behave differently (for example, reject unauthorized requests) by overriding this method.

This method should either return True (possibly after sending a 100 Continue response) or send an error response and return False.


Handle a single HTTP request.

You normally don’t need to override this method; see the class __doc__ string for information on how to handle specific HTTP commands such as GET and POST.


Return the current time formatted for logging.

log_error(format, *args)

Log an error.

This is called when a request cannot be fulfilled. By default it passes the message on to log_message().

Arguments are the same as for log_message().

XXX This should go to the separate error log.

log_message(format, *args)

Log an arbitrary message.

This is used by all other logging functions. Override it if you have specific logging wishes.

The first argument, FORMAT, is a format string for the message to be logged. If the format string contains any % escapes requiring parameters, they should be specified as subsequent arguments (it’s just like printf!).

The client ip and current date/time are prefixed to every message.

Unicode control characters are replaced with escaped hex before writing the output to stderr.

log_request(code='-', size='-')

Log an accepted request.

This is called by send_response().


Parse a request (internal).

The request should be stored in self.raw_requestline; the results are in self.command, self.path, self.request_version and self.headers.

Return True for success, False for failure; on failure, any relevant error response has already been sent back.

send_error(*args, **kwargs)[source]

Dummy override to avoid crashing sphinx builds on invalid upstream docstring.

send_header(keyword, value)

Send a MIME header to the headers buffer.

send_response(code, message=None)

Add the response header to the headers buffer and log the response code.

Also send two standard headers with the server software version and the current date.

send_response_only(code, message=None)

Send the response header only.


Return the server software version string.

default_request_version = 'HTTP/0.9'
disable_nagle_algorithm = False
error_content_type = 'text/html;charset=utf-8'
error_message_format = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n        "http://www.w3.org/TR/html4/strict.dtd">\n<html>\n    <head>\n        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">\n        <title>Error response</title>\n    </head>\n    <body>\n        <h1>Error response</h1>\n        <p>Error code: %(code)d</p>\n        <p>Message: %(message)s.</p>\n        <p>Error code explanation: %(code)s - %(explain)s.</p>\n    </body>\n</html>\n'
monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
protocol_version = 'HTTP/1.0'
rbufsize = -1
responses = {HTTPStatus.CONTINUE: ('Continue', 'Request received, please continue'), HTTPStatus.SWITCHING_PROTOCOLS: ('Switching Protocols', 'Switching to new protocol; obey Upgrade header'), HTTPStatus.PROCESSING: ('Processing', ''), HTTPStatus.EARLY_HINTS: ('Early Hints', ''), HTTPStatus.OK: ('OK', 'Request fulfilled, document follows'), HTTPStatus.CREATED: ('Created', 'Document created, URL follows'), HTTPStatus.ACCEPTED: ('Accepted', 'Request accepted, processing continues off-line'), HTTPStatus.NON_AUTHORITATIVE_INFORMATION: ('Non-Authoritative Information', 'Request fulfilled from cache'), HTTPStatus.NO_CONTENT: ('No Content', 'Request fulfilled, nothing follows'), HTTPStatus.RESET_CONTENT: ('Reset Content', 'Clear input form for further input'), HTTPStatus.PARTIAL_CONTENT: ('Partial Content', 'Partial content follows'), HTTPStatus.MULTI_STATUS: ('Multi-Status', ''), HTTPStatus.ALREADY_REPORTED: ('Already Reported', ''), HTTPStatus.IM_USED: ('IM Used', ''), HTTPStatus.MULTIPLE_CHOICES: ('Multiple Choices', 'Object has several resources -- see URI list'), HTTPStatus.MOVED_PERMANENTLY: ('Moved Permanently', 'Object moved permanently -- see URI list'), HTTPStatus.FOUND: ('Found', 'Object moved temporarily -- see URI list'), HTTPStatus.SEE_OTHER: ('See Other', 'Object moved -- see Method and URL list'), HTTPStatus.NOT_MODIFIED: ('Not Modified', 'Document has not changed since given time'), HTTPStatus.USE_PROXY: ('Use Proxy', 'You must use proxy specified in Location to access this resource'), HTTPStatus.TEMPORARY_REDIRECT: ('Temporary Redirect', 'Object moved temporarily -- see URI list'), HTTPStatus.PERMANENT_REDIRECT: ('Permanent Redirect', 'Object moved permanently -- see URI list'), HTTPStatus.BAD_REQUEST: ('Bad Request', 'Bad request syntax or unsupported method'), HTTPStatus.UNAUTHORIZED: ('Unauthorized', 'No permission -- see authorization schemes'), HTTPStatus.PAYMENT_REQUIRED: ('Payment Required', 'No payment -- see charging schemes'), HTTPStatus.FORBIDDEN: ('Forbidden', 'Request forbidden -- authorization will not help'), HTTPStatus.NOT_FOUND: ('Not Found', 'Nothing matches the given URI'), HTTPStatus.METHOD_NOT_ALLOWED: ('Method Not Allowed', 'Specified method is invalid for this resource'), HTTPStatus.NOT_ACCEPTABLE: ('Not Acceptable', 'URI not available in preferred format'), HTTPStatus.PROXY_AUTHENTICATION_REQUIRED: ('Proxy Authentication Required', 'You must authenticate with this proxy before proceeding'), HTTPStatus.REQUEST_TIMEOUT: ('Request Timeout', 'Request timed out; try again later'), HTTPStatus.CONFLICT: ('Conflict', 'Request conflict'), HTTPStatus.GONE: ('Gone', 'URI no longer exists and has been permanently removed'), HTTPStatus.LENGTH_REQUIRED: ('Length Required', 'Client must specify Content-Length'), HTTPStatus.PRECONDITION_FAILED: ('Precondition Failed', 'Precondition in headers is false'), HTTPStatus.REQUEST_ENTITY_TOO_LARGE: ('Request Entity Too Large', 'Entity is too large'), HTTPStatus.REQUEST_URI_TOO_LONG: ('Request-URI Too Long', 'URI is too long'), HTTPStatus.UNSUPPORTED_MEDIA_TYPE: ('Unsupported Media Type', 'Entity body in unsupported format'), HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE: ('Requested Range Not Satisfiable', 'Cannot satisfy request range'), HTTPStatus.EXPECTATION_FAILED: ('Expectation Failed', 'Expect condition could not be satisfied'), HTTPStatus.IM_A_TEAPOT: ("I'm a Teapot", 'Server refuses to brew coffee because it is a teapot.'), HTTPStatus.MISDIRECTED_REQUEST: ('Misdirected Request', 'Server is not able to produce a response'), HTTPStatus.UNPROCESSABLE_ENTITY: ('Unprocessable Entity', ''), HTTPStatus.LOCKED: ('Locked', ''), HTTPStatus.FAILED_DEPENDENCY: ('Failed Dependency', ''), HTTPStatus.TOO_EARLY: ('Too Early', ''), HTTPStatus.UPGRADE_REQUIRED: ('Upgrade Required', ''), HTTPStatus.PRECONDITION_REQUIRED: ('Precondition Required', 'The origin server requires the request to be conditional'), HTTPStatus.TOO_MANY_REQUESTS: ('Too Many Requests', 'The user has sent too many requests in a given amount of time ("rate limiting")'), HTTPStatus.REQUEST_HEADER_FIELDS_TOO_LARGE: ('Request Header Fields Too Large', 'The server is unwilling to process the request because its header fields are too large'), HTTPStatus.UNAVAILABLE_FOR_LEGAL_REASONS: ('Unavailable For Legal Reasons', 'The server is denying access to the resource as a consequence of a legal demand'), HTTPStatus.INTERNAL_SERVER_ERROR: ('Internal Server Error', 'Server got itself in trouble'), HTTPStatus.NOT_IMPLEMENTED: ('Not Implemented', 'Server does not support this operation'), HTTPStatus.BAD_GATEWAY: ('Bad Gateway', 'Invalid responses from another server/proxy'), HTTPStatus.SERVICE_UNAVAILABLE: ('Service Unavailable', 'The server cannot process the request due to a high load'), HTTPStatus.GATEWAY_TIMEOUT: ('Gateway Timeout', 'The gateway server did not receive a timely response'), HTTPStatus.HTTP_VERSION_NOT_SUPPORTED: ('HTTP Version Not Supported', 'Cannot fulfill request'), HTTPStatus.VARIANT_ALSO_NEGOTIATES: ('Variant Also Negotiates', ''), HTTPStatus.INSUFFICIENT_STORAGE: ('Insufficient Storage', ''), HTTPStatus.LOOP_DETECTED: ('Loop Detected', ''), HTTPStatus.NOT_EXTENDED: ('Not Extended', ''), HTTPStatus.NETWORK_AUTHENTICATION_REQUIRED: ('Network Authentication Required', 'The client needs to authenticate to gain network access')}
server_version = 'BaseHTTP/0.6'
sys_version = 'Python/3.9.18'
timeout = None
wbufsize = 0
weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']