{"id":19860315,"url":"https://github.com/toni08bit/outside","last_synced_at":"2025-08-21T07:06:01.522Z","repository":{"id":184296678,"uuid":"671577371","full_name":"toni08bit/outside","owner":"toni08bit","description":"An easy-to-use python web framework. Inspired by Flask.","archived":false,"fork":false,"pushed_at":"2025-01-24T19:06:44.000Z","size":59,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T22:12:26.725Z","etag":null,"topics":["flask","http","http-server","nginx","python3","ssl","websocket","websockets"],"latest_commit_sha":null,"homepage":"https://toni08.de/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/toni08bit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-27T16:28:28.000Z","updated_at":"2025-01-24T19:06:47.000Z","dependencies_parsed_at":"2023-07-27T20:54:41.561Z","dependency_job_id":"5e7fc8d6-c89c-4cb7-9dbc-05b67290c45a","html_url":"https://github.com/toni08bit/outside","commit_stats":null,"previous_names":["billplayztoday/outside","toni08bit/outside"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toni08bit%2Foutside","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toni08bit%2Foutside/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toni08bit%2Foutside/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toni08bit%2Foutside/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toni08bit","download_url":"https://codeload.github.com/toni08bit/outside/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251986606,"owners_count":21675950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flask","http","http-server","nginx","python3","ssl","websocket","websockets"],"created_at":"2024-11-12T15:03:55.980Z","updated_at":"2025-05-02T04:30:19.748Z","avatar_url":"https://github.com/toni08bit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `outside` Module\n\nThe `outside` module provides an HTTP and WebSocket server implementation with extensive customization options, error handling, and request/response management. It is designed to facilitate the creation of HTTP servers with dynamic routing, SSL support, and WebSocket functionality. It works similar to other projects (e.g. Flask), but does not require any other programs like nginx.\n\n## Getting Started\n\nThere is a [Quick Start](QUICKSTART.md) available.\n\n### Example Usage\n\n```python\nfrom outside import OutsideHTTP\n\n# Create an HTTP server instance\nserver = OutsideHTTP((\"127.0.0.1\", 8080))\n\n# Define a simple route handler\ndef hello_world(request):\n    return Response(\n        status_code = 200,\n        headers = {\"Content-Type\": \"text/plain\"},\n        content = \"Hello, World!\"\n    )\n\n# Add the route to the server\nserver.set_route(\"/hello\", hello_world)\n\n# Start the server\nserver.run()\n```\n\n## Contents\n- [Classes](#classes)\n  - [OutsideHTTP](#outsidehttp)\n  - [OutsideHTTP_Redirect](#outsidehttp_redirect)\n  - [WebSocket](#websocket)\n  - [WebSocketConnection](#websocketconnection)\n  - [Request](#request)\n  - [Response](#response)\n  - [ScheduledResponse](#scheduledresponse)\n  - [FilePath](#filepath)\n  - [ResponseCookie](#responsecookie)\n- [Functions](#functions)\n  - [get_insensitive_header](#get_insensitive_header)\n  - [get_description](#get_description)\n\n## Classes\n\nDISCLAIMER: Classes/Functions/Methods marked with *(!)* are typically not required to be created by the user of the module.\n\n### `OutsideHTTP`\n```python\nclass OutsideHTTP(host: tuple[str, int])\n```\nA class that represents an HTTP server with configurable settings, dynamic routing, and error handling.\n\n#### Parameters\n- `host`: A tuple containing the IP address and port where the server will be hosted.\n\n#### Methods\n\n- `set_route(route: str, handler: Callable) -\u003e None`\n  - Adds a new route to the server.\n  - **Parameters:**\n    - `route`: A string representing the URL path for the route.\n    - `handler`: A callable function that handles requests to the route.\n  - **Example:**\n    ```python\n    server.set_route(\"/api/data\", data_handler)\n    ```\n\n- `remove_route(route: str) -\u003e None`\n  - Removes an existing route from the server.\n  - **Parameters:**\n    - `route`: The route to remove.\n  - **Example:**\n    ```python\n    server.remove_route(\"/api/data\")\n    ```\n\n- `set_errorhandler(errorcode: int, handler: Callable) -\u003e None`\n  - Sets a custom error handler for a specific HTTP status code.\n  - **Parameters:**\n    - `errorcode`: HTTP status code for which the error handler is set.\n    - `handler`: A callable function that handles errors for the specified code.\n  - **Example:**\n    ```python\n    def not_found_handler(request, message=None):\n        return Response(status_code=404, headers={}, content=\"Not Found\")\n    \n    server.set_errorhandler(404, not_found_handler)\n    ```\n\n- `remove_errorhandler(errorcode: int) -\u003e None`\n  - Removes an existing error handler for a specific HTTP status code.\n  - **Parameters:**\n    - `errorcode`: The error code for which the handler will be removed.\n\n- `terminate(signum: Optional[int] = None, stackframe: Optional = None) -\u003e None`\n  - Gracefully terminates the server and all active connections.\n\n- `run() -\u003e None`\n  - Starts the HTTP server and begins listening for connections.\n  - **Example:**\n    ```python\n    # Start the HTTP server\n    server.run()\n    ```\n\n#### Attributes\n\n- `config`: A dictionary containing various server configuration options such as `host`, `backlog_length`, `max_workers`, `process_timeout`, and others.\n- `_terminate_process`: A boolean flag indicating whether the server should terminate.\n- `_active_requests`: A list of active HTTP requests.\n- `_routes`: A dictionary of routes and their corresponding handlers.\n- `_error_routes`: A dictionary of error handlers for HTTP status codes.\n\n### `OutsideHTTP_Redirect`\n```python\nclass OutsideHTTP_Redirect(host: tuple[str, int], destination: str)\n```\nA class that represents an HTTP server that redirects all incoming requests to a specified destination.\n\n#### Parameters\n- `host`: A tuple containing the IP address and port where the server will be hosted.\n- `destination`: The destination URL to which all incoming requests will be redirected.\n\n#### Methods\n\n- `run() -\u003e None`\n  - Starts the redirect server and begins listening for connections.\n\n- `terminate() -\u003e None`\n  - Terminates the redirect server.\n\n#### Example\n```python\nredirect_server = OutsideHTTP_Redirect((\"127.0.0.1\", 80), \"https://example.com\")\nredirect_server.run()\n```\n\n### `WebSocket`\n```python\nclass WebSocket\n```\nA class that facilitates WebSocket connections and message handling.\n\n#### Methods\n\n- `on_connection(handler: Callable) -\u003e None`\n  - Sets the handler function for incoming WebSocket connections.\n  - **Parameters:**\n    - `handler`: A callable function that handles WebSocket connections.\n  - **Example:**\n    ```python\n    def websocket_handler(connection):\n        while True:\n            message = connection.recv()\n            connection.send(message)  # Echo back the message\n    \n    websocket_server = WebSocket()\n    websocket_server.on_connection(websocket_handler)\n    ```\n\n- `on_exit(handler: Callable) -\u003e None`\n  - Sets the handler function to be called when the WebSocket connection is closed.\n  - **Parameters:**\n    - `handler`: A callable function that handles WebSocket exit events.\n\n### `WebSocketConnection` *(!)*\n```python\nclass WebSocketConnection(request_class: Request, http_socket: socket.socket, activity_queue: multiprocessing.Queue, terminate_function: Callable)\n```\nA class that manages an individual WebSocket connection.\n\n#### Methods\n\n- `recv() -\u003e bytes`\n  - Receives data from the WebSocket connection.\n  - **Returns:** The received data as bytes.\n\n- `send(data: bytes) -\u003e None`\n  - Sends data to the WebSocket connection.\n  - **Parameters:**\n    - `data`: The data to send, as bytes.\n\n- `exit() -\u003e None`\n  - Terminates the WebSocket connection.\n\n### `Request` *(!)*\n```python\nclass Request(method: str, headers: dict, content: bytes, version: str, url: str, address: tuple[str, int])\n```\nA class that represents an HTTP request.\n\n#### Methods\n\n- `json() -\u003e Optional[dict]`\n  - Parses the request content as JSON.\n  - **Returns:** The parsed JSON data as a dictionary, or `None` if parsing fails.\n  - **Example:**\n    ```python\n    request_data = request.json()\n    if request_data:\n        print(request_data)\n    ```\n\n#### Attributes\n\n- `method`: The HTTP method of the request (e.g., 'GET', 'POST').\n- `headers`: A dictionary of the request headers.\n- `cookies`: A dictionary of cookies included in the request.\n- `content`: The body content of the request.\n- `version`: The HTTP version used in the request.\n- `url`: The URL of the request.\n- `params`: A dictionary of URL query parameters.\n- `address`: A tuple containing the client's IP address and port.\n\n### `Response` *(!)*\n```python\nclass Response(status_code: int, headers: dict, content: Union[str, bytes, FilePath], cookies: dict = {})\n```\nA class that represents an HTTP response.\n\n#### Attributes\n\n- `status_code`: The HTTP status code of the response (e.g., 200, 404).\n- `headers`: A dictionary of response headers.\n- `content`: The response content, which can be a string, bytes, or a `FilePath` object.\n- `cookies`: A dictionary of cookies to be included in the response.\n\n### `ScheduledResponse` *(!)*\n```python\nclass ScheduledResponse(request: Request, route_function: Callable, error_routes: dict)\n```\nA class that schedules the generation and handling of an HTTP response based on a request and a route function.\n\n#### Methods\n\n- `run() -\u003e Optional[Response]`\n  - Executes the route function and generates an HTTP response.\n  - **Returns:** A `Response` object or `None` if an error occurs.\n\n### `FilePath`\n```python\nclass FilePath(path: str)\n```\nA class that represents a file to be sent as a response.\n\n#### Methods\n\n- `read(read_range: Optional[tuple[int, int]] = None, twice: bool = False) -\u003e bytes`\n  - Reads and returns the content of the file, or a specific range of bytes.\n  - **Parameters:**\n    - `read_range`: A tuple specifying the byte range to read (start, end).\n    - `twice`: A boolean indicating whether the file should be read again.\n\n#### Attributes\n\n- `path`: The path to the file.\n- `read_start`: The starting byte position for reading.\n- `read_end`: The ending byte position for reading.\n\n#### Example\n```python\nfile_response = FilePath(\"/path/to/file.txt\")\n```\n\n### `ResponseCookie`\n```python\nclass ResponseCookie(value: str, max_age: int, domain: str, http_only: bool, secure: bool, path: str, same_site\n\n: str)\n```\nA class that represents a cookie to be included in an HTTP response.\n\n#### Attributes\n\n- `value`: The value of the cookie.\n- `max_age`: The maximum age of the cookie, in seconds.\n- `domain`: The domain for which the cookie is valid.\n- `http_only`: A boolean indicating whether the cookie is HTTP-only.\n- `secure`: A boolean indicating whether the cookie is secure.\n- `path`: The path for which the cookie is valid.\n- `same_site`: The SameSite attribute of the cookie.\n\n## Functions\n\n### `get_insensitive_header` *(!)*\n```python\ndef get_insensitive_header(headers: dict, header_name: str) -\u003e Optional[str]\n```\nFetches a header value from a dictionary, case-insensitively.\n\n#### Parameters\n- `headers`: A dictionary of headers.\n- `header_name`: The name of the header to fetch.\n\n#### Returns\n- The value of the header if found, otherwise `None`.\n\n#### Example\n```python\nheaders = {\"Content-Type\": \"application/json\", \"User-Agent\": \"my-app\"}\ncontent_type = get_insensitive_header(headers, \"content-type\")\nprint(content_type)  # Output: \"application/json\"\n```\n\n### `get_description`\n```python\ndef get_description(code: int) -\u003e str\n```\nFetches the description of an HTTP status code.\n\n#### Parameters\n- `code`: The HTTP status code.\n\n#### Returns\n- A string description of the status code.\n\n#### Example\n```python\ndescription = get_description(404)\nprint(description)  # Output: \"Not Found\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoni08bit%2Foutside","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoni08bit%2Foutside","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoni08bit%2Foutside/lists"}