{ "info": { "author": "AaylaSecura1138", "author_email": "aayla.secura.1138@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "# Overview\n\n`mixnmatchttp` is a modular HTTP/S server based on [Python's http\nserver](https://docs.python.org/3/library/http.server.html) that lets you \"mix\n'n' match\" various functionalities. It defines several request handlers, which\nare wrappers around `http.server.SimpleHTTPRequestHandler`, as well as\na `ThreadingHTTPServer` which can be used in place of Python's\n`http.server.HTTPServer` for multi-threading support.\n\n# Quick start\n\nRequest handlers define special endpoints and/or templates as class attributes.\n\nEndpoints are the RESTful API of the server. A request which does not map to an\nendpoint is treated as a request for a file or directory (Python's http server\nhandles it, unless your class overrides the `do_(GET|POST|...)` methods).\nA request which does map to an endpoint will call an endpoint handler: a method\nof your class by the name `do_{underscope-separated path}` with \"path\" being\nthe most-specific (longest) path for which a method is defined. E.g.\n`/foo/bar/baz` will try to call `do_foo_bar_baz`, then `do_foo_bar`, then\n`do_foo`, and finally `do_default`. `do_default` is defined in\n`BaseHTTPRequestHandler` but your class may want to override it.\n\nTemplate pages are parametrized response bodies. Templates specify a template\npage to be used with and give a dictionary of parameters and values to use with\nthe template. Each parameter value may also contain dynamic parameters, which\nare given to the `BaseHTTPRequestHandler.page_from_template` method, which\nconstructs the final page.\n\nYou can inherit from one or more of the `*HTTPRequestHandlers`. Each parent's\nendpoints/templates will be copied to, without overwriting, your child class'\nendpoints/templates.\n\n---\n\n**Important notes:**\n\n * If you need to override any of the HTTP method handlers (e.g. `do_GET`),\n you must decorate them with `mixnmatchttp.handlers.base.methodhandler`, as\n shown in the demo below. And if you need to call any of the parent's HTTP\n method handlers you must call the original wrapped method using the\n `__wrapped__` attribute, as shown in the demo.\n\n---\n\n## Defining endpoints\n\nEndpoints, templates and template pages constructors have the same signature as\nfor a dictionary. Endpoints are of type `mixnmatchttp.endpoints.Endpoint`,\nwhile templates and template pages are of type\n`mixnmatchttp.common.DictNoClobber`. However, you can define them as\na dictionary, or any type which has a dictionary-like interface, and\n`BaseHTTPRequestHandler`'s meta class will convert them to the appropriate\nclass.\n\nFor example you can define endpoints like so:\n\n```python\nclass MyHandler(BaseHTTPRequestHandler):\n _endpoints = mixnmatchttp.endpoints.Endpoint(\n some_sub={\n '$allowed_methods': {'GET', 'POST'},\n '$nargs': 1,\n 'some_sub_sub': {\n '$nargs': endpoints.ARGS_ANY,\n '$raw_args': True, # don't canonicalize rest of path\n }\n },\n some_other_sub={})\n```\n\nor like so:\n\n```python\nclass MyHandler(BaseHTTPRequestHandler):\n _endpoints = mixnmatchttp.endpoints.Endpoint({\n 'some_sub': {\n '$allowed_methods': {'GET', 'POST'},\n '$nargs': 1,\n 'some_sub_sub': {\n '$nargs': endpoints.ARGS_ANY,\n '$raw_args': True, # don't canonicalize rest of path\n }\n },\n },\n some_other_sub={})\n```\n\nor like so:\n\n```python\nclass MyHandler(BaseHTTPRequestHandler):\n _endpoints = {\n 'some_sub': {\n '$allowed_methods': {'GET', 'POST'},\n '$nargs': 1,\n 'some_sub_sub': {\n '$nargs': endpoints.ARGS_ANY,\n '$raw_args': True, # don't canonicalize rest of path\n }\n },\n 'some_other_sub': {}\n }\n```\n\n\nAny keyword arguments or dictionary keys starting with `$` correspond to an\nattribute (without the `$`) which specifies how an endpoint can be called.\nAll other keyword arguments/keys become child endpoints of the parent; their\nvalue should be another `Endpoint` (or any dictionary-like object).\n\nDefault endpoint attributes are:\n\n```python\ndisabled=False|True # specifies if the enpoint cannot be called directly;\n # False for child endpoints but True for root endpoint\nallowed_methods={'GET','HEAD'} # a set of allowed HTTP methods; HEAD is added to the\n # set if 'GET' is present\nnargs=0 # how many slash-separated arguments the endpoint can take;\n # can be a number of any of:\n # mixnmatchttp.endpoints.ARGS_OPTIONAL for 0 or 1\n # mixnmatchttp.endpoints.ARGS_ANY for any number\n # mixnmatchttp.endpoints.ARGS_REQUIRED for 1 or more\n # !!only reliable if raw_args is False!!\nraw_args=False # whether arguments should not be canonicalized,\n # e.g. /foo/..//bar/./baz will not be turned to /bar/baz\n```\n\nChild endpoints are enabled by default, the root endpoint is disabled by\ndefault; if you want it enabled, either manually change the `disabled`\nattribute, or construct it like so:\n\n```python\nclass MyHandler(BaseHTTPRequestHandler):\n _endpoints = {\n 'some_sub': { ... },\n '$disabled': False, # a request for / will now call do_ or do_default\n # instead of do_(GET|POST|...)\n }\n```\n\n## Handling parsed endpoints\n\nWhen a path resolves to an endpoint, `ep`, the corresponding endpoint handler\n(`do_???`) will be passed a single argument:\na `mixnmatchttp.endpoints.ParsedEndpoint` (inherits from\n`mixnmatchttp.endpoints.Endpoint`) initialized from the original `ep` with the\nfollowing additional attributes:\n\n * `httpreq`: the instance of `BaseHTTPRequestHandler` for this request\n * `handler`: partial of the `httpreq`'s method selected as a handler, with the\n first argument being the `ParsedEndpoint` itself\n * `root`: longest path of the endpoint (with a leading `/`) corresponding to\n a defined handler, i.e. if the path is `/foo/bar` and `do_foo` is\n selected, `root` will be `/foo`; if using `do_default`, `root` is empty (`''`).\n * `sub`: rest of the path of the endpoint without a leading `/`, e.g. `bar` or `foo/bar`\n * `args`: everything following the endpoint's path without a leading `/`\n * `argslen`: the number of arguments it was called with (length of array from `/` separated `args`)\n\n## Example: Implementing a server\n\nSome methods that you may want to override, as well as implementing a custom\nendpoint and template, are shown below for `MyHandler`:\n\n```python\n# from __future__ import unicode_literals\nfrom __future__ import print_function\nfrom __future__ import division\nfrom __future__ import absolute_import\nfrom builtins import *\nfrom future import standard_library\nstandard_library.install_aliases()\nimport re\nimport ssl\nfrom http.server import HTTPServer\nfrom mixnmatchttp.servers import ThreadingHTTPServer\nfrom mixnmatchttp import endpoints\nfrom mixnmatchttp.handlers import BaseHTTPRequestHandler,methodhandler\nfrom mixnmatchttp.common import DictNoClobber\n\nclass MyHandler(BaseHTTPRequestHandler):\n _endpoints = endpoints.Endpoint(\n foobar={ }, # will use do_default handler\n refreshme={\n '$nargs': endpoints.ARGS_OPTIONAL,\n },\n debug={\n # these are for when /debug is called\n '$allowed_methods': {'GET', 'POST'},\n '$nargs': 1,\n 'sub': { # will use do_debug handler\n # these are for when /debug/sub is called\n '$nargs': endpoints.ARGS_ANY,\n '$raw_args': True, # don't canonicalize rest of path\n }\n },\n )\n _template_pages = DictNoClobber(\n simpletxt={\n 'data':'$CONTENT',\n 'type':'text/html'\n },\n simplehtml={\n 'data':'''\n \n \n
\n \n $HEAD\n