# Flask Allowed Hosts
This extension provides a way to restrict access to your Flask application based on the incoming request's hostname or
IP address or IP address range (network).
## Features
- Per-route configuration options.
- Customize denied access behavior.
- Two usage options: class-based or decorator-based.
- Restrict access by hostname, IP address or IP address range (network).
## Installation
Install the package using pip:
```cmd
pip install flask-allowed-hosts
```
## Usage
### Class-Based Usage
1. Initialize the `AllowedHosts` class.
2. Define allowed hosts (optional).
3. Define a function for denied access behavior (optional).
4. Apply access control to routes using `@allowed_hosts.limit()` decorator (optional).
#### Example:
```python
from flask import Flask, jsonify, abort
from flask_allowed_hosts import AllowedHosts
app = Flask(__name__)
ALLOWED_HOSTS = ["93.184.215.14", "api.example.com"]
def custom_on_denied():
error = {"error": "Oops! Looks like you are not allowed to access this page!"}
return jsonify(error), 403
allowed_hosts = AllowedHosts(app, allowed_hosts=ALLOWED_HOSTS, on_denied=custom_on_denied)
# Allows all incoming requests
@app.route("/api/public", methods=["GET"])
def public_endpoint():
data = {"message": "This is public!"}
return jsonify(data), 200
# Only allows incoming requests from "93.184.215.14" and "api.example.com"
@app.route("/api/private", methods=["GET"])
@allowed_hosts.limit()
def private_endpoint():
data = {"message": "This is private!"}
return jsonify(data), 200
# We can override the allowed_hosts list and the on_denied function for each route
@app.route("/api/private/secret", methods=["GET"])
@allowed_hosts.limit(allowed_hosts=["127.0.0.1"], on_denied=lambda: abort(404))
def secret_private_endpoint():
data = {"message": "This is very private!"}
return jsonify(data), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
```
### Decorator-Based Usage (Legacy)
**Warning**: This approach might cause unexpected behavior when combined with the class-based usage.
1. Define allowed hosts (optional).
2. Define a function for denied access behavior (optional).
3. Apply access control to routes using `@limit_hosts` decorator.
#### Example:
```python
from flask import Flask, jsonify
from flask_allowed_hosts import limit_hosts
app = Flask(__name__)
ALLOWED_HOSTS = ["93.184.215.14", "api.example.com"]
def custom_on_denied():
error = {"error": "Custom Denied Response"}
return jsonify(error), 403
# Allows all incoming requests
@app.route("/api/public", methods=["GET"])
def public_endpoint():
data = {"message": "This is public!"}
return jsonify(data), 200
# Only allows incoming requests from "93.184.215.14" and "api.example.com"
@app.route("/api/private", methods=["GET"])
@limit_hosts(allowed_hosts=ALLOWED_HOSTS, on_denied=custom_on_denied)
def private_endpoint():
return jsonify({"message": "This is private!"}), 200
```
### More Examples
You can find more examples in
the [examples directory](https://github.com/riad-azz/flask-allowed-hosts/tree/main/examples).
## Configuration
### Initialization Parameters
- `app`: The Flask application instance (optional).
- `allowed_hosts`: List of allowed hosts (optional, defaults to `None` which allows all hosts).
- `on_denied`: Function for denied access behavior (optional).
### Flask Config and Environment Variables
#### Flask Configuration
The extension respects these configurations:
- `ALLOWED_HOSTS`: List of allowed hosts in Flask config.
- `ALLOWED_HOSTS_ON_DENIED`: Function for denied access behavior in Flask config.
**Precedence**: Values provided during initialization override Flask config values.
#### Environment Variables
You can enable debug mode by setting the `ALLOWED_HOSTS_DEBUG` environment variable to `True`:
```shell
export ALLOWED_HOSTS_DEBUG="True"
```
This will print helpful debug messages to the console.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Support
If you have any questions or feedback, please feel free
to [open an issue or a pull request](https://github.com/riad-azz/flask-allowed-hosts/issues).
## License
This project is licensed under the [MIT] License - see the LICENSE.md file for details.
Raw data
{
"_id": null,
"home_page": "https://github.com/riad-azz/flask-allowed-hosts",
"name": "flask-allowed-hosts",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "flask, allowed hosts, web development, security, flask extension, ip validation, host validation, hostnames validation",
"author": "Riadh Azzoun",
"author_email": "riadh.azzoun@hotmail.com",
"download_url": "https://files.pythonhosted.org/packages/d8/d4/2a785e5e44db51c0127530e7330d6a3d5c9ec0569daae56933acd6ecfeac/flask_allowed_hosts-1.2.0.tar.gz",
"platform": null,
"description": "# Flask Allowed Hosts\r\n\r\nThis extension provides a way to restrict access to your Flask application based on the incoming request's hostname or\r\nIP address or IP address range (network).\r\n\r\n## Features\r\n\r\n- Per-route configuration options.\r\n- Customize denied access behavior.\r\n- Two usage options: class-based or decorator-based.\r\n- Restrict access by hostname, IP address or IP address range (network).\r\n\r\n## Installation\r\n\r\nInstall the package using pip:\r\n\r\n```cmd\r\npip install flask-allowed-hosts\r\n```\r\n\r\n## Usage\r\n\r\n### Class-Based Usage\r\n\r\n1. Initialize the `AllowedHosts` class.\r\n2. Define allowed hosts (optional).\r\n3. Define a function for denied access behavior (optional).\r\n4. Apply access control to routes using `@allowed_hosts.limit()` decorator (optional).\r\n\r\n#### Example:\r\n\r\n```python\r\nfrom flask import Flask, jsonify, abort\r\nfrom flask_allowed_hosts import AllowedHosts\r\n\r\napp = Flask(__name__)\r\n\r\nALLOWED_HOSTS = [\"93.184.215.14\", \"api.example.com\"]\r\n\r\n\r\ndef custom_on_denied():\r\n error = {\"error\": \"Oops! Looks like you are not allowed to access this page!\"}\r\n return jsonify(error), 403\r\n\r\n\r\nallowed_hosts = AllowedHosts(app, allowed_hosts=ALLOWED_HOSTS, on_denied=custom_on_denied)\r\n\r\n\r\n# Allows all incoming requests\r\n@app.route(\"/api/public\", methods=[\"GET\"])\r\ndef public_endpoint():\r\n data = {\"message\": \"This is public!\"}\r\n return jsonify(data), 200\r\n\r\n\r\n# Only allows incoming requests from \"93.184.215.14\" and \"api.example.com\"\r\n@app.route(\"/api/private\", methods=[\"GET\"])\r\n@allowed_hosts.limit()\r\ndef private_endpoint():\r\n data = {\"message\": \"This is private!\"}\r\n return jsonify(data), 200\r\n\r\n\r\n# We can override the allowed_hosts list and the on_denied function for each route\r\n@app.route(\"/api/private/secret\", methods=[\"GET\"])\r\n@allowed_hosts.limit(allowed_hosts=[\"127.0.0.1\"], on_denied=lambda: abort(404))\r\ndef secret_private_endpoint():\r\n data = {\"message\": \"This is very private!\"}\r\n return jsonify(data), 200\r\n\r\n\r\nif __name__ == '__main__':\r\n app.run(host='0.0.0.0', port=5000, debug=True)\r\n```\r\n\r\n### Decorator-Based Usage (Legacy)\r\n\r\n**Warning**: This approach might cause unexpected behavior when combined with the class-based usage.\r\n\r\n1. Define allowed hosts (optional).\r\n2. Define a function for denied access behavior (optional).\r\n3. Apply access control to routes using `@limit_hosts` decorator.\r\n\r\n#### Example:\r\n\r\n```python\r\nfrom flask import Flask, jsonify\r\nfrom flask_allowed_hosts import limit_hosts\r\n\r\napp = Flask(__name__)\r\n\r\nALLOWED_HOSTS = [\"93.184.215.14\", \"api.example.com\"]\r\n\r\n\r\ndef custom_on_denied():\r\n error = {\"error\": \"Custom Denied Response\"}\r\n return jsonify(error), 403\r\n\r\n\r\n# Allows all incoming requests\r\n@app.route(\"/api/public\", methods=[\"GET\"])\r\ndef public_endpoint():\r\n data = {\"message\": \"This is public!\"}\r\n return jsonify(data), 200\r\n\r\n\r\n# Only allows incoming requests from \"93.184.215.14\" and \"api.example.com\"\r\n@app.route(\"/api/private\", methods=[\"GET\"])\r\n@limit_hosts(allowed_hosts=ALLOWED_HOSTS, on_denied=custom_on_denied)\r\ndef private_endpoint():\r\n return jsonify({\"message\": \"This is private!\"}), 200\r\n```\r\n\r\n### More Examples\r\n\r\nYou can find more examples in\r\nthe [examples directory](https://github.com/riad-azz/flask-allowed-hosts/tree/main/examples).\r\n\r\n## Configuration\r\n\r\n### Initialization Parameters\r\n\r\n- `app`: The Flask application instance (optional).\r\n- `allowed_hosts`: List of allowed hosts (optional, defaults to `None` which allows all hosts).\r\n- `on_denied`: Function for denied access behavior (optional).\r\n\r\n### Flask Config and Environment Variables\r\n\r\n#### Flask Configuration\r\n\r\nThe extension respects these configurations:\r\n\r\n- `ALLOWED_HOSTS`: List of allowed hosts in Flask config.\r\n- `ALLOWED_HOSTS_ON_DENIED`: Function for denied access behavior in Flask config.\r\n\r\n**Precedence**: Values provided during initialization override Flask config values.\r\n\r\n#### Environment Variables\r\n\r\nYou can enable debug mode by setting the `ALLOWED_HOSTS_DEBUG` environment variable to `True`:\r\n\r\n```shell\r\nexport ALLOWED_HOSTS_DEBUG=\"True\"\r\n```\r\n\r\nThis will print helpful debug messages to the console.\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please feel free to submit a Pull Request.\r\n\r\n## Support\r\n\r\nIf you have any questions or feedback, please feel free\r\nto [open an issue or a pull request](https://github.com/riad-azz/flask-allowed-hosts/issues).\r\n\r\n## License\r\n\r\nThis project is licensed under the [MIT] License - see the LICENSE.md file for details.\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Flask extension to limit access to your routes by using allowed hostnames and IP addresses.",
"version": "1.2.0",
"project_urls": {
"Homepage": "https://github.com/riad-azz/flask-allowed-hosts"
},
"split_keywords": [
"flask",
" allowed hosts",
" web development",
" security",
" flask extension",
" ip validation",
" host validation",
" hostnames validation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0561a63d77e88bf255350395614b11c04158ad224f5e1a579153ee0089c94e8e",
"md5": "133267fd32648503d9f767cb52377aaa",
"sha256": "0d391121b9d4da46570a86cd70d9ae38fd74e356ce61d0faf07d807d1b61e82c"
},
"downloads": -1,
"filename": "flask_allowed_hosts-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "133267fd32648503d9f767cb52377aaa",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 7772,
"upload_time": "2024-10-10T03:58:11",
"upload_time_iso_8601": "2024-10-10T03:58:11.219490Z",
"url": "https://files.pythonhosted.org/packages/05/61/a63d77e88bf255350395614b11c04158ad224f5e1a579153ee0089c94e8e/flask_allowed_hosts-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d8d42a785e5e44db51c0127530e7330d6a3d5c9ec0569daae56933acd6ecfeac",
"md5": "f063dd8eea00cc85284044f6825032e5",
"sha256": "2cbd159b7dd1d01628f082b28c0ce9bceee5b3811f70fc77731dce53a3ac13ab"
},
"downloads": -1,
"filename": "flask_allowed_hosts-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "f063dd8eea00cc85284044f6825032e5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 6606,
"upload_time": "2024-10-10T03:58:13",
"upload_time_iso_8601": "2024-10-10T03:58:13.270057Z",
"url": "https://files.pythonhosted.org/packages/d8/d4/2a785e5e44db51c0127530e7330d6a3d5c9ec0569daae56933acd6ecfeac/flask_allowed_hosts-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-10 03:58:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "riad-azz",
"github_project": "flask-allowed-hosts",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "flask-allowed-hosts"
}