make release script black compliant and tweak documentation with indexing and format
Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
This commit is contained in:
parent
b7702bc3e8
commit
2d82b8951f
|
@ -7,24 +7,24 @@ Guides
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
sanic/getting_started
|
sanic/getting_started
|
||||||
sanic/routing
|
sanic/config
|
||||||
|
sanic/logging
|
||||||
sanic/request_data
|
sanic/request_data
|
||||||
sanic/response
|
sanic/response
|
||||||
|
sanic/cookies
|
||||||
|
sanic/routing
|
||||||
|
sanic/blueprints
|
||||||
sanic/static_files
|
sanic/static_files
|
||||||
|
sanic/versioning
|
||||||
sanic/exceptions
|
sanic/exceptions
|
||||||
sanic/middleware
|
sanic/middleware
|
||||||
sanic/blueprints
|
|
||||||
sanic/websocket
|
sanic/websocket
|
||||||
sanic/config
|
|
||||||
sanic/cookies
|
|
||||||
sanic/decorators
|
sanic/decorators
|
||||||
sanic/streaming
|
sanic/streaming
|
||||||
sanic/class_based_views
|
sanic/class_based_views
|
||||||
sanic/custom_protocol
|
sanic/custom_protocol
|
||||||
sanic/sockets
|
sanic/sockets
|
||||||
sanic/ssl
|
sanic/ssl
|
||||||
sanic/logging
|
|
||||||
sanic/versioning
|
|
||||||
sanic/debug_mode
|
sanic/debug_mode
|
||||||
sanic/testing
|
sanic/testing
|
||||||
sanic/deploying
|
sanic/deploying
|
||||||
|
|
|
@ -118,9 +118,9 @@ app = Sanic(__name__)
|
||||||
app.blueprint(api)
|
app.blueprint(api)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using blueprints
|
## Using Blueprints
|
||||||
|
|
||||||
Blueprints have much the same functionality as an application instance.
|
Blueprints have almost the same functionality as an application instance.
|
||||||
|
|
||||||
### WebSocket routes
|
### WebSocket routes
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ async def close_connection(app, loop):
|
||||||
Blueprints can be very useful for API versioning, where one blueprint may point
|
Blueprints can be very useful for API versioning, where one blueprint may point
|
||||||
at `/v1/<routes>`, and another pointing at `/v2/<routes>`.
|
at `/v1/<routes>`, and another pointing at `/v2/<routes>`.
|
||||||
|
|
||||||
When a blueprint is initialised, it can take an optional `url_prefix` argument,
|
When a blueprint is initialised, it can take an optional `version` argument,
|
||||||
which will be prepended to all routes defined on the blueprint. This feature
|
which will be prepended to all routes defined on the blueprint. This feature
|
||||||
can be used to implement our API versioning scheme.
|
can be used to implement our API versioning scheme.
|
||||||
|
|
||||||
|
@ -210,8 +210,8 @@ can be used to implement our API versioning scheme.
|
||||||
from sanic.response import text
|
from sanic.response import text
|
||||||
from sanic import Blueprint
|
from sanic import Blueprint
|
||||||
|
|
||||||
blueprint_v1 = Blueprint('v1', url_prefix='/v1')
|
blueprint_v1 = Blueprint('v1', url_prefix='/api', version="v1")
|
||||||
blueprint_v2 = Blueprint('v2', url_prefix='/v2')
|
blueprint_v2 = Blueprint('v2', url_prefix='/api', version="v2")
|
||||||
|
|
||||||
@blueprint_v1.route('/')
|
@blueprint_v1.route('/')
|
||||||
async def api_v1_root(request):
|
async def api_v1_root(request):
|
||||||
|
@ -222,7 +222,7 @@ async def api_v2_root(request):
|
||||||
return text('Welcome to version 2 of our documentation')
|
return text('Welcome to version 2 of our documentation')
|
||||||
```
|
```
|
||||||
|
|
||||||
When we register our blueprints on the app, the routes `/v1` and `/v2` will now
|
When we register our blueprints on the app, the routes `/v1/api` and `/v2/api` will now
|
||||||
point to the individual blueprints, which allows the creation of *sub-sites*
|
point to the individual blueprints, which allows the creation of *sub-sites*
|
||||||
for each API version.
|
for each API version.
|
||||||
|
|
||||||
|
@ -232,8 +232,8 @@ from sanic import Sanic
|
||||||
from blueprints import blueprint_v1, blueprint_v2
|
from blueprints import blueprint_v1, blueprint_v2
|
||||||
|
|
||||||
app = Sanic(__name__)
|
app = Sanic(__name__)
|
||||||
app.blueprint(blueprint_v1, url_prefix='/v1')
|
app.blueprint(blueprint_v1)
|
||||||
app.blueprint(blueprint_v2, url_prefix='/v2')
|
app.blueprint(blueprint_v2)
|
||||||
|
|
||||||
app.run(host='0.0.0.0', port=8000, debug=True)
|
app.run(host='0.0.0.0', port=8000, debug=True)
|
||||||
```
|
```
|
||||||
|
@ -246,7 +246,7 @@ takes the format `<blueprint_name>.<handler_name>`. For example:
|
||||||
```python
|
```python
|
||||||
@blueprint_v1.route('/')
|
@blueprint_v1.route('/')
|
||||||
async def root(request):
|
async def root(request):
|
||||||
url = request.app.url_for('v1.post_handler', post_id=5) # --> '/v1/post/5'
|
url = request.app.url_for('v1.post_handler', post_id=5) # --> '/v1/api/post/5'
|
||||||
return redirect(url)
|
return redirect(url)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,29 +86,52 @@ DB_USER = 'appuser'
|
||||||
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 take 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 |
|
||||||
|
|
||||||
### The different Timeout variables:
|
### The different Timeout variables:
|
||||||
|
|
||||||
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 `REQUEST_TIMEOUT` value (in seconds), this is considered a Client Error so Sanic generates a HTTP 408 response and sends that to the client. Adjust this value higher if your clients routinely pass very large request payloads or upload requests very slowly.
|
#### `REQUEST_TIMEOUT`
|
||||||
|
|
||||||
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` value (in seconds), this is considered a Server Error so Sanic generates a HTTP 503 response and sets that to the client. Adjust this value higher if your application is likely to have long-running process that delay the generation of a response.
|
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
|
||||||
|
`REQUEST_TIMEOUT` value (in seconds), this is considered a Client Error so Sanic generates an `HTTP 408` response
|
||||||
|
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.
|
||||||
|
|
||||||
### What is Keep Alive? And what does the Keep Alive Timeout value do?
|
#### `RESPONSE_TIMEOUT`
|
||||||
|
|
||||||
Keep-Alive is a HTTP feature indroduced in HTTP 1.1. When sending a HTTP request, the client (usually a web browser application) can set a Keep-Alive header to indicate for the http server (Sanic) to not close the TCP connection after it has send the response. This allows the client to reuse the existing TCP connection to send subsequent HTTP requests, and ensures more efficient network traffic for both the client and the server.
|
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`
|
||||||
|
value (in seconds), this is considered a Server Error so Sanic generates an `HTTP 503` response and sends that to 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.
|
||||||
|
|
||||||
The `KEEP_ALIVE` config variable is set to `True` in Sanic by default. If you don't need this feature in your application, set it to `False` to cause all client connections to close immediately after a response is sent, regardless of the Keep-Alive header on the request.
|
#### `KEEP_ALIVE_TIMEOUT`
|
||||||
|
|
||||||
The amount of time the server holds the TCP connection open is decided by the server itself. In Sanic, that value is configured using the `KEEP_ALIVE_TIMEOUT` value. By default, it is set to 5 seconds, this is the same default setting as the Apache HTTP server and is a good balance between allowing enough time for the client to send a new request, and not holding open too many connections at once. Do not exceed 75 seconds unless you know your clients are using a browser which supports TCP connections held open for that long.
|
##### 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)
|
||||||
|
can set a `Keep-Alive` header to indicate the http server (Sanic) to not close the TCP connection after it has send the response.
|
||||||
|
This allows the client to reuse the existing TCP connection to send subsequent HTTP requests, and ensures more efficient
|
||||||
|
network traffic for both the client and the server.
|
||||||
|
|
||||||
|
The `KEEP_ALIVE` config variable is set to `True` in Sanic by default. If you don't need this feature in your application,
|
||||||
|
set it to `False` to cause all client connections to close immediately after a response is sent, regardless of
|
||||||
|
the `Keep-Alive` header on the request.
|
||||||
|
|
||||||
|
The amount of time the server holds the TCP connection open is decided by the server itself.
|
||||||
|
In Sanic, that value is configured using the `KEEP_ALIVE_TIMEOUT` value. By default, it is set to 5 seconds.
|
||||||
|
This is the same default setting as the Apache HTTP server and is a good balance between allowing enough time for
|
||||||
|
the client to send a new request, and not holding open too many connections at once. Do not exceed 75 seconds unless
|
||||||
|
you know your clients are using a browser which supports TCP connections held open for that long.
|
||||||
|
|
||||||
For reference:
|
For reference:
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
# Custom Protocols
|
|
||||||
|
|
||||||
*Note: this is advanced usage, and most readers will not need such functionality.*
|
|
||||||
|
|
||||||
You can change the behavior of Sanic's protocol by specifying a custom
|
|
||||||
protocol, which should be a subclass
|
|
||||||
of
|
|
||||||
[asyncio.protocol](https://docs.python.org/3/library/asyncio-protocol.html#protocol-classes).
|
|
||||||
This protocol can then be passed as the keyword argument `protocol` to the `sanic.run` method.
|
|
||||||
|
|
||||||
The constructor of the custom protocol class receives the following keyword
|
|
||||||
arguments from Sanic.
|
|
||||||
|
|
||||||
- `loop`: an `asyncio`-compatible event loop.
|
|
||||||
- `connections`: a `set` to store protocol objects. When Sanic receives
|
|
||||||
`SIGINT` or `SIGTERM`, it executes `protocol.close_if_idle` for all protocol
|
|
||||||
objects stored in this set.
|
|
||||||
- `signal`: a `sanic.server.Signal` object with the `stopped` attribute. When
|
|
||||||
Sanic receives `SIGINT` or `SIGTERM`, `signal.stopped` is assigned `True`.
|
|
||||||
- `request_handler`: a coroutine that takes a `sanic.request.Request` object
|
|
||||||
and a `response` callback as arguments.
|
|
||||||
- `error_handler`: a `sanic.exceptions.Handler` which is called when exceptions
|
|
||||||
are raised.
|
|
||||||
- `request_timeout`: the number of seconds before a request times out.
|
|
||||||
- `request_max_size`: an integer specifying the maximum size of a request, in bytes.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
An error occurs in the default protocol if a handler function does not return
|
|
||||||
an `HTTPResponse` object.
|
|
||||||
|
|
||||||
By overriding the `write_response` protocol method, if a handler returns a
|
|
||||||
string it will be converted to an `HTTPResponse object`.
|
|
||||||
|
|
||||||
```python
|
|
||||||
from sanic import Sanic
|
|
||||||
from sanic.server import HttpProtocol
|
|
||||||
from sanic.response import text
|
|
||||||
|
|
||||||
app = Sanic(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class CustomHttpProtocol(HttpProtocol):
|
|
||||||
|
|
||||||
def __init__(self, *, loop, request_handler, error_handler,
|
|
||||||
signal, connections, request_timeout, request_max_size):
|
|
||||||
super().__init__(
|
|
||||||
loop=loop, request_handler=request_handler,
|
|
||||||
error_handler=error_handler, signal=signal,
|
|
||||||
connections=connections, request_timeout=request_timeout,
|
|
||||||
request_max_size=request_max_size)
|
|
||||||
|
|
||||||
def write_response(self, response):
|
|
||||||
if isinstance(response, str):
|
|
||||||
response = text(response)
|
|
||||||
self.transport.write(
|
|
||||||
response.output(self.request.version)
|
|
||||||
)
|
|
||||||
self.transport.close()
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
async def string(request):
|
|
||||||
return 'string'
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/1')
|
|
||||||
async def response(request):
|
|
||||||
return text('response')
|
|
||||||
|
|
||||||
app.run(host='0.0.0.0', port=8000, protocol=CustomHttpProtocol)
|
|
||||||
```
|
|
76
docs/sanic/custom_protocol.rst
Normal file
76
docs/sanic/custom_protocol.rst
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
Custom Protocols
|
||||||
|
================
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This is advanced usage, and most readers will not need such functionality.
|
||||||
|
|
||||||
|
You can change the behavior of Sanic's protocol by specifying a custom
|
||||||
|
protocol, which should be a subclass
|
||||||
|
of `asyncio.protocol <https://docs.python.org/3/library/asyncio-protocol.html#protocol-classes>`_.
|
||||||
|
This protocol can then be passed as the keyword argument ``protocol`` to the ``sanic.run`` method.
|
||||||
|
|
||||||
|
The constructor of the custom protocol class receives the following keyword
|
||||||
|
arguments from Sanic.
|
||||||
|
|
||||||
|
- ``loop``: an ``asyncio``-compatible event loop.
|
||||||
|
- ``connections``: a ``set`` to store protocol objects. When Sanic receives
|
||||||
|
``SIGINT`` or ``SIGTERM``, it executes ``protocol.close_if_idle`` for all protocol
|
||||||
|
objects stored in this set.
|
||||||
|
- ``signal``: a ``sanic.server.Signal`` object with the ``stopped`` attribute. When
|
||||||
|
Sanic receives ``SIGINT`` or ``SIGTERM``, ``signal.stopped`` is assigned ``True``.
|
||||||
|
- ``request_handler``: a coroutine that takes a ``sanic.request.Request`` object
|
||||||
|
and a ``response`` callback as arguments.
|
||||||
|
- ``error_handler``: a ``sanic.exceptions.Handler`` which is called when exceptions
|
||||||
|
are raised.
|
||||||
|
- ``request_timeout``: the number of seconds before a request times out.
|
||||||
|
- ``request_max_size``: an integer specifying the maximum size of a request, in bytes.
|
||||||
|
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
An error occurs in the default protocol if a handler function does not return
|
||||||
|
an ``HTTPResponse`` object.
|
||||||
|
|
||||||
|
By overriding the ``write_response`` protocol method, if a handler returns a
|
||||||
|
string it will be converted to an ``HTTPResponse object``.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
from sanic import Sanic
|
||||||
|
from sanic.server import HttpProtocol
|
||||||
|
from sanic.response import text
|
||||||
|
|
||||||
|
app = Sanic(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomHttpProtocol(HttpProtocol):
|
||||||
|
|
||||||
|
def __init__(self, *, loop, request_handler, error_handler,
|
||||||
|
signal, connections, request_timeout, request_max_size):
|
||||||
|
super().__init__(
|
||||||
|
loop=loop, request_handler=request_handler,
|
||||||
|
error_handler=error_handler, signal=signal,
|
||||||
|
connections=connections, request_timeout=request_timeout,
|
||||||
|
request_max_size=request_max_size)
|
||||||
|
|
||||||
|
def write_response(self, response):
|
||||||
|
if isinstance(response, str):
|
||||||
|
response = text(response)
|
||||||
|
self.transport.write(
|
||||||
|
response.output(self.request.version)
|
||||||
|
)
|
||||||
|
self.transport.close()
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
async def string(request):
|
||||||
|
return 'string'
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/1')
|
||||||
|
async def response(request):
|
||||||
|
return text('response')
|
||||||
|
|
||||||
|
app.run(host='0.0.0.0', port=8000, protocol=CustomHttpProtocol)
|
||||||
|
|
|
@ -11,6 +11,7 @@ A list of Sanic extensions created by the community.
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
- [Sanic JWT](https://github.com/ahopkins/sanic-jwt): Authentication, JWT, and permission scoping for Sanic.
|
- [Sanic JWT](https://github.com/ahopkins/sanic-jwt): Authentication, JWT, and permission scoping for Sanic.
|
||||||
|
- [Secure](https://github.com/cakinney/secure): Secure 🔒 is a lightweight package that adds optional security headers and cookie attributes for Python web frameworks.
|
||||||
- [Sessions](https://github.com/subyraman/sanic_session): Support for sessions. Allows using redis, memcache or an in memory store.
|
- [Sessions](https://github.com/subyraman/sanic_session): Support for sessions. Allows using redis, memcache or an in memory store.
|
||||||
- [CORS](https://github.com/ashleysommer/sanic-cors): A port of flask-cors.
|
- [CORS](https://github.com/ashleysommer/sanic-cors): A port of flask-cors.
|
||||||
- [Sanic-JWT-Extended](https://github.com/devArtoria/Sanic-JWT-Extended): Provides extended JWT support for
|
- [Sanic-JWT-Extended](https://github.com/devArtoria/Sanic-JWT-Extended): Provides extended JWT support for
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
# Logging
|
|
||||||
|
|
||||||
|
|
||||||
Sanic allows you to do different types of logging (access log, error log) on the requests based on the [python3 logging API](https://docs.python.org/3/howto/logging.html). You should have some basic knowledge on python3 logging if you want to create a new configuration.
|
|
||||||
|
|
||||||
### Quick Start
|
|
||||||
|
|
||||||
A simple example using default settings would be like this:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from sanic import Sanic
|
|
||||||
from sanic.log import logger
|
|
||||||
from sanic.response import text
|
|
||||||
|
|
||||||
app = Sanic('test')
|
|
||||||
|
|
||||||
@app.route('/')
|
|
||||||
async def test(request):
|
|
||||||
logger.info('Here is your log')
|
|
||||||
return text('Hello World!')
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run(debug=True, access_log=True)
|
|
||||||
```
|
|
||||||
|
|
||||||
After the server is running, you can see some messages looks like:
|
|
||||||
```
|
|
||||||
[2018-11-06 21:16:53 +0800] [24622] [INFO] Goin' Fast @ http://127.0.0.1:8000
|
|
||||||
[2018-11-06 21:16:53 +0800] [24667] [INFO] Starting worker [24667]
|
|
||||||
```
|
|
||||||
|
|
||||||
You can send a request to server and it will print the log messages:
|
|
||||||
```
|
|
||||||
[2018-11-06 21:18:53 +0800] [25685] [INFO] Here is your log
|
|
||||||
[2018-11-06 21:18:53 +0800] - (sanic.access)[INFO][127.0.0.1:57038]: GET http://localhost:8000/ 200 12
|
|
||||||
```
|
|
||||||
|
|
||||||
To use your own logging config, simply use `logging.config.dictConfig`, or
|
|
||||||
pass `log_config` when you initialize `Sanic` app:
|
|
||||||
|
|
||||||
```python
|
|
||||||
app = Sanic('test', log_config=LOGGING_CONFIG)
|
|
||||||
```
|
|
||||||
|
|
||||||
And to close logging, simply assign access_log=False:
|
|
||||||
|
|
||||||
```python
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run(access_log=False)
|
|
||||||
```
|
|
||||||
|
|
||||||
This would skip calling logging functions when handling requests.
|
|
||||||
And you could even do further in production to gain extra speed:
|
|
||||||
|
|
||||||
```python
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# disable debug messages
|
|
||||||
app.run(debug=False, access_log=False)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
By default, log_config parameter is set to use sanic.log.LOGGING_CONFIG_DEFAULTS dictionary for configuration.
|
|
||||||
|
|
||||||
There are three `loggers` used in sanic, and **must be defined if you want to create your own logging configuration**:
|
|
||||||
|
|
||||||
- sanic.root:<br>
|
|
||||||
Used to log internal messages.
|
|
||||||
|
|
||||||
- sanic.error:<br>
|
|
||||||
Used to log error logs.
|
|
||||||
|
|
||||||
- sanic.access:<br>
|
|
||||||
Used to log access logs.
|
|
||||||
|
|
||||||
#### Log format:
|
|
||||||
|
|
||||||
In addition to default parameters provided by python (asctime, levelname, message),
|
|
||||||
Sanic provides additional parameters for access logger with:
|
|
||||||
|
|
||||||
- host (str)<br>
|
|
||||||
request.ip
|
|
||||||
|
|
||||||
|
|
||||||
- request (str)<br>
|
|
||||||
request.method + " " + request.url
|
|
||||||
|
|
||||||
|
|
||||||
- status (int)<br>
|
|
||||||
response.status
|
|
||||||
|
|
||||||
|
|
||||||
- byte (int)<br>
|
|
||||||
len(response.body)
|
|
||||||
|
|
||||||
|
|
||||||
The default access log format is
|
|
||||||
```python
|
|
||||||
%(asctime)s - (%(name)s)[%(levelname)s][%(host)s]: %(request)s %(message)s %(status)d %(byte)d
|
|
||||||
```
|
|
103
docs/sanic/logging.rst
Normal file
103
docs/sanic/logging.rst
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
Logging
|
||||||
|
=======
|
||||||
|
|
||||||
|
Sanic allows you to do different types of logging (access log, error
|
||||||
|
log) on the requests based on the `python3 logging API`_. You should
|
||||||
|
have some basic knowledge on python3 logging if you want to create a new
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
Quick Start
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
A simple example using default settings would be like this:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
from sanic import Sanic
|
||||||
|
from sanic.log import logger
|
||||||
|
from sanic.response import text
|
||||||
|
|
||||||
|
app = Sanic('test')
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
async def test(request):
|
||||||
|
logger.info('Here is your log')
|
||||||
|
return text('Hello World!')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(debug=True, access_log=True)
|
||||||
|
|
||||||
|
After the server is running, you can see some messages looks like:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[2018-11-06 21:16:53 +0800] [24622] [INFO] Goin' Fast @ http://127.0.0.1:8000
|
||||||
|
[2018-11-06 21:16:53 +0800] [24667] [INFO] Starting worker [24667]
|
||||||
|
|
||||||
|
You can send a request to server and it will print the log messages:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[2018-11-06 21:18:53 +0800] [25685] [INFO] Here is your log
|
||||||
|
[2018-11-06 21:18:53 +0800] - (sanic.access)[INFO][127.0.0.1:57038]: GET http://localhost:8000/ 200 12
|
||||||
|
|
||||||
|
To use your own logging config, simply use
|
||||||
|
``logging.config.dictConfig``, or pass ``log_config`` when you
|
||||||
|
initialize ``Sanic`` app:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
app = Sanic('test', log_config=LOGGING_CONFIG)
|
||||||
|
|
||||||
|
And to close logging, simply assign access_log=False:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(access_log=False)
|
||||||
|
|
||||||
|
This would skip calling logging functions when handling requests. And
|
||||||
|
you could even do further in production to gain extra speed:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# disable debug messages
|
||||||
|
app.run(debug=False, access_log=False)
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
By default, ``log_config`` parameter is set to use
|
||||||
|
``sanic.log.LOGGING_CONFIG_DEFAULTS`` dictionary for configuration.
|
||||||
|
|
||||||
|
There are three ``loggers`` used in sanic, and **must be defined if you
|
||||||
|
want to create your own logging configuration**:
|
||||||
|
|
||||||
|
================ ==============================
|
||||||
|
Logger Name Usecase
|
||||||
|
================ ==============================
|
||||||
|
``sanic.root`` Used to log internal messages.
|
||||||
|
``sanic.error`` Used to log error logs.
|
||||||
|
``sanic.access`` Used to log access logs.
|
||||||
|
================ ==============================
|
||||||
|
|
||||||
|
Log format:
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
In addition to default parameters provided by python (``asctime``,
|
||||||
|
``levelname``, ``message``), Sanic provides additional parameters for
|
||||||
|
access logger with:
|
||||||
|
|
||||||
|
===================== ========================================== ========
|
||||||
|
Log Context Parameter Parameter Value Datatype
|
||||||
|
===================== ========================================== ========
|
||||||
|
``host`` ``request.ip`` str
|
||||||
|
``request`` ``request.method`` + " " + ``request.url`` str
|
||||||
|
``status`` ``response.status`` int
|
||||||
|
``byte`` ``len(response.body)`` int
|
||||||
|
===================== ========================================== ========
|
||||||
|
|
||||||
|
The default access log format is ``%(asctime)s - (%(name)s)[%(levelname)s][%(host)s]: %(request)s %(message)s %(status)d %(byte)d``
|
||||||
|
|
||||||
|
.. _python3 logging API: https://docs.python.org/3/howto/logging.html
|
|
@ -164,24 +164,24 @@ url = app.url_for('post_handler', post_id=5, arg_one='one', arg_two='two')
|
||||||
url = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'])
|
url = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'])
|
||||||
# /posts/5?arg_one=one&arg_one=two
|
# /posts/5?arg_one=one&arg_one=two
|
||||||
```
|
```
|
||||||
- Also some special arguments (`_anchor`, `_external`, `_scheme`, `_method`, `_server`) passed to `url_for` will have special url building (`_method` is not support now and will be ignored). For example:
|
- Also some special arguments (`_anchor`, `_external`, `_scheme`, `_method`, `_server`) passed to `url_for` will have special url building (`_method` is not supported now and will be ignored). For example:
|
||||||
```python
|
```python
|
||||||
url = app.url_for('post_handler', post_id=5, arg_one='one', _anchor='anchor')
|
url = app.url_for('post_handler', post_id=5, arg_one='one', _anchor='anchor')
|
||||||
# /posts/5?arg_one=one#anchor
|
# /posts/5?arg_one=one#anchor
|
||||||
|
|
||||||
url = app.url_for('post_handler', post_id=5, arg_one='one', _external=True)
|
url = app.url_for('post_handler', post_id=5, arg_one='one', _external=True)
|
||||||
# //server/posts/5?arg_one=one
|
# //server/posts/5?arg_one=one
|
||||||
# _external requires passed argument _server or SERVER_NAME in app.config or url will be same as no _external
|
# _external requires you to pass an argument _server or set SERVER_NAME in app.config if not url will be same as no _external
|
||||||
|
|
||||||
url = app.url_for('post_handler', post_id=5, arg_one='one', _scheme='http', _external=True)
|
url = app.url_for('post_handler', post_id=5, arg_one='one', _scheme='http', _external=True)
|
||||||
# http://server/posts/5?arg_one=one
|
# http://server/posts/5?arg_one=one
|
||||||
# when specifying _scheme, _external must be True
|
# when specifying _scheme, _external must be True
|
||||||
|
|
||||||
# you can pass all special arguments one time
|
# you can pass all special arguments at once
|
||||||
url = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'], arg_two=2, _anchor='anchor', _scheme='http', _external=True, _server='another_server:8888')
|
url = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'], arg_two=2, _anchor='anchor', _scheme='http', _external=True, _server='another_server:8888')
|
||||||
# http://another_server:8888/posts/5?arg_one=one&arg_one=two&arg_two=2#anchor
|
# http://another_server:8888/posts/5?arg_one=one&arg_one=two&arg_two=2#anchor
|
||||||
```
|
```
|
||||||
- All valid parameters must be passed to `url_for` to build a URL. If a parameter is not supplied, or if a parameter does not match the specified type, a `URLBuildError` will be thrown.
|
- All valid parameters must be passed to `url_for` to build a URL. If a parameter is not supplied, or if a parameter does not match the specified type, a `URLBuildError` will be raised.
|
||||||
|
|
||||||
## WebSocket routes
|
## WebSocket routes
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ async def feed(request, ws):
|
||||||
app.add_websocket_route(my_websocket_handler, '/feed')
|
app.add_websocket_route(my_websocket_handler, '/feed')
|
||||||
```
|
```
|
||||||
|
|
||||||
Handlers for a WebSocket route are passed the request as first argument, and a
|
Handlers to a WebSocket route are invoked with the request as first argument, and a
|
||||||
WebSocket protocol object as second argument. The protocol object has `send`
|
WebSocket protocol object as second argument. The protocol object has `send`
|
||||||
and `recv` methods to send and receive data respectively.
|
and `recv` methods to send and receive data respectively.
|
||||||
|
|
||||||
|
@ -243,7 +243,8 @@ app.blueprint(bp)
|
||||||
|
|
||||||
## User defined route name
|
## User defined route name
|
||||||
|
|
||||||
You can pass `name` to change the route name to avoid using the default name (`handler.__name__`).
|
A custom route name can be used by passing a `name` argument while registering the route which will
|
||||||
|
override the default route name generated using the `handler.__name__` attribute.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
|
@ -305,8 +306,8 @@ def handler(request):
|
||||||
|
|
||||||
## Build URL for static files
|
## Build URL for static files
|
||||||
|
|
||||||
You can use `url_for` for static file url building now.
|
Sanic supports using `url_for` method to build static file urls. In case if the static url
|
||||||
If it's for file directly, `filename` can be ignored.
|
is pointing to a directory, `filename` parameter to the `url_for` can be ignored. q
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
WebSocket
|
WebSocket
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Sanic supports websockets, to setup a WebSocket:
|
Sanic provides an easy to user abstraction on top of `websockets`. To setup a WebSocket:
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ decorator:
|
||||||
app.add_websocket_route(feed, '/feed')
|
app.add_websocket_route(feed, '/feed')
|
||||||
|
|
||||||
|
|
||||||
Handlers for a WebSocket route are passed the request as first argument, and a
|
Handlers for a WebSocket route is invoked with the request as first argument, and a
|
||||||
WebSocket protocol object as second argument. The protocol object has ``send``
|
WebSocket protocol object as second argument. The protocol object has ``send``
|
||||||
and ``recv`` methods to send and receive data respectively.
|
and ``recv`` methods to send and receive data respectively.
|
||||||
|
|
||||||
|
|
199
release.py
199
release.py
|
@ -14,13 +14,22 @@ from requests import patch
|
||||||
GIT_COMMANDS = {
|
GIT_COMMANDS = {
|
||||||
"get_tag": ["git describe --tags --abbrev=0"],
|
"get_tag": ["git describe --tags --abbrev=0"],
|
||||||
"commit_version_change": [
|
"commit_version_change": [
|
||||||
"git add . && git commit -m 'Bumping up version from {current_version} to {new_version}'"],
|
"git add . && git commit -m 'Bumping up version from "
|
||||||
"create_new_tag": ["git tag -a {new_version} -m 'Bumping up version from {current_version} to {new_version}'"],
|
"{current_version} to {new_version}'"
|
||||||
|
],
|
||||||
|
"create_new_tag": [
|
||||||
|
"git tag -a {new_version} -m 'Bumping up version from "
|
||||||
|
"{current_version} to {new_version}'"
|
||||||
|
],
|
||||||
"push_tag": ["git push origin {new_version}"],
|
"push_tag": ["git push origin {new_version}"],
|
||||||
"get_change_log": ['git log --no-merges --pretty=format:"%h::: %cn::: %s" {current_version}..']
|
"get_change_log": [
|
||||||
|
'git log --no-merges --pretty=format:"%h::: %cn::: %s" '
|
||||||
|
"{current_version}.."
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
RELASE_NOTE_TEMPLATE = """
|
|
||||||
|
RELEASE_NOTE_TEMPLATE = """
|
||||||
# {{ release_name }} - {% now 'utc', '%Y-%m-%d' %}
|
# {{ release_name }} - {% now 'utc', '%Y-%m-%d' %}
|
||||||
|
|
||||||
To see the exhaustive list of pull requests included in this release see:
|
To see the exhaustive list of pull requests included in this release see:
|
||||||
|
@ -37,23 +46,25 @@ https://github.com/huge-success/sanic/milestone/{{milestone}}?closed=1
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
JINJA_RELASE_NOTE_TEMPLATE = Environment(
|
JINJA_RELEASE_NOTE_TEMPLATE = Environment(
|
||||||
loader=BaseLoader, extensions=['jinja2_time.TimeExtension']).from_string(RELASE_NOTE_TEMPLATE)
|
loader=BaseLoader, extensions=["jinja2_time.TimeExtension"]
|
||||||
|
).from_string(RELEASE_NOTE_TEMPLATE)
|
||||||
|
|
||||||
RELEASE_NOTE_UPDATE_URL = \
|
RELEASE_NOTE_UPDATE_URL = (
|
||||||
"https://api.github.com/repos/huge-success/sanic/releases/tags/{new_version}?access_token={token}"
|
"https://api.github.com/repos/huge-success/sanic/releases/tags/"
|
||||||
|
"{new_version}?access_token={token}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _run_shell_command(command: list):
|
def _run_shell_command(command: list):
|
||||||
try:
|
try:
|
||||||
process = Popen(command, stderr=PIPE, stdout=PIPE, stdin=PIPE,
|
process = Popen(
|
||||||
shell=True)
|
command, stderr=PIPE, stdout=PIPE, stdin=PIPE, shell=True
|
||||||
|
)
|
||||||
output, error = process.communicate()
|
output, error = process.communicate()
|
||||||
return_code = process.returncode
|
return_code = process.returncode
|
||||||
return output.decode("utf-8"), error, return_code
|
return output.decode("utf-8"), error, return_code
|
||||||
except:
|
except:
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
return None, None, -1
|
return None, None, -1
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +77,10 @@ def _fetch_current_version(config_file: str) -> str:
|
||||||
config_parser = RawConfigParser()
|
config_parser = RawConfigParser()
|
||||||
with open(config_file) as cfg:
|
with open(config_file) as cfg:
|
||||||
config_parser.read_file(cfg)
|
config_parser.read_file(cfg)
|
||||||
return config_parser.get("version", "current_version") or _fetch_default_calendar_release_version()
|
return (
|
||||||
|
config_parser.get("version", "current_version")
|
||||||
|
or _fetch_default_calendar_release_version()
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return _fetch_default_calendar_release_version()
|
return _fetch_default_calendar_release_version()
|
||||||
|
|
||||||
|
@ -77,8 +91,11 @@ def _change_micro_version(current_version: str):
|
||||||
return ".".join(version_string)
|
return ".".join(version_string)
|
||||||
|
|
||||||
|
|
||||||
def _get_new_version(config_file: str = "./setup.cfg", current_version: str = None,
|
def _get_new_version(
|
||||||
micro_release: bool = False):
|
config_file: str = "./setup.cfg",
|
||||||
|
current_version: str = None,
|
||||||
|
micro_release: bool = False,
|
||||||
|
):
|
||||||
if micro_release:
|
if micro_release:
|
||||||
if current_version:
|
if current_version:
|
||||||
return _change_micro_version(current_version)
|
return _change_micro_version(current_version)
|
||||||
|
@ -100,16 +117,21 @@ def _get_current_tag(git_command_name="get_tag"):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _update_release_version_for_sanic(current_version, new_version, config_file):
|
def _update_release_version_for_sanic(
|
||||||
|
current_version, new_version, config_file
|
||||||
|
):
|
||||||
config_parser = RawConfigParser()
|
config_parser = RawConfigParser()
|
||||||
with open(config_file) as cfg:
|
with open(config_file) as cfg:
|
||||||
config_parser.read_file(cfg)
|
config_parser.read_file(cfg)
|
||||||
config_parser.set("version", "current_version", new_version)
|
config_parser.set("version", "current_version", new_version)
|
||||||
|
|
||||||
version_file = config_parser.get("version", "file")
|
version_file = config_parser.get("version", "file")
|
||||||
current_version_line = config_parser.get("version", "current_version_pattern").format(
|
current_version_line = config_parser.get(
|
||||||
current_version=current_version)
|
"version", "current_version_pattern"
|
||||||
new_version_line = config_parser.get("version", "new_version_pattern").format(new_version=new_version)
|
).format(current_version=current_version)
|
||||||
|
new_version_line = config_parser.get(
|
||||||
|
"version", "new_version_pattern"
|
||||||
|
).format(new_version=new_version)
|
||||||
|
|
||||||
with open(version_file) as init_file:
|
with open(version_file) as init_file:
|
||||||
data = init_file.read()
|
data = init_file.read()
|
||||||
|
@ -122,10 +144,16 @@ def _update_release_version_for_sanic(current_version, new_version, config_file)
|
||||||
config_parser.write(config)
|
config_parser.write(config)
|
||||||
|
|
||||||
command = GIT_COMMANDS.get("commit_version_change")
|
command = GIT_COMMANDS.get("commit_version_change")
|
||||||
command[0] = command[0].format(new_version=new_version, current_version=current_version)
|
command[0] = command[0].format(
|
||||||
|
new_version=new_version, current_version=current_version
|
||||||
|
)
|
||||||
_, err, ret = _run_shell_command(command)
|
_, err, ret = _run_shell_command(command)
|
||||||
if int(ret) != 0:
|
if int(ret) != 0:
|
||||||
print("Failed to Commit Version upgrade changes to Sanic: {}".format(err.decode("utf-8")))
|
print(
|
||||||
|
"Failed to Commit Version upgrade changes to Sanic: {}".format(
|
||||||
|
err.decode("utf-8")
|
||||||
|
)
|
||||||
|
)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,20 +172,25 @@ def _generate_change_log(current_version: str = None):
|
||||||
|
|
||||||
for line in str(output).split("\n"):
|
for line in str(output).split("\n"):
|
||||||
commit, author, description = line.split(":::")
|
commit, author, description = line.split(":::")
|
||||||
if 'GitHub' not in author:
|
if "GitHub" not in author:
|
||||||
commit_details["authors"][author] = 1
|
commit_details["authors"][author] = 1
|
||||||
commit_details["commits"].append(" - ".join([commit, description]))
|
commit_details["commits"].append(" - ".join([commit, description]))
|
||||||
|
|
||||||
return commit_details
|
return commit_details
|
||||||
|
|
||||||
|
|
||||||
def _generate_markdown_document(milestone, release_name, current_version, release_version):
|
def _generate_markdown_document(
|
||||||
global JINJA_RELASE_NOTE_TEMPLATE
|
milestone, release_name, current_version, release_version
|
||||||
|
):
|
||||||
|
global JINJA_RELEASE_NOTE_TEMPLATE
|
||||||
release_name = release_name or release_version
|
release_name = release_name or release_version
|
||||||
change_log = _generate_change_log(current_version=current_version)
|
change_log = _generate_change_log(current_version=current_version)
|
||||||
return JINJA_RELASE_NOTE_TEMPLATE.render(
|
return JINJA_RELEASE_NOTE_TEMPLATE.render(
|
||||||
release_name=release_name, milestone=milestone, changelogs=change_log["commits"],
|
release_name=release_name,
|
||||||
authors=change_log["authors"].keys())
|
milestone=milestone,
|
||||||
|
changelogs=change_log["commits"],
|
||||||
|
authors=change_log["authors"].keys(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _tag_release(new_version, current_version, milestone, release_name, token):
|
def _tag_release(new_version, current_version, milestone, release_name, token):
|
||||||
|
@ -165,25 +198,27 @@ def _tag_release(new_version, current_version, milestone, release_name, token):
|
||||||
global RELEASE_NOTE_UPDATE_URL
|
global RELEASE_NOTE_UPDATE_URL
|
||||||
for command_name in ["create_new_tag", "push_tag"]:
|
for command_name in ["create_new_tag", "push_tag"]:
|
||||||
command = GIT_COMMANDS.get(command_name)
|
command = GIT_COMMANDS.get(command_name)
|
||||||
command[0] = command[0].format(new_version=new_version, current_version=current_version)
|
command[0] = command[0].format(
|
||||||
|
new_version=new_version, current_version=current_version
|
||||||
|
)
|
||||||
out, error, ret = _run_shell_command(command=command)
|
out, error, ret = _run_shell_command(command=command)
|
||||||
if int(ret) != 0:
|
if int(ret) != 0:
|
||||||
print("Failed to execute the command: {}".format(command[0]))
|
print("Failed to execute the command: {}".format(command[0]))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
change_log = _generate_markdown_document(milestone, release_name, current_version, new_version)
|
change_log = _generate_markdown_document(
|
||||||
|
milestone, release_name, current_version, new_version
|
||||||
|
)
|
||||||
|
|
||||||
body = {
|
body = {"name": release_name or new_version, "body": change_log}
|
||||||
"name": release_name or new_version,
|
|
||||||
"body": change_log
|
|
||||||
}
|
|
||||||
|
|
||||||
headers = {
|
headers = {"content-type": "application/json"}
|
||||||
"content-type": "application/json"
|
|
||||||
}
|
|
||||||
|
|
||||||
response = patch(RELEASE_NOTE_UPDATE_URL.format(new_version=new_version, token=token),
|
response = patch(
|
||||||
data=dumps(body), headers=headers)
|
RELEASE_NOTE_UPDATE_URL.format(new_version=new_version, token=token),
|
||||||
|
data=dumps(body),
|
||||||
|
headers=headers,
|
||||||
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,31 +226,79 @@ def release(args: Namespace):
|
||||||
current_tag = _get_current_tag()
|
current_tag = _get_current_tag()
|
||||||
current_version = _fetch_current_version(args.config)
|
current_version = _fetch_current_version(args.config)
|
||||||
if current_tag and current_version not in current_tag:
|
if current_tag and current_version not in current_tag:
|
||||||
print("Tag mismatch between what's in git and what was provided by --current-version. "
|
print(
|
||||||
"Existing: {}, Give: {}".format(current_tag, current_version))
|
"Tag mismatch between what's in git and what was provided by "
|
||||||
|
"--current-version. Existing: {}, Give: {}".format(
|
||||||
|
current_tag, current_version
|
||||||
|
)
|
||||||
|
)
|
||||||
exit(1)
|
exit(1)
|
||||||
new_version = args.release_version or _get_new_version(args.config, current_version, args.micro_release)
|
new_version = args.release_version or _get_new_version(
|
||||||
_update_release_version_for_sanic(current_version=current_version, new_version=new_version, config_file=args.config)
|
args.config, current_version, args.micro_release
|
||||||
_tag_release(current_version=current_version, new_version=new_version,
|
)
|
||||||
milestone=args.milestone, release_name=args.release_name, token=args.token)
|
_update_release_version_for_sanic(
|
||||||
|
current_version=current_version,
|
||||||
|
new_version=new_version,
|
||||||
|
config_file=args.config,
|
||||||
|
)
|
||||||
|
_tag_release(
|
||||||
|
current_version=current_version,
|
||||||
|
new_version=new_version,
|
||||||
|
milestone=args.milestone,
|
||||||
|
release_name=args.release_name,
|
||||||
|
token=args.token,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
cli = ArgumentParser(description="Sanic Release Manager")
|
cli = ArgumentParser(description="Sanic Release Manager")
|
||||||
cli.add_argument("--release-version", "-r", help="New Version to use for Release",
|
cli.add_argument(
|
||||||
|
"--release-version",
|
||||||
|
"-r",
|
||||||
|
help="New Version to use for Release",
|
||||||
default=_fetch_default_calendar_release_version(),
|
default=_fetch_default_calendar_release_version(),
|
||||||
required=False)
|
required=False,
|
||||||
cli.add_argument("--current-version", "-cv", help="Current Version to default in case if you don't want to "
|
)
|
||||||
|
cli.add_argument(
|
||||||
|
"--current-version",
|
||||||
|
"-cv",
|
||||||
|
help="Current Version to default in case if you don't want to "
|
||||||
"use the version configuration files",
|
"use the version configuration files",
|
||||||
default=None, required=False)
|
default=None,
|
||||||
cli.add_argument("--config", "-c", help="Configuration file used for release", default="./setup.cfg",
|
required=False,
|
||||||
required=False)
|
)
|
||||||
cli.add_argument("--token", "-t", help="Git access token with necessary access to Huge Sanic Org",
|
cli.add_argument(
|
||||||
required=True)
|
"--config",
|
||||||
cli.add_argument("--milestone", "-ms", help="Git Release milestone information to include in relase note",
|
"-c",
|
||||||
required=True)
|
help="Configuration file used for release",
|
||||||
cli.add_argument("--release-name", "-n", help="Release Name to use if any", required=False)
|
default="./setup.cfg",
|
||||||
cli.add_argument("--micro-release", "-m", help="Micro Release with patches only",
|
required=False,
|
||||||
default=False, action='store_true', required=False)
|
)
|
||||||
|
cli.add_argument(
|
||||||
|
"--token",
|
||||||
|
"-t",
|
||||||
|
help="Git access token with necessary access to Huge Sanic Org",
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
cli.add_argument(
|
||||||
|
"--milestone",
|
||||||
|
"-ms",
|
||||||
|
help="Git Release milestone information to include in relase note",
|
||||||
|
required=True,
|
||||||
|
)
|
||||||
|
cli.add_argument(
|
||||||
|
"--release-name",
|
||||||
|
"-n",
|
||||||
|
help="Release Name to use if any",
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
cli.add_argument(
|
||||||
|
"--micro-release",
|
||||||
|
"-m",
|
||||||
|
help="Micro Release with patches only",
|
||||||
|
default=False,
|
||||||
|
action="store_true",
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
args = cli.parse_args()
|
args = cli.parse_args()
|
||||||
release(args)
|
release(args)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user