This commit is contained in:
Lagicrus 2019-10-11 14:00:27 +01:00
parent 3bd95cbe3b
commit 291747d575

View File

@ -1,114 +1,136 @@
# Configuration Configuration
=============
Any reasonably complex application will need configuration that is not baked into the actual code. Settings might be different for different environments or installations. Any reasonably complex application will need configuration that is not baked into the actual code. Settings might be different for different environments or installations.
## Basics Basics
------
Sanic holds the configuration in the `config` attribute of the application object. The configuration object is merely an object that can be modified either using dot-notation or like a dictionary: Sanic holds the configuration in the `config` attribute of the application object. The configuration object is merely an object that can be modified either using dot-notation or like a dictionary:
``` .. code-block:: python
app = Sanic('myapp') app = Sanic('myapp')
app.config.DB_NAME = 'appdb' app.config.DB_NAME = 'appdb'
app.config.DB_USER = 'appuser' app.config.DB_USER = 'appuser'
```
Since the config object actually is a dictionary, you can use its `update` method in order to set several values at once: Since the config object actually is a dictionary, you can use its `update` method in order to set several values at once:
``` .. code-block:: python
db_settings = { db_settings = {
'DB_HOST': 'localhost', 'DB_HOST': 'localhost',
'DB_NAME': 'appdb', 'DB_NAME': 'appdb',
'DB_USER': 'appuser' 'DB_USER': 'appuser'
} }
app.config.update(db_settings) app.config.update(db_settings)
```
In general the convention is to only have UPPERCASE configuration parameters. The methods described below for loading configuration only look for such uppercase parameters. In general the convention is to only have UPPERCASE configuration parameters. The methods described below for loading configuration only look for such uppercase parameters.
## Loading Configuration Loading Configuration
---------------------
There are several ways how to load configuration. There are several ways how to load configuration.
### From Environment Variables From Environment Variables
~~~~~~~~~~~~~~~~~~~~~~~~~~
Any variables defined with the `SANIC_` prefix will be applied to the sanic config. For example, setting `SANIC_REQUEST_TIMEOUT` will be loaded by the application automatically and fed into the `REQUEST_TIMEOUT` config variable. You can pass a different prefix to Sanic: Any variables defined with the `SANIC_` prefix will be applied to the sanic config. For example, setting `SANIC_REQUEST_TIMEOUT` will be loaded by the application automatically and fed into the `REQUEST_TIMEOUT` config variable. You can pass a different prefix to Sanic:
```python .. code-block:: python
app = Sanic(load_env='MYAPP_') app = Sanic(load_env='MYAPP_')
```
Then the above variable would be `MYAPP_REQUEST_TIMEOUT`. If you want to disable loading from environment variables you can set it to `False` instead: Then the above variable would be `MYAPP_REQUEST_TIMEOUT`. If you want to disable loading from environment variables you can set it to `False` instead:
```python .. code-block:: python
app = Sanic(load_env=False)
```
### From an Object app = Sanic(load_env=False)
From an Object
~~~~~~~~~~~~~~
If there are a lot of configuration values and they have sensible defaults it might be helpful to put them into a module: If there are a lot of configuration values and they have sensible defaults it might be helpful to put them into a module:
``` .. code-block:: python
import myapp.default_settings import myapp.default_settings
app = Sanic('myapp') app = Sanic('myapp')
app.config.from_object(myapp.default_settings) app.config.from_object(myapp.default_settings)
```
or also by path to config: or also by path to config:
``` .. code-block:: python
app = Sanic('myapp') app = Sanic('myapp')
app.config.from_object('config.path.config.Class') app.config.from_object('config.path.config.Class')
```
You could use a class or any other object as well. You could use a class or any other object as well.
### From a File From a File
~~~~~~~~~~~
Usually you will want to load configuration from a file that is not part of the distributed application. You can load configuration from a file using `from_pyfile(/path/to/config_file)`. However, that requires the program to know the path to the config file. So instead you can specify the location of the config file in an environment variable and tell Sanic to use that to find the config file: Usually you will want to load configuration from a file that is not part of the distributed application. You can load configuration from a file using `from_pyfile(/path/to/config_file)`. However, that requires the program to know the path to the config file. So instead you can specify the location of the config file in an environment variable and tell Sanic to use that to find the config file:
``` .. code-block:: python
app = Sanic('myapp') app = Sanic('myapp')
app.config.from_envvar('MYAPP_SETTINGS') app.config.from_envvar('MYAPP_SETTINGS')
```
Then you can run your application with the `MYAPP_SETTINGS` environment variable set: Then you can run your application with the `MYAPP_SETTINGS` environment variable set:
``` .. code-block:: python
$ MYAPP_SETTINGS=/path/to/config_file python3 myapp.py
INFO: Goin' Fast @ http://0.0.0.0:8000 #$ MYAPP_SETTINGS=/path/to/config_file python3 myapp.py
``` #INFO: Goin' Fast @ http://0.0.0.0:8000
The config files are regular Python files which are executed in order to load them. This allows you to use arbitrary logic for constructing the right configuration. Only uppercase variables are added to the configuration. Most commonly the configuration consists of simple key value pairs: The config files are regular Python files which are executed in order to load them. This allows you to use arbitrary logic for constructing the right configuration. Only uppercase variables are added to the configuration. Most commonly the configuration consists of simple key value pairs:
``` .. code-block:: python
# config_file # config_file
DB_HOST = 'localhost' DB_HOST = 'localhost'
DB_NAME = 'appdb' DB_NAME = 'appdb'
DB_USER = 'appuser' DB_USER = 'appuser'
```
## Builtin Configuration Values Builtin Configuration Values
----------------------------
Out of the box there are just a few predefined values which can be overwritten when creating the application. Out of the box there are just a few predefined values which can be overwritten when creating the application.
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| Variable | Default | Description | | Variable | Default | Description |
| ------------------------- | ----------------- | --------------------------------------------------------------------------- | +===========================+===================+=============================================================================+
| REQUEST_MAX_SIZE | 100000000 | How big a request may be (bytes) | | REQUEST_MAX_SIZE | 100000000 | How big a request may be (bytes) |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| REQUEST_BUFFER_QUEUE_SIZE | 100 | Request streaming buffer queue size | | REQUEST_BUFFER_QUEUE_SIZE | 100 | Request streaming buffer queue size |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| REQUEST_TIMEOUT | 60 | How long a request can take to arrive (sec) | | REQUEST_TIMEOUT | 60 | How long a request can take to arrive (sec) |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| RESPONSE_TIMEOUT | 60 | How long a response can take to process (sec) | | RESPONSE_TIMEOUT | 60 | How long a response can take to process (sec) |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| KEEP_ALIVE | True | Disables keep-alive when False | | KEEP_ALIVE | True | Disables keep-alive when False |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| KEEP_ALIVE_TIMEOUT | 5 | How long to hold a TCP connection open (sec) | | KEEP_ALIVE_TIMEOUT | 5 | How long to hold a TCP connection open (sec) |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| GRACEFUL_SHUTDOWN_TIMEOUT | 15.0 | How long to wait to force close non-idle connection (sec) | | GRACEFUL_SHUTDOWN_TIMEOUT | 15.0 | How long to wait to force close non-idle connection (sec) |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| ACCESS_LOG | True | Disable or enable access log | | ACCESS_LOG | True | Disable or enable access log |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| PROXIES_COUNT | -1 | The number of proxy servers in front of the app (e.g. nginx; see below) | | PROXIES_COUNT | -1 | The number of proxy servers in front of the app (e.g. nginx; see below) |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| FORWARDED_FOR_HEADER | "X-Forwarded-For" | The name of "X-Forwarded-For" HTTP header that contains client and proxy ip | | FORWARDED_FOR_HEADER | "X-Forwarded-For" | The name of "X-Forwarded-For" HTTP header that contains client and proxy ip |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
| REAL_IP_HEADER | "X-Real-IP" | The name of "X-Real-IP" HTTP header that contains real client ip | | REAL_IP_HEADER | "X-Real-IP" | The name of "X-Real-IP" HTTP header that contains real client ip |
+---------------------------+-------------------+-----------------------------------------------------------------------------+
### The different Timeout variables: The different Timeout variables:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#### `REQUEST_TIMEOUT` `REQUEST_TIMEOUT`
#################
A request timeout measures the duration of time between the instant when a new open TCP connection is passed to the A request timeout measures the duration of time between the instant when a new open TCP connection is passed to the
Sanic backend server, and the instant when the whole HTTP request is received. If the time taken exceeds the Sanic backend server, and the instant when the whole HTTP request is received. If the time taken exceeds the
@ -116,7 +138,8 @@ Sanic backend server, and the instant when the whole HTTP request is received. I
and sends that to the client. Set this parameter's value higher if your clients routinely pass very large request payloads and sends that to the client. Set this parameter's value higher if your clients routinely pass very large request payloads
or upload requests very slowly. or upload requests very slowly.
#### `RESPONSE_TIMEOUT` `RESPONSE_TIMEOUT`
##################
A response timeout measures the duration of time between the instant the Sanic server passes the HTTP request to the A response timeout measures the duration of time between the instant the Sanic server passes the HTTP request to the
Sanic App, and the instant a HTTP response is sent to the client. If the time taken exceeds the `RESPONSE_TIMEOUT` Sanic App, and the instant a HTTP response is sent to the client. If the time taken exceeds the `RESPONSE_TIMEOUT`
@ -124,9 +147,11 @@ value (in seconds), this is considered a Server Error so Sanic generates an `HTT
client. Set this parameter's value higher if your application is likely to have long-running process that delay the client. Set this parameter's value higher if your application is likely to have long-running process that delay the
generation of a response. generation of a response.
#### `KEEP_ALIVE_TIMEOUT` `KEEP_ALIVE_TIMEOUT`
####################
##### What is Keep Alive? And what does the Keep Alive Timeout value do? What is Keep Alive? And what does the Keep Alive Timeout value do?
******************************************************************
`Keep-Alive` is a HTTP feature introduced in `HTTP 1.1`. When sending a HTTP request, the client (usually a web browser application) `Keep-Alive` is a HTTP feature introduced in `HTTP 1.1`. When sending a HTTP request, the client (usually a web browser application)
can set a `Keep-Alive` header to indicate the http server (Sanic) to not close the TCP connection after it has send the response. can set a `Keep-Alive` header to indicate the http server (Sanic) to not close the TCP connection after it has send the response.
@ -144,17 +169,18 @@ the client to send a new request, and not holding open too many connections at o
you know your clients are using a browser which supports TCP connections held open for that long. you know your clients are using a browser which supports TCP connections held open for that long.
For reference: For reference:
```
Apache httpd server default keepalive timeout = 5 seconds
Nginx server default keepalive timeout = 75 seconds
Nginx performance tuning guidelines uses keepalive = 15 seconds
IE (5-9) client hard keepalive limit = 60 seconds
Firefox client hard keepalive limit = 115 seconds
Opera 11 client hard keepalive limit = 120 seconds
Chrome 13+ client keepalive limit > 300+ seconds
```
### Proxy configuration * Apache httpd server default keepalive timeout = 5 seconds
* Nginx server default keepalive timeout = 75 seconds
* Nginx performance tuning guidelines uses keepalive = 15 seconds
* IE (5-9) client hard keepalive limit = 60 seconds
* Firefox client hard keepalive limit = 115 seconds
* Opera 11 client hard keepalive limit = 120 seconds
* Chrome 13+ client keepalive limit > 300+ seconds
Proxy configuration
~~~~~~~~~~~~~~~~~~~
When you use a reverse proxy server (e.g. nginx), the value of `request.ip` will contain ip of a proxy, typically `127.0.0.1`. Sanic may be configured to use proxy headers for determining the true client IP, available as `request.remote_addr`. The full external URL is also constructed from header fields if available. When you use a reverse proxy server (e.g. nginx), the value of `request.ip` will contain ip of a proxy, typically `127.0.0.1`. Sanic may be configured to use proxy headers for determining the true client IP, available as `request.remote_addr`. The full external URL is also constructed from header fields if available.
@ -162,12 +188,10 @@ Without proper precautions, a malicious client may use proxy headers to spoof it
Services behind reverse proxies must configure `FORWARDED_SECRET`, `REAL_IP_HEADER` and/or `PROXIES_COUNT`. Services behind reverse proxies must configure `FORWARDED_SECRET`, `REAL_IP_HEADER` and/or `PROXIES_COUNT`.
#### Forwarded header Forwarded header
################
``` .. Forwarded: for="1.2.3.4"; proto="https"; host="yoursite.com"; secret="Pr0xy", for="10.0.0.1"; proto="http"; host="proxy.internal"; by="_1234proxy"
Forwarded: for="1.2.3.4"; proto="https"; host="yoursite.com"; secret="Pr0xy",
for="10.0.0.1"; proto="http"; host="proxy.internal"; by="_1234proxy"
```
* Set `FORWARDED_SECRET` to an identifier used by the proxy of interest. * Set `FORWARDED_SECRET` to an identifier used by the proxy of interest.
@ -177,14 +201,14 @@ Sanic ignores any elements without the secret key, and will not even parse the h
All other proxy headers are ignored once a trusted forwarded element is found, as it already carries complete information about the client. All other proxy headers are ignored once a trusted forwarded element is found, as it already carries complete information about the client.
#### Traditional proxy headers Traditional proxy headers
#########################
``` .. X-Real-IP: 1.2.3.4
X-Real-IP: 1.2.3.4
X-Forwarded-For: 1.2.3.4, 10.0.0.1 X-Forwarded-For: 1.2.3.4, 10.0.0.1
X-Forwarded-Proto: https X-Forwarded-Proto: https
X-Forwarded-Host: yoursite.com X-Forwarded-Host: yoursite.com
```
* Set `REAL_IP_HEADER` to `x-real-ip`, `true-client-ip`, `cf-connecting-ip` or other name of such header. * Set `REAL_IP_HEADER` to `x-real-ip`, `true-client-ip`, `cf-connecting-ip` or other name of such header.
* Set `PROXIES_COUNT` to the number of entries expected in `x-forwarded-for` (name configurable via `FORWARDED_FOR_HEADER`). * Set `PROXIES_COUNT` to the number of entries expected in `x-forwarded-for` (name configurable via `FORWARDED_FOR_HEADER`).
@ -193,7 +217,8 @@ If client IP is found by one of these methods, Sanic uses the following headers
* `x-forwarded-proto`, `x-forwarded-host`, `x-forwarded-port`, `x-forwarded-path` and if necessary, `x-scheme`. * `x-forwarded-proto`, `x-forwarded-host`, `x-forwarded-port`, `x-forwarded-path` and if necessary, `x-scheme`.
#### Proxy config if using ... Proxy config if using ...
#########################
* a proxy that supports `forwarded`: set `FORWARDED_SECRET` to the value that the proxy inserts in the header * a proxy that supports `forwarded`: set `FORWARDED_SECRET` to the value that the proxy inserts in the header
* Apache Traffic Server: `CONFIG proxy.config.http.insert_forwarded STRING for|proto|host|by=_secret` * Apache Traffic Server: `CONFIG proxy.config.http.insert_forwarded STRING for|proto|host|by=_secret`
@ -206,6 +231,7 @@ If client IP is found by one of these methods, Sanic uses the following headers
* `x-forwarded-for`: set `PROXIES_COUNT` to `1` for a single proxy, or a greater number to allow Sanic to select the correct IP * `x-forwarded-for`: set `PROXIES_COUNT` to `1` for a single proxy, or a greater number to allow Sanic to select the correct IP
* no proxies: no configuration required! * no proxies: no configuration required!
#### Changes in Sanic 19.9 Changes in Sanic 19.9
#####################
Earlier Sanic versions had unsafe default settings. From 19.9 onwards proxy settings must be set manually, and support for negative PROXIES_COUNT has been removed. Earlier Sanic versions had unsafe default settings. From 19.9 onwards proxy settings must be set manually, and support for negative PROXIES_COUNT has been removed.