Compare commits

...

1505 Commits

Author SHA1 Message Date
Harsha Narayana
d758f7c6df GIT1505: Backport changes from #1502 to 18.12LTS (#1507)
* GIT1505: backport changes from #1502 to 18.12LTS

* GIT1505: fix pytest version to address UT failures

* fix: GIT1505: fix unittests with caplog and some other warnings

Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-06 08:36:03 -06:00
7
aa7f2759a6 Merge pull request #1438 from yunstanford/master
18.12 Release
2018-12-27 11:15:07 -08:00
Yun Xu
9b9dd67797 adopt CalVer: MM.YY.MICRO, 18.12.0 release 2018-12-27 11:00:38 -08:00
7
3f73bc075a Merge pull request #1437 from FlouieInCl/master
Fix typo in exceptions.md
2018-12-27 09:59:00 -08:00
Yun Xu
56989a017b 18.12 release 2018-12-27 08:55:17 -08:00
JeongKyungSeo
ada5918bc8 Fix typo in exceptions.md 2018-12-27 16:11:37 +09:00
Jacob
4efd450b32 Add tests (#1433)
* Add tests for remove_route()

* Add tests for sanic/router.py

* Add tests for sanic/cookies.py

* Disable reset logging in test_logging.py

* Add tests for sanic/request.py

* Add tests for ContentRangeHandler

* Add tests for exception at response middleware

* Fix cached_handlers for ErrorHandler.lookup()

* Add test for websocket request timeout

* Add tests for getting cookies of StreamResponse, Remove some unused variables in tests/test_cookies.py

* Add tests for nested error handle
2018-12-22 09:21:45 -06:00
Omar Ryhan
d2670664ba Update exceptions.md (#1431)
Documented error handling from ``app.error_handler.add``
Documented custom error handling by subclassing.
2018-12-22 09:21:03 -06:00
7
fa7405fe9c Merge pull request #1422 from ashleysommer/server_slots
Add in some server.py __slots__ attribute names that are missing.
2018-12-15 13:58:22 -08:00
Jacob
33297f48a5 Add tests (#1430) 2018-12-13 11:50:50 -06:00
Ashley Sommer
06297a1918 Add in some server.py __slots__ property names that are missing. 2018-12-03 11:22:17 +10:00
Harsha Narayana
aa0874b6d8 100% Coverage for Sanic Blueprint (#1419)
* add unit tests to completely cover blueprints

Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>

* fix typo in the unit test code

Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2018-11-25 13:56:34 -06:00
7
822ced6294 Merge pull request #1416 from chenjr0719/add_tests_for_static
Add tests for static and update document
2018-11-21 23:01:37 +08:00
jacob
1a59614f79 Add stream_large_files and host examples in static_file document 2018-11-20 14:28:08 +08:00
jacob
f2d528e52a Add tests for static 2018-11-20 12:28:00 +08:00
Hasan Ramezani
f7adc5f84c Fix remove_entity_headers helper function (#1415)
* Fix `remove_entity_headers` helper function

* Add test for `remove_entity_headers` helper function
2018-11-19 09:30:53 -06:00
7
e955e833c4 Merge pull request #33 from huge-success/master
Merge upstream master branch
2018-11-16 13:02:16 +08:00
Tim&Anna
096c44b910 Update extensions.md (#1263)
* Update extensions.md

add an extension: sanic-script

* Update extensions.md
2018-11-14 07:16:43 -06:00
Nir Galon
efb9a42045 Change deprecated verify_ssl to ssl (#1155) 2018-11-14 07:16:14 -06:00
7
296cda7801 Merge pull request #1411 from devArtoria/patch-2
ADD: Sanic-JWT-Extended extension to extension docs
2018-11-13 13:49:35 +08:00
Lewis
90b9d73244 ADD: Sanic-JWT-Extended extension 2018-11-13 14:39:29 +09:00
Richard K
c8b0e7f2a7 Created methods to append and finish body content on Request (#1379)
* created methods to append and finish body content on request.py so the underlying body instance can have certain flexibility; modified server.py to reflect these changes

* - made some adjustments (including the Request.body_init method) as requested by @ahopkins;
- created a new test with a custom Request class implementation of the flexibility provided by the new methods;
2018-11-12 09:11:41 -06:00
7
6ce88ab5a4 Merge pull request #1400 from chenjr0719/add_tests_for_log
Add test for sanic.root logger and update the docs of logging
2018-11-12 20:45:05 +08:00
7
e13ab805df Merge pull request #1409 from yunstanford/windows-ci
CI Support for Windows
2018-11-12 20:05:21 +08:00
Yun Xu
e58ea8c7b4 fix unit test for windows ci
fix unit tests for windows ci

add appveyor build status badge

add readthedoc build status badge
2018-11-12 01:04:53 -08:00
jacob
dd5bac61cb Update document for logging 2018-11-12 16:09:12 +08:00
Jacob
6270b27a97 Merge branch 'master' into add_tests_for_log 2018-11-12 09:53:44 +08:00
Hasan Ramezani
f89ba1d39f Add tests for is_entity_header and is_hop_by_hop_header helper functions (#1410) 2018-11-11 10:57:57 -06:00
Yun Xu
8b5d137d8f fix .appveyor.yml 2018-11-10 06:11:01 -08:00
Yun Xu
2629fab649 add .appveyor.yml for windows ci support 2018-11-10 05:50:22 -08:00
7
92cd10c6a8 Merge pull request #32 from huge-success/master
merge upstream master branch
2018-11-10 21:26:37 +08:00
7
cc3edb90dc Merge pull request #1408 from harshanarayana/feature/Unit_Test_Enhancements
Additional Unit Tests
2018-11-10 20:46:51 +08:00
Harsha Narayana
c60ba81984 cleanup stale test for cookie object
Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2018-11-10 16:54:24 +05:30
Harsha Narayana
ece3cdaa2e add unit tests for App Config, Cokkies and Request handler
Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2018-11-10 16:50:30 +05:30
7
4cb40f2042 Merge pull request #1403 from harshanarayana/fix/GIT-1398-Http_Response_Content_Length_Mismatch
Fix Content-Length Mismatch while using json and ujson
2018-11-10 00:14:03 +08:00
7
0e9f350982 Merge pull request #1405 from hramezani/test_has_message_body
Add test for has_message_body helper function.
2018-11-08 22:20:07 +08:00
Hasan Ramezani
cf439f01f8 Add test for has_message_body helper function. 2018-11-07 21:29:12 +01:00
Harsha Narayana
f1f1b8a630 add additional test cases to validate Content-Length header
Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2018-11-07 22:07:28 +05:30
Harsha Narayana
d4d1df03c9 fix content length mismatch in windows and other platform
The current implementation of `sanic` attempts to make use of `ujson` if
it's available in the system and if not, it will default to the inbuilt
`json` module provided by python.

The current implementation of `ujson` does not provide a mechanism to
provide a custom `seperators` parameter as part of the `dumps` method
invocation and the default behavior of the module is to strip all the
spaces around seperators such as `:` and `,`. This leads to an
inconsistency in the response length when the response is generated
using the `ujson` and in built `json` module provided by python.

To maintain the consistency, this commit overrides the default behavior
of the `dumps` method provided by the `json` module to add a `seperators`
argument that will strip the white spaces around these character like
the default behavior of `ujson`

This addresses the issue referenced in #1398

Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2018-11-07 21:38:32 +05:30
Harsha Narayana
92b73a6f4f fix Range header handling for static files (#1402)
This commit fixes the issue in the `Range` header handling that was done
while serving the file contents.

As per the HTTP response standards, a status code of 206 will be used in
case if the Range is returning a partial value and default of 200 in
other cases.

Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2018-11-07 07:36:56 -06:00
Meng Wang
b63c06c75a fix the logger and make it work (#1397)
* fix the logger and make it work

* modify test_logging parameters and add a new unit test
2018-11-06 08:39:38 -06:00
jacob
3e3bce422e Add test for sanic.root logger and update the docs of logging 2018-11-06 21:27:01 +08:00
Stephen Sadowski
e3a27c2cc4 Merge pull request #1391 from AndresSan6/loop_exception
Handle "loop" exception in app.py
2018-11-05 08:19:01 -06:00
Stephen Sadowski
f13f451084 Merge pull request #1385 from lixxu/master
update doc for latest blueprint code
2018-11-05 07:40:12 -06:00
Stephen Sadowski
df0e3de911 Merge pull request #1393 from ashleysommer/pickleable-app-blueprint
Fix pickling blueprints Fixes #1392
2018-11-05 07:24:15 -06:00
Ashley Sommer
8466be8728 Fix type pikcle->pickle in multiprocessing test 2018-11-04 15:27:25 +10:00
Ashley Sommer
5cf2144b3f Fix pickling blueprints
Change the string passed in the "name" section of the namedtuples in Blueprint to match the name of the Blueprint module attribute name.
This allows blueprints to be pickled and unpickled, without errors, which is a requirment of running Sanic in multiprocessing mode in Windows.
Added a test for pickling and unpickling blueprints
Added a test for pickling and unpickling sanic itself
Added a test for enabling multiprocessing on an app with a blueprint (only useful to catch this bug if the tests are run on Windows).
2018-11-04 15:04:12 +10:00
Andres Sanchez
7c182f63c8 Indentation fix 2018-11-01 10:59:45 -06:00
Andres Sanchez
056180782c Removed unnecessary changes to request and router files, changes to fix lint test 2018-11-01 10:53:53 -06:00
Andres Sanchez
ff0d5870e9 Merge branch 'lintfix' into loop_exception
Made changes unnecesarry changes in request and router files, went back to previous commit and made correct changes to fix lint
2018-11-01 10:40:47 -06:00
Andres Sanchez
b70176f8c7 Fixed character limit per line in requested changes for app.py 2018-11-01 10:36:34 -06:00
Andres Sanchez
e3655b525d Modifications to ruequest and router files to fix linting issues. 2018-11-01 10:04:40 -06:00
Andres Sanchez
e63d0091af Assert was chnaged for an if and updated error messages 2018-10-31 15:23:29 -06:00
Andres Sanchez
7b0af2d80d Handle loop exception in app.py 2018-10-31 13:35:03 -06:00
Stephen Sadowski
7d79a86d4d Merge pull request #1387 from huge-success/docbuild
Resolve build of latex documentation relating to markdown lists
2018-10-30 16:13:29 -05:00
Adam Hopkins
ba46aff069 Resolve build of latex documentation relating to markdown lists 2018-10-30 22:39:17 +02:00
lixxu
7a65471ba5 update doc for latest blueprint code 2018-10-29 16:54:34 +08:00
Stephen Sadowski
c7c46da975 Merge pull request #1383 from huge-success/docbuild
Fix documentation build errors
2018-10-26 08:19:10 -05:00
Adam Hopkins
c708e8425f Fix documentation build errors 2018-10-26 11:57:28 +03:00
Eli Uriegas
905c51bef0 Merge pull request #1371 from yunstanford/integrate-isort
codestyle: Integrate isort
2018-10-23 16:05:36 -07:00
Eli Uriegas
bd87098b7e Merge pull request #1368 from yunstanford/fix-redirect
Add '%' to quote_plus's `safe` parameter in response.redirect
2018-10-23 15:12:02 -07:00
Eli Uriegas
5f486cc25f Merge pull request #1378 from hramezani/fix_some_lint_error
Fix some test files lint errors.
2018-10-23 15:10:15 -07:00
Eli Uriegas
f79fb72a33 Merge pull request #1377 from yunstanford/fix-readthedoc-build
Fix readthedoc build
2018-10-23 15:07:25 -07:00
Yun Xu
0505aa2dda refactor import 2018-10-23 14:53:39 -07:00
Hasan Ramezani
485ff32e42 Fix all test files lint errors. 2018-10-23 11:04:17 +02:00
Stephen Sadowski
5ead67972f Merge pull request #1375 from sjsadowski/master
Added documentation for AF_INET6 and AF_UNIX socket usage
2018-10-21 15:28:40 -05:00
Yun Xu
9c860dbff3 fix readthedoc build 2018-10-21 01:56:48 -07:00
Stephen Sadowski
a20ad99638 Added documentation for AF_INET6 and AF_UNIX socket usage 2018-10-19 13:33:01 -05:00
Yun Xu
8ef7bf8e7b integrate with isort 2018-10-17 21:20:16 -07:00
7
0d5be1969a Merge pull request #31 from huge-success/master
Merge Upstream master branch
2018-10-17 21:02:44 -07:00
Adam Hopkins
d06ea9bfc3 Merge pull request #1370 from huge-success/ahopkins-patch-1
Update issue templates
2018-10-17 09:47:22 +03:00
Adam Hopkins
57e79882e1 Update issue templates 2018-10-16 15:42:52 +03:00
Yun Xu
20d1ab60c7 remove unused json import 2018-10-15 22:13:42 -07:00
Yun Xu
277c2ce2d2 fix redirect with quoted param 2018-10-15 21:53:11 -07:00
7
34e51f01d1 Merge pull request #30 from huge-success/master
Merge Upstream Master Branch
2018-10-15 20:04:57 -07:00
7
f4b4e3a58c Merge pull request #1366 from hramezani/lint_test_blueprints
Fix some lint errors and warnings in `tests/test_blueprints.py`
2018-10-14 21:02:48 -07:00
7
def2e033c8 Merge pull request #1365 from yunstanford/codestyle-black
Codestyle black
2018-10-14 10:07:09 -07:00
Hasan Ramezani
dfec18278b Fix some lint errors and warnings in tests/test_blueprints.py. 2018-10-14 16:09:47 +02:00
Yun Xu
cd5bdecda3 add codestyle badge in README 2018-10-13 18:33:02 -07:00
Yun Xu
9b6217ba41 fix travisci 2018-10-13 18:19:08 -07:00
Yun Xu
272f6e195d added black for lint check 2018-10-13 18:10:43 -07:00
Yun Xu
aa9bf04dfe run black against sanic module 2018-10-13 17:55:33 -07:00
7
9ae6dfb6d2 Merge pull request #29 from huge-success/master
merge upstream master branch
2018-10-13 17:28:32 -07:00
7
619bb79a2f Merge pull request #1336 from untitaker/logging-refactor
Try not to stringify exception in logging messages
2018-10-13 16:54:57 -07:00
7
0cad831eca Merge pull request #1364 from yunstanford/raise-exception-when-param-conflicts
Raise exception when param conflicts
2018-10-13 16:28:59 -07:00
Yun Xu
f15a7fb588 fix flake8 2018-10-12 23:06:43 -07:00
Yun Xu
1bdf9ca057 add py37 in setup.py 2018-10-12 22:58:49 -07:00
Yun Xu
c8c370b784 raise exception when param conflicts in route 2018-10-12 22:57:56 -07:00
7
63182f55f7 Merge pull request #28 from huge-success/master
Merge upstream master branch
2018-10-12 22:38:37 -07:00
Stephen Sadowski
41759248e2 Merge pull request #1361 from yunstanford/cancel-request-when-connection-lost
Cancel request when connection lost
2018-10-12 07:25:10 -05:00
Yun Xu
3149d5a66d add unit test for request_stream 2018-10-11 23:12:33 -07:00
Yun Xu
8b13597099 add unit tests for verifying 2018-10-11 23:02:21 -07:00
Yun Xu
36032cc26e cancel task when connection_lost 2018-10-11 22:38:26 -07:00
7
4cb107aedc Merge pull request #27 from huge-success/master
Merge upstream master branch
2018-10-11 22:34:09 -07:00
7
176f8d1981 Merge pull request #1358 from hramezani/fix_config_tests
Change the config test to remove `NamedTemporaryFile`
2018-10-11 21:39:48 -07:00
Hasan Ramezani
9a26030bd5 Change the config test to remove NamedTemporaryFile 2018-10-11 17:34:46 +02:00
Stephen Sadowski
6778f4d9e0 Merge pull request #1342 from hramezani/load_config_file_syntax_error
Handle syntax error in load config file.
2018-10-11 08:56:48 -05:00
Stephen Sadowski
fd61b9e3e2 Merge pull request #1327 from hatarist/fix-1323
Rename the `http` module to `helpers`
2018-10-11 07:56:51 -05:00
Stephen Sadowski
298d5cdf24 Merge pull request #1334 from chenjr0719/master
Fix TypeError when use Blueprint.group() to group blueprint with defa…
2018-10-11 07:28:10 -05:00
7
1bf1c9d006 Merge pull request #26 from huge-success/master
Merge upstream master branch
2018-10-10 20:33:57 -07:00
7
7dc62be5cf Merge pull request #1335 from abuckenheimer/fix_windows_unittests
unittests passing on windows again
2018-10-10 20:15:35 -07:00
jacob
be580a6a5b Clean up files created by pytest-html 2018-10-11 10:06:05 +08:00
7
8ce519668b Merge pull request #1353 from abn/fix-unhandled-exception
Simplify request ip and port retrieval logic
2018-10-09 23:33:51 -07:00
jacob
801258c46a Merge branch 'master' of github.com:chenjr0719/sanic 2018-10-10 14:04:45 +08:00
jacob
32a1db3622 Remove normpath 2018-10-10 14:04:21 +08:00
7
ed1f3daacc Merge pull request #1352 from devArtoria/patch-1
Fix missing quotes in decorator example
2018-10-08 21:57:34 -07:00
Alec Buckenheimer
b7d74c82ba simplified aiohttp version diffs, reverted worker import policy 2018-10-08 22:48:21 -04:00
Arun Babu Neelicattu
c3b31a6fb0 Simplify request ip and port retrieval logic
This change also ensures that cases where transport stream is
already closed is handled gracefully.
2018-10-08 21:25:47 +02:00
Hasan Ramezani
f4c55bbc07 Handle config error in load config file. 2018-10-08 19:17:06 +02:00
Lewis
a16842f7bc Fix missing quotes in decorator example 2018-10-08 18:59:15 +09:00
7
439a38664f Merge pull request #25 from huge-success/master
Merge upstream master branch
2018-10-07 20:32:52 -07:00
7
5cc12fd945 Merge pull request #1348 from hramezani/add_config_test
Add test for `config.from_object`.
2018-10-07 19:53:58 -07:00
7
fe116fff5a Merge pull request #1350 from hramezani/config_documentation
Add missed documentation for config section.
2018-10-07 13:58:06 -07:00
Stephen Sadowski
06aaaf4727 Merge pull request #1351 from yunstanford/integrate-with-codecov
Integrate with codecov
2018-10-07 10:13:31 -05:00
Yun Xu
6deb9b49b2 correct Codecov badge url 2018-10-06 21:39:04 -07:00
Yun Xu
d59e92d3e5 integrate with codecov 2018-10-06 21:31:04 -07:00
7
cc83c1f0cf Merge pull request #24 from huge-success/master
merge upstream master branch
2018-10-06 21:22:54 -07:00
Hasan Ramezani
1fe7306af8 Add missed documentation for config section. 2018-10-07 01:32:36 +02:00
Hasan Ramezani
c796d73fc3 Add test for config.from_object. 2018-10-07 00:14:37 +02:00
Markus Unterwaditzer
eb93f884f3 fix: Missing import 2018-10-05 16:47:12 +02:00
Markus Unterwaditzer
3673feb256 fix: typo 2018-10-05 16:33:46 +02:00
Markus Unterwaditzer
7c9c783e9d deprecate Handler.log 2018-10-05 16:31:01 +02:00
Stephen Sadowski
74a4b9efaa Merge pull request #1345 from huge-success/ahopkins-patch-1
Update README.rst
2018-10-04 18:45:47 -05:00
Stephen Sadowski
4466e8cce1 Merge pull request #1304 from ignatenkobrain/fedora
Switch to websockets 6.0
2018-10-04 18:45:22 -05:00
Adam Hopkins
b689037984 Update README.rst 2018-10-04 12:31:57 +03:00
Stephen Sadowski
db1ba21d88 Merge pull request #1343 from vltr/httptools_pinned
pinned httptools requirement to version 0.0.10+
2018-10-03 19:27:25 -05:00
Eli Uriegas
50d270ef7c Merge pull request #1316 from sjsadowski/master
Updated changelog.md for 0.8.x
2018-10-03 15:19:21 -07:00
Richard Kuesters
d1a578b555 pinned httptools requirement to version 0.0.10+ 2018-10-03 12:22:29 -03:00
Stephen Sadowski
76e9859cf8 Merge branch 'master' into master 2018-10-03 09:56:29 -05:00
Stephen Sadowski
add9d363c5 Merge branch 'master' into logging-refactor 2018-10-03 09:55:01 -05:00
Stephen Sadowski
1498baab0f Merge pull request #1338 from hramezani/improve_config_test
Check error message and fix some lint error in test config.
2018-10-03 09:18:46 -05:00
Stephen Sadowski
df7f63d45d Merge branch 'master' into improve_config_test 2018-10-03 06:30:44 -05:00
Stephen Sadowski
f7425126a1 Merge pull request #1341 from ashleysommer/unnecessary_code
Fixes #1340
2018-10-03 06:30:22 -05:00
Ashley Sommer
790047e450 Fixes #1340 2018-10-03 10:59:24 +10:00
Stephen Sadowski
9198b5b0be Merge branch 'master' into improve_config_test 2018-10-02 13:21:23 -05:00
Stephen Sadowski
d534acb79d Merge branch 'master' into logging-refactor 2018-10-01 15:41:07 -05:00
Hasan Ramezani
d100f54551 Check error message and fix some lint error in test config. 2018-10-01 20:36:21 +02:00
Stephen Sadowski
7a9e100b0f Merge branch 'master' into fix_windows_unittests 2018-10-01 10:10:48 -05:00
Stephen Sadowski
fafe23d7c2 Merge pull request #1337 from cmcaine/fix-error-msg
Fix whitespace in error message
2018-10-01 09:31:45 -05:00
Alec Buckenheimer
9a08bdae4a fix flake8 linelength errors 2018-10-01 09:46:18 -04:00
Colin Caine
bcc11fa7fe Fix whitespace in error message 2018-09-30 09:36:55 +01:00
Markus Unterwaditzer
7d0c0fdf7c fix: Namespacing of sanic logger 2018-09-29 22:40:05 +02:00
Markus Unterwaditzer
0e33d46ead Try not to stringify exception in logging messages
This just fixes the worst offenders that trip up error reporting tools
like Sentry.io
2018-09-29 22:32:51 +02:00
Alec Buckenheimer
efbacc17cf unittests passing on windows again 2018-09-29 13:54:47 -04:00
jacob
bd6dbd9090 Fix TypeError when use Blueprint.group() to group blueprint with default url_prefix, Use os.path.normpath to avoid invalid url_prefix like api//v1 2018-09-29 18:23:16 +08:00
Eli Uriegas
076cf51fb2 Merge pull request #1305 from Stranger6667/app-fixture
Reuse app fixture in tests
2018-09-26 18:30:46 -07:00
Igor Hatarist
f8a6af1e28 Rename the http module to helpers to prevent conflicts with the built-in Python http library (fixes #1323) 2018-09-25 20:46:40 +03:00
Stephen Sadowski
96912f436d Corrected Raphael Deem's name in changelog - sorry @r0fls! 2018-09-24 09:05:58 -05:00
Raphael Deem
f0e162442f Merge branch 'master' into app-fixture 2018-09-21 15:16:00 -07:00
Eli Uriegas
04b8dd989f Merge pull request #1315 from seemethere/multidocs
Add multidict to readthedocs environment.yml
2018-09-15 19:03:56 +02:00
Stephen Sadowski
5851c8bd91 revised formatting for CHANGELOG.md 2018-09-14 13:30:57 -05:00
Stephen Sadowski
78efcf93f8 Updated changelog for all accepted PRs from 0.7.0 to Current 2018-09-14 10:56:32 -05:00
Eli Uriegas
bb35bc3898 Add multidict to readthedocs environment.yml
Signed-off-by: Eli Uriegas <seemethere101@gmail.com>
2018-09-14 16:00:29 +02:00
Stephen Sadowski
f38783bdef Merge pull request #1 from huge-success/master
Merge from head
2018-09-14 08:20:37 -05:00
Channel Cat
d8f9986089 Re-releasing with updated credentials 2018-09-13 02:24:31 -07:00
Channel Cat
3e616b599a update encrypted creds for new org 2018-09-13 02:17:27 -07:00
Channel Cat
d38fc17191 Update version to test pypi 2018-09-13 01:50:32 -07:00
Channel Cat
7ae0eb0dc3 Transfer ownership 2018-09-13 01:39:24 -07:00
Channel Cat
9082eb56a7 Update version to circumvent pypi upload errors 2018-09-06 13:51:31 -07:00
Igor Gnatenko
c578974246 Switch to websockets 6.0
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
2018-09-02 09:23:30 +02:00
dmitry.dygalo
fec81ffe73 Reuse app fixture in tests 2018-08-26 16:43:14 +02:00
Ashley Sommer
30e6a310f1 Pausable response streams (#1179)
* This commit adds handlers for the asyncio/uvloop protocol callbacks for pause_writing and resume_writing.
These are needed for the correct functioning of built-in tcp flow-control provided by uvloop and asyncio.
This is somewhat of a breaking change, because the `write` function in user streaming callbacks now must be `await`ed.
This is necessary because it is possible now that the http protocol may be paused, and any calls to write may need to wait on an async event to be called to become unpaused.

Updated examples and tests to reflect this change.

This change does not apply to websocket connections. A change to websocket connections may be required to match this change.

* Fix a couple of PEP8 errors caused by previous rebase.

* update docs

add await syntax to response.write in response-streaming docs.

* remove commented out code from a test file
2018-08-18 18:12:13 -07:00
Eli Uriegas
a87934d434 Merge pull request #1292 from seemethere/increment_080
Increment to 0.8.0
2018-08-17 11:52:47 -07:00
Eli Uriegas
b398c1fe72 Increment to 0.8.0
Signed-off-by: Eli Uriegas <seemethere101@gmail.com>
2018-08-17 11:43:15 -07:00
Eli Uriegas
6f813f940e Merge pull request #1278 from ashleysommer/graceful_cancel
Gracefully handle when the request_handler_task is cancelled.
2018-08-17 11:41:39 -07:00
Eli Uriegas
d52498b787 Merge pull request #1284 from ashleysommer/aiohttp_update
Fix broken tests when aiohttp >= 3.3.0
2018-08-17 11:40:49 -07:00
Ashley Sommer
79e35bbdf6 Fix auto_reload in Linux (#1286)
* Fix two problems with the auto_reloader in Linux.
1) Change 'posix' to 'linux' in sys.plaform check, because 'posix' is an invalid value and 'linux' is the correct value to use here.
2) In kill_process_children, don't just kill the 2nd level procs, also kill the 1st level procs.
   Also in kill_process_children, catch and ignore errors in the case that the child proc is already killed.

* Fix flake8 formatting on PR
2018-08-16 23:30:03 -07:00
Innokenty Lebedev
1814ff05f4 Add sse extension (#1288) 2018-08-16 11:59:58 -07:00
Ashley Sommer
ec226e33cb Pin aiohttp <= 3.2.1 in requirements-dev.txt (fixes errors for new contributors checking out the code and setting up a dev environment)
Future-proof the some test cases so they work with aiohttp >= 3.3.0, in case we bump the aiohttp version in the future.
2018-08-16 15:00:23 +10:00
hqy
6abdf9f9c1 fixed #1143 (#1276)
* fixed #1143

* fixed build failed with create_serve call _helper failed
2018-08-15 10:23:04 -07:00
abuckenheimer
212da1029e disabled auto_reload by default in windows (#1280) 2018-08-07 11:48:18 -07:00
Ashley Sommer
afea15e4a7 Add a test for the graceful CancelledError handling. The user app should _never_ see a CancelledError bubble up, nor should they be able to catch it, because the response is already sent at that point. 2018-08-06 15:02:12 +10:00
Ashley Sommer
39ff02b6e4 Modifications the handle_request function to detect and gracefully handle the case that the request_handler Task is canceled by the sanic server while it is handling the request. One common occurrence of this is when the server issues a ResponseTimeout error, it also cancels the response_handler Task.
The Canceled exception handler purposely sets `response` to `None` to drop references to the handler coroutine, in an attempt to preemptively release resources.
This commit also fixes a possible reference-before-assignment of the `response` variable in the `handle_request` function.
Finally, another byproduct of this change is that ResponseMiddleware will no longer run if the `response` is `None`.
2018-08-06 14:12:30 +10:00
Cosmo Borsky
b238be54a4 Add content_type flag to Sanic.static (#1267)
* Add content_type flag to Sanic.static

Fixes #1266

* Fix flake8 error in travis

Add line to document `content_type` arg

* Fix content_type for file streams

Update tests

herp derp

* Remove content_type as an arg to HTTPResponse

`response.HTTPResponse` will default to `headers['Content-Type']` instead of `content_type`
https://github.com/channelcat/sanic/pull/1267#discussion_r204190913
2018-07-20 22:31:15 -07:00
Cosmo Borsky
377c9890a3 Support status code for file reponse (#1269)
Fixes #1268
2018-07-20 13:39:10 -07:00
ciscorn
599834b0e1 Add subprotocols param to add_websocket_route (#1261) 2018-07-16 12:20:26 -07:00
John Doe
a39a7ca9d5 Add url_bytes to Request (#1258)
We need to have access to the raw unparsed URL.
2018-07-16 12:13:27 -07:00
Ave
cd22745e6b Sanitize the URL before redirecting (#1260)
* URL Quote the URL before redirecting

* Use safe url instead of unsafe one

* Fix query params

* fix build

* Whitelist all reserved characters from rfc3986

* Add tests for redirect url sanitizing

* Remove check for resulting URL on header injection test

The thing the tests are testing for can be implemented in other
ways that don't redirect to 100% the same address, but they'll all have
to match the remaining parts of the test to succeed.
2018-07-12 21:31:33 -07:00
7
334649dfd4 Fix response ci header (#1244)
* add unit tests, which should fail

* fix CIDict

* moving CIDict to avoid circular imports

* fix unit tests

* use multidict for headers

* fix cookie

* add version constraint for multidict

* omit test coverage for __main__.py

* make flake8 happy

* consolidate check in for loop

* travisci retry build
2018-07-11 01:44:21 -07:00
fanjindong
becbc5f9ef fix one example and add one example (#1257) 2018-07-11 01:42:34 -07:00
7
a7dd73c657 Merge pull request #23 from channelcat/master
py37 (#1256)
2018-07-03 22:12:02 -07:00
7
f9b29fd7e7 py37 (#1256)
* add py37 to travisci

* use dist:xenial for py37

* sudo: true in .travici

* bump websockets version for py37 support and fix unit tests
2018-07-03 22:07:08 -07:00
7
f770e16f6d Merge pull request #22 from channelcat/master
merge upstream master branch
2018-06-26 23:33:35 -07:00
Arnulfo Solís
9092ee9f0e HTTP Entity Headers (#1127)
* introduced basic entity and hopbyhop header identification

* removed entity headers

* coding style fixes

* remove unneeded header check

* moved from bytes to unicode in headers

* changed list to tuple in empty response statuses
2018-06-26 22:25:25 -07:00
GaryO
01257f65a6 Make auto reloader work on Mac (#1249) 2018-06-18 15:16:10 -07:00
7
c1222175b3 Merge pull request #21 from channelcat/master
remote tracking
2018-06-10 20:17:27 -07:00
Volodymyr Maksymiv
5ff481952d add UUID support (#1241) 2018-06-09 01:16:17 -07:00
7
baa689ad43 Fix failed build and add websockets version specifier (#1239)
* add websockets version constraint

* fix failed build
2018-06-07 10:07:26 -07:00
Philip Xu
2f30f4f69f Fixed #1231 - release resource no matter what (#1232) 2018-06-06 14:43:57 -07:00
Raphael Deem
202a4c6525 make request truthy if has transport (#1222) 2018-05-16 14:12:12 -07:00
7
7928b9b3a2 Merge pull request #20 from channelcat/master
merge upstream master branch
2018-04-29 21:50:07 -07:00
Adam Hopkins
e1c9020268 Update extensions.md (#1205)
Changing the description of [Sanic JWT](https://github.com/ahopkins/sanic-jwt) to include permission scoping
2018-04-29 18:41:17 -07:00
Philip Xu
04a12b436e Added Sanic-Auth, Sanic-CookieSession and Sanic-WTF to Extensions doc (#1210) 2018-04-29 18:40:18 -07:00
Fantix King
818a8c2196 Added GINO to Extensions doc (#1200) 2018-04-21 21:02:49 -07:00
Arnulfo Solís
b6715464fd added init docs (#1167) 2018-04-01 20:53:08 -07:00
Raphael Deem
8f2d543d9f default to auto_reload in debug mode (#1159)
* default to auto_reload in debug mode

* disable auto-reload in testing client
2018-04-01 20:52:56 -07:00
Raphael Deem
6cf320bedb Merge pull request #1181 from kot83/patch-1
rename function in examples to post_json
2018-03-29 20:13:48 -07:00
kot83
a850ce5086 rename function to something else
function already defined
2018-03-29 15:57:10 -07:00
Raphael Deem
ef3bdf5408 Merge pull request #1180 from ashleysommer/fix_aiohttp_breakages
Fix failing tests when aiohttp>=3.1.0
2018-03-29 01:05:50 -07:00
Ashley Sommer
94b9bc7950 Some of the tests in Sanic (test_request_timout, test_response_timeout, test_keep_alive_timeout) use a custom SanicClient with modified methods. This relies on overriding internal aiohttp Client classes.
In aiohttp 3.1.0 there were some breaking changes that caused the custom methods to be no longer compatible with latest upstream aiohttp Client class.
See: 903073283f
and: b42e0ced46

This commit adds aiohttp version checks to adapt to these changes.
2018-03-29 11:54:59 +10:00
Raphael Deem
8a07463a67 Merge pull request #1175 from PyManiacGR/patch-1
Fix try_everything example.
2018-03-28 00:41:07 -07:00
PyManiac
2995b23929 Update try_everything.py 2018-03-24 15:55:15 +02:00
TheRubyDoggy
eb4276373b Fix try_everything example. 2018-03-24 15:34:41 +02:00
Raphael Deem
79df52e519 Merge pull request #1169 from charlax/patch-1
Clarify arguments to request/response middleware
2018-03-21 10:46:09 -07:00
Charles-Axel Dein
3dfb31b1b9 Clarify arguments to request/response middleware 2018-03-21 12:07:26 +01:00
Raphael Deem
c4c4ed70d9 Merge pull request #1163 from vopankov/master
Add __weakref__ to Request slots
2018-03-17 14:52:25 -07:00
Raphael Deem
45422df1b7 Merge pull request #1162 from yunstanford/fix-hang-build
Fix hang build and failed builds
2018-03-16 11:14:44 -07:00
Yun Xu
e0b7624414 fix hang build 2018-03-15 22:06:58 -07:00
Yun Xu
b0ecb3170f fix hang build 2018-03-15 22:03:36 -07:00
Yun Xu
fc8b5f378a migrate to trusty 2018-03-15 21:39:21 -07:00
Yun Xu
d42cb7ddb3 fix hang build 2018-03-15 21:28:52 -07:00
Панков Василий
6454ac0944 Add __weakref__ to Request slots 2018-03-14 13:37:15 +03:00
7
31cf83f10b Merge pull request #19 from channelcat/master
merge upstream master branch
2018-03-13 22:11:40 -07:00
Raphael Deem
cc84005593 Merge pull request #1157 from kinware/feature/add-route-streams
Allow streaming handlers in app.add_route()
2018-03-13 00:08:25 -07:00
Kinware
915d2732a1 Allow streaming handlers in add_route 2018-03-12 20:21:59 +01:00
Raphael Deem
44bc47361e Merge pull request #1149 from channelcat/travis-retry
use travis_retry on tox
2018-03-06 15:54:19 -08:00
Raphael Deem
3619b07843 Merge pull request #1146 from yunstanford/upgrade-test-client
Upgrade test client
2018-03-01 23:18:20 -08:00
Raphael Deem
ad3f588c79 use travis_retry on tox 2018-03-01 23:16:49 -08:00
Yun Xu
a2fc37121b migrating all to async syntax 2018-03-01 22:35:58 -08:00
Raphael Deem
7f36d20123 Merge pull request #1145 from yingshaoxo/patch-1
add an necessary import for better understanding
2018-02-28 01:19:29 -08:00
Yun Xu
d1a8e8b042 fixed unit tests 2018-02-27 22:25:38 -08:00
Yun Xu
c39ddd00d3 workaround fix for an issue in aiohttp.Client 2018-02-27 21:42:41 -08:00
Yun Xu
d55e453bd5 cleaning up 2018-02-27 20:26:49 -08:00
Raphael Deem
bffed27bdb Merge pull request #1142 from clarksun/patch-1
exception.md code sample miss 'async' prefix
2018-02-27 01:03:47 -08:00
7
fffcb158f1 Merge pull request #18 from channelcat/master
Merge upstream master branch
2018-02-26 22:19:30 -08:00
Yun Xu
eca98a54eb fixed all unit tests 2018-02-26 22:18:21 -08:00
Yun Xu
46ed2c5270 upgrade aiohttp for test_client 2018-02-26 22:08:05 -08:00
Sun Wei
23ea0b7ec9 exception.md code sample miss 'async' prefix 2018-02-26 16:09:26 +08:00
yingshaoxo
ef26cb283b add an necessary import for better understanding
add `from sanic.response import redirect`
2018-02-26 11:24:54 +08:00
Eli Uriegas
b8bb77eff6 Merge pull request #1137 from Julien00859/1136
sanic.handlers.ErrorHandler.response handler call was too restrictive
2018-02-21 09:55:52 -06:00
Julien00859
9c75ad3de1 close #1136 2018-02-21 00:50:27 +01:00
Eli Uriegas
0b38dea613 Merge pull request #1117 from abuckenheimer/env_dependent_ujson_uvloop
only install ujson and uvloop with cpython on non windows machines
2018-02-20 13:13:21 -06:00
Raphael Deem
7e4a9e3bc2 Merge pull request #1047 from Yaser-Amiri/master
Add auto reloading.
2018-02-16 11:11:49 -08:00
Raphael Deem
36f12c822f Merge pull request #1122 from knowsuchagency/master
add app.register_listener method
2018-02-15 16:58:27 -08:00
Raphael Deem
0cbea0f5d3 Merge pull request #1129 from cloudship/patch-1
raw requires a bytes-like object
2018-02-14 20:44:40 -08:00
panxb
e735fe54c3 raw requires a bytes-like object
raw requires a bytes-like object, or an object that implements __bytes__, not 'str'
2018-02-15 00:11:37 +08:00
Stephan Fitzpatrick
e911e2e1df updated doc 2018-02-13 23:58:03 -08:00
Stephan Fitzpatrick
1d75f6c2be changed docstring spacing 2018-02-13 10:15:16 -08:00
Raphael Deem
ad8a168469 Merge pull request #1121 from tandalf/issue-1120
Fixed bug when passing a list into route decorator's host argument #1120
2018-02-12 12:48:13 -08:00
Raphael Deem
74fc502089 Merge pull request #1124 from yunstanford/add-doc
Expose WebSocket Param and Add Doc
2018-02-11 02:02:13 -08:00
Yun Xu
dfc2166d8b add websocket.rst to index.rst 2018-02-10 12:21:23 -08:00
Yun Xu
2b70346db4 fix doc 2018-02-09 21:32:09 -08:00
Yun Xu
090df6f224 add websocket section in doc 2018-02-09 21:26:39 -08:00
Yun Xu
745a1d6e94 document websocket args 2018-02-09 21:03:21 -08:00
Yun Xu
0fe0796870 expose websocket protocol arguments 2018-02-09 20:44:02 -08:00
7
224b56bd3a Merge pull request #17 from channelcat/master
merge from upstream sanic
2018-02-09 20:12:29 -08:00
Stephan Fitzpatrick
571b5b544d added app.register_listener method w/test 2018-02-09 14:01:17 -08:00
Timothy Ebiuwhe
220b40f7f4 Added regression tests for issue #1120 2018-02-09 22:33:34 +01:00
Timothy Ebiuwhe
60774c5a49 Fixed bug that occurs on calling @app.route or any of it's variants
causes a route to be added twice. One without the slash, the other with the
Setting strict_slashes to false when a route does not end with slashes
slash. This is ok if the Router._add method runs linearly, but problematic
when it runs recursively. Unfortunately recursion is triggered when
the host param to the Router._add function is a list of hosts.
2018-02-09 22:27:20 +01:00
Raphael Deem
6d37ef7256 Merge pull request #1109 from DirkGuijt/master
fixed bug in multipart/form-data parser
2018-02-08 00:11:20 -08:00
Dirk Guijt
e083224df1 changed bewline formatting 2018-02-07 09:29:44 +01:00
Alec Buckenheimer
5ef567405f fixed platform from windows to win32 2018-02-06 19:56:25 -05:00
Raphael Deem
ea2521f430 Merge pull request #1112 from boboldehampsink/extend_websocketprotocol_arguments
Extend WebSocketProtocol arguments
2018-02-06 15:05:58 -08:00
Alec Buckenheimer
82cb182fe7 added pip requirement to only install ujson and uvloop with cpython on non windows machines 2018-02-06 09:57:16 -05:00
Raphael Deem
3fe31ff551 Merge pull request #1104 from arnulfojr/minor/keep-alive-timeout-log-level
KeepAlive Timeout log level change to debug
2018-02-02 18:54:24 -08:00
Dirk Guijt
48d45f1ca4 sorry, style issue again 2018-02-03 03:14:04 +01:00
Dirk Guijt
ddf2a604d1 changed 'file' variable to 'form_file' to prevent overwriting the reserved word 2018-02-03 03:07:07 +01:00
Raphael Deem
8b920d9d56 Merge pull request #1113 from arnulfojr/bugfix/content-length-header-on-X04
Content Length header on 204 and 304 responses
2018-02-02 13:18:08 -08:00
Arnulfo Solis
f2c0489452 replaced comparison for in operator 2018-02-02 20:19:15 +01:00
Arnulfo Solis
f5a2d19199 touch commit 2018-02-02 14:13:14 +01:00
Arnulfo Solis
86fed12d91 less flake8 warnings in response test 2018-02-02 14:05:57 +01:00
Arnulfo Solis
7ca3ad5d4c no body and content length to 0 when 304 response is returned 2018-02-02 13:24:51 +01:00
Dirk Guijt
1eecffce97 fixed minor flake8 style problem 2018-02-02 09:57:06 +01:00
Dirk Guijt
5c341a2b00 made field name mandatory in multipart/form-data headers
A field name in the Content-Disposition header is required by the multipart/form-data spec. If one field/part does not have it, it will be omitted from the request. When this happens, we log it to DEBUG.
2018-02-02 09:43:42 +01:00
Arnulfo Solis
0ab64e9803 simplified logic when handling the body 2018-02-02 09:29:54 +01:00
Dirk Guijt
27108334f1 Merge branch 'master' of https://github.com/DirkGuijt/sanic 2018-02-02 00:55:58 +01:00
Dirk Guijt
788253cbe8 changes based on discussion on PR #1109 2018-02-02 00:55:51 +01:00
Arnulfo Solis
4b6e89a526 added one more test 2018-02-01 20:00:32 +01:00
Arnulfo Solis
68fd1b66b5 Response model now handles the 204 no content 2018-02-01 17:51:51 +01:00
Bob Olde Hampsink
5806666949 Extend WebSocketProtocol arguments to accept all arguments of websockets.protocol.WebSocketCommonProtocol 2018-02-01 16:23:10 +01:00
DirkGuijt
a76d8108fe small code style change
changed double quotes to single quotes to match the coding style
2018-02-01 11:55:30 +01:00
Arnulfo Solis
2135294e2e changed None to return empty string instead of null string 2018-02-01 11:52:55 +01:00
Dirk Guijt
ed1c563d1f fixed bug in multipart/form-data parser
Sanic automatically assumes that a form field is a file if it has a content-type header, even though the header is text/plain or application/json. This is a fix for it, I took into account the RFC7578 specification regarding the defaults.
2018-02-01 11:30:24 +01:00
Raphael Deem
74efa3a108 Merge pull request #1105 from manisenkov/upgrade-status-to-beta
Upgrade development status to beta
2018-01-31 14:36:06 -08:00
manisenkov
49c29e6862 Upgrade development status to beta 2018-01-31 23:25:50 +01:00
Raphael Deem
17d7f24825 Merge pull request #1108 from manisenkov/pin-pytest-version
Pin pytest version to 3.3.2
2018-01-31 14:24:04 -08:00
manisenkov
f23c3da4ff Pin pytest version to 3.3.2 2018-01-31 22:58:48 +01:00
Arnulfo Solis
cabcf50fbe KeepAlive Timeout log level change to debug 2018-01-30 11:26:15 +01:00
Raphael Deem
8b23b5d389 Merge pull request #1101 from SirEdvin/master
Provide information about sanic-oauth extension
2018-01-29 15:00:11 -08:00
SirEdvin
37eb2c1db6 Provide information about sanic-oauth extension 2018-01-27 10:28:53 +02:00
Eli Uriegas
9751a37343 Merge pull request #1098 from shahinism/refactor/docker
Install Python 3.5 and 3.6 on docker container
2018-01-26 14:01:21 -08:00
Eli Uriegas
ed3bdd3443 Merge pull request #1100 from NyanKiyoshi/master
No longer raising a missing parameter when value is null
2018-01-26 13:56:52 -08:00
NyanKiyoshi
285ad9bdc1 No longer raising a missing parameter when value is null
When passing a null value as parameter (ex.: 0, None or False), Sanic said "Error: Required parameter `param` was not passed to url_for"

Example:

```
@app.route("/<idx>")
def route(rq, idx):
    pass
```

```
url_for("route", idx=0)
```

No longer raises: `Error: Required parameter `idx` was not passed to url_for`
2018-01-26 21:13:43 +01:00
Shahin
16f5914c90 Install Python 3.5 and 3.6 on docker container
To cover all supported versions of Python using Tox
2018-01-24 16:46:45 +03:30
Raphael Deem
72d56a89a2 Merge pull request #1094 from caitinggui/master
update class_based_views
2018-01-23 17:25:59 -08:00
Raphael Deem
1135c8c1b1 Merge pull request #1097 from howie6879/master
Add parameter check
2018-01-23 17:25:25 -08:00
caitinggui
ec4339bd47 update description 2018-01-24 09:02:07 +08:00
howie6879
6c0fbef843 Add parameter check 2018-01-24 08:17:55 +08:00
howie6879
040c85a43b Add parameter check 2018-01-24 08:11:47 +08:00
Raphael Deem
420554c737 Merge pull request #1096 from kyb3r/patch-1
Typo in readme?
2018-01-22 23:56:16 -08:00
howie6879
f20b854dd2 Add parameter check 2018-01-22 14:52:30 +08:00
howie6879
3844cec7a4 Add parameter check 2018-01-22 14:12:41 +08:00
howie.hu
0db49f7520 Merge pull request #4 from channelcat/master
Update
2018-01-22 13:36:48 +08:00
Kyber
f8dedcaa1e Typo in readme? 2018-01-22 15:55:29 +11:00
Yaser Amiri
f8b1122467 Revert "Change parsing cookies mechanism. (like Django instade of http.cookies.SimpleCookie)"
This reverts commit ba1dbacd35.
2018-01-21 09:10:15 +03:30
Raphael Deem
f3bf5e9a5c Merge pull request #1090 from yunstanford/patch-signal-handling
Patch signal handling
2018-01-20 14:03:23 -08:00
Yaser Amiri
ba1dbacd35 Change parsing cookies mechanism. (like Django instade of http.cookies.SimpleCookie) 2018-01-20 12:49:16 +03:30
caitinggui
4036f1c121 update class_based_views 2018-01-19 16:20:07 +08:00
Raphael Deem
22ad697d1f Merge pull request #1078 from eltrhn/master
Add support for blueprint groups and nesting
2018-01-18 17:26:52 -08:00
Eli
a10d7469cd Add blueprint groups + nesting 2018-01-18 17:20:51 -08:00
Raphael Deem
06c3153d22 Merge pull request #1092 from mattfox/patch-1
Add request.method to documentation
2018-01-17 16:10:42 -08:00
Matt Fox
9677158b75 Add request.method to documentation 2018-01-17 07:31:39 -08:00
Raphael Deem
226a73141b Merge pull request #1091 from yunstanford/patch-router-fix
Patch router fix
2018-01-17 00:15:33 -08:00
Raphael Deem
da3201bf35 Merge pull request #1088 from cosven/master
use single quote in readme.rst
2018-01-16 13:34:39 -08:00
Yun Xu
7daebc6aea fix Router.check_dynamic_route_exists 2018-01-15 17:53:37 -08:00
Yun Xu
d9002769cf fix a typo 2018-01-15 17:49:11 -08:00
Yun Xu
6d0b30953a add unit test which should fail on original code 2018-01-15 17:40:44 -08:00
Yun Xu
09d6452475 fixed unit test 2018-01-15 15:15:08 -08:00
Yun Xu
6a61fce84e worker process should ignore SIGINT when run_multiple 2018-01-15 11:53:15 -08:00
Yun Xu
11017902be signal handling 2018-01-15 11:23:49 -08:00
7
bd7333723e Merge pull request #16 from channelcat/master
Merge upstream master branch
2018-01-15 10:48:34 -08:00
cosven
6648250fb9 Merge pull request #1 from cosven/cosven-patch-1
use single quote in readme.rst
2018-01-15 14:56:52 +08:00
cosven
a94a2d46d0 use single quote in readme.rst
As we use single quote in sanic package, we may be supposed to use single quote in readme also?
2018-01-15 14:55:36 +08:00
Raphael Deem
ab97018c78 Merge pull request #1082 from channelcat/1042
fix exception handling
2018-01-13 17:06:46 -08:00
Raphael Deem
be702b0924 Merge pull request #1087 from Stranger6667/fix-get_socket
Fix typo
2018-01-13 17:06:03 -08:00
Dmitry Dygalo
c5c10cfb50 Fix typo 2018-01-13 17:56:29 +01:00
howie.hu
5682d642a6 Merge pull request #3 from channelcat/master
Update
2018-01-10 09:23:43 +08:00
Raphael Deem
62c6d7274c Merge pull request #1083 from bow/fix/log_response_host
Fix log_response to correctly output request ip and port
2018-01-09 13:55:14 -08:00
bow
4f8633375d Fix log_response to correctly output request ip and port 2018-01-09 13:47:01 +01:00
Raphael Deem
9f559818e5 Merge pull request #1081 from howie6879/master
Fix: the Chinese URI
2018-01-08 15:54:46 -08:00
howie6879
5f329f72ee Update test_routes.py 2018-01-08 08:38:54 +08:00
howie6879
7303a06f83 Fix: the Chinese URI 2018-01-07 12:07:18 +08:00
howie6879
e34de96b24 Fix: the Chinese URI 2018-01-07 12:06:21 +08:00
howie6879
42cd424274 Fix: the Chinese URI 2018-01-07 10:59:12 +08:00
howie.hu
9426e94314 Merge pull request #2 from channelcat/master
Update
2018-01-07 09:57:51 +08:00
r0fls
7a1dab3319 fix exception handling 2018-01-05 14:12:22 -08:00
Raphael Deem
d63ec84745 Merge pull request #1037 from youknowone/xdist
Boost test speed by pytest-xdist
2018-01-05 12:10:27 -08:00
Raphael Deem
0e7e2f4e5b Merge pull request #1080 from channelcat/1079
fix timeout bug when self.transport is None
2018-01-04 15:01:40 -08:00
r0fls
46521240a9 fix timeout bug when self.transport is None 2018-01-03 23:33:22 -08:00
Jeong YunWon
a8827a5d95 Boost test speed by pytest-xdist 2018-01-03 18:52:25 +09:00
Raphael Deem
ca0bc1cb7d Merge pull request #1076 from channelcat/1074
fix strict_slashes bug when route has slash
2018-01-01 12:47:48 -08:00
r0fls
8c28ce7d79 fix strict_slashes bug when route has slash 2018-01-01 02:24:48 -08:00
r0fls
5b051f0891 add test 2018-01-01 02:14:55 -08:00
Raphael Deem
c93de9450a Merge pull request #1073 from Kurlov/master
remove uvloop for windows setup
2017-12-29 14:56:38 -08:00
Aleksandr Kurlov
96976fa892 remove uvloop for windows setup 2017-12-29 23:04:22 +05:00
Raphael Deem
c14e99cef0 Merge pull request #1071 from r0fls/1062-docs
udpate docs with add_task app injection
2017-12-28 02:01:23 -08:00
Raphael Deem
c91a806774 udpate docs with add_task app injection 2017-12-28 01:59:16 -08:00
Raphael Deem
2f0076f429 Merge pull request #1063 from r0fls/1062
try to inject the app in add_task method
2017-12-27 11:40:05 -08:00
Raphael Deem
a1ffc6d55b try to inject the app in add_task method 2017-12-27 01:06:43 -08:00
Yaser Amiri
9bdf7a9980 Revert files those fixed for flake problems. 2017-12-26 23:35:54 +03:30
Yaser Amiri
81494453b0 Remove dependency on requests library.
Change auto reloader enviroment varible name to SANIC_SERVER_RUNNING
Fix some typo mistakes, flake uncompatibilities and such problems.
Raise NotImplementedError for operating systems except posix systems for auto reloading.
2017-12-26 19:17:13 +03:30
Raphael Deem
008cbe5ce7 Merge pull request #1069 from r0fls/1050
add samesite cookie to cookie keys
2017-12-24 02:50:37 -08:00
Raphael Deem
5ee35e7eeb add samesite cookie to cookie keys 2017-12-24 02:33:52 -08:00
Raphael Deem
1a98e70281 Merge pull request #1066 from r0fls/1065
allow add_task after server starts
2017-12-21 23:44:18 -08:00
Raphael Deem
8e3f3977bd allow add_task after server starts 2017-12-21 23:37:42 -08:00
Raphael Deem
04b04f094c Merge pull request #1064 from r0fls/1061
double quotes in unauthorized exception per rfc7230
2017-12-21 18:59:41 -08:00
Raphael Deem
9c02cdbad9 double quotes in unauthorized exception per rfc7230 2017-12-21 18:05:05 -08:00
Raphael Deem
c30e805623 Merge pull request #1060 from seemethere/fix_readthedocs_builds
Add sphinxcontrib-asyncio to environment.yml
2017-12-20 23:40:04 -08:00
Eli Uriegas
cd81538ce3 Add sphinxcontrib-asyncio to environment.yml
readthedocs builds were broken because they were missing this dependency

Signed-off-by: Eli Uriegas <seemethere101@gmail.com>
2017-12-19 22:55:50 -06:00
howie.hu
68cb280513 Merge pull request #1 from channelcat/master
Update
2017-12-20 09:08:52 +08:00
Raphael Deem
19466a15b4 Merge pull request #1055 from youknowone/cancel-timeout
Cancel request tasks when response timeout is triggered
2017-12-17 16:46:29 -08:00
Jeong YunWon
d54b406cba Cancel request tasks when response timeout is triggered
Before: Even after raising ResponseTimeout, server still processes
remaining tasks until it is done
After: Before raising ResponseTimeout, server stops working task.
2017-12-14 18:43:52 +09:00
Raphael Deem
72254a7af9 Merge pull request #1054 from r0fls/rfc7231
fix issues with method not allowed response
2017-12-13 23:42:37 -08:00
Raphael Deem
52feff266e fix edge case with methods as None 2017-12-13 23:23:04 -08:00
Raphael Deem
2c3f50e34a fix stream handling 2017-12-13 23:06:18 -08:00
Raphael Deem
2b0258c13a fix issues with method not allowed response 2017-12-11 20:12:26 -08:00
Raphael Deem
2585900692 Merge pull request #1053 from danpalmer/master
Fix ip and socket data format on V6
2017-12-11 20:24:52 -06:00
Dan Palmer
48c2dcb110 Fix ip and socket data format on V6 2017-12-11 22:16:03 +00:00
Dan Palmer
10a378bd46 Typo 2017-12-11 14:33:43 +00:00
Yaser Amiri
3fe3c2c79f Add test for auto reloading. 2017-12-07 20:19:40 +03:30
Yaser Amiri
52c2a8484e Add auto reloader. 2017-12-07 16:30:54 +03:30
Eli Uriegas
21435c1863 Merge pull request #1045 from seemethere/increment_070
Increment to 0.7.0
2017-12-05 19:27:11 -08:00
Eli Uriegas
1ea3ab7fe8 Increment to 0.7.0
Signed-off-by: Eli Uriegas <seemethere101@gmail.com>
2017-12-05 19:13:16 -08:00
Raphael Deem
1b0ad2c3cd Merge pull request #1035 from yunstanford/patch-N
Adopt new websockets interface
2017-12-02 01:27:09 -08:00
Raphael Deem
aa4821864a Merge pull request #1039 from lixxu/master
check request.ip before using it
2017-11-28 19:47:34 -08:00
lixxu
283762224c clean codes 2017-11-28 14:47:43 +08:00
lixxu
f50a37fc88 ignore error if request.ip is None 2017-11-28 14:44:32 +08:00
Yun Xu
076f0515ca Fix flake8 2017-11-25 21:14:18 -08:00
Yun Xu
049f12096d fix unit tests 2017-11-25 21:07:38 -08:00
Yun Xu
f09c0393ba adopt new websockets interface 2017-11-25 21:01:22 -08:00
7
472bbcf293 Merge pull request #15 from channelcat/master
Merge upstream master branch
2017-11-25 20:49:09 -08:00
Raphael Deem
7a3f9daccf Merge pull request #1025 from nkoshell/route-version-params
Route version params
2017-11-20 23:43:22 -08:00
Nikita Koshelev
76511d61e0 Added removing duplicate 'v' for Router.add() version parameter
Fix sanic/router.py:123:80: E501 line too long (80 > 79 characters)
2017-11-18 01:39:00 +03:00
Nikita Koshelev
8e7475ccf6 Added regex escaping for Router.add() version parameter 2017-11-18 01:22:42 +03:00
Raphael Deem
820d8c7bf5 Merge pull request #1021 from EdwardBetts/spelling
Correct spelling mistakes.
2017-11-16 16:26:40 -08:00
Edward Betts
cfc75b4f1a Correct spelling mistakes. 2017-11-15 15:46:39 +00:00
Raphael Deem
98567fe5a8 Merge pull request #1008 from youknowone/pytest-xdist
Let SanicTestClient has its own port
2017-11-10 10:50:01 -08:00
Raphael Deem
05bb812e2b Merge pull request #1010 from Yaser-Amiri/master
Change unit tests names with repeated names.
2017-11-08 20:25:45 -08:00
Yaser Amiri
c9876a6c88 Change unit tests names with repeated names. 2017-11-08 14:14:57 +03:30
Raphael Deem
979b5a52d3 Merge pull request #1005 from joar/feature/static-strict-slashes
Add strict_slashes to {app, blueprint}.static()
2017-11-07 07:49:32 -08:00
Joar Wandborg
e70535e8d7 Use .get instead of .pop 2017-11-07 10:34:17 +01:00
Jeong YunWon
ed8725bf6c Let SanicTestClient has its own port
For parallel test running, the servers must have different ports.
See examples/pytest_xdist.py for example.
2017-11-06 17:29:32 +09:00
Raphael Deem
098cd70e82 Merge pull request #1007 from furious-luke/master
Call connection_open after websocket handshake
2017-11-05 14:26:19 -08:00
Raphael Deem
969dac2033 Merge pull request #1004 from Stibbons/optionalize_log_config
Optionalize app.run dictConfig (fix #1000)
2017-11-04 12:35:38 -07:00
Gaetan Semet
49b1d667f1 Optionalize app.run dictConfig (fix #1000)
Signed-off-by: Gaetan Semet <gaetan@xeberon.net>
2017-11-04 15:58:27 +01:00
Luke Hodkinson
bca1e08411 Call connection_open after websocket handshake
It seems that due to (recent?) changes in the websocket library, we
now need to call "connection_open" to flag that the websocket is now
ready to use. I've added that call just after the call to
"connection_made".
2017-11-04 22:04:59 +11:00
Raphael Deem
bf6ed217c2 Merge pull request #1006 from r0fls/routing-fix
check if method is added in strict slash logic
2017-11-04 00:09:52 -07:00
Raphael Deem
bb8e9c6438 check if method is added in strict slash logic 2017-11-03 18:36:06 -07:00
Joar Wandborg
f128ed5b1f Set threshold to 1MiB instead of 0.97MiB
Reference: https://en.wikipedia.org/wiki/Mebibyte#Definition
2017-11-03 14:37:01 +01:00
Joar Wandborg
ff5786d61b pep8 2017-11-03 14:33:24 +01:00
Joar Wandborg
ca596c8ecd Add strict_slashes to {Sanic, Blueprint}().static() 2017-11-02 15:44:36 +01:00
Raphael Deem
c3bcafb514 Merge pull request #997 from ignatenkobrain/localhost
tests: do not assume that locahost == 127.0.0.1
2017-11-01 00:22:14 -07:00
Igor Gnatenko
a9c7d95e9b tests: do not assume that locahost == 127.0.0.1
Signed-off-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
2017-10-31 09:39:09 +01:00
Raphael Deem
01042c1d98 Merge pull request #992 from r0fls/968
remove port from ip
2017-10-25 22:15:07 -07:00
Raphael Deem
5bf722c7ae remove bare exceptions 2017-10-25 21:58:31 -07:00
Raphael Deem
c2191153cf remove port from ip 2017-10-23 21:37:59 -07:00
davidtgq
5bcbc5a337 Replaced COMMON_STATUS_CODES with a simple 200 check for more fast (#982)
* Replaced COMMON_STATUS_CODES with a simple 200 check for more fast

* Added IPware algorithm

* Remove HTTP prefix from Django-style headers
Remove right_most_proxy because it's outside spec

* Remove obvious docstrings

* Revert "Replaced COMMON_STATUS_CODES with a simple 200 check for more fast"

This reverts commit 15b6980

* Revert "Added IPware algorithm"

This reverts commit bdf66cb

WTF HOW DO I GIT

* Revert "Revert "Replaced COMMON_STATUS_CODES with a simple 200 check for more fast""

This reverts commit d8df095

* Revert "Added IPware algorithm"

This reverts commit bdf66cb

* Delete ip.py
2017-10-19 16:43:07 -07:00
Eli Uriegas
f721f90add Merge pull request #820 from youknowone/worker-protocol
Protocol configurable gunicorn worker
2017-10-19 16:21:28 -07:00
Eli Uriegas
0e92d8ce2c Merge branch 'master' into worker-protocol 2017-10-19 16:21:18 -07:00
Eli Uriegas
727d6a1b61 Merge pull request #972 from lanfon72/patch-2
to fix condition error that used in `log_response`
2017-10-19 16:16:57 -07:00
Raphael Deem
666c0847b7 Merge pull request #976 from ashleysommer/fix_websocket_timeout
Fix Websocket protocol timeouts after #939
2017-10-18 21:20:52 -07:00
Raphael Deem
0a411f9bba Merge pull request #985 from ashleysommer/ashleysommer-docs-spf
Add Sanic-Plugins-Framework library to Extensions doc
2017-10-18 21:20:13 -07:00
Ashley Sommer
49f3ba39f9 Add Sanic-Plugins-Framework library to Extensions doc
I made a new tool for devs to use for easily and quickly creating Sanic Plugins (extensions), and for application builders to easily use those plugins in their app.
2017-10-18 17:52:03 +10:00
Raphael Deem
794128a053 Merge pull request #981 from kszucs/manifest
Include LICENSE file in manifest
2017-10-17 10:31:19 -07:00
Krisztián Szűcs
e6be3b2313 include LICENSE file in manifest 2017-10-17 16:05:24 +02:00
Raphael Deem
c5cdcf0f95 Merge pull request #975 from ashleysommer/timeouts_documentation
Add documentation for new Timeout values, after #939
2017-10-16 09:13:49 -07:00
Ashley Sommer
ea5b07f636 Update websocket protocol to accomodate changes in HTTP protocol from https://github.com/channelcat/sanic/pull/939
Fixes https://github.com/channelcat/sanic/issues/969
2017-10-16 11:06:33 +10:00
Ashley Sommer
477e6b8663 Add documentation for REQUEST_TIMEOUT, RESPONSE_TIMEOUT and KEEP_ALIVE_TIMEOUT config values.
Fixed some inconsistent default values.
2017-10-16 10:53:45 +10:00
Raphael Deem
a0d8418b40 Merge pull request #965 from samael500/master
fix issue #959
2017-10-13 14:58:46 -07:00
Raphael Deem
006fb08024 Merge pull request #966 from yunstanford/patch-M
Sanic routes should not pass angled params with empty names
2017-10-13 02:18:20 -07:00
lanf0n
4578f6016b to fix condition error that used in log_response
`request` class is derived from `dict`, so it will never be `True`.
2017-10-13 16:48:02 +08:00
Raphael Deem
5b06bcc57d Merge pull request #967 from samael500/custom_filename
Custom filename
2017-10-13 01:35:11 -07:00
Raphael Deem
d4bb14a511 Merge pull request #971 from pcinkh/socket_disconnects_speedup
Critical speedup websocket disconnects from O(N) to O(1)
2017-10-13 01:25:14 -07:00
pcinkh
6d2f5da506 Speedup websocket disconnects. 2017-10-11 14:02:26 +03:00
Yun Xu
c96df86111 make flake8 happy 2017-10-09 07:58:04 -07:00
Maks Skorokhod
86f87cf4ac 🔧 no use f'string' 2017-10-09 17:55:35 +03:00
Yun Xu
770a8fb288 raise exception for invalid param syntax 2017-10-09 07:54:39 -07:00
Maks Skorokhod
c4e3a98ea7 add test for custom filename 2017-10-09 17:45:42 +03:00
Maks Skorokhod
07e95dba4f 🔁 customize filename in file response 2017-10-09 17:45:22 +03:00
7
9bc1abcd00 Merge pull request #14 from channelcat/master
merge upstream master branch
2017-10-09 07:19:57 -07:00
Maks Skorokhod
4d515b05f3 fix missed assertion 2017-10-09 17:18:04 +03:00
Maks Skorokhod
64edf7ad9c upd test for connection lost error 2017-10-09 16:00:32 +03:00
Maks Skorokhod
7610c0fb2e 🔧 log Connection lost only if debug 2017-10-09 15:50:36 +03:00
Raphael Deem
0189e4ed59 Merge pull request #962 from ProstoMaxim/fix_logs
Fix logs
2017-10-08 20:16:11 -07:00
Raphael Deem
8018c9b91d Merge pull request #961 from r0fls/fix-920
fix false cookie encoding and output
2017-10-06 23:57:30 -07:00
Max Murashov
4b3920daba Fix logs 2017-10-06 16:53:30 +03:00
Raphael Deem
d876e3ed5c fix false cookie encoding and output 2017-10-05 22:20:50 -07:00
Raphael Deem
086b5daa53 Merge pull request #960 from piotrbulinski/refactor_server_access_log
Refactor access log for server.HttpProtocol
2017-10-05 20:20:28 -07:00
Piotr Buliński
4b877e3f6b Update server.py 2017-10-05 09:28:13 +02:00
Piotr Buliński
8ce749e339 Update server.py 2017-10-05 09:27:18 +02:00
Piotr Buliński
752ddfa7fc Merge branch 'master' into refactor_server_access_log 2017-10-05 09:26:19 +02:00
Raphael Deem
8700c96c4d Merge pull request #942 from yunstanford/patch-logging-refactor
Patch logging refactor
2017-10-05 00:22:02 -07:00
Piotr Bulinski
e3852ceeca Refactor access log for server 2017-10-04 12:50:57 +02:00
Yun Xu
225ea49b6f resolve conflicts again 2017-10-01 01:22:27 -07:00
Raphael Deem
15fd49037f Merge pull request #939 from ashleysommer/keepalive_timeout
Split RequestTimeout, ResponseTimeout, and KeepAliveTimeout into different timeouts
2017-09-30 22:15:50 -07:00
Raphael Deem
2fb4697e12 Merge pull request #952 from ahopkins/patch-1
Update extensions.md
2017-09-29 18:33:30 -07:00
Eli Uriegas
1a9f770317 Merge pull request #957 from lanfon72/master
add sphinx extension to add asyncio-specific markups
2017-09-29 11:17:29 -07:00
lanf0n
62871ec9b3 add sphinx extension to add asyncio-specific markups 2017-09-30 01:16:26 +08:00
Raphael Deem
39c64214ee Merge pull request #953 from r0fls/949
support vhosts in static routes
2017-09-27 01:28:43 -07:00
Raphael Deem
9aec5febb8 support vhosts in static routes 2017-09-27 01:24:49 -07:00
Adam Hopkins
91b2167eba Update extensions.md
Add - [JWT](https://github.com/ahopkins/sanic-jwt): Authentication extension for JSON Web Tokens (JWT) extension package.
2017-09-27 11:07:06 +03:00
Raphael Deem
00d40a35cd Merge pull request #951 from lixxu/master
fix bug and set scheme to http if not provided
2017-09-26 21:57:54 -07:00
lixxu
f96ab02767 set scheme to http if not provided 2017-09-27 09:59:49 +08:00
Raphael Deem
4ce699e57f Merge pull request #944 from blazehu/master
add __repr__ for sanic request
2017-09-25 13:58:09 -07:00
Raphael Deem
4ee042c330 Merge pull request #948 from chiuczek/json-dependency-injection
Use dependency injection to allow alternative json parser or encoder
2017-09-24 21:05:39 -07:00
Yun Xu
0b23f4ff81 resolve conflicts 2017-09-23 06:19:09 -07:00
Hugh McNamara
5cef1634ed use json_loads function in json property of request 2017-09-22 10:19:15 +01:00
Eli Uriegas
1b0286916e Merge pull request #947 from lanfon72/patch-1
to fix if platform is windows.
2017-09-19 10:15:35 -07:00
Hugh McNamara
a8f764c161 make method instead of property for alternative json decoding of request 2017-09-19 18:12:53 +01:00
Hugh McNamara
1d719252cb use dependency injection to allow alternative json parser or encoder 2017-09-19 14:58:49 +01:00
lanf0n
d8cebe1188 to fix if platform is windows. 2017-09-19 18:14:25 +08:00
Eli Uriegas
329ebf6a5d Merge pull request #946 from trthhrtz/patch-1
Update getting_started.md
2017-09-18 11:13:48 -07:00
Kuzma Leshakov
c836441a75 Update getting_started.md
Hello World example at the main Readme file (https://github.com/channelcat/sanic/blob/master/README.rst) is different, it returns json. Here is returned text. In the following examples, such as Routing (http://sanic.readthedocs.io/en/latest/sanic/routing.html) is again used json. Therefore I suggest to make examples the same, having json as output
2017-09-18 11:37:32 +03:00
huyuhan
074d36eeba add __repr__ for sanic request 2017-09-15 21:15:05 +08:00
huyuhan
f6eb35f67d add __repr__ for sanic request 2017-09-15 21:05:25 +08:00
huyuhan
77f70a0792 add __repr__ for sanic request 2017-09-15 20:56:44 +08:00
huyuhan
12dafd07b8 add __repr__ for sanic request 2017-09-15 18:34:56 +08:00
Eli Uriegas
9fb8bec715 Merge pull request #943 from crvv/master
fix #763, sanic can't decode latin1 encoded header value
2017-09-14 13:38:44 -07:00
Wèi Cōngruì
eb1146c6b6 fix #763, sanic can't decode latin1 encoded header value 2017-09-14 19:23:02 +08:00
Yun Xu
730f7c5e41 add doc for customizing logging config 2017-09-13 18:30:38 -07:00
Yun Xu
5cabc9cff2 update doc 2017-09-13 18:16:58 -07:00
Yun Xu
ddc039ed2e update doc 2017-09-13 18:14:46 -07:00
Eli Uriegas
a146ebd856 Merge pull request #941 from aiosin/master
add status codes and teapot example
2017-09-13 11:39:14 -07:00
Yun Xu
5ee7b6caeb fixing small issue 2017-09-13 10:35:34 -07:00
Yun Xu
9c4b0f7b15 fix flake8 2017-09-13 07:40:42 -07:00
aiosin
2e5d1ddff9 add status codes and teapot example 2017-09-13 14:08:29 +02:00
Yun Xu
24bdb1ce98 add unit tests/refactoring 2017-09-12 23:42:42 -07:00
Ashley Sommer
8eb59ad4dc Fixed error where the RequestTimeout test wasn't actually testing the correct behaviour
Fixed error where KeepAliveTimeout wasn't being triggered in the test suite, when using uvloop
Fixed test cases when using other asyncio loops such as uvloop
Fixed Flake8 linting errors
2017-09-13 10:18:36 +10:00
Raphael Deem
d8c8ccd180 Merge pull request #932 from lixxu/master
static files url building using url_for
2017-09-12 12:59:04 -07:00
Yun Xu
a46e004f07 apply new loggers 2017-09-11 22:12:49 -07:00
Ashley Sommer
173f94216a Fixed the delays, and expected responses, in the keepalive_timeout tests 2017-09-12 13:40:43 +10:00
Ashley Sommer
1a74accd65 finished the keepalive_timeout tests 2017-09-12 13:09:42 +10:00
Ashley Sommer
2979e03148 WIP - Split RequestTimeout, ResponseTimout, and KeepAliveTimeout into different timeouts, with different callbacks. 2017-09-11 17:17:33 +10:00
Yun Xu
4bdb9a2c8e prototype 2017-09-10 23:19:09 -07:00
Yun Xu
8f6fa5e9ff old logging cleanup 2017-09-10 18:44:54 -07:00
Yun Xu
986135ff76 remove DefaultFilter 2017-09-10 18:39:42 -07:00
Yun Xu
c9cbc00e36 use access_log as param 2017-09-10 18:38:52 -07:00
Yun Xu
c9a40c180a remove some logging stuff 2017-09-10 11:11:16 -07:00
7
125cb17fcb Merge pull request #13 from channelcat/master
sync from upstream master branch
2017-09-09 16:52:13 -07:00
Raphael Deem
53a5bd2319 Merge pull request #936 from yunstanford/patch-debug-logging
Patch debug logging
2017-09-08 20:49:16 -07:00
Raphael Deem
4fd68f9af3 Merge pull request #935 from iad42/patch-1
Added information on request.token
2017-09-08 20:49:01 -07:00
Yun Xu
c4417b399b fixing debug logging 2017-09-08 17:47:05 -07:00
7
c2a3e42a53 Merge pull request #12 from channelcat/master
merge upstream master branch
2017-09-08 17:39:50 -07:00
Anatoly Ivanov
73c04f5a89 Added information on request.token
The manual lacked info about request.token, which keeps authorization data. See https://github.com/channelcat/sanic/blob/master/sanic/request.py#L84 for details
2017-09-08 14:21:49 +03:00
lixxu
195f707f14 missing '/' in doc 2017-09-06 19:19:59 +08:00
lixxu
bc20dc5c62 use url_for for url building for static files 2017-09-06 19:17:52 +08:00
Raphael Deem
8b4ca51805 Merge pull request #931 from Tim-Erwin/envvar_prefix
make the prefix for environment variables alterable
2017-09-05 11:22:56 -07:00
Tim Mundt
e2e25eb751 fixed flake convention 2017-09-05 11:05:31 +02:00
Tim Mundt
9572ecc5ea test for env var prefix 2017-09-05 10:58:48 +02:00
Tim Mundt
97d8b9e908 documentation for env var prefix; allow passing in the prefix through the app constructor 2017-09-05 10:41:55 +02:00
Tim Mundt
c59a8a60eb make the prefix for environment variables alterable 2017-09-05 09:53:33 +02:00
Raphael Deem
158da0927a Merge pull request #901 from lixxu/master
add name option for route building
2017-08-31 15:29:03 -07:00
Eli Uriegas
78a7338346 Merge pull request #922 from timka/patch-1
Example logging X-Request-Id transparently
2017-08-31 10:35:48 -07:00
Eli Uriegas
90e5c8d39b Merge pull request #904 from jiaxiaolei/master
feat(examples): add `authorized_sanic.py`
2017-08-31 10:35:23 -07:00
Raphael Deem
7a6f2d8336 Merge pull request #926 from manisenkov/patch-1
Fix LICENSE date and name
2017-08-30 17:49:59 -07:00
Maksim Anisenkov
f49554aa57 Fix LICENSE date and name 2017-08-30 15:30:22 +02:00
Timur
0a72168f8f Example logging X-Request-Id transparently 2017-08-29 23:05:57 +03:00
Raphael Deem
5011bfef55 Merge pull request #917 from CharAct3/bugfix/fix_unauthorized
fix #914, change arguments of Unauthorized.__init__
2017-08-24 13:45:58 -07:00
Darren
6038813d03 fix #914, change arguments of Unauthorized.__init__ 2017-08-24 22:59:25 +08:00
Raphael Deem
fee9de96de Merge pull request #908 from Ezi4Zy/master
fix: error param
2017-08-23 16:22:13 -07:00
xmsun
35e028cd99 fix: error param 2017-08-22 16:40:42 +08:00
lixxu
145cdd5c1b Merge branch 'use-route-name-for-method' 2017-08-22 14:02:56 +08:00
lixxu
762b2782ee use name to define route name for different methods on same url 2017-08-22 14:02:38 +08:00
jiaxiaolei
91f031b661 feat(examples): add authorized_sanic.py
You can check a request if the client is authorized
to access a resource by the decorator `authorized`
2017-08-21 22:40:07 +08:00
lixxu
eab809d410 add name option for route building 2017-08-21 18:05:34 +08:00
Raphael Deem
826f1b4713 Merge pull request #898 from jiaxiaolei/master
feat(examples): add `add_task_sanic.py`
2017-08-21 00:32:38 -07:00
Raphael Deem
fa1a95ae91 Merge pull request #900 from yunstanford/patch-default-strict-slashes
Patch default strict slashes
2017-08-21 00:31:42 -07:00
Yun Xu
63babae63d add doc 2017-08-21 00:28:01 -07:00
Raphael Deem
db9924a399 Merge pull request #899 from hatarist/patch-2
Add a line on headers in the "Request Data" docs
2017-08-20 23:51:07 -07:00
Yun Xu
5d23c7644b add unit tests 2017-08-20 23:37:22 -07:00
Yun Xu
ef81a9f547 make strict_slashes default value configurable 2017-08-20 23:11:38 -07:00
7
747c21da70 Merge pull request #11 from channelcat/master
merge upstream master branch
2017-08-20 22:51:19 -07:00
Igor Hatarist
439ff11d13 Added a line on headers in the "Request Data" docs 2017-08-20 19:28:09 +03:00
jiaxiaolei
947364e15f feat(exapmles): add add_task_sanic.py 2017-08-20 11:11:14 +08:00
Eli Uriegas
750115b727 Merge pull request #894 from pkuphy/patch-1
fix typo
2017-08-18 10:44:35 -07:00
pkuphy
a55efc832d fix typo 2017-08-19 01:03:54 +08:00
Raphael Deem
c96bd21389 Merge pull request #892 from jiaxiaolei/master
docs(README): Make it clear and easy to read.
2017-08-18 02:09:19 -07:00
jiaxiaolei
dd241bd6fa docs(README): Make it clear and easy to read. 2017-08-18 17:00:34 +08:00
Raphael Deem
0dbde7400f Merge pull request #889 from dongweiming/doc
Fix blueprint doc
2017-08-16 00:19:58 -07:00
dongweiming
2587f6753d Fix blueprint doc 2017-08-15 22:04:25 +08:00
Raphael Deem
4155e76a81 Merge pull request #886 from yunstanford/fix-cov-report
Fix cov report
2017-08-14 16:21:50 -07:00
Yun Xu
756bd19181 do not fail if no files for coverage combine 2017-08-10 08:39:02 -07:00
Yun Xu
fbb2344895 fix cov report 2017-08-10 07:55:38 -07:00
7
bda6c85638 Merge pull request #10 from channelcat/master
merge upstream master branch
2017-08-10 07:47:45 -07:00
Raphael Deem
df4a149cd0 Merge pull request #885 from yunstanford/master
add triggers events when async create_server
2017-08-09 15:59:44 -07:00
Yun Xu
80f27b1db9 add unit tests and make flake8 happy 2017-08-08 22:21:40 -07:00
Yun Xu
d5d1d3b45a add trigger before_start events in create_server 2017-08-08 21:58:10 -07:00
Eli Uriegas
c797c3f22d Merge pull request #883 from miguelgrinberg/websocket-subprotocols
Weboscket subprotocol negotiation
2017-08-08 11:49:21 -07:00
Miguel Grinberg
375ed23216 Weboscket subprotocol negotiation
Fixes #874
2017-08-08 11:40:44 -07:00
Raphael Deem
7b66a56cad Merge pull request #870 from MichaelYusko/small-amendment
Did the small changes for better readable
2017-08-03 18:39:26 -07:00
MichaelYusko
7216bf7835 merge master into local branch 2017-08-03 12:11:47 +03:00
Eli Uriegas
8b24c35ac7 Merge pull request #878 from seemethere/increment_060
Increment to 0.6.0
2017-08-02 19:13:39 -07:00
Eli Uriegas
f80a6ae228 Increment to 0.6.0 2017-08-02 19:11:53 -07:00
7
9b3fbe4593 fixed small doc issue (#877) 2017-08-02 10:15:18 -07:00
Yun Xu
f99a723627 fixed small doc issue 2017-08-02 09:05:33 -07:00
7
181ffb00a7 Merge pull request #9 from channelcat/master
merging upstream master branch
2017-08-02 09:04:31 -07:00
Eli Uriegas
222eca64d7 Merge pull request #875 from cctse/patch-1
add some example links for readme
2017-08-01 09:36:37 -07:00
akc
1b687f3feb add some example links 2017-08-01 16:32:15 +08:00
Eli Uriegas
2228104bff Merge pull request #862 from zyguan/revert-599fbce
revert 599fbce
2017-07-31 13:51:04 -07:00
Raphael Deem
402c3752c4 Merge pull request #871 from Frzk/unauthorized-exception
Simplified the Unauthorized exception __init__ signature.
2017-07-31 12:23:12 -07:00
François KUBLER
69a8bb5e1f Fixed a trailing white space in the docstring. 2017-07-28 22:29:45 +02:00
Raphael Deem
0d76f9e030 Merge pull request #873 from yunstanford/fix-timeout-issue
Fix timeout issue
2017-07-28 09:49:22 -07:00
Yun Xu
eb8f65c58b switch to use dist: precise 2017-07-27 22:21:19 -07:00
7
e0e27a671e Merge pull request #8 from channelcat/master
merge upstream master branch
2017-07-27 20:01:59 -07:00
François KUBLER
b65eb69d9f Simplified the Unauthorized exception __init__ signature.
(again).
Use of **kwargs makes it more straight forward and easier to use.
2017-07-27 23:00:27 +02:00
Raphael Deem
8118e542fb Merge pull request #866 from Nikamura/patch-1
Fix typo in documentation
2017-07-26 13:18:52 -07:00
Raphael Deem
c866759bd4 Merge pull request #868 from cclauss/patch-2
Comment: F821 undefined name is done on purpose
2017-07-26 13:18:29 -07:00
MichaelYusko
429f7377cb Did the small changes for better readable 2017-07-26 19:32:23 +03:00
cclauss
40776e5324 Comment: F821 undefined name is done on purpose
Comment helps readers and `# noqa` silences linters
2017-07-26 12:44:30 +02:00
Karolis Mažukna
621343112d Fix typo in documentation 2017-07-25 13:29:17 +03:00
Raphael Deem
eb06e6ba51 Merge pull request #863 from zyguan/issue-760
handle keep-alive timeout gracefully
2017-07-25 00:54:43 -07:00
zyguan
da91b16244 add tests 2017-07-24 18:21:15 +08:00
zyguan
918e2ba8d0 Revert "fix #752"
This reverts commit 599fbcee6e.
2017-07-24 11:53:11 +08:00
zyguan
f50dc83829 handle keep-alive timeout gracefully 2017-07-24 01:37:36 +08:00
Raphael Deem
e8a9b4743b Merge pull request #861 from yunstanford/add-jinja-sanic
Add jinja2-sanic
2017-07-22 20:16:21 -07:00
Yun Xu
f34226425e add jinja2-sanic 2017-07-22 18:41:53 -07:00
7
e27c7ba36f Merge pull request #7 from channelcat/master
merge upstreaming master branch
2017-07-22 18:28:38 -07:00
Raphael Deem
1aad527956 Merge pull request #824 from Frzk/unauthorized-exception
Simplified the `Unauthorized.__init__` signature.
2017-07-21 23:50:36 -07:00
Raphael Deem
173c62acb6 Merge branch 'master' into unauthorized-exception 2017-07-21 01:54:45 -07:00
Raphael Deem
76605d7dfe Merge pull request #858 from mohd-akram/freebsd-syslog
Fix FreeBSD syslog path
2017-07-20 20:50:25 -07:00
Mohamed Akram
32be1a6496 Fix FreeBSD syslog path 2017-07-20 03:02:40 +04:00
Raphael Deem
c7d43aa544 Merge pull request #853 from yunstanford/patch-proxy-fix
proxy fix
2017-07-17 01:01:26 -07:00
Yun Xu
198bf55b7b flake8 fix 2017-07-14 17:23:18 -07:00
Yun Xu
75378d3567 add remote_addr property for proxy fix 2017-07-14 09:29:16 -07:00
7
55cb371569 Merge pull request #6 from channelcat/master
merge upstreaming master branch
2017-07-13 20:07:15 -07:00
Raphael Deem
5bb97d25d0 Merge pull request #839 from asvetlov/patch-1
Drop benchmarks from README
2017-07-13 14:41:57 -07:00
Andrew Svetlov
b2017cae77 Drop benchmarks from readme 2017-07-13 23:41:04 +02:00
Raphael Deem
35af903d4a Merge pull request #851 from zenixls2/issue-805
don't let default LOGGING to dictConfig influence already existed configs
2017-07-13 12:49:29 -07:00
zenix
426e00b6f4 dont let dictConfig influence already exists configs 2017-07-13 15:09:04 +09:00
Raphael Deem
8e62b3e438 Merge pull request #850 from r0fls/versioning
Versioning
2017-07-12 22:37:14 -07:00
Raphael Deem
4265ad5f23 add versioning 2017-07-12 22:19:42 -07:00
Raphael Deem
c181eb0539 Merge branch 'master' of https://github.com/channelcat/sanic 2017-07-12 21:12:15 -07:00
Raphael Deem
e0f06753c6 Merge pull request #831 from yunstanford/auto-doc
Improve Documentation.
2017-07-12 20:20:51 -07:00
Raphael Deem
8aafd72ef0 Merge branch 'auto-doc' of https://github.com/yunstanford/sanic 2017-07-12 20:19:30 -07:00
Raphael Deem
48549ce97b Merge pull request #847 from youknowone/gunicorn
ensure loop.close() and sys.exit() in gunicorn worker
2017-07-12 18:19:39 -07:00
Jeong YunWon
47abf83960 Protocol configurable gunicorn worker 2017-07-12 22:30:13 +09:00
Jeong YunWon
be0f3731b4 ensure loop.close() and sys.exit() in gunicorn worker 2017-07-12 22:26:58 +09:00
Raphael Deem
b755431b93 Merge pull request #844 from sfermigier/patch-1
Add missing code block qualifier
2017-07-10 15:26:57 -07:00
Stefane Fermigier
04ff393875 Add missing code block qualifier 2017-07-10 22:11:12 +02:00
Raphael Deem
7841274300 Merge pull request #843 from yunstanford/case-insensitive-check
Case insensitive check
2017-07-10 12:44:25 -07:00
Yun Xu
235687d983 should call lower just once 2017-07-10 12:37:21 -07:00
Yun Xu
3d75e6ed95 case-insensitive check for header fields 2017-07-10 12:29:47 -07:00
Andrew Svetlov
eb9af8bceb Drop aiohttp from benchmark table
The reason is: aiohttp with disabled access log shows about 16,000 RPS on sanic's own benchmark.
It's pretty much faster than 3,000 RPS from the table.

I'm not a Sanic dev team member. You should not trust users to update this table but manage periodic updates yourself.
If you don't want to do it --- it's up to you.
Please just drop very incorrect and outdated numbers from README in this case.
2017-07-09 08:18:45 +02:00
7
39ea434513 Merge pull request #5 from channelcat/master
merge upstream master branch
2017-07-08 14:23:00 -07:00
Raphael Deem
f0a956467c Merge pull request #815 from yunstanford/master
add graceful timeout when shutdown
2017-07-08 11:31:37 -07:00
Yun Xu
e48bd08095 make flake8 happy 2017-07-02 10:05:33 -07:00
Yun Xu
5d00717f39 improve doc and remove warnings 2017-07-02 10:02:04 -07:00
Yun Xu
3fff685c44 add auto-doc support 2017-07-01 23:46:34 -07:00
Raphael Deem
1e75265eed Merge pull request #756 from qwesda/master
fixes #755 fragmented headers
2017-06-30 18:24:51 -07:00
Eli Uriegas
b6ac3ef445 Merge pull request #826 from yunstanford/pytest-sanic
Pytest sanic
2017-06-30 18:17:15 -07:00
Raphael Deem
421f78f3e6 Merge pull request #814 from Frzk/forbidden-exception
Added a Forbidden exception
2017-06-30 18:11:23 -07:00
Eli Uriegas
b71fdcfc20 Merge pull request #829 from Frzk/config_doc
Fixed an error : `Sanic.__init__` doesn't have a `load_vars` parameter.
2017-06-30 10:06:30 -07:00
François KUBLER
021e9b228a Fixed a small error : Sanic.__init__ doesn't have a load_vars parameter.
It is `load_env`.
2017-06-30 16:24:41 +02:00
Raphael Deem
00d4533022 Merge pull request #821 from Frzk/bearer-support
Inverted the order of prefixes in Request.token property.
2017-06-29 09:43:34 -07:00
Yun Xu
fd5faeb5dd add an example 2017-06-29 09:14:21 -07:00
Yun Xu
e7c8035ed7 add pytest-sanic 2017-06-29 09:06:17 -07:00
François KUBLER
e427e38da8 Simplified the Unauthorized.__init__ signature.
It doesn't really make sense to have a `realm` parameter in the method signature.
Instead, one can simply set the realm in the `challenge` dict if necessary.

Also fixed the tests accordingly (and added a new one for "Bearer" auth-scheme).
2017-06-29 12:34:52 +02:00
François KUBLER
1f24abc3d2 Fixed support for "Bearer" and "Token" auth-schemes.
Removed the test for "Authentication: Bearer Token <TOKEN>" which was not supposed to exist (see https://github.com/channelcat/sanic/pull/821)
Also added a call to `split` when retrieving the token value to handle cases where there are leading or trailing spaces.
2017-06-29 10:23:49 +02:00
François
76e62779ba Merge branch 'master' into forbidden-exception 2017-06-28 17:25:40 +02:00
Eli Uriegas
1af343ef50 Merge pull request #823 from ojii/cookies-warning
Added a warning to the cookies documentation about security
2017-06-27 19:35:35 -07:00
Jonas Obrist
412ffd1592 Added a warning to the cookies documentation about security 2017-06-28 11:05:59 +09:00
Daniel Schwarz
b141fec573 Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	sanic/server.py
2017-06-27 13:32:49 +02:00
François KUBLER
d2e14abfd5 Inverted the order of prefixes in Request.token property.
As suggested by @allan-simon
See: https://github.com/channelcat/sanic/pull/811#pullrequestreview-46144327
2017-06-27 12:57:47 +02:00
Raphael Deem
d4abca0480 Merge pull request #818 from youknowone/debug
Introduce debug mode for HTTP protocol
2017-06-26 22:02:37 -07:00
Raphael Deem
529f5822ee Merge pull request #819 from r0fls/817
convert environment vars to int if digits
2017-06-26 21:54:54 -07:00
Raphael Deem
395d85a12f use try/except 2017-06-26 21:35:01 -07:00
Raphael Deem
4379a4b067 float logic 2017-06-26 20:59:59 -07:00
Raphael Deem
ad8e1cbf62 convert environment vars to int if digits 2017-06-26 20:49:41 -07:00
Jeong YunWon
dc5a70b0de Introduce debug mode for HTTP protocol 2017-06-26 21:13:13 +09:00
Yun Xu
b5d1f52ea4 make flake8 happy 2017-06-25 10:22:40 -07:00
Yun Xu
221cf235b5 fix a unit test 2017-06-25 01:03:28 -07:00
Yun Xu
7720e31a31 add unit test 2017-06-25 00:51:59 -07:00
Yun Xu
d812affef0 add graceful_shutdown_timeout to gunicorn worker 2017-06-25 00:51:14 -07:00
Yun Xu
5c19eb34bf add graceful_shutdown_timeout 2017-06-24 19:00:33 -07:00
7
e18ebaee3d Merge pull request #4 from channelcat/master
merge upstream master branch
2017-06-24 18:21:13 -07:00
Eli Uriegas
dbcbf12456 Merge pull request #811 from Frzk/bearer-support
Added support for 'Authorization: Bearer <TOKEN>' header...
2017-06-23 10:32:21 -07:00
Eli Uriegas
c04b44057c Merge pull request #813 from Frzk/unauthorized-exception
Added an Unauthorized exception
2017-06-23 10:30:51 -07:00
François KUBLER
60aa60f48e Fixed the test for the new Unauthorized exception. 2017-06-23 17:16:31 +02:00
François KUBLER
2848d7c80e Added a Forbidden exception
Also added a small test.
2017-06-23 16:44:57 +02:00
François KUBLER
9fcdacb624 Modified the name of an argument. 2017-06-23 16:29:04 +02:00
François KUBLER
cf1713b085 Added a Unauthorized exception.
Also added a few tests related to this new exception.
2017-06-23 16:12:15 +02:00
7
f049a4ca67 Recycling gunicorn worker (#800)
* add recycling feature to gunicorn worker

* add unit tests

* add more unit tests, and remove redundant trigger_events call

* fixed up unit tests

* make flake8 happy

* address feedbacks

* make flake8 happy

* add doc
2017-06-22 13:26:50 -07:00
François KUBLER
55f860da2f Added support for 'Authorization: Bearer <TOKEN>' header in Request.token property.
Also added a test case for that kind of header.
2017-06-22 18:11:23 +02:00
Eli Uriegas
b5369e611c Merge pull request #764 from stopspazzing/master
Clean up of examples.
2017-06-20 14:53:37 -07:00
Jeremy Zimmerman
3d1dd1c6ac re-add extensions.md to fix merge conflict. 2017-06-20 14:49:12 -07:00
Eli Uriegas
10a363b275 Merge pull request #809 from jrocketfingers/feature/allow-textual-responses
Allow textual responses when using test_client and aiohttp 2
2017-06-20 10:30:26 -07:00
Nikola Kolevski
d865c5e2b6 Conform to pep8 2017-06-20 13:22:28 +02:00
Nikola Kolevski
9fac37588c Allow textual responses when using test_client and aiohttp 2 2017-06-20 13:15:30 +02:00
Jeremy Zimmerman
aac0d58417 Delete extensions.md
non-core content moved to wiki
2017-06-19 15:18:32 -07:00
Eli Uriegas
b37e6187d4 Merge pull request #802 from yunstanford/add-match-info
Add match_info property to request class
2017-06-18 10:15:46 -07:00
Yun Xu
20138ee85f add match_info to request 2017-06-17 09:47:58 -07:00
Raphael Deem
6dc569cde5 Merge pull request #795 from ekampf/patch-1
Prevent `run` from overriding logging config set in constructor
2017-06-15 23:39:09 -07:00
Eran Kampf
77cf0b678a Fix has_log value 2017-06-15 11:21:08 -07:00
Eran Kampf
2dfb061063 Prevent run from overriding logging config set in constructor
When creating the `Sanic` instance I provide it with a customized `log_config`.
Calling `run` overrides these settings unless I provide it *again* with the same `log_config`.
This is confusing and error prone. `run` shouldnt override configurations set in the `Sanic` constructor...
2017-06-15 10:39:00 -07:00
7
e4669e2581 Merge pull request #3 from channelcat/master
merge upstream master branch
2017-06-12 22:15:31 -07:00
Eli Uriegas
df47cf72d3 Merge pull request #791 from seemethere/add_docs_requirements
Add docs requirements
2017-06-12 10:55:45 -07:00
Eli Uriegas
ba1b34e375 Add docs requirements
Closes channelcat/sanic#787
2017-06-12 10:29:38 -07:00
Eli Uriegas
950b5ee529 Merge pull request #789 from yunstanford/coverage-report
Coverage report
2017-06-11 23:38:04 -07:00
Raphael Deem
041c48de19 Merge pull request #790 from r0fls/752
fix #752
2017-06-11 23:24:32 -07:00
Raphael Deem
599fbcee6e fix #752 2017-06-11 23:20:04 -07:00
Yun Xu
ce2df8030c quick fix for test_gunicorn_worker test 2017-06-11 09:06:48 -07:00
Yun Xu
47e761bbe2 add coverage report 2017-06-11 08:49:35 -07:00
7
0646baa18d Merge pull request #2 from channelcat/master
remote-tracking with upstream
2017-06-10 11:54:11 -07:00
Eli Uriegas
38997c1b47 Merge pull request #786 from yunstanford/handle_stream_404
Handle stream 404
2017-06-10 10:03:54 -07:00
Yun Xu
acaafabc23 retry build 2017-06-10 09:57:32 -07:00
Yun Xu
6a80bdafa6 add unit tests 2017-06-10 09:48:30 -07:00
Yun Xu
cf30ed745c also should handle InvalidUsage exception 2017-06-10 09:42:48 -07:00
Eli Uriegas
a399fb4044 Merge pull request #785 from youknowone/gunicorn
Gunicorn worker hints app weather it is being terminated
2017-06-09 11:00:12 -07:00
Yun Xu
24b946e850 make flake8 happy 2017-06-09 08:43:23 -07:00
Yun Xu
236daf48ff add unit tests 2017-06-09 08:42:48 -07:00
Yun Xu
4942af27dc handle NotFound 2017-06-09 08:33:34 -07:00
7
3adb90071b Merge pull request #1 from channelcat/master
merge upstream project
2017-06-09 08:23:14 -07:00
Jeong YunWon
29b4a2a08c Gunicorn worker hints app weather it is being terminated
For now, `Sanic.is_running` is set when the worker is started but not
unset when it is about to stopped. Setting the flag for quit signal
will not affect working requests, but the `Sanic.is_running` flag still
can be used to support graceful termination.
2017-06-09 14:51:15 +09:00
Eli Uriegas
e1331fc0a2 Merge pull request #783 from yunstanford/master
add content_type property in request
2017-06-08 17:30:07 -07:00
Yun Xu
3802f8ff65 unit tests 2017-06-08 17:25:22 -07:00
Eli Uriegas
4b0abdbe7c Merge pull request #782 from yunstanford/sanic-transmute-doc
add sanic-transmute
2017-06-08 14:27:29 -07:00
Yun Xu
81889fd7a3 add unit tests 2017-06-07 20:48:07 -07:00
Yun Xu
aac99c45c0 add content_type property in request 2017-06-07 20:46:48 -07:00
Yun Xu
566a6369a5 add sanic-transmute 2017-06-07 20:27:54 -07:00
Eli Uriegas
4fdf340d04 Merge pull request #773 from mbatchkarov/await-json-too
Testing: store JSON response in local request
2017-06-07 12:05:30 -07:00
Miroslav Batchkarov
ddd7145153 check json is None if body is not JSON 2017-06-07 10:03:27 +01:00
Miroslav Batchkarov
3f22b644b6 wrap call to json in try-except to make tests pass 2017-06-07 09:57:07 +01:00
Eli Uriegas
639c9f579d Merge pull request #774 from algtmatt/feature/logging_doc_fixes
Small logging docs fixes
2017-06-05 10:56:00 -07:00
Matthew Snyder
735b8665f1 Small logging docs fixes 2017-06-05 10:42:17 -07:00
Miroslav Batchkarov
199fa50a9d also store json result in local request 2017-06-05 16:24:23 +01:00
Jeremy Zimmerman
aac5ad8504 Merge remote-tracking branch 'origin/master' 2017-06-01 16:53:36 -07:00
Jeremy Zimmerman
349c108ebc re-added request_stream example. 2017-06-01 16:52:56 -07:00
Eli Uriegas
3b464782ef Merge pull request #765 from ttopholm/master
Added content_type to be set for son response
2017-06-01 16:29:08 -05:00
Tue Topholm
3d97fd8d2a Removed whitespace 2017-06-01 23:09:37 +02:00
Tue Topholm
c102e76146 Fixed line width 2017-06-01 23:01:27 +02:00
Jeremy Zimmerman
beee7b68bf reverted back to default 0.0.0.0 host 2017-06-01 14:01:13 -07:00
Tue Topholm
f47e571d92 Added content_type to be set for son response 2017-06-01 22:53:56 +02:00
Jeremy Zimmerman
4b5320a8f0 Clean up of examples. Removes non-core examples, optimizes and restyles remaining to strictly follow PEP 8 styling guidelines. Non-Core examples will be moved to Wiki. 2017-06-01 11:53:05 -07:00
Daniel Schwarz
30c2c89c6b fix partial url parsing 2017-05-30 16:13:49 +02:00
Raphael Deem
4a1d1a0dc1 Merge pull request #750 from xenu256/patch-1
aiomysql has DictCursor
2017-05-29 22:54:09 -07:00
Raphael Deem
360adc9130 Merge pull request #757 from monobot/asyncOrmV020
update asyncorm version example to 0.2.0
2017-05-29 22:51:46 -07:00
Raphael Deem
cc21abe843 Merge pull request #751 from ak04nv/patch-1
Update jinja_example.py
2017-05-28 23:50:16 -07:00
monobot
9a27555763 update asyncorm version example to 0.2.0 2017-05-29 00:01:56 +01:00
Daniel Schwarz
aaef2fbd01 fix flake8 errors 2017-05-28 18:46:07 +02:00
Anton Kochnev
5bb640ca17 Update jinja_example.py
Added python version check for enabling async mode.
2017-05-28 14:37:41 +08:00
Daniel Schwarz
0e5c7a62cb remove debug messages 2017-05-27 22:36:08 +02:00
Daniel Schwarz
1b33e05f74 fix debug log messages 2017-05-27 16:32:39 +02:00
Daniel Schwarz
53a04309ff add header_fragment handeling 2017-05-27 16:28:57 +02:00
Daniel Schwarz
dc411651b6 add check for header and value 2017-05-27 15:36:57 +02:00
Daniel Schwarz
514540b90b add debug for header values 2017-05-27 15:32:37 +02:00
Tadas Talaikis
a5249d1f5d aiomysql has DictCursor 2017-05-27 11:06:45 +03:00
Eli Uriegas
21aa3f6578 Merge pull request #748 from messense/feature/websocket-config
Add websocket max_size and max_queue configuration
2017-05-26 10:44:49 -05:00
messense
0024edbbb9 Add websocket max_size and max_queue configuration 2017-05-26 11:15:28 +08:00
Raphael Deem
23cb39b557 Merge pull request #744 from algtmatt/feature/from_file_doc_fix
Update config file loader docs
2017-05-24 18:16:10 -07:00
Eli Uriegas
48de321869 Merge pull request #697 from 38elements/stream
Add Request.stream
2017-05-24 16:22:52 -07:00
Raphael Deem
c6d68009d2 Merge pull request #745 from messense/feature/gunicorn-worker-test-case
Add a simple integration test for Gunicorn worker
2017-05-23 20:53:01 -07:00
Raphael Deem
2cab267405 Merge pull request #734 from ashleysommer/static_large_file_stream
Add option to static helper to use streaming for large files.
2017-05-23 20:52:12 -07:00
messense
6bdc0d2e5e Fix Gunicorn worker 2017-05-23 11:28:12 +08:00
messense
3eed81c1eb Add a simple integration test for Gunicorn worker 2017-05-23 11:04:27 +08:00
Raphael Deem
b447807b36 Merge pull request #742 from r0fls/700
changes required for unix socket support
2017-05-22 19:29:32 -07:00
Eli Uriegas
2771c8c32e Merge pull request #738 from messense/feature/conduct
Add Code of Conduct
2017-05-22 15:34:01 -07:00
Eli Uriegas
21a88bc2d3 Add maintainers email address 2017-05-22 15:31:05 -07:00
Matthew Snyder
57c1838f68 Update config file loader docs 2017-05-22 14:10:08 -07:00
Raphael Deem
52b0254ec6 unix socket support; fixes #700 2017-05-21 03:15:06 -07:00
Raphael Deem
49631542ce Merge pull request #732 from jrocketfingers/feature/explicit-register-middleware
Extract register_middleware into a method.
2017-05-21 03:06:12 -07:00
Raphael Deem
4b80ffb9eb Merge pull request #740 from r0fls/739
add abort function
2017-05-21 02:20:02 -07:00
Raphael Deem
9efa7c116d remove redundant code; decode response 2017-05-20 23:27:00 -07:00
Raphael Deem
5d9c8d59a0 add abort() test 2017-05-20 14:43:57 -07:00
Raphael Deem
1a60201f68 flake8 spacing 2017-05-20 10:44:09 -07:00
Raphael Deem
f3186abf09 SANIC_EXCEPTIONS -> _sanic_exceptions 2017-05-20 10:29:00 -07:00
Raphael Deem
6bcc0d3c7f Merge remote-tracking branch 'upstream/master' 2017-05-20 02:17:26 -07:00
Raphael Deem
57b9a57dde Update README.rst 2017-05-20 02:17:12 -07:00
Raphael Deem
28994f4b64 update todo 2017-05-20 02:15:45 -07:00
Raphael Deem
588b4712bf add exception decorator 2017-05-20 01:24:34 -07:00
Raphael Deem
d3b6208057 add abort function 2017-05-19 18:52:19 -07:00
Ashley Sommer
ef80953b1b Fix flake8 line length error. 2017-05-20 09:56:05 +10:00
ashleysommer
72db1188c7 Add an option to the static() helper to switch on streaming for large files.
By default uses a 1M threshold.
ie. if the static file to serve is >= 1M it will stream the file.
This threshold value is configurable by passing an int instead of a bool to `stream_large_files` parameter of `static()`.
2017-05-20 09:56:05 +10:00
Raphael Deem
0858d3c544 Merge pull request #733 from ashleysommer/file_stream
Add file_stream response handler
2017-05-19 16:48:12 -07:00
Ashley Sommer
5c5656f981 Moved file_stream tests to test_responses.py 2017-05-20 09:41:36 +10:00
Raphael Deem
58a9c92d75 fix 739 2017-05-19 13:35:04 -07:00
Eli Uriegas
a6dc4646db Merge pull request #737 from 38elements/deploying
Fix Running via Gunicorn in deploying.md
2017-05-19 12:10:36 -07:00
messense
8ff553e926 Add Code of Conduct 2017-05-19 23:09:44 +08:00
38elements
848a5c61f0 Fix Running via Gunicorn in deploying.md 2017-05-19 23:22:57 +09:00
Raphael Deem
d49000e9f4 Merge pull request #736 from fanjindong/examples_read
debug 'Blueprint names must be unique'
2017-05-19 01:45:06 -07:00
fanjindong
a82145c4e6 debug 'Blueprint names must be unique' 2017-05-19 16:26:56 +08:00
Ashley Sommer
181edb7235 Test file() and file_stream() response helpers.
Added test for `file()` response helper and `file_stream()` response helper.
2017-05-19 13:01:21 +10:00
Ashley Sommer
ff2ae11ac8 Remove exception print(e) statement. 2017-05-19 13:00:01 +10:00
Johnny Rocketfingers
3f841f3b21 Switch to non-hardcoded register_middleware. 2017-05-18 22:08:44 +02:00
ashleysommer
181977ad4e Added brief documentation with an example for file_stream
Added test to ensure `file_stream()` works in the test suite.
2017-05-18 18:12:26 +10:00
ashleysommer
e155fe403d Add file_stream response handler
For streaming large static files
Like `file()` but breaks the file into chunks and sends it with a `StreamingHTTPResponse`
Chunk size is configurable, but defaults to 4k, this seemed to be the sweet spot in my testing.
Also supports ContentRange same as `file()` does.
2017-05-18 18:04:28 +10:00
Johnny Rocketfingers
bf5438d573 Extract register_middleware into a method. 2017-05-18 06:36:11 +02:00
Raphael Deem
0e4aaf8856 Merge pull request #731 from jrocketfingers/fix/token-missing-auth-headers
Check that the Authorization headers are actually provided.
2017-05-17 13:10:12 -07:00
Raphael Deem
5c44ce1637 Merge pull request #719 from messense/feature/worker-uvloop
Gunicorn worker should not require uvloop
2017-05-17 12:47:19 -07:00
Raphael Deem
974fe25a11 Merge pull request #722 from messense/feature/ci-without-ext
Add py3*-no-ext test env
2017-05-17 12:47:05 -07:00
Johnny
58bae83558 Add a regression test. 2017-05-17 11:15:45 +02:00
Johnny
5d309af86f Check that the headers are actually provided. 2017-05-17 11:08:50 +02:00
messense
ec857d1c53 Drop tox-travis 2017-05-17 12:21:56 +08:00
messense
2f84cdd708 Fix websocket handler bug on Python3.5 with no uvloop 2017-05-17 12:12:25 +08:00
messense
7cc02e84ed Fix json loads bug on Python 3.5 2017-05-17 12:12:25 +08:00
Raphael Deem
87c2a5bc97 Merge pull request #724 from suoning/doc-logger
update logging doc
2017-05-16 21:10:57 -07:00
Eli Uriegas
826c2e0f4e Merge pull request #725 from 38elements/contributing
Add rule in CONTRIBUTING.md
2017-05-15 14:45:57 -07:00
Eli Uriegas
b5e25e13b7 Merge pull request #727 from argaen/update_aiocache_example
Update aiocache example to latest version
2017-05-15 11:39:02 -07:00
argaen
f9653114d1 Update aiocache example to latest version 2017-05-15 20:30:52 +02:00
Eli Uriegas
6b7e19891b Get rid of un-needed s, Fix some formatting. 2017-05-15 10:54:47 -07:00
38elements
a677f14423 Add rule in CONTRIBUTING.md 2017-05-15 21:28:35 +09:00
suoning
dddce3f30d update logging, Remove the comments 2017-05-15 13:59:03 +08:00
Raphael Deem
be93d670a3 Merge pull request #717 from jrocketfingers/fix/ipv6-access-log
Fix "TypeError: not all arguments converted during string formatting"
2017-05-14 20:28:07 -07:00
suoning
68d4bb6ffe update logging doc 2017-05-15 10:54:30 +08:00
suoning
a27471178a update logger doc 2017-05-15 10:25:19 +08:00
messense
66fcb0cc8f Add py3*-no-ext test env 2017-05-15 10:10:50 +08:00
messense
05d0ddc281 Gunicorn worker should not require uvloop 2017-05-15 00:01:51 +08:00
Johnny Rocketfingers
b1890f50b6 Conform to pep8 2017-05-14 10:15:11 +02:00
Johnny Rocketfingers
b44c707e94 Prevent incorrect tuple size on get_extra_info errors
According to https://docs.python.org/3/library/asyncio-protocol.html#asyncio.BaseTransport.get_extra_info,
get_extra_info fails by returning None. This is an attempt in
normalization of the response in cases of AF_INET, AF_INET6 and
erroneous return values.
2017-05-14 09:56:56 +02:00
Johnny
4c7675939a Fix "TypeError: not all arguments converted during string formatting"
socket.getpeername() returns AF_INET6 address family four-tuple, with
flowid and scopeid.

In server's write_response, an exception is raised when an IPv6 client
connects due to four-tuple elements having two unused elements (flowid
and scopeid).

This makes sure that only the first two (host and port) are used in log
string formatting.
2017-05-13 17:35:04 +02:00
Eli Uriegas
fa1b7de52a Merge pull request #706 from messense/feature/remove-log-file
Remove timedRotatingFile log config
2017-05-12 10:56:19 -07:00
Eli Uriegas
666f8c8d3c Merge pull request #712 from stopspazzing/master
Fixed plotly_example, now works
2017-05-12 10:39:57 -07:00
Jeremy Zimmerman
996c0b3280 Fixed with a working example
Remember:
K.I.S.S
2017-05-11 13:40:16 -07:00
Eli Uriegas
f9d428de8b Merge pull request #711 from stopspazzing/master
Use of register_blueprint will be deprecated, why not upgrade?
2017-05-11 12:53:43 -07:00
Jeremy Zimmerman
a17b3f1b84 Use of register_blueprint will be deprecated, why not upgrade? 2017-05-11 12:33:57 -07:00
Jeremy Zimmerman
f39512aa63 double if statement (#707)
* Migrated `%` string formating

* double if statement

combined double 'if' to a single 'if' with 'and'

* Revert "Fix "Prefer `format()` over string interpolation operator" issue"
2017-05-11 11:49:32 -07:00
Raphael Deem
23ee9f64d4 Merge pull request #710 from monobot/asyncorm_update
modify the asyncorm example, with the new lazy querysets
2017-05-11 10:35:52 -07:00
monobot
ad68739df7 modify the asyncorm example, for the new lazy querysets 2017-05-11 18:15:04 +01:00
38elements
a50d8421b8 Add heading in streaming.md 2017-05-11 19:18:58 +09:00
messense
3ea1b07906 Revert "Add access.log and error.log to .gitignore"
This reverts commit fc0d69616c.
2017-05-11 11:19:03 +08:00
messense
c3683662c2 Remove timedRotatingFile log config 2017-05-11 11:18:59 +08:00
Eli Uriegas
861865807a Merge pull request #705 from stopspazzing/patch-2
spelling mistake
2017-05-10 10:52:29 -07:00
Jeremy Zimmerman
18930082e2 spelling mistake
fixed incorrect spelling
2017-05-10 09:38:57 -07:00
38elements
6a14e49479 Replace stream decorator to stream parameter 2017-05-09 22:31:15 +09:00
Raphael Deem
c530d5f016 Merge pull request #704 from seemethere/fix_camel_case
Fix camel case module
2017-05-08 20:50:39 -07:00
Eli Uriegas
ac5e1a6ebd Fix import 2017-05-08 20:47:20 -07:00
Eli Uriegas
bb6de53f28 Fix docs 2017-05-08 20:44:19 -07:00
Eli Uriegas
bfcd499cc2 Remove default_filter module, put into logging 2017-05-08 20:41:34 -07:00
Eli Uriegas
3e88ec18e2 Actually add file >.> 2017-05-08 20:37:44 -07:00
Eli Uriegas
1fb640c313 Fix camel case module 2017-05-08 20:36:57 -07:00
Eli Uriegas
bece3d2bcf Merge pull request #702 from seemethere/increment_054
Increment to 0.5.4
2017-05-08 17:44:50 -07:00
Eli Uriegas
307d866bb6 Increment to 0.5.4 2017-05-08 17:44:23 -07:00
Eli Uriegas
95c9514a44 Merge pull request #701 from seemethere/increment_053
Increment to 0.5.3
2017-05-08 17:42:54 -07:00
Eli Uriegas
768be433d6 Increment to 0.5.3 2017-05-08 17:42:26 -07:00
38elements
4d4f38fb35 is_request_stream for CompositionView and HTTPMethodView 2017-05-09 01:04:03 +09:00
38elements
15ad07f03d Fix streaming.md 2017-05-08 00:10:36 +09:00
38elements
0b53c413a7 Add stream decorator for HTTPMethodView 2017-05-07 21:33:15 +09:00
38elements
931397c7e1 Add stream for CompositionView 2017-05-07 18:38:48 +09:00
38elements
ef2cc7ebf5 Add Request.stream 2017-05-07 18:38:48 +09:00
Eli Uriegas
8d3fd75ec2 Merge pull request #695 from kszucs/aiopeewee
aiopeewee example
2017-05-05 11:31:37 -07:00
Szucs Krisztian
a42b254c33 use async version of model_to_dict 2017-05-05 10:51:12 +02:00
Szucs Krisztian
d24e1ae110 removed lines from distributed example 2017-05-05 08:25:18 +02:00
Szucs Krisztian
2e7badab4e aiopeewee example 2017-05-05 08:19:09 +02:00
Raphael Deem
7cf3d49f00 Merge pull request #690 from 38elements/sanic_endpoint_test
Remove utils.py
2017-05-03 23:56:13 -07:00
38elements
25037006bf Remove utils.py 2017-05-04 15:52:18 +09:00
Eli Uriegas
f611eb2c2b Merge pull request #686 from 38elements/loop
Remove loop argument in run() and create_server()
2017-05-03 15:27:16 -07:00
38elements
e12c10b087 Remove loop argument in run() and create_server() 2017-05-03 17:52:19 +09:00
Raphael Deem
9527e5ded8 Merge pull request #685 from r0fls/document-create-server
document create_server method
2017-05-02 22:45:51 -07:00
Raphael Deem
23b4b20b4f document create_server method 2017-05-02 22:44:42 -07:00
Eli Uriegas
7f9ecd659c Merge pull request #682 from graingert/fix-readme.rst-encoding
fix README.rst -> long_description encoding
2017-05-02 10:48:45 -07:00
Eli Uriegas
bb31d465f2 Add distribution types 2017-05-02 10:47:55 -07:00
Thomas Grainger
834468e8e7 fix README.rst -> long_description encoding 2017-05-02 17:37:17 +01:00
Eli Uriegas
4720513672 Merge pull request #679 from graingert/verify-readme-rst-pypi
verify readme for PyPI
2017-05-02 09:31:01 -07:00
Eli Uriegas
a480110d43 Merge pull request #681 from 38elements/deprecation
Remove before_start, before_stop, after_start and after_stop
2017-05-02 09:28:33 -07:00
38elements
0a2c95cc10 Remove before_start, before_stop, after_start and after_stop 2017-05-02 23:07:09 +09:00
Thomas Grainger
9d2e32902d check readme in travis 2017-05-02 10:17:24 +01:00
Thomas Grainger
77b6413526 validate readme for PyPI 2017-05-02 10:05:06 +01:00
Thomas Grainger
9e502099e0 add readme to package directly 2017-05-02 10:05:05 +01:00
Eli Uriegas
c6a7e44ae7 Merge pull request #678 from stopspazzing/patch-1
misspelling
2017-05-01 17:27:31 -07:00
Jeremy Zimmerman
1bf06312b8 misspelling
acutal -> actual
2017-05-01 17:07:38 -07:00
Eli Uriegas
c35721abbd Merge pull request #670 from ticosax/set-exit-code-on-error
In case of error when starting sanic
2017-05-01 15:16:02 -07:00
Eli Uriegas
7f3c417078 Merge pull request #677 from abuckenheimer/master
added exception chain rendering in debug #675
2017-05-01 15:15:34 -07:00
Alec Buckenheimer
69511c2783 added exception chain rendering in debug #675 2017-05-01 12:56:33 -04:00
Eli Uriegas
158a94d34c Merge pull request #674 from 38elements/test-for-uri-template
Add test for uri_template
2017-04-30 20:22:51 -07:00
Eli Uriegas
db58bd68f5 Merge pull request #673 from 38elements/routing
Fix docs/sanic/routing.md
2017-04-30 20:22:30 -07:00
38elements
e65f08a2c8 Fix docs/sanic/routing.md 2017-04-30 22:03:16 +09:00
38elements
ab8f616385 Add test for uri_template 2017-04-30 21:57:32 +09:00
Eli Uriegas
6dc6f9bbb5 Merge pull request #671 from banteg/uri-template
Expose matched request uri template
2017-04-28 14:22:59 -07:00
banteg
7754bb995b expose matched request uri template 2017-04-29 02:39:56 +07:00
Nicolas Delaby
d1fefce61c fixup! In case of error when starting sanic 2017-04-28 20:06:44 +02:00
Nicolas Delaby
c3abdab9c4 The main process that spawn sub processes doesn't run any loop.
let's not try to stop one
2017-04-28 19:57:49 +02:00
Nicolas Delaby
8b13e103fd In case of error when starting sanic
Don't exit with code 0
2017-04-28 19:08:51 +02:00
Eli Uriegas
5f94f65f4f Merge pull request #669 from 38elements/log
Add access.log and error.log to .gitignore
2017-04-28 07:40:42 -07:00
38elements
fc0d69616c Add access.log and error.log to .gitignore 2017-04-28 18:52:15 +09:00
Raphael Deem
656f5b93d6 Merge pull request #668 from seemethere/stop_workers_on_sigint
Add the killing of children
2017-04-27 22:39:48 -07:00
Eli Uriegas
436d37c079 Add the killing of children
Kills children processes when parent process receives a signal to
shutdown.

Solves for #594
2017-04-27 17:47:08 -07:00
Eli Uriegas
ed0081fcf7 Merge pull request #625 from zenixls2/master
based on issue #608, create access log
2017-04-27 14:31:53 -07:00
Eli Uriegas
140062f8a3 Merge pull request #662 from rsrdesarrollo/master
invariant: body after request is processed must be binary
2017-04-27 14:31:28 -07:00
Raphael Deem
75f5fa7c06 Merge pull request #666 from pyx/issue-665
Fix #665 - ImportError not preserved in __main__.py
2017-04-27 00:32:09 -07:00
Philip Xu
9152a1a266 Improved on wording 2017-04-27 03:16:38 -04:00
Philip Xu
ade89ab795 Fix #665 - ImportError not preserved in __main__.py 2017-04-26 22:57:19 -04:00
zenix
95cfdee8b8 Merge branch 'master' of https://github.com/channelcat/sanic 2017-04-26 14:50:42 +09:00
zenix
63a27cc5e2 add document on logging 2017-04-26 14:50:21 +09:00
Eli Uriegas
472face796 Add link to issue tracking sanic projects! 2017-04-25 21:50:49 -07:00
Raphael Deem
8d537a6d0b Merge pull request #663 from mmaybeno/fix_jinja_example_typo
Fix typo for jinja example and converted to dir
2017-04-25 20:29:12 -07:00
Matt Maybeno
b3101d339e Fix typo for jinja example and converted to dir 2017-04-25 20:10:46 -07:00
Raúl Sampedro
85acddddba invariant: body after request is processed must be binary 2017-04-25 12:00:27 +02:00
zenix
c9d747d97f fix merge error 2017-04-25 11:46:13 +09:00
zenix
0bba267808 Merge branch 'master' of https://github.com/channelcat/sanic 2017-04-25 11:07:40 +09:00
Eli Uriegas
1036242064 Merge pull request #661 from seemethere/increment_052
Increment to 0.5.2
2017-04-24 13:39:39 -05:00
Eli Uriegas
5fd62098bd Increment to 0.5.2 2017-04-24 11:37:04 -07:00
Raphael Deem
74cc7be922 Merge branch 'master' into master 2017-04-24 00:47:01 -07:00
Raphael Deem
b3814ca89a Merge pull request #646 from r0fls/637
allow disabling keep alive
2017-04-24 00:43:16 -07:00
Raphael Deem
b75a321e4a Merge pull request #644 from kszucs/master
Example to use dask distibuted
2017-04-22 01:14:34 -07:00
Raphael Deem
9caa4fec4a Merge pull request #656 from r0fls/token-rework
update token attribute
2017-04-21 22:44:42 -07:00
Raphael Deem
a0cba1aee1 accept token directly in auth header 2017-04-21 22:36:45 -07:00
Raphael Deem
97018ad62f Merge pull request #655 from seemethere/fix_gunicorn_worker
Fix duplicate signal settings for gunicorn worker
2017-04-21 22:16:43 -07:00
Eli Uriegas
a7d17fae44 Fix duplicate signal settings for gunicorn worker 2017-04-21 17:06:52 -05:00
Raphael Deem
6ce0050979 Merge pull request #652 from 38elements/signal-stopped
Fix `this.signal.stopped` is `True` #639
2017-04-20 13:06:28 -07:00
38elements
bc035fca78 Remove unnecessary variables 2017-04-20 18:27:28 +09:00
38elements
df914a92e4 Fix this.signal.stopped is True #639 2017-04-19 11:19:01 +09:00
Szucs Krisztian
1b939a6823 work with distributed 1.16.1 2017-04-17 11:05:19 +02:00
Raphael Deem
81b6d988ec NO_KEEP_ALIVE -> KEEP_ALIVE 2017-04-16 22:43:49 -07:00
Raphael Deem
7e9b65feca Merge pull request #647 from r0fls/645
use absolute path in static root
2017-04-16 22:06:40 -07:00
Raphael Deem
6f098b3d21 add no_keep_alive setting to docs 2017-04-16 22:05:34 -07:00
Raphael Deem
5ddb0488f2 allow disabling keep alive 2017-04-16 22:03:20 -07:00
Raphael Deem
3e87314adf use absolute path in static root 2017-04-16 21:58:10 -07:00
Raphael Deem
f6d4a06661 Merge pull request #643 from aryeh/allow_unknown_status_codes
Allow unknown status codes
2017-04-16 18:42:59 -07:00
Raphael Deem
ff17fc95e6 Merge pull request #632 from messense/feature/path-route
Add path type for router
2017-04-16 18:39:10 -07:00
Eli Uriegas
c5a46f1cea Merge pull request #638 from seemethere/add_contributing_rules
Add new contributing rules
2017-04-16 13:15:01 -05:00
Eli Uriegas
0b072189c4 Merge pull request #641 from TomIsPrettyCool/master
Use render_async and a template env with the Jinja2 example.
2017-04-16 13:14:35 -05:00
Szucs Krisztian
5b22d1486a fix syntax error in comment 2017-04-16 18:13:00 +02:00
Szucs Krisztian
9eb48c2b0d dask distributed example 2017-04-16 18:11:24 +02:00
aryeh
ff0632001c prevent crash for unknown response codes
set text for unknown status code, otherwise when None is used exception occurs.
2017-04-16 10:07:29 -04:00
aryeh
28bd09a2ea Merge pull request #1 from channelcat/master
pull master
2017-04-16 09:48:59 -04:00
Tom Haines
c6aaa9b09c Use render_async and a template env with jinja2 2017-04-16 13:50:07 +01:00
Eli Uriegas
20d9ec1fd2 Fix the numbered list 2017-04-14 14:38:45 -05:00
Eli Uriegas
2c45c2d3c0 Add new contributing rules 2017-04-14 14:35:28 -05:00
Eli Uriegas
18829e648a Merge pull request #635 from yeahx/master
fix directory traversal flaw
2017-04-14 14:01:29 -05:00
Eli Uriegas
a64c636a33 Merge pull request #627 from Sniedes722/master
Updating examples for 0.5.0
2017-04-14 13:21:43 -05:00
Shawn Niederriter
5796f211c1 Added detailed plotly example project 2017-04-14 17:17:23 +00:00
lazydog
ae09dec05e fixed UnboundLocalError 2017-04-14 03:38:55 +08:00
lazydog
afd51e0823 fix directory traversal flaw 2017-04-14 02:55:39 +08:00
zenix
0bbf826b21 fix typo 2017-04-13 16:52:40 +09:00
zenix
02d1900e2f try to fix container error 2017-04-13 16:49:36 +09:00
zenix
73da11b04c switch to use streaming for access log and error log 2017-04-13 16:26:13 +09:00
zenix
4af07e3731 change naming of default log config 2017-04-13 13:49:45 +09:00
zenix
7f60f85cd4 Merge branch 'master' of https://github.com/channelcat/sanic 2017-04-13 13:35:37 +09:00
messense
4c66cb1854 Fix static files router 2017-04-13 12:11:38 +08:00
messense
35b92e1511 Add path type for router 2017-04-13 11:34:35 +08:00
Raphael Deem
e5d3fe52c5 Merge pull request #630 from 38elements/keep_alive
Refactor keep_alive
2017-04-12 19:46:33 -07:00
Raphael Deem
63fe7c0a86 Merge pull request #631 from adamserafini/fix-installation
Fix installation on Ubuntu 16.10 #629
2017-04-12 18:53:23 -07:00
zenix
c5f137c715 fix original code logic 2017-04-12 18:52:01 +09:00
zenix
66923bc0e3 remove unused param 2017-04-12 18:48:16 +09:00
zenix
8bf7b5a323 remove unused dependency 2017-04-12 18:45:38 +09:00
zenix
36d4d85849 change to use default python config code 2017-04-12 18:44:47 +09:00
zenix
5f0e05f3bf fix flake8 2017-04-12 18:08:06 +09:00
adam.serafini
235e5511eb Bump version 2017-04-12 11:02:13 +02:00
zenix
6fb60ae0b1 Merge branch 'master' of https://github.com/channelcat/sanic 2017-04-12 18:01:12 +09:00
adam.serafini
6b2883074b Fix installation on Ubuntu 16.10
Fixes issue #629. Printing a unicode string at the end of the
setup.py script is asking for trouble. It's also redundant:
the pip tool itself tells the user whether the installation was
successful or not.
2017-04-12 10:59:03 +02:00
38elements
7fe418d1b7 Refactor keep_alive 2017-04-12 17:55:22 +09:00
zenix
f872ceb0d9 fix bug in access logging when error happens 2017-04-12 17:39:17 +09:00
Shawn Niederriter
0f10a36b40 Added url_for example 2017-04-12 06:20:35 +00:00
Shawn Niederriter
3c45c9170f Fixed to merge with #626 2017-04-11 21:55:45 +00:00
Shawn Niederriter
a0730aeb44 Merge https://github.com/channelcat/sanic
Version 0.0.5
2017-04-11 21:47:08 +00:00
Eli Uriegas
e5fdc7fdd0 Merge pull request #626 from seemethere/increment_050
Increment to 0.5.0
2017-04-11 16:05:26 -05:00
Eli Uriegas
015c87b5e1 Add traceback for better debugging 2017-04-11 16:02:57 -05:00
Eli Uriegas
d20a49e500 Lock chardet for now... 2017-04-11 16:02:49 -05:00
Shawn Niederriter
adb7331670 Updated examples for 0.5.0 2017-04-11 20:34:55 +00:00
Eli Uriegas
084f0d27a3 Increment to 0.5.0 2017-04-11 15:19:00 -05:00
Eli Uriegas
522a0beec0 Merge pull request #622 from aryeh/provide_request_object
Allow a custom Request class to be passed in to Sanic
2017-04-11 15:13:05 -05:00
zenix
bf46bcf376 Merge branch 'logging' 2017-04-11 19:03:35 +09:00
zenix
f330c3f8c5 add logging based on issue #608, add default config 2017-04-11 18:59:07 +09:00
Raphael Deem
77a51c1e05 Merge pull request #617 from Sniedes722/master
Update Examples for 0.4.2
2017-04-10 19:07:29 -07:00
Raphael Deem
144f215705 Merge pull request #623 from qwIvan/master
Fixed #615
2017-04-10 18:58:31 -07:00
ivan
51b01b6b44 Merge branch 'master' of github.com:qwIvan/sanic 2017-04-10 18:33:43 +08:00
ivan
09885534c6 fixed #615 2017-04-10 18:31:28 +08:00
aryeh
b9dfec38c2 Break long line (> 80 chars) into 2 lines 2017-04-09 13:38:36 -04:00
aryeh
2ef8120073 Allow a custom Request class to be passed in to Sonic
Allowing a custom Request class to be defined would enable either a different Request class or a subclass of Request to be used, providing more flexibility.
2017-04-09 13:29:21 -04:00
Raphael Deem
52ff2e0e63 Merge pull request #621 from r0fls/620
fix python -m method of running
2017-04-08 13:32:17 -07:00
Raphael Deem
8cf7dce33f fix python -m method of running 2017-04-08 13:31:17 -07:00
Shawn Niederriter
9d3bb4a37a Updated examples in-line with response docs 2017-04-06 19:47:25 +00:00
Shawn Niederriter
c30437448b Updated aiohttp & run_async examples, added redirect 2017-04-06 19:42:05 +00:00
Raphael Deem
7e3496f8aa Merge pull request #614 from dkruchinin/middleware
Response middleware should be called even if server replies with an error
2017-04-06 11:49:44 -07:00
Shawn Niederriter
46ac79f4dc Update run_async demo 2017-04-06 14:39:54 -04:00
Shawn Niederriter
833b14e353 Updated aiohttp example. 2017-04-06 13:33:29 -04:00
Eli Uriegas
e9eca25792 Merge pull request #616 from r0fls/610
use socket.set_inheritable instead of os version
2017-04-04 15:17:31 -05:00
Raphael Deem
1854ad133c use socket.set_inheritable instead of os version 2017-04-04 13:13:52 -07:00
Eli Uriegas
2b5e723ea5 Merge pull request #519 from youknowone/recall-379
Add #379 again and make related test rework
2017-04-04 15:08:57 -05:00
Raphael Deem
9a18906edd Merge pull request #612 from dkruchinin/prom
Add prometheus extension
2017-04-04 11:06:43 -07:00
Raphael Deem
93cb7582c2 Merge branch 'master' into prom 2017-04-04 11:06:32 -07:00
Raphael Deem
b4529639f6 Merge pull request #611 from ashleysommer/master
Add Sanic-RestPlus to extensions.
2017-04-04 11:06:02 -07:00
Dan Kruchinin
f0a59fccf8 flake8-related fixes 2017-04-04 17:19:45 +01:00
Dan Kruchinin
46dbaf95a6 Response middleware should be called even if server replies with error 2017-04-04 15:55:43 +01:00
Dan Kruchinin
d418b03708 Add prometheus extension 2017-04-04 14:22:31 +01:00
Ashley Sommer
765e90ecfa update extensions
Add Sanic-RestPlus!
2017-04-04 13:40:59 +10:00
Ashley Sommer
ff1e88dde6 Merge pull request #2 from channelcat/master
update to latest sanic
2017-04-04 13:39:21 +10:00
Eli Uriegas
62ebcba647 Add graphql integration extension
Closes #579
2017-04-03 14:45:18 -05:00
Jeong YunWon
429e90183b Add #379 again and make related test rework
Original PR: https://github.com/channelcat/sanic/pull/379
2017-04-03 18:56:39 +09:00
Raphael Deem
875790e862 Merge pull request #606 from monobot/master
Fix URL Parse Error #599
2017-04-02 12:16:24 -07:00
monobot
25edbe6805 update docs 2017-04-02 02:28:16 +01:00
monobot
e148b50d6a Merge remote-tracking branch 'upstream/master' 2017-04-02 00:02:49 +01:00
Raphael Deem
06d46d56cd Merge pull request #602 from jkbbwr/fix/env-install
Flake8 cleanup. Setup environmental variables.
2017-03-31 10:42:21 -07:00
Jakob Bowyer
edd8770c67 Restored tests to upstream/master 2017-03-31 08:53:46 +01:00
Jakob Bowyer
daedda8547 Checked out original tests 2017-03-31 08:51:12 +01:00
Raphael Deem
df9d897e75 Merge pull request #607 from nosahama/hotfix/docs-cookie-typo-fix
Typo Fix in docs/sanic/cookies.md
2017-03-30 16:24:58 -07:00
nosaevb
fcd8e5e5ad Typo Fix in docs/sanic/cookies.md 2017-03-30 23:02:46 +01:00
monobot
6c003f71f4 Merge remote-tracking branch 'upstream/master' 2017-03-29 23:54:11 +01:00
monobot
5b704478d9 raw_args for request objects 2017-03-29 22:06:54 +01:00
Eli Uriegas
60eb528d68 Merge pull request #491 from r0fls/remove-stop-event
remove stop_event
2017-03-29 07:08:55 -05:00
Jakob Bowyer
1cf730d957 Added usage documentation for optional installs 2017-03-29 10:12:24 +01:00
Raphael Deem
171110b445 Merge pull request #604 from seemethere/add_docker_unittest_support
Fixing the unittests
2017-03-29 02:03:54 -07:00
Jakob Bowyer
22699db855 Moved skips to seperate pull request 2017-03-29 09:16:53 +01:00
Eli Uriegas
18405b3908 There was a line missing here? 2017-03-28 22:57:58 -05:00
Eli Uriegas
f0a55b5cbb Fix line length again... 2017-03-28 22:51:23 -05:00
Eli Uriegas
04a0774ee5 Fix line length 2017-03-28 22:51:23 -05:00
Eli Uriegas
3a8cfb1f45 Make these tests not so far apart 2017-03-28 22:51:23 -05:00
Eli Uriegas
dcc19d17d4 Lock to aiohttp 1.3.5 for now 2017-03-28 22:51:23 -05:00
Eli Uriegas
1ef69adc6f Simplify this as well, it replicated effort 2017-03-28 22:51:23 -05:00
Eli Uriegas
75a4df0f32 Simplify this, it had a lot of fluff 2017-03-28 22:51:23 -05:00
Eli Uriegas
8ba1b5fc35 Add docker support for local unit testing
Addresses consistency across different OS's by making it very similar to
the base Travis image.
2017-03-28 22:51:23 -05:00
Eli Uriegas
a09471ac6c Merge pull request #600 from monobot/master
added asyncorm example
2017-03-28 22:50:20 -05:00
Eli Uriegas
a916eea684 Merge pull request #601 from SakuraSound/master
Detailed example with logging, database access, environment variables, and basic middleware
2017-03-28 22:49:26 -05:00
Eli Uriegas
511998d8e1 Merge pull request #573 from r0fls/env-config
allow setting config from individual env variables
2017-03-28 22:24:37 -05:00
Joir-dan Gumbs
e3cf50f791 Changed out redis middleware for redis listeners (open/close). Fleshed out the payloads of both endpoints. Added comment about required packages. 2017-03-28 15:00:23 -07:00
Jakob Bowyer
42ba5298a7 Flake8 cleanup. Setup environmental variables.
Skipping broken tests unrelated.
2017-03-28 10:50:09 +01:00
Joir-dan Gumbs
ee79750a22 Cleaned up functions. Added extra middleware function to log endpoint being called. Added documentation to make easier to understand. 2017-03-28 01:22:36 -07:00
Raphael Deem
1787f8617f Merge pull request #592 from weargoggles/patch-1
Document synchronous response.write in streaming
2017-03-27 20:14:20 -07:00
Joir-dan Gumbs
748ca28185 Created detailed example of using sanic. Adds configurations based on various environment variables, handles database access (using aioredis), uses middleware to check for db object and attach it to request object, and logs events to a logfile (which is set using environment variables). 2017-03-27 15:42:13 -07:00
monobot
9c68d713ba added asyncorm example 2017-03-27 22:47:35 +01:00
Raphael Deem
fc69678206 Merge remote-tracking branch 'upstream/master' into remove-stop-event 2017-03-26 15:59:31 -07:00
Raphael Deem
aebd717039 fix merge conflict 2017-03-26 15:49:58 -07:00
Raphael Deem
1ddb01ac44 remove stop_event 2017-03-26 15:48:41 -07:00
Raphael Deem
3e279cd670 Merge pull request #593 from itielshwartz/master
add sanic-nginx-docker-example to extensions.md
2017-03-26 11:50:45 -07:00
Raphael Deem
724c03630a Update extensions.md 2017-03-26 11:49:15 -07:00
itiel
b00b2561e5 add sanic-nginx-docker-example to extensions.md 2017-03-26 21:16:03 +03:00
Raphael Deem
c5b50fe3cf allow setting config from individual env variables 2017-03-25 17:45:55 -07:00
Raphael Deem
df9884de3c Merge pull request #576 from matuusu/master
fix http status code not propagating in response
2017-03-24 19:23:20 -07:00
Pete Wildsmith
65ae7669f9 Document synchronous response.write in streaming
The Streaming section of the docs was updated to make clear that a synchronous write should be used in the callback, but this section was not updated.
2017-03-24 10:11:30 +00:00
Raphael Deem
179606feb1 Merge pull request #590 from r0fls/blueprint-strict-slash
add blueprint strict_slashes
2017-03-23 18:42:21 -07:00
Raphael Deem
536140340e Merge pull request #585 from subyraman/listener-docs
add docs for server lifecycle listeners and `add_task`
2017-03-23 18:38:48 -07:00
Raphael Deem
5d293df64b add blueprint strict_slashes 2017-03-23 18:37:06 -07:00
Suby Raman
6188891a53 add-listeners-docs 2017-03-23 15:49:23 -04:00
Raphael Deem
9774661cfe Merge pull request #580 from skytoup/master
Fix testing not support binary file
2017-03-23 12:22:08 -07:00
Raphael Deem
563bc34fb5 Merge pull request #578 from messense/feature/gunicorn-deploy-doc
Add documentation for Gunicorn worker
2017-03-23 12:20:00 -07:00
Raphael Deem
9c95ab3a28 Merge pull request #584 from subyraman/add-decorators-info
add decorator docs
2017-03-23 12:19:23 -07:00
Suby Raman
b776c37b36 add decorator docs 2017-03-23 15:16:46 -04:00
Eli Uriegas
5b3f92b70f Merge pull request #577 from seemethere/fix_tests_after_aiohttp_2
Hotfixes tests failing from URL object change
2017-03-23 13:56:16 -05:00
ivan
1562b81522 add arg load_body in testing 2017-03-23 20:48:57 +08:00
ivan
be1016ace6 merge upstream 2017-03-23 20:08:19 +08:00
ivan
ee27c689e1 commented aiohttp load response body in testing 2017-03-23 20:06:39 +08:00
skytoup
fdbf452ced 1. try...catch aiohttp encode response body to text in test_client
2. add tests static binary file
2017-03-23 15:22:00 +08:00
messense
3d9927dee0 Add documentation for Gunicorn worker 2017-03-23 09:12:23 +08:00
Raphael Deem
1456b128d2 Merge pull request #572 from sourcepirate/master
Removed raw string in cookies documentation
2017-03-22 14:55:20 -07:00
Eli Uriegas
166f77cb86 Merge pull request #545 from messense/feature/gunicorn-worker
Addition of a gunicorn worker
2017-03-22 16:27:06 -05:00
Eli Uriegas
5577838905 Hotfixes tests failing from URL object change
aiohttp decided to use yarl for their new URL objects so that they
aren't plain strings anymore which means that this single test fails.
Not a huge change but this should fix the testing suite.
2017-03-22 16:21:35 -05:00
matuusu
9c15982299 Update response.py
fix status code not propagating from response.stream to response.StreamingHTTPResponse
2017-03-22 12:40:40 +01:00
sourcepirate
63c24122db Removed raw string in cookies documentation 2017-03-22 06:39:23 +05:30
messense
1396ca903d Fix before_stop event 2017-03-20 14:27:02 +08:00
messense
d1fb5bdc30 Fix async before_server_start hook bug 2017-03-20 14:25:32 +08:00
messense
e27812bf3e Set signal.stopped = True on closing 2017-03-20 14:25:32 +08:00
messense
11a3cf9b99 Add signal handling 2017-03-20 14:25:32 +08:00
messense
a90d70feae Check connections is not None 2017-03-20 14:25:32 +08:00
messense
466b34735c Set app.is_running to True 2017-03-20 14:25:32 +08:00
messense
7ca9116e37 Trigger before_stop before closing server, after_stop before closing
loop
2017-03-20 14:25:31 +08:00
messense
decd3e737c Flake8 fix 2017-03-20 14:25:31 +08:00
messense
f35442ad1b Fix RuntimeError: this event loop is already running 2017-03-20 14:25:31 +08:00
messense
2b296435b3 Trigger events 2017-03-20 14:25:31 +08:00
messense
19ee1dfecc Gunicorn worker 2017-03-20 14:25:31 +08:00
Raphael Deem
7da4596ef8 Merge pull request #567 from Sniedes722/master
Added Sanic-OAuth to extensions.
2017-03-19 14:20:19 -07:00
Shawn Niederriter
a379ef6781 Added Sanic-OAuth to extensions. 2017-03-18 23:56:11 -04:00
Raphael Deem
7beb065be3 Merge pull request #562 from lixxu/master
update function name as it not halt request actually
2017-03-18 13:17:24 -07:00
Raphael Deem
38b9091513 Merge pull request #443 from sourcepirate/master
Fixed sanic peewee example.
2017-03-17 13:12:39 -07:00
Raphael Deem
96db3c9601 Merge pull request #564 from messense/feature/aioredis-example
Add an aioredis example
2017-03-17 13:11:19 -07:00
Raphael Deem
43c4fc8e33 Merge pull request #559 from r0fls/557
accept strict_slash routes
2017-03-17 13:10:26 -07:00
messense
986ff101ce Add an aioredis example 2017-03-17 14:16:13 +08:00
lixxu
94c83c445f fix broken table 2017-03-17 14:01:54 +08:00
lixxu
625865412f update function name as it not halt request actually 2017-03-17 13:12:17 +08:00
Raphael Deem
46677e69ce accept strict_slash routes 2017-03-16 11:46:07 -07:00
Eli Uriegas
5fbca5b823 Merge pull request #561 from kdelwat/master
Fix ReadTheDocs build errors
2017-03-16 09:02:39 -05:00
Eli Uriegas
879fab120f Merge pull request #560 from miguelgrinberg/cancel-websocket-tasks
cancel websocket tasks if server is stopped
2017-03-16 09:02:30 -05:00
Cadel Watson
391b24bc17 Add websockets dependency to ReadTheDocs environment 2017-03-16 17:01:49 +11:00
Cadel Watson
d713533d26 Fix docstring formatting errors 2017-03-16 16:52:18 +11:00
Cadel Watson
24f745a334 Fix formatting errors in RST files 2017-03-16 16:51:02 +11:00
Cadel Watson
86f3101861 Add autodoc extension to Sphinx configuration 2017-03-16 16:50:33 +11:00
Miguel Grinberg
fd823c63ab cancel websocket tasks if server is stopped 2017-03-15 22:45:19 -07:00
Raphael Deem
fa69892f70 Merge pull request #558 from Zheaoli/master
Add a new example by using aiomysql
2017-03-15 20:05:37 -07:00
lizheao
cfc53d0d26 Change some code in sanic aiomysql code 2017-03-15 14:42:22 +08:00
lizheao
97c2056e4a Change some code in sanic aiomysql code 2017-03-15 14:41:54 +08:00
lizheao
0ad0164171 Change some code in sanic aiomysql code 2017-03-15 14:41:38 +08:00
lizheao
df0e285b6f Add a new example 2017-03-15 14:12:37 +08:00
Raphael Deem
e92f1b8c28 Merge pull request #556 from AntonDnepr/fix-414
Small changes to the docs and tests for the #414
2017-03-14 21:07:55 -07:00
Anton Zhyrnyi
410f86c960 fix for docs&tests 2017-03-14 20:53:58 +02:00
Raphael Deem
85f27320e7 Merge pull request #553 from ashleysommer/ashleysommer-add-dispatch-extension
Add Dispatcher Extension to Extensions page in Docs
2017-03-13 17:00:46 -07:00
Raphael Deem
9a3fac90e1 Merge pull request #551 from messense/feature/documentation-links
Add hyperlinks in response documentation
2017-03-13 17:00:00 -07:00
Raphael Deem
6984f6eec4 Merge pull request #549 from ai0/websocket-scheme
add websocket scheme in request
2017-03-13 16:59:47 -07:00
Ashley Sommer
d05f502fc8 Add Dispatcher Extension
Adds a link to the extension
https://github.com/ashleysommer/sanic-dispatcher
And a very short description
2017-03-14 08:37:53 +10:00
Jing Su
ba41ab8f67 fix typo 2017-03-13 18:36:22 +08:00
Jing Su
250bb7e29d add websocket secure scheme in request @messense 2017-03-13 18:34:43 +08:00
messense
48a26fd5df Add hyperlinks in response documentation 2017-03-13 16:20:12 +08:00
Jing Su
3af26540ec add websocket scheme in request 2017-03-13 13:28:35 +08:00
Raphael Deem
7d9de068d9 Merge pull request #544 from messense/feature/document-response
Add response documentation
2017-03-11 22:49:53 -08:00
messense
d174917a07 Add response documentation 2017-03-12 14:31:51 +08:00
Eli Uriegas
af398fc4c4 Merge pull request #543 from r0fls/windows-setup
windows setup
2017-03-11 21:57:15 -08:00
Raphael Deem
878ef446a2 refactor redundant print logic 2017-03-11 21:54:07 -08:00
Raphael Deem
668f6477bb fix spacing 2017-03-11 21:46:31 -08:00
Raphael Deem
01a770cbca windows setup 2017-03-11 19:32:38 -08:00
Raphael Deem
23a1174aa2 Merge pull request #542 from nszceta/master
Faster asyncpg queries via a global connection pool
2017-03-11 16:07:16 -08:00
Raphael Deem
414020e75b Merge pull request #541 from r0fls/speedup
remove default host attribute in router
2017-03-11 16:07:05 -08:00
Adam Gradzki
ed74bccad6 Faster asyncpg queries via a global connection pool
In my benchmarks I was able to obtain a 17% performance
improvement over the current asyncpg demo code with a shared
connection pool.

Resolves: #540
See also: #531
2017-03-11 17:55:57 -06:00
Raphael Deem
0eedde445c remove default host attribute in router 2017-03-11 15:39:48 -08:00
Raphael Deem
88bf78213f Merge pull request #512 from subyraman/fix-url-building
Fix `request.url` and other url properties
2017-03-10 00:38:16 -08:00
Raphael Deem
d342461a51 Merge pull request #535 from ai0/master
Update blueprints example
2017-03-10 00:36:02 -08:00
Raphael Deem
dffaaf8751 Merge pull request #533 from 38elements/patch-1
Fix bail_out()
2017-03-10 00:35:54 -08:00
Raphael Deem
313edadf47 Merge pull request #528 from r0fls/523
allow running with SSL via commandline
2017-03-10 00:35:46 -08:00
Raphael Deem
c9ce33dfe6 Merge pull request #524 from r0fls/exception-list
allow exceptions to be a list
2017-03-10 00:35:38 -08:00
Raphael Deem
0f50ac7205 Merge pull request #517 from r0fls/empty-json
return valid json in request.json
2017-03-10 00:35:26 -08:00
Raphael Deem
e807c08275 Merge pull request #536 from lixxu/master
add sanic-babel extension
2017-03-09 12:28:22 -08:00
Lix Xu
893977365c Update extensions.md
add babel extension
2017-03-09 23:58:02 +08:00
Jing Su
0cac45809f add blueprints websocket example 2017-03-09 18:33:34 +08:00
Jing Su
489ca3c207 use blueprint method instead of deprecated register_blueprint 2017-03-09 18:31:19 +08:00
38elements
313535c599 Fix bail_out() 2017-03-09 13:36:01 +09:00
Raphael Deem
7f1e0557c9 Merge pull request #532 from r0fls/example-asyncpg-close
close connection in asyncpg example
2017-03-08 18:51:44 -08:00
Raphael Deem
0860f84a39 close connection in asyncpg example 2017-03-08 18:50:41 -08:00
Raphael Deem
2fe9e78b6d Merge pull request #525 from r0fls/518
rename TestClient
2017-03-08 18:24:13 -08:00
Raphael Deem
2ba30f2022 allow running with SSL via commandline 2017-03-07 19:57:10 -08:00
Raphael Deem
b3b27cab34 Merge pull request #527 from r0fls/asyncpg-example
update asyncpg example
2017-03-07 19:34:10 -08:00
Raphael Deem
694207a86d update asyncpg example 2017-03-07 19:32:26 -08:00
Raphael Deem
90138c4bae return valid json in request.json 2017-03-07 18:03:45 -08:00
Raphael Deem
58a833e987 rename TestClient 2017-03-07 17:13:23 -08:00
Raphael Deem
86c5a569d5 allow exceptions to be a list 2017-03-07 16:22:23 -08:00
Eli Uriegas
19592e8eea Merge pull request #473 from subyraman/explore-streams-v2
Add `stream` method for streaming content, add docs and examples
2017-03-05 17:51:44 -08:00
Eli Uriegas
8e6678d526 Merge pull request #469 from miguelgrinberg/websocket-support
websocket support
2017-03-05 17:42:49 -08:00
Suby Raman
e792a1e030 add host test 2017-03-03 14:51:13 -05:00
Suby Raman
f0e818a28c add host test 2017-03-03 13:32:32 -05:00
Suby Raman
69bd63b742 add docs 2017-03-03 11:59:33 -05:00
Suby Raman
b40f30f2e5 fix tests 2017-03-03 11:49:35 -05:00
Suby Raman
1fbde87ec2 initial commit 2017-03-03 11:44:50 -05:00
Eli Uriegas
f9dc34c8fa Merge pull request #510 from jamesstidard/patch-2
Sanic EnvConfig
2017-03-02 22:21:16 -06:00
James Stidard
f7186f5331 Sanic EnvConfig
Services like Heroku force your hand into using environment variables. Made this to help.
2017-03-02 21:22:07 +00:00
Eli Uriegas
6a680e4db0 Merge pull request #509 from kcy1019/master
Fix exception_monitoring example
2017-03-02 10:48:05 -06:00
고창영(Chang-young Koh)
f6b69f412f Fix exception_monitoring example 2017-03-03 00:55:08 +09:00
Eli Uriegas
5aed18862d Merge pull request #506 from zenixls2/bugfix/bind-listener
special handling when sock is provided and number of workers > 1
2017-03-02 09:08:59 -06:00
(Zenix) Han-Sheng Huang
62bf213a6e pass flake8 2017-03-02 13:42:55 +09:00
(Zenix) Han-Sheng Huang
e5c32e9b48 special handling when sock is provided and number of workers > 1 2017-03-02 13:27:52 +09:00
Raphael Deem
b87dc37fbb Merge pull request #500 from r0fls/revert-498
Revert "add reuse_port to create_server"
2017-02-28 19:29:29 -08:00
Raphael Deem
002d4cb37c Revert "add reuse_port to create_server"
This reverts commit c3386dec84.
2017-02-28 19:27:42 -08:00
Raphael Deem
ff321fc355 Merge pull request #499 from r0fls/498
add reuse_port to create_server
2017-02-28 19:24:35 -08:00
Raphael Deem
c3386dec84 add reuse_port to create_server 2017-02-28 19:21:53 -08:00
Eli Uriegas
927d2761f7 Merge pull request #496 from bohea/master
rate limiting for sanic
2017-02-28 09:03:03 -06:00
Eli Uriegas
5e5f513088 Merge pull request #497 from seemethere/increment_041
Increment version to 0.4.1
2017-02-28 08:55:34 -06:00
Eli Uriegas
9fcf725061 Increment version to 0.4.1 2017-02-28 08:55:04 -06:00
Eli Uriegas
601e015f00 Merge pull request #495 from r0fls/494
fix routing issue with slashes
2017-02-28 08:54:15 -06:00
bohea
3289e8403a Update extensions.md 2017-02-28 17:34:40 +08:00
James Stidard
104a7c7d05 Added app to websocket request (#1) 2017-02-27 22:35:28 -08:00
Miguel Grinberg
7560660ec7 handle timeouts and disconnects properly 2017-02-27 22:35:28 -08:00
Miguel Grinberg
40ccb4a0dd websocket documentation 2017-02-27 22:35:28 -08:00
Miguel Grinberg
f90288f5dc websocket routes in blueprints 2017-02-27 22:35:28 -08:00
Miguel Grinberg
3bf79898d9 websocket unit test 2017-02-27 22:35:28 -08:00
Miguel Grinberg
1d6e11ca10 addressed feedback 2017-02-27 22:35:28 -08:00
Miguel Grinberg
6e903ee7d5 websocket support, using websockets package 2017-02-27 22:35:28 -08:00
Raphael Deem
21fb1dff7e fix routing issue with slashes 2017-02-27 20:01:11 -08:00
Eli Uriegas
da924a359c Merge pull request #493 from seemethere/fix_install
Attempt to remedy install problems from 0.4.0
2017-02-27 10:19:13 -06:00
Eli Uriegas
a5066f15dc Attempt to remedy install problems from 0.4.0
Relates to 1436fb3ef4
2017-02-27 10:14:47 -06:00
Raphael Deem
2dca53a696 remove stop_event 2017-02-26 16:37:48 -08:00
Eli Uriegas
bfbcdf8b86 Merge pull request #488 from seemethere/increment_version_040
Increment version to 0.4.0
2017-02-25 13:37:09 -06:00
Eli Uriegas
42e1d18470 Increment version to 0.4.0 2017-02-25 13:36:47 -06:00
Raphael Deem
435dc72aa1 Merge pull request #484 from r0fls/483
use getattr for request url in error handler
2017-02-24 10:12:04 -08:00
Raphael Deem
66c380548b use getattr for request url in error handler 2017-02-23 23:17:31 -08:00
Raphael Deem
13f81e9a6f Merge pull request #480 from subyraman/patch-2
Add documentation about `request.app`
2017-02-23 18:52:11 -08:00
Eli Uriegas
68c8796adb Merge pull request #481 from lixxu/master
url_for has something wrong with //
2017-02-23 18:27:13 -06:00
Suby Raman
4232f5342e correct indendation 2017-02-23 11:47:39 -05:00
lixxu
28c31359bf bug: url / will be empty 2017-02-24 00:45:50 +08:00
Suby Raman
a36e815227 Add documentation about request.app 2017-02-23 11:42:59 -05:00
lixxu
ff3d33d5e0 bug: url_for in blueprint may have // at the beginning 2017-02-24 00:17:43 +08:00
Eli Uriegas
d015d6b103 Merge pull request #476 from seemethere/inject_app_into_request
Inject app into request object
2017-02-23 09:12:41 -06:00
Eli Uriegas
0d160fbeaa Merge pull request #478 from messense/fix-requests-post-test-cases
Fix exception collection typo
2017-02-22 20:43:53 -06:00
messense
fedd7920a8 Fix exception collection typo 2017-02-23 10:39:14 +08:00
Eli Uriegas
6afac06596 Merge pull request #477 from messense/fix-requests-post-test-cases
Fix test cases for requests post
2017-02-22 20:39:03 -06:00
messense
91b2b40b9a Fix test cases for requests post 2017-02-23 10:36:08 +08:00
Eli Uriegas
56ecb6a3ea Inject app into request object
Allows for injection of the app object into the request object through
the request handler.

This allows for users to setup things like database connections etc. in
listeners and then utilize them throughout the their various route
handlers.

Usage is fairly simple like so:
```python
@app.get('/')
async def handler(request):
    request.app.anything
```

Name is up in the air but I'll leave this up for a few days and I'll
change it if we get a consensus
2017-02-22 11:34:14 -06:00
Eli Uriegas
64f73f624f Merge pull request #471 from r0fls/vhost-default
allow default vhost
2017-02-22 11:08:28 -06:00
Eli Uriegas
20b78b68a6 Merge pull request #470 from r0fls/url-slash
route logic for trailing slash
2017-02-22 11:07:23 -06:00
Suby Raman
d8a6d7e02f response.write should be synchronous for performance reasons 2017-02-22 10:42:16 -05:00
Raphael Deem
d1cc14201b Merge pull request #474 from r0fls/remove-ws-extension
remove websocket extension
2017-02-21 15:31:50 -08:00
Raphael Deem
a57ec9e669 remove websocket extension 2017-02-21 15:30:42 -08:00
Suby Raman
1a8961587c more info in docs 2017-02-21 11:38:57 -05:00
Suby Raman
fa13ad8849 clean up imports 2017-02-21 11:36:45 -05:00
Suby Raman
8b23dec322 improve performance 2017-02-21 11:28:45 -05:00
Suby Raman
4e8aac4b41 rebase 2017-02-21 11:05:06 -05:00
Raphael Deem
9c72b557ec allow default vhost 2017-02-20 16:52:36 -08:00
Raphael Deem
207ec1e032 route logic for trailing slash 2017-02-20 16:11:28 -08:00
Eli Uriegas
ff5d4276bc Merge pull request #468 from hhstore/master
fix import path.
2017-02-20 07:29:11 -06:00
hhstore
26c9618e63 fix import path. 2017-02-20 17:57:15 +08:00
Eli Uriegas
9c306899ba Merge pull request #464 from tommyip/patch-1
Fix typo in routing.md
2017-02-19 11:40:48 -06:00
Tommy Ip
4b7e7aab33 Fix typo in routing.md 2017-02-19 12:39:39 +00:00
Eli Uriegas
2921e9f868 Merge pull request #463 from subyraman/patch-1
add sanic_compress extension
2017-02-18 18:56:17 -06:00
Suby Raman
70b7606cb8 add sanic_compress extension 2017-02-18 19:53:32 -05:00
Eli Uriegas
0cae91d525 Merge pull request #459 from seemethere/add_app_loop_safety
Add app loop safety
2017-02-18 16:53:49 -06:00
Eli Uriegas
2c2a28e46b Add better error message around app.loop 2017-02-18 12:29:25 -06:00
Eli Uriegas
c75d484f23 Merge branch 'master' of github.com:channelcat/sanic into add_app_loop_safety 2017-02-17 07:10:59 -06:00
Eli Uriegas
072f7fec30 Merge pull request #460 from seemethere/fix_travis_build
Fix coverage build
2017-02-17 07:10:27 -06:00
Eli Uriegas
a73379495f Fix coverage build
Moved `sanic.py` to `app.py` this change reflects that
2017-02-17 07:06:57 -06:00
Eli Uriegas
0b914866eb Merge pull request #401 from youknowone/error-logging
Enhance error logging
2017-02-17 07:01:40 -06:00
Eli Uriegas
f12186d024 Merge pull request #438 from r0fls/coverage
add coverage to tox
2017-02-17 07:01:14 -06:00
Eli Uriegas
4a2835dc84 Merge pull request #458 from lixxu/master
add user_agent to request
2017-02-17 07:00:52 -06:00
Eli Uriegas
55dc45de33 Merge pull request #455 from seemethere/add_better_response_error_detection
Adds some safety around response types being wrong
2017-02-17 06:59:52 -06:00
Eli Uriegas
39aa64ff68 Remove un-needed loop assignment 2017-02-17 06:57:41 -06:00
Eli Uriegas
94bb91f2fa Adds some safety around app loop property 2017-02-17 06:54:26 -06:00
Lix Xu
f553ca95a5 add user_agent to request 2017-02-17 15:12:07 +08:00
Jeong YunWon
b44e8167d7 Enhance error logging
- Prevent to fall into error logging recursion when it doesn't have
request info (Print 'Unknown' when the request is still `None`
- Print repr(e) rather than str(e)
2017-02-17 14:05:46 +09:00
Eli Uriegas
36c1122d20 Merge pull request #457 from seemethere/remove_double_logging_message
Removes the extra logging message for run
2017-02-16 21:53:25 -06:00
Eli Uriegas
ad13529eaa Removes the extra logging message for run
Solves for #456
2017-02-16 21:51:19 -06:00
Eli Uriegas
04c8f4a5ed Adds some safety around response types being wrong
Before we didn't check if the response object was actually a response
object. This PR catches the exception should it happen and reports it to
the user.
2017-02-16 17:49:14 -06:00
Eli Uriegas
850446195f Merge pull request #441 from robintiwari/master
added sanic motor (async driver for mongodb) example
2017-02-16 17:19:42 -06:00
Eli Uriegas
865506546f Merge pull request #440 from r0fls/isinstance
isinstance -> try/except
2017-02-16 17:19:04 -06:00
Eli Uriegas
fe72fadedd Merge pull request #432 from agoose77/cleanups
Bugfix & simplfication for host based routing
2017-02-16 17:18:24 -06:00
Eli Uriegas
9cf9d3ad5c Merge pull request #453 from seemethere/add_file_example
Adds file response object example
2017-02-16 17:17:29 -06:00
Eli Uriegas
426d0e6af1 Merge pull request #454 from seemethere/fix_empty_request_args
Default request.args to RequestParameters
2017-02-16 17:16:55 -06:00
Eli Uriegas
483b442b7d Default request.args to RequestParameters 2017-02-16 15:54:20 -06:00
Eli Uriegas
9420b0c947 Adds file response object example 2017-02-16 15:53:31 -06:00
Eli Uriegas
dcfb7345f0 Merge pull request #451 from abuckenheimer/master
#449 use stdlib json module if ujson is unavailible
2017-02-16 14:14:45 -06:00
Alec Buckenheimer
f9ab24a077 #449 use stdlib json module if ujson is unavailible 2017-02-16 15:03:52 -05:00
Raphael Deem
f932d16ba7 Merge pull request #448 from Typhon66/patch-1
Adding sanic_crud to extensions
2017-02-16 09:57:58 -08:00
Typhon
7d9acc3c36 Adding sanic_crud to extensions 2017-02-16 09:49:48 -08:00
Eli Uriegas
72f735124f Merge pull request #446 from subyraman/document-error
Fix blueprint documentation re: prefixes
2017-02-16 11:21:23 -06:00
Suby Raman
6ea5a4719a add url_for doc in blueprint 2017-02-16 11:48:31 -05:00
Suby Raman
f8c50b7f1e fix blueprints documentation 2017-02-16 11:46:19 -05:00
Eli Uriegas
feb1f1d71a Merge pull request #444 from lixxu/master
simple motor wrapper
2017-02-16 09:46:09 -06:00
Lix Xu
550afc27dc simple motor wrapper 2017-02-16 22:36:16 +08:00
sourcepirate
e6a828572a Changed method name from create to new 2017-02-16 11:07:49 +05:30
plasmashadow
6ea43d8e6d Fixed sanic_peewee error and added a simple interface to query and create 2017-02-16 10:58:52 +05:30
@robintiwari
d13af4bdc4 updated examples 2017-02-15 22:11:16 -06:00
Robin
53a365dd2b added sanic motor (async driver for mongodb) example 2017-02-15 21:42:25 -06:00
Raphael Deem
6726affa7e isinstance -> try/except 2017-02-15 19:34:45 -08:00
Eli Uriegas
6ecf2a6eb2 Merge pull request #439 from seemethere/move_sanic_to_app
Moves sanic/sanic.py to sanic/app.py
2017-02-15 21:03:41 -06:00
Eli Uriegas
a359e11f97 Merge pull request #422 from r0fls/420
move logging to method in ErrorHandler
2017-02-15 21:03:15 -06:00
Eli Uriegas
54b2d74068 Get rid of relative imports 2017-02-15 20:54:00 -06:00
Eli Uriegas
c99aa7279b Moves sanic/sanic.py to sanic/app.py
Functionality wise this won't change much for most users, unless you
were directly importing from `sanic.sanic` in which case I am sorry if
you're affected by this.

Main motivation was because jedi autocompletion didn't work with this
and we were using relative imports to compensate for the fact that
having a module inside of your module with the same name creates major
namespace problems.
2017-02-15 20:47:34 -06:00
Raphael Deem
4fa568ce8a add coverage to tox 2017-02-15 15:20:43 -08:00
Eli Uriegas
874698b93f Merge pull request #431 from subyraman/test-client-v2
Add Flask-like `test_client` to replace `sanic_endpoint_test`
2017-02-15 15:44:30 -06:00
Eli Uriegas
b286fc1e4a Merge pull request #436 from lixxu/master
simple pagination support
2017-02-15 13:31:57 -06:00
Raphael Deem
1cf1024332 Merge branch 'master' into 420 2017-02-15 09:29:52 -08:00
Lix Xu
6b391b701b simple pagination support 2017-02-15 13:27:58 +08:00
Raphael Deem
efc90f8f5a Merge pull request #434 from agoose77/fix_warn_error
Fix mistake in warning
2017-02-14 16:46:37 -08:00
Angus Hollands
6535ba7c24 Fix mistake in warning 2017-02-14 20:53:55 +00:00
Angus Hollands
5c29c3d160 Merge branch 'master' of https://github.com/channelcat/sanic into cleanups 2017-02-14 20:47:28 +00:00
Angus Hollands
742d4bff78 Change to iterable as Python3.5 doesn't support Collection.
We don't really need the getitem and len attributes anyway
2017-02-14 20:46:14 +00:00
Suby Raman
7726ffa3f7 remove documentation about passing in the loop 2017-02-14 15:44:43 -05:00
Angus Hollands
b442d78ebb Bugfix & simplfication for host based routing (if list of hosts passed after a previous vhost route was added, previously attempted to add set to set)
Add comment documenting substandard behaviour
2017-02-14 20:32:04 +00:00
Eli Uriegas
d44edb5930 Merge pull request #430 from aquacash5/master
Added raw response for bag o' bytes responses
2017-02-14 14:19:01 -06:00
Suby Raman
d5633b3705 fix deprecation message 2017-02-14 15:16:58 -05:00
Suby Raman
3b68dc72e7 rework testing 2017-02-14 14:51:20 -05:00
Angus Hollands
51611c3934 Pep8 cleanups (#429)
* PEP8 cleanups

* PEP8 cleanups (server.py)

* PEP8 cleanups (blueprints.py)

* PEP8 cleanups (config.py)

* PEP8 cleanups (cookies.py)

* PEP8 cleanups (handlers.py)

* PEP8 cleanups (request.py)

* PEP8 cleanups (response.py)

* PEP8 cleanups (router.py)

* PEP8 cleanups (sanic.py) #2

* PEP8 cleanups (server.py) #2

* PEP8 cleanups (static.py)

* PEP8 cleanups (utils.py)

* PEP8 cleanups (views.py)
Updated docstring
2017-02-14 13:10:19 -06:00
Kyle Blöm
747b7567d7 Changed docstring for raw response 2017-02-14 09:40:33 -08:00
Kyle Blöm
797891d6cf Added raw response for bag o' bytes responses 2017-02-14 09:27:39 -08:00
Eli Uriegas
286dc3c32b Merge pull request #399 from lixxu/master
improve url_for to support multi values and special options
2017-02-14 10:27:54 -06:00
Eli Uriegas
a66ba21c3d Merge pull request #421 from Superman132/master
Fixed readme
2017-02-14 10:26:41 -06:00
Eli Uriegas
b139810b6a Merge pull request #424 from growingdever/blueprint-support-view
support view instance for blueprint add_route method
2017-02-14 10:26:05 -06:00
Eli Uriegas
dddc18d77c Merge pull request #427 from agoose77/trigger_cleanup
Simplify trigger events (now guaranteeed to receive list of events)
2017-02-14 09:34:34 -06:00
Angus Hollands
56f56d008a Simplify trigger events (now guaranteeed to receive list of events)
Don't bother checking if list empty - this function is not called often
2017-02-14 15:15:15 +00:00
growingdever
81a8a99b6e wrap over width comment 2017-02-14 17:20:39 +09:00
growingdever
07aa0ee7ad - copy codes from Sonic.add_route
- modify comment by r0fls
2017-02-14 17:15:38 +09:00
growingdever
b66a6bddbc fix typo 2017-02-14 14:30:07 +09:00
growingdever
d57d90fe6b - make blueprint add_route method support view instance
- update documentation that doesn't specify url_prefix parameter
2017-02-14 14:23:22 +09:00
Raphael Deem
de6c646ee8 move logging to method in ErrorHandler 2017-02-13 19:44:54 -08:00
lixxu
4839ede64f update test for url_for and update routing.md doc 2017-02-14 10:26:30 +08:00
Superman132
84f5faf653 Update README.rst 2017-02-13 20:48:37 -05:00
Superman132
281077bc26 Update README.rst 2017-02-13 19:35:03 -05:00
Superman132
ed5fe9ae9f Merge pull request #1 from channelcat/master
Merge commits with master
2017-02-13 19:31:33 -05:00
Eli Uriegas
1866e4ef44 Merge pull request #418 from argaen/fix_cache_example
Use decorator for cache example
2017-02-13 17:23:29 -06:00
Eli Uriegas
a6a07c3b3a Merge pull request #411 from r0fls/ensure-future
Ensure future
2017-02-13 17:13:26 -06:00
argaen
b2af8e640c Use decorator 2017-02-14 00:12:39 +01:00
Raphael Deem
7a3f5d508b fix merge conflicts 2017-02-13 14:19:44 -08:00
Eli Uriegas
7e1fd03104 Merge pull request #417 from argaen/fix_cache_example
Fixed aiocache example according to new loop policy
2017-02-13 16:11:26 -06:00
argaen
758415d326 Fixed aiocache example according to new loop policy 2017-02-13 23:08:42 +01:00
Eli Uriegas
1660041470 Merge pull request #408 from agoose77/master
Use app decorator instead of run arguments for before_start
2017-02-13 12:54:46 -06:00
Eli Uriegas
1783df883e Merge pull request #416 from subyraman/more-view-tests
Add CompositionView tests, simplify checks for invalid/duplicate methods
2017-02-13 11:09:56 -06:00
Suby Raman
b2be821637 reverse router changes 2017-02-13 11:55:00 -05:00
Suby Raman
051ff2b325 remove repr stuff 2017-02-13 11:50:09 -05:00
Suby Raman
4d6f9ffd7c rebase 2017-02-13 11:45:55 -05:00
Suby Raman
d614823013 rebase 2017-02-13 11:38:28 -05:00
Eli Uriegas
48aa51b739 Merge pull request #413 from r0fls/loop-signal-handlers
use try/except when adding loop sig handlers
2017-02-13 10:13:56 -06:00
Raphael Deem
41c6125e1b use try/except when adding loop sig handlers 2017-02-12 14:43:00 -08:00
Eli Uriegas
bb3d48f98b Merge pull request #412 from seemethere/improving_performance
Header performance gains
2017-02-12 15:48:45 -06:00
Raphael Deem
b5e46e83e2 ensure_future -> add_task 2017-02-12 12:29:12 -08:00
Angus Hollands
2340910b46 Update deprecation message
Fix bug with single callbacks
2017-02-12 18:15:14 +00:00
Eli Uriegas
d8c4c1525d Merge pull request #406 from agoose77/master_pre_patches_1
Cleanup middleware decorator
2017-02-12 12:14:50 -06:00
Eli Uriegas
6713ef7726 Remove unused import 2017-02-12 12:09:06 -06:00
Eli Uriegas
ae7555b065 Performance was down so this brings it back up
Changes from #378 introduced about a 10k request/sec slowdown. This
tries to rememdy it while keeping the same functionality but it's still
not as fast as 0.3.1
2017-02-12 12:05:14 -06:00
Angus Hollands
ee6ff0cc60 Add deprecation and old API 2017-02-12 12:28:02 +00:00
Raphael Deem
94b2352c2c add ensure_future method 2017-02-11 17:40:17 -08:00
Eli Uriegas
cf3f943feb Merge pull request #409 from r0fls/loop-attribute
add loop property
2017-02-11 18:31:50 -06:00
Eli Uriegas
55c4d583b9 Merge pull request #410 from r0fls/extensions
add extension to docs
2017-02-11 18:31:16 -06:00
Raphael Deem
0e1bb6ab04 add loop property 2017-02-11 16:28:35 -08:00
Raphael Deem
7944cff7a5 add extension to docs 2017-02-11 15:31:58 -08:00
Angus Hollands
8b08a370c5 Remove todo 2017-02-11 14:39:32 +00:00
Angus Hollands
2d5fd2fe1c fix test 2017-02-11 14:35:44 +00:00
Angus Hollands
b5e50ecb75 Use app decorator instead of run arguments for before_start
Mirror listener of blueprints
2017-02-11 14:30:17 +00:00
Angus Hollands
e00c9d0ee0 Fix line length 2017-02-11 12:39:04 +00:00
Angus Hollands
be9c9f045a Cleanup middleware decorator 2017-02-11 12:27:25 +00:00
Raphael Deem
75fca1b9c7 Merge pull request #402 from agoose77/patch-1
Don't ask for uvloop on windows
2017-02-10 12:11:12 -08:00
Angus Hollands
1436fb3ef4 Don't ask for uvloop on windows
This is a tricky issue, but essentially uvloop is unavailable on windows. This means for windows users, we have to install Sanic with no requirements, and then manually specify all requirements apart from uvloop.

However, Sanic will work with standard asyncio event loop. So, I propose we remove the uvloop requirement on windows. This patch doesn't touch any demo imports.
2017-02-10 13:14:36 +00:00
Raphael Deem
2bfd127218 Merge pull request #400 from aquacash5/master
added build folder to .gitignore
2017-02-09 23:13:49 -08:00
Kyle Blöm
de5da63d5c added build folder to .gitignore 2017-02-09 18:49:11 -08:00
lixxu
fb419eaa36 fix bug: netloc always in url if SERVER_NAME defined in config even _external not true 2017-02-09 18:26:17 +08:00
lixxu
cf2a363e5e improve url_for to support multi values for one arg, add _anchor/_external/_scheme options 2017-02-09 16:44:23 +08:00
Eli Uriegas
7401facc21 Merge pull request #398 from seemethere/fix_errors_from_content_range
Fixes errors related to #378
2017-02-08 20:06:02 -06:00
Eli Uriegas
579afe012b Fixes errors related to #378 2017-02-08 19:59:34 -06:00
Eli Uriegas
4f856e8783 Merge pull request #378 from aquacash5/master
Added the tests, code formatting changes, and the Range Request feature.
2017-02-08 19:39:29 -06:00
Eli Uriegas
eb059183f7 Merge branch 'master' into master 2017-02-08 19:37:32 -06:00
Eli Uriegas
419156f7cc Merge pull request #397 from seemethere/increment_031
Increment to v0.3.1
2017-02-08 19:23:20 -06:00
Eli Uriegas
b7f7883fb7 Increment to v0.3.1 2017-02-08 19:22:51 -06:00
Eli Uriegas
a5a7490bca Merge pull request #379 from youknowone/exception
Let exception handler handle inherited exceptions
2017-02-08 19:20:42 -06:00
Eli Uriegas
6724d8131c Merge pull request #387 from subyraman/url-for-v3
Add `url_for` method for simple routes, blueprints, HTTPMethodView
2017-02-08 19:20:09 -06:00
Raphael Deem
a19bb15070 Merge pull request #389 from chenfengyuan/fix_run_async_demo
fix run_async demo
2017-02-07 14:58:48 -08:00
Eli Uriegas
2ee0147848 Merge pull request #386 from youknowone/sanic_endpoint_test
Fix sanic_endpoint_test working with redirects
2017-02-07 10:57:05 -06:00
Eli Uriegas
252f1add7e Merge pull request #394 from brian-bates/tox-cleanup
Add missing dependency to tox.ini
2017-02-07 10:55:52 -06:00
Jeong YunWon
413c92c631 Let exception handler handle inherited exceptions
Original sanic exception handler only could handle exact matching
exceptions. New `lookup` method will provide ability to looking up
their ancestors without additional cost of performance.
2017-02-07 21:08:31 +09:00
Suby Raman
36d519026f reject unnamed handlers 2017-02-06 11:11:00 -05:00
Fengyuan Chen
aa54785918 fix always warning loop is passed issue 2017-02-06 11:11:00 -05:00
Raphael Deem
d6b386083f Merge pull request #390 from chenfengyuan/pass_loop_warning
fix always warning loop is passed issue
2017-02-05 14:01:41 -08:00
Brian Bates
82f383b64f Add missing dependency
Added missing `aiofiles` to tox.ini and cleaned up requirements files.
2017-02-05 11:44:01 -08:00
Jeong YunWon
a15ee3ad06 Fix sanic_endpoint_test working with redirects
Before fix, it raises error like:

```
tests/test_utils.py F

================================= FAILURES =================================
______________________________ test_redirect _______________________________

app = <sanic.sanic.Sanic object at 0x1045fda20>, method = 'get', uri = '/1', gather_request = True, debug = False
server_kwargs = {}, request_args = (), request_kwargs = {}
_collect_request = <function sanic_endpoint_test.<locals>._collect_request at 0x1045ec950>
_collect_response = <function sanic_endpoint_test.<locals>._collect_response at 0x1045ec7b8>

    def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
                            debug=False, server_kwargs={},
                            *request_args, **request_kwargs):
        results = []
        exceptions = []

        if gather_request:
            def _collect_request(request):
                results.append(request)
            app.request_middleware.appendleft(_collect_request)

        async def _collect_response(sanic, loop):
            try:
                response = await local_request(method, uri, *request_args,
                                               **request_kwargs)
                results.append(response)
            except Exception as e:
                exceptions.append(e)
            app.stop()

        app.run(host=HOST, debug=debug, port=PORT,
                after_start=_collect_response, **server_kwargs)

        if exceptions:
            raise ValueError("Exception during request: {}".format(exceptions))

        if gather_request:
            try:
>               request, response = results
E               ValueError: too many values to unpack (expected 2)

sanic/utils.py:47: ValueError

During handling of the above exception, another exception occurred:

utils_app = <sanic.sanic.Sanic object at 0x1045fda20>

    def test_redirect(utils_app):
        """Test sanic_endpoint_test is working for redirection"""
>       request, response = sanic_endpoint_test(utils_app, uri='/1')

tests/test_utils.py:33:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

app = <sanic.sanic.Sanic object at 0x1045fda20>, method = 'get', uri = '/1', gather_request = True, debug = False
server_kwargs = {}, request_args = (), request_kwargs = {}
_collect_request = <function sanic_endpoint_test.<locals>._collect_request at 0x1045ec950>
_collect_response = <function sanic_endpoint_test.<locals>._collect_response at 0x1045ec7b8>

    def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
                            debug=False, server_kwargs={},
                            *request_args, **request_kwargs):
        results = []
        exceptions = []

        if gather_request:
            def _collect_request(request):
                results.append(request)
            app.request_middleware.appendleft(_collect_request)

        async def _collect_response(sanic, loop):
            try:
                response = await local_request(method, uri, *request_args,
                                               **request_kwargs)
                results.append(response)
            except Exception as e:
                exceptions.append(e)
            app.stop()

        app.run(host=HOST, debug=debug, port=PORT,
                after_start=_collect_response, **server_kwargs)

        if exceptions:
            raise ValueError("Exception during request: {}".format(exceptions))

        if gather_request:
            try:
                request, response = results
                return request, response
            except:
                raise ValueError(
                    "Request and response object expected, got ({})".format(
>                       results))
E               ValueError: Request and response object expected, got ([{}, {}, {}, <ClientResponse(http://127.0.0.1:42101/3) [200 OK]>
E               <CIMultiDictProxy('Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '2', 'Connection': 'keep-alive', 'Keep-Alive': 'timeout=1')>
E               ])

sanic/utils.py:52: ValueError
```
2017-02-05 13:57:04 +09:00
Fengyuan Chen
29680cb515 fix always warning loop is passed issue 2017-02-04 16:09:09 +08:00
Fengyuan Chen
884749f345 fix run_async demo 2017-02-04 15:27:46 +08:00
Suby Raman
5c63ce666c punctuation 2017-02-02 14:21:59 -05:00
Suby Raman
5632d073be update docs 2017-02-02 13:00:15 -05:00
Suby Raman
f9056099f9 all works 2017-02-02 12:52:48 -05:00
Suby Raman
7c09ec29f7 rebase 2017-02-02 12:21:14 -05:00
Eli Uriegas
6f0b09509e Merge pull request #213 from sfstpala/master
Make it possible to disable the logo by subclassing Config
2017-02-01 23:07:52 -06:00
Eli Uriegas
31c53d67e2 Merge pull request #384 from seemethere/update_static_tests
Updates static tests to test for issue #374
2017-02-01 15:20:34 -06:00
Eli Uriegas
6a322ba3f8 Updates static tests to test for issue #374
Adds a test to test for serving a static directory at the root uri '/'
to address concerns found in #374. Also rewrites the tests so that they
are parametrized and do more with less.
2017-02-01 09:00:57 -06:00
Raphael Deem
dece636d54 Merge pull request #383 from r0fls/derp
typo: async_run -> run_async
2017-02-01 00:29:12 -08:00
Raphael Deem
b29f648148 typo: async_run -> run_async 2017-01-31 12:46:02 -08:00
Eli Uriegas
c91d264ff1 Merge pull request #380 from channelcat/openapi-extension
Added sanic-openapi to extensions
2017-01-31 07:39:38 -06:00
Eli Uriegas
487e3352e4 Revert "fix async run, add tests"
This reverts commit 41da793b5a.
2017-01-31 07:30:17 -06:00
Channel Cat
34966fb182 Added sanic-openapi to extensions 2017-01-31 01:24:41 -08:00
Eli Uriegas
17a92a58b2 Merge pull request #369 from r0fls/fix-async-run
fix async run, add tests
2017-01-30 22:21:25 -06:00
Raphael Deem
60d3e5b9e0 Merge pull request #377 from r0fls/373
update route method docs
2017-01-30 17:07:26 -08:00
Kyle Blöm
d193a1eb70 Added the tests, code formatting changes, and the Range Request feature. 2017-01-30 17:04:51 -08:00
Raphael Deem
1501c56bbc update route method docs 2017-01-30 16:42:43 -08:00
Eli Uriegas
6d18fb6bae Merge pull request #363 from r0fls/run-helper
Run helper
2017-01-30 05:51:50 -06:00
Eli Uriegas
eac26a4514 Merge pull request #372 from JordanP/fix_docs_config
Fix docs/config.md: the MYAPP_SETTINGS is not exported
2017-01-30 05:43:29 -06:00
Channel Cat
1649f30808 Updated password 2017-01-30 02:22:12 -08:00
Jordan Pittier
82680bf43f Fix docs/config.md: the MYAPP_SETTINGS is not exported
If we don"t `export` the variable, it's not available in subcommand:

MYAPP_SETTINGS=/path/to/config_file; python3 -c "import os; os.environ['MYAPP_SETTINGS']"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.5/os.py", line 725, in __getitem__
    raise KeyError(key) from None
KeyError: 'MYAPP_SETTINGS'

The ';' is the culprit here.
2017-01-30 10:39:02 +01:00
Raphael Deem
41da793b5a fix async run, add tests 2017-01-29 23:47:47 -08:00
Raphael Deem
cfb5734b85 Merge pull request #371 from channelcat/blueprint-shorthand
Blueprint route shorthand
2017-01-29 23:23:47 -08:00
Channel Cat
b72d841619 . 2017-01-29 23:21:00 -08:00
Channel Cat
0ef39f35ae Added route shorthands to blueprints 2017-01-29 23:20:38 -08:00
Channel Cat
38d1ed76d2 Merge pull request #368 from channelcat/blueprint-clarity
Restructured blueprint class for clarity
2017-01-29 18:47:27 -08:00
Channel Cat
4c80cd185f Fix flake8 2017-01-29 17:44:46 -08:00
Channel Cat
629524af04 Restructured blueprint class
Blueprints currently queue functions to be called, which are simple, yet
hard to inspect.  These changes allow tools to be built that analyze
blueprints more easily.
2017-01-29 17:39:55 -08:00
Channel Cat
a245e54bd3 Merge pull request #367 from channelcat/fix-rtd-build
Fix readthedocs includes
2017-01-29 16:46:48 -08:00
Channel Cat
52e485cce9 Fix readthedocs includes 2017-01-29 16:46:16 -08:00
Channel Cat
02d374b65b Merge pull request #365 from channelcat/fix-rtd-build
Adding readthedocs file
2017-01-29 16:41:41 -08:00
Channel Cat
0de6bb0063 Adding readthedocs file 2017-01-29 16:40:36 -08:00
Channel Cat
9d6b379999 Merge pull request #364 from channelcat/fix-rtd-build
Fix readthedocs build
2017-01-29 16:38:29 -08:00
Channel Cat
c132c4e673 fix conflict part 2 2017-01-29 16:32:57 -08:00
Channel Cat
6962dcd66c fix conflict 2017-01-29 16:31:37 -08:00
Channel Cat
2a9496fcda Fix readthedocs build 2017-01-29 16:25:22 -08:00
Raphael Deem
82d1d30a41 review updates 2017-01-29 14:01:00 -08:00
Eli Uriegas
85639d0806 Revert "testing"
This reverts commit 3fd6ecaedb.
2017-01-29 15:55:47 -06:00
Channel Cat
3fd6ecaedb testing 2017-01-29 13:52:17 -08:00
Channel Cat
884d3a0316 Fix RTD build 2017-01-29 13:45:44 -08:00
Raphael Deem
10dbb9186d combine logic from create_server() and run() 2017-01-29 13:36:13 -08:00
Eli Uriegas
a547798b08 Merge pull request #360 from seemethere/fix_route_overloading_for_dynamic_routes
Fixes route overloading for dynamic routes
2017-01-29 15:35:13 -06:00
Eli Uriegas
894b434875 Merge pull request #362 from channelcat/read-the-docs
Added basic readthedocs support
2017-01-29 15:34:58 -06:00
Eli Uriegas
8db0ece459 Merge branch 'master' into read-the-docs 2017-01-29 15:31:22 -06:00
Eli Uriegas
f56c5e3a45 Merge pull request #199 from Tim-Erwin/improved_config
added methods to load config from a file
2017-01-29 15:27:34 -06:00
Eli Uriegas
0a5fa72099 Add logic to make dynamic route merging work
This is by no means the final solution but it's a start in the right
direction. Eventually what needs to happen is we need to reduce the
complexity of the routing. CompsitionView can probably be removed later
on in favor of better Route objects. Also in the next version of sanic
we need to move merge_route and add_parameter out of the add_route logic
and just have them as standalone methods.

The tests should cover everything that we need so that if any changes
are made we can identify regression.
2017-01-29 15:16:07 -06:00
Channel Cat
0eaccea38f updated project name in docs build 2017-01-29 12:49:59 -08:00
Channel Cat
de32c389d0 Added basic readthedocs support 2017-01-29 12:47:00 -08:00
Raphael Deem
753d2da6db fix async run 2017-01-28 15:47:29 -08:00
Eli Uriegas
d3344da9c5 Add a pesky newline 2017-01-27 22:15:34 -06:00
Eli Uriegas
ae0876876e Switch them to verifying headers instead 2017-01-27 22:13:16 -06:00
Eli Uriegas
dea8e16f49 Force method to lower 2017-01-27 22:07:31 -06:00
Eli Uriegas
13803bdb30 Update for HTTPMethodView compatibility 2017-01-27 22:05:46 -06:00
Eli Uriegas
7257e5794f Merge pull request #359 from r0fls/fix-warnings
fix deprecation warnings
2017-01-27 21:05:51 -06:00
Eli Uriegas
41c52487ee Fixes route overloading for dynamic routes
Addresses #353, now dynamic routes work alongside our newly minted
overloaded routes! Also fixed an unintended side effect where methods
were still being passed in as None for `Sanic.add_route`.
2017-01-27 21:00:33 -06:00
Raphael Deem
0eb779185d fix deprecation warnings 2017-01-27 18:09:19 -08:00
Eli Uriegas
3d790a71a0 Merge pull request #358 from seemethere/incrment_version_030
Increment version to 0.3.0
2017-01-27 19:37:02 -06:00
Eli Uriegas
cfc32d940a Increment version to 0.3.0 2017-01-27 19:36:03 -06:00
Eli Uriegas
59242df7d6 Move serve_multiple, fix tests (#357)
* Move serve_multiple, remove stop_events, fix tests

Moves serve_multiple out of the app, removes stop_event (adds a
deprecation warning, but it also wasn't doing anything) fixes
multiprocessing tests so that they don't freeze pytest's runner.

Other notes:

Also moves around some imports so that they are better optimized as
well.

* Re-add in stop_event, maybe it wasn't so bad!

* Get rid of unused warnings import
2017-01-27 19:34:21 -06:00
Eli Uriegas
fad9fbca6f Merge pull request #335 from r0fls/remove-loop
remove loop as argument and update examples
2017-01-27 19:25:09 -06:00
Eli Uriegas
c81c92967c Merge pull request #354 from JordanP/use_isinstance
Use ``isinstance(`` instead of ``issubclass(type(``
2017-01-27 15:05:12 -06:00
Jordan Pittier
fa36dcbe09 Use `isinstance( instead of issubclass(type(`
When we already have an `instance` it's less typing and faster to
use `isinstance`.
2017-01-27 11:11:29 +01:00
Raphael Deem
c72bcc136c add semaphore concurrency limit example 2017-01-26 17:43:54 -08:00
Raphael Deem
d52f5f0b09 remove loop as argument and update examples 2017-01-26 17:38:46 -08:00
Eli Uriegas
4f6650fce2 Merge pull request #349 from kdelwat/compositionview-docs
Add documentation for the CompositionView class
2017-01-26 19:38:32 -06:00
Raphael Deem
2774414f9e Merge pull request #350 from r0fls/deprecate-loop
add deprecate loop message
2017-01-26 15:24:43 -08:00
Eli Uriegas
c1f1dca22c Merge pull request #351 from r0fls/revert-log-changes
use string formatting in start message
2017-01-26 17:17:49 -06:00
Raphael Deem
965fbc917d use string formatting in start message 2017-01-26 15:11:53 -08:00
Raphael Deem
2a1b63c93c add deprecate loop message 2017-01-26 15:07:42 -08:00
Cadel Watson
011be51232 Add documentation for the CompositionView class 2017-01-27 09:52:41 +11:00
Eli Uriegas
d1c4f3172f Merge pull request #348 from r0fls/275
add async run
2017-01-26 10:37:52 -06:00
Raphael Deem
14697c7ea9 review changes 2017-01-26 08:36:00 -08:00
Raphael Deem
54ca8c787b add async run 2017-01-25 22:47:18 -08:00
Channel Cat
88c3bffe20 Merge pull request #342 from channelcat/fix-slow-upload
Fix slow upload
2017-01-25 22:04:48 -08:00
Channel Cat
a4f85cd02e Merge pull request #343 from channelcat/cookie-usability
Cookie deletion and default path
2017-01-25 21:59:43 -08:00
Channel Cat
fd118a41fd Only use request.body 2017-01-25 21:56:49 -08:00
Channel Cat
b0f71c5304 Fixed default path in documentation 2017-01-25 21:48:39 -08:00
Raphael Deem
a162f2ce34 Merge branch 'master' into cookie-usability 2017-01-25 21:24:30 -08:00
Eli Uriegas
0f64702d72 Merge pull request #347 from r0fls/345
false cookie attributes should not be set
2017-01-25 18:51:02 -06:00
Raphael Deem
3c355f19eb false cookie attributes should not be set 2017-01-25 16:47:14 -08:00
Raphael Deem
fb9f2171a9 Merge pull request #346 from r0fls/event-docstring
fix before/after event docstrings
2017-01-25 16:29:10 -08:00
Raphael Deem
4efcb6d5ad fix before/after event docstrings 2017-01-25 16:25:16 -08:00
Raphael Deem
5ddc166b12 Merge pull request #344 from atbentley/docs
Update blueprints docs with correct listener example
2017-01-25 10:48:17 -08:00
Andrew Bentley
ecd7e5bdd3 Update blueprints docs with correct listener example 2017-01-25 23:01:57 +11:00
Channel Cat
d0a121ad06 Added del cookie and default path 2017-01-25 01:53:39 -08:00
Channel Cat
85a28d3c30 Fix slow upload 2017-01-25 01:19:21 -08:00
Tim Mundt
5bba3388a0 Merge branch 'master' into improved_config 2017-01-25 09:36:21 +01:00
Eli Uriegas
0ad31a471b Merge pull request #341 from r0fls/340
set error handler debug from run debug arg
2017-01-24 21:07:15 -06:00
Raphael Deem
28f7abd1f8 set error handler debug from run debug arg 2017-01-24 17:24:06 -08:00
Raphael Deem
049a5a7493 Merge pull request #339 from lixxu/master
add sanic-jinja2 extension
2017-01-23 23:46:26 -08:00
Lix Xu
a9ee01c7ec add sanic-jinja2 extension 2017-01-24 15:34:32 +08:00
Manuel Miranda
1f89b15792 Caching example (#334)
* Caching example using aiocache

* Caching example using aiocache

* Added aiocache to requirements

* Fixed example with newest aiocache

* Fixed bug in cache example
2017-01-23 10:19:42 -06:00
Raphael Deem
afe390d407 Merge pull request #253 from dutradda/add_register_sys_signals_flag
add a flag to skip SIGINT and SIGTERM signals registration
2017-01-21 23:09:12 -08:00
Eli Uriegas
6f4f2758d6 Merge pull request #331 from ctlaltdefeat/json-response-args
allowed passing arguments to json response encoder
2017-01-21 15:31:57 -06:00
ctlaltdefeat
592ee5f839 fixed line length to satisfy travis 2017-01-21 23:02:02 +02:00
ctlaltdefeat
a811c84e99 allowed passing arguments to json response encoder 2017-01-21 22:40:34 +02:00
Eli Uriegas
214162adf0 Merge branch 'master' into add_register_sys_signals_flag 2017-01-21 10:25:57 -06:00
Raphael Deem
28396c8620 Merge pull request #327 from awiddersheim/logging-override
Make it easier to override logging
2017-01-20 16:23:03 -08:00
Andrew Widdersheim
72fba62e09 Make it easier to override logging
Take influence from how Werkzeug configures logging by only configuring
a handler if no root handlers were previously configured by the end
user.
2017-01-20 18:26:55 -05:00
Raphael Deem
5669cafc59 Merge pull request #328 from awiddersheim/remove-multidict
Remove multidict requirement
2017-01-20 15:14:39 -08:00
Andrew Widdersheim
0c7275da1a Remove multidict requirement
This is no longer necessary after #302.
2017-01-20 18:12:54 -05:00
Eli Uriegas
e5cbf25cbd Merge pull request #325 from seemethere/add_key_error
Simplify RequestParameters
2017-01-20 15:27:00 -06:00
Eli Uriegas
c3cf618e84 Merge pull request #326 from seemethere/fix_exception_monitoring_documentation
Fix exception_monitoring example to actually work
2017-01-20 14:39:26 -06:00
Eli Uriegas
7780a8c187 Merge pull request #320 from r0fls/method-decorators
add method shorthands
2017-01-20 14:38:34 -06:00
Eli Uriegas
40f1e14bb7 Fix exception_monitoring example to actually work
Closes #324

Super was used incorrectly in the example, also fixed some formatting
here and there.
2017-01-20 14:36:15 -06:00
Eli Uriegas
a7cd4ccd09 Simplify RequestParameters
Simplifies request parameters, it defined a bit more than it had too,
added some docstrings and made the code simpler as well. Should now
raise a KeyError on __getitem__ as @amsb had noted on commit 9dd954b
2017-01-20 14:31:24 -06:00
Raphael Deem
6fd69b6284 separate tests 2017-01-20 10:19:14 -08:00
Raphael Deem
96424b6b0a add method shorthands 2017-01-20 00:07:22 -08:00
Eli Uriegas
bef34d66f5 Merge pull request #314 from seemethere/make_closed_transport_handling_more_robust
Add exception handling for closed transports
2017-01-19 21:31:30 -06:00
Eli Uriegas
c6049be688 Merge pull request #316 from youknowone/route-get
For function decorators, ['GET'] is the default methods
2017-01-19 21:31:06 -06:00
Eli Uriegas
5ea653244e Merge pull request #319 from seemethere/fix_docs_links
Fixes doc link extensions from .html to .md
2017-01-19 21:30:40 -06:00
Eli Uriegas
596bb54ee3 Oops on 2 of the non-relative links 2017-01-19 21:26:37 -06:00
Eli Uriegas
7554e87374 Fixes doc link extensions from .html to .md
Whoops! Totally missed that all the links pointed to `.html` files
instead of `.md` files
2017-01-19 21:24:08 -06:00
Cadel Watson
6176964bdf Clarify, reformat, and add to documentation guides (#318)
* Reorder and clarify the 'Request Data' guide, adding a section on RequestParameters

* Clarify routing guide, adding introduction and HTTP types sections

* Clarify the use-cases of middleware

* Clean up formatting in the exceptions guide and add some common exceptions.

* Fix formatting of blueprints and add use-case example.

* Clarify the class-based views guide

* Clarify and fix formatting of cookies guide

* Clarify static files guide

* Clarify the custom protocols guide.

* Add more information to the deploying guide

* Fix broken list in the community extensions list.

* Add introduction and improve warning to contributing guide

* Expand getting started guide

* Reorder guides and add links between them

* Standardise heading capitalisation
2017-01-19 21:18:52 -06:00
Eli Uriegas
f77bb81def Merge pull request #229 from kdelwat/sphinx-docs
Use Sphinx for documentation
2017-01-19 16:54:02 -06:00
Eli Uriegas
ed4752bbc0 Move transport close to finally statment 2017-01-19 16:35:48 -06:00
Cadel Watson
30862c0a3e Update documentation generation instructions. 2017-01-20 09:32:08 +11:00
Cadel Watson
7c4ffa8866 Merge branch 'master' into sphinx-docs 2017-01-20 09:30:42 +11:00
Eli Uriegas
a79f073077 Merge pull request #228 from seanpar203/issue_41
Adding more docstrings
2017-01-19 16:18:28 -06:00
Raphael Deem
4682d7b4b8 Merge pull request #296 from mdaue/ssl
Add SSL context to server
2017-01-19 11:29:07 -08:00
Raphael Deem
d2217b5c5f Merge branch 'master' into ssl 2017-01-19 11:23:21 -08:00
Jeong YunWon
0a160c4a0b For function decorators, ['GET'] is the default methods 2017-01-19 23:56:51 +09:00
Eli Uriegas
aed8255a8b Merge pull request #315 from h4ck3rm1k3/patch-1
untie
2017-01-19 08:28:18 -06:00
James Michael DuPont
ba60659894 untie 2017-01-19 04:04:16 -05:00
Raphael Deem
1ad7b95437 Merge pull request #306 from zkanda/always-log-error-exception
Always log if there's an exception occurred.
2017-01-19 00:22:46 -08:00
zkanda
cc43ee3b3d Always log of there's an exception occured. 2017-01-19 16:03:12 +08:00
Eli Uriegas
5a7b70c054 Merge pull request #313 from r0fls/logging-var
remove logger from run
2017-01-18 23:50:07 -06:00
Eli Uriegas
e9bfa30c1d Add exception handling for closed transports
Adds handling for closed transports in the server for `write_response`
as well as `write_error`, letting it all flow to `bail_out` seemed to be
a little light handed in terms of telling the logs where the
error actually occured.

Handling to fix the infinite `write_error` loop is still there and those
exceptions will get reported on in the debug logs.
2017-01-18 23:46:22 -06:00
Raphael Deem
bb83a25a52 remove logger from run 2017-01-18 21:45:30 -08:00
Eli Uriegas
99c8d779dc Merge pull request #312 from r0fls/allow-vhost-lists
allow using a list of hosts on a route
2017-01-18 23:42:59 -06:00
Raphael Deem
2c1ff5bf5d allow using a list of hosts on a route 2017-01-18 19:41:32 -08:00
Eli Uriegas
e218a59911 Merge pull request #311 from youknowone/route-overload
Feature: Routing overload
2017-01-18 16:32:46 -06:00
Jeong YunWon
11f3c79a77 Feature: Routing overload
When user specifies HTTP methods to function handlers, it automatically
will be overloaded unless they duplicate.

Example:

    # This is a new route. It works as before.
    @app.route('/overload', methods=['GET'])
    async def handler1(request):
        return text('OK1')

    # This is the exiting route but a new method. They are merged and
    # work as combined. The route will serve all of GET, POST and PUT.
    @app.route('/overload', methods=['POST', 'PUT'])
    async def handler2(request):
        return text('OK2')

    # This is the existing route and PUT method is the duplicated method.
    # It raises RouteExists.
    @app.route('/overload', methods=['PUT', 'DELETE'])
    async def handler3(request):
	return text('Duplicated')
2017-01-19 07:12:45 +09:00
Cadel Watson
5cfd8b9aa8 Fix formatting of 'Final Word' in README 2017-01-19 08:58:13 +11:00
Cadel Watson
ebce7b01c7 Add new guides to documentation index 2017-01-19 08:54:20 +11:00
Cadel Watson
9d4b104d2d Merge branch 'master' into sphinx-docs 2017-01-19 08:48:54 +11:00
Raphael Deem
5a6fb679c9 Merge pull request #309 from seemethere/fix_write_error_loop
Fixes write_error loop from bail_out function
2017-01-17 18:11:22 -08:00
Raphael Deem
9102a9cd6e Merge branch 'master' into ssl 2017-01-17 18:09:33 -08:00
Eli Uriegas
573d1da0ef Fixes write_error loop from bail_out function
Fixes stack-overflow found in #307
2017-01-17 18:28:22 -06:00
Raphael Deem
2848dce968 Merge pull request #308 from r0fls/287
update logging placement
2017-01-17 15:51:38 -08:00
Raphael Deem
ba1e006585 update logging placement 2017-01-17 15:49:17 -08:00
Eli Uriegas
9108a4c69f Merge pull request #291 from subyraman/master
Add rich HTML traceback in debug mode, add HTML 500 page in prod
2017-01-17 15:47:37 -06:00
Eli Uriegas
f42ceb1baa Merge pull request #304 from gpip/missing_ip_slots
cannot use the new .ip without updating __slots__
2017-01-17 10:54:21 -06:00
Guilherme Polo
5903dd2939 cannot use the new .ip without updating __slots__ 2017-01-17 02:58:45 -02:00
Eli Uriegas
55b39a3f15 Merge pull request #301 from r0fls/cache-remote-ip
cache the remote IP property
2017-01-16 20:07:53 -06:00
Raphael Deem
9bc69f7de9 use hasattr 2017-01-16 17:35:08 -08:00
Channel Cat
2aa380c5a3 Merge pull request #302 from channelcat/request-headers-ci
Trimmed down features of CIMultiDict
2017-01-16 17:08:12 -08:00
Channel Cat
638fbcb619 Encoding needs a default 2017-01-16 17:03:55 -08:00
Channel Cat
ccbbce0036 Fix header capitalization on input
also removed redundant utf-8 in encodes/decodes
2017-01-16 16:55:55 -08:00
Channel Cat
41918eaf0a Trimmed down features of CIMultiDict 2017-01-16 16:12:42 -08:00
Eli Uriegas
5c344f7efa Remove redundant else 2017-01-16 17:51:56 -06:00
Raphael Deem
213580ea78 cache the remote IP property 2017-01-16 15:48:55 -08:00
Eli Uriegas
d5fd269fda Merge pull request #300 from channelcat/move-request-ip-retry
Moved Remote-Addr header to request.ip
2017-01-16 17:35:04 -06:00
Ubuntu
2cf4baddfb Moved Remote-Addr header to request.ip so it can be pulled on-demand 2017-01-16 23:27:50 +00:00
Eli Uriegas
48d496936a Merge pull request #294 from subyraman/redirect
Add redirect method from @pcdinh
2017-01-16 13:53:02 -06:00
Eli Uriegas
e410c06a68 Merge pull request #293 from r0fls/extensions-docs
Extensions docs
2017-01-15 19:37:30 -06:00
Eli Uriegas
f6c2d0bcaf Merge pull request #297 from seemethere/increment_020
Increment version to 0.2.0
2017-01-14 11:25:10 -06:00
Eli Uriegas
e2a16f96a8 Increment version to 0.2.0 2017-01-14 11:24:31 -06:00
Matt Daue
49fdc6563f Add SSL to server
Add ssl variable passthrough to following:
-- sanic.run
-- server.serve
Add ssl variable to loop.create_server to enable built-in async context socket wrapper
Update documentation
Tested with worker = 1, and worker = 2.

Signed-off-by: Matt Daue <mattdaue@gmail.com>
2017-01-14 07:16:59 -05:00
Suby Raman
b5bbef09c5 add redirect method 2017-01-14 00:47:28 -05:00
Suby Raman
7a1e089725 add headers none test 2017-01-14 00:45:04 -05:00
Suby Raman
7de3f7aa78 rename test app 2017-01-14 00:43:30 -05:00
Suby Raman
02b9a0a297 add redirect code from @pcdinh 2017-01-14 00:41:54 -05:00
Tim Mundt
0b9094d348 Merge branch 'master' into improved_config 2017-01-13 12:34:56 +01:00
Raphael Deem
a86cc32dff Update extensions.md
Since there have been a few extensions discussed in open issues, it makes sense to start keeping track of them.
2017-01-12 19:30:22 -08:00
Raphael Deem
974c857a97 add a list of extensions 2017-01-12 19:25:08 -08:00
Suby Raman
6e53fa03f5 add beautifulsoup4 to tox 2017-01-12 20:03:35 -05:00
Suby Raman
8c5e214131 html and tests pass 2017-01-12 19:54:34 -05:00
Eli Uriegas
cf60ebd988 Merge pull request #289 from seemethere/update_request_form_getitem
Update request.form to work with __getitem__
2017-01-11 17:02:45 -06:00
Eli Uriegas
9dd954bccd Update request.form to work with __getitem__ 2017-01-11 16:55:34 -06:00
Eli Uriegas
a02eb8e7cb Merge pull request #284 from r0fls/remove-defualt-type
remove default from host in _get method
2017-01-11 10:01:11 -06:00
Eli Uriegas
a93ca9b8f1 Merge pull request #285 from r0fls/blueprint-domains
add vhosts to blueprints
2017-01-11 10:00:35 -06:00
Raphael Deem
15e4ec7ffb add ability to override default host in blueprint 2017-01-10 22:08:15 -08:00
Raphael Deem
62df50e22b add vhosts to blueprints 2017-01-10 21:35:07 -08:00
Raphael Deem
055430d4b8 remove default from host in _get method 2017-01-10 16:01:21 -08:00
Eli Uriegas
57f27c41e0 Merge pull request #278 from r0fls/vhosts
add support for virtual hosts
2017-01-10 15:18:36 -06:00
Cadel Watson
385328ffd5 Generate API documentation in the _api folder 2017-01-10 09:41:00 +11:00
Cadel Watson
34d1e5e67e Convert README to RestructuredText and include it in the documentation index. 2017-01-10 09:28:33 +11:00
Raphael Deem
4f832ac9af add support for virtual hosts 2017-01-08 18:46:29 -08:00
Eli Uriegas
b0bf989056 Merge pull request #261 from yoloseem/parsed_json
Cache request.json even when it's empty.
2017-01-08 11:57:33 -06:00
Eli Uriegas
fd0e8624c4 Merge pull request #276 from r0fls/workers
Fix multiple worker problem
2017-01-08 11:57:10 -06:00
Eli Uriegas
5566668a5f Change the skips to actual pytest skips
By using the builtin pytest skips we can identify that the tests are still there but are being currently skipped.

Will update later to remove the skips once we figure out why they freeze with pytest (I experienced this same issue with multiprocessing when testing start/stop events).
2017-01-08 11:55:08 -06:00
Raphael Deem
f8e6becb9e skip multiprocessing tests 2017-01-07 18:58:02 -08:00
Raphael Deem
dd28d70680 fix stop event 2017-01-07 18:46:38 -08:00
Raphael Deem
ed8e3f237c this branch is broken 2017-01-07 15:28:21 -08:00
Raphael Deem
77c04c4cf9 fix multiple worker problem 2017-01-07 12:57:14 -08:00
Eli Uriegas
ebc8d7168a Merge pull request #274 from AntonDnepr/cbw_fixes
Class based views fixes
2017-01-07 10:07:14 -06:00
Anton Zhyrney
434fa74e67 removed debug from test 2017-01-07 07:14:27 +02:00
Anton Zhyrney
47a4f34cdf tests&small update 2017-01-07 07:13:49 +02:00
Anton Zhyrney
1317b1799c add docstrings&updated docs 2017-01-07 06:57:07 +02:00
Anton Zhyrney
fcae4a9f0a added as_view 2017-01-07 06:30:23 +02:00
Eli Uriegas
d733c5bb7c Merge pull request #271 from easydaniel/master
Asyncpg example
2017-01-06 09:11:42 -06:00
Eli Uriegas
baf8254907 Change Ellipsis to None for consistency 2017-01-05 15:29:57 -06:00
Eli Uriegas
802e7d4654 Merge pull request #269 from r0fls/263
add configurable backlog
2017-01-04 20:37:19 -06:00
Raphael Deem
616e20d467 move backlog to run() 2017-01-04 09:31:06 -08:00
easydaniel
5c7c2cf85e Update sanic_asyncpg_example.py
Remove unused library
2017-01-04 23:35:06 +08:00
DanielChien
1942644434 modify config to varbles 2017-01-04 23:30:29 +08:00
DanielChien
b67482de9b add example for asyncpg 2017-01-04 23:29:09 +08:00
Eli Uriegas
35bb71f952 Merge pull request #270 from seemethere/add_server_event_tests
Add server event tests
2017-01-04 00:32:13 -06:00
Eli Uriegas
9c91b09ab1 Fix this to actually reflect current behavior 2017-01-04 00:23:59 -06:00
Eli Uriegas
06911a8d2e Add tests for server start/stop event functions 2017-01-04 00:23:35 -06:00
Raphael Deem
e7922c1b54 add configurable backlog #263 2017-01-03 18:36:31 -08:00
Eli Uriegas
16959caa34 Merge pull request #259 from yoloseem/route
Correct Router documentation
2017-01-03 18:47:54 -06:00
Eli Uriegas
0675f388b9 Merge pull request #255 from seemethere/add_more_verbose_debug_error_handling
Add more verbose debug error handling
2017-01-03 15:43:26 -06:00
Eli Uriegas
b4ad9459da Merge pull request #260 from yoloseem/gitign
Update .gitignore
2017-01-03 14:42:00 -06:00
Eli Uriegas
8a9b1fee14 Merge pull request #265 from youknowone/test-middleware-schedule
Prevent flooding of meaningless traceback in `sanic_endpoint_test`
2017-01-03 14:41:23 -06:00
Jeong YunWon
e6eb697bb2 Use constant PORT rather than literal in test code (#266) 2017-01-03 14:40:13 -06:00
Eli Uriegas
4ccc782e29 Merge pull request #209 from 38elements/protocol
Customizable protocol
2017-01-03 11:52:54 -06:00
Hyunjun Kim
cfdd9f66d1 Correct sanic.router.Router documentation 2017-01-02 14:32:22 +09:00
Hyunjun Kim
035cbf84ae Cache request.json even when it's null or empty
In case of request body is set to `{}`, `[]` or `null`, even it's
already processed, parsed_json won't be used due to its boolean
evaluation.
2017-01-02 14:20:20 +09:00
Hyunjun Kim
31e92a8b4f Update .gitignore
* .python-version is generated by `pyenv local` command
* .eggs/ directory contains *.egg files
2017-01-02 13:33:24 +09:00
Jeong YunWon
87c24e5a7c Prevent flooding of meaningless traceback in sanic_endpoint_test
When Sanic has an exception in a request middleware, it fails to
save request object in `results`. In `sanic_endpoint_test`, because
it always requires `results` to have both `request` and `response` objects,
it prints traceback like attached example. It is not a user code and
it doesn't give any information to users, it is better to suppress
to print this kind of error.

To fix it, this patch insert collect hook as first request middleware
to guarantee to successfully run it always.

```
app = <sanic.sanic.Sanic object at 0x1102b5358>, method = 'get', uri = '/ping/', gather_request = True, loop = None
debug = True, request_args = (), request_kwargs = {}
_collect_request = <function sanic_endpoint_test.<locals>._collect_request at 0x11286c158>
_collect_response = <function sanic_endpoint_test.<locals>._collect_response at 0x11286c378>

    def sanic_endpoint_test(app, method='get', uri='/', gather_request=True,
                            loop=None, debug=False, *request_args,
                            **request_kwargs):
        results = []
        exceptions = []

        if gather_request:
            @app.middleware
            def _collect_request(request):
                results.append(request)

        async def _collect_response(sanic, loop):
            try:
                response = await local_request(method, uri, *request_args,
                                               **request_kwargs)
                results.append(response)
            except Exception as e:
                exceptions.append(e)
            app.stop()

        app.run(host=HOST, debug=debug, port=42101,
                after_start=_collect_response, loop=loop)

        if exceptions:
            raise ValueError("Exception during request: {}".format(exceptions))

        if gather_request:
            try:
>               request, response = results
E               ValueError: not enough values to unpack (expected 2, got 1)

../sanic/sanic/utils.py:46: ValueError
```
2017-01-02 13:18:22 +09:00
Eli Uriegas
552ff9d736 Merge pull request #235 from yoloseem/patch-1
Allow Sanic-inherited application
2016-12-31 13:21:44 -06:00
Eli Uriegas
738396c2e2 Merge pull request #236 from seanpar203/token_property
Add token property to request
2016-12-31 13:21:12 -06:00
Eli Uriegas
9f18b5a096 Merge pull request #248 from youknowone/debuggable-typecheck
Handle hooks parameters in more debuggable way
2016-12-31 13:17:06 -06:00
Eli Uriegas
15c965c08c Make exception tests test unhandled exceptions
* Adds tests for unhandled exceptions
* Adds tests for unhandled exceptions in exception handlers
* Rewrites tests to utilize pytest fixtures (No need to create the app
on import)
2016-12-30 13:50:12 -06:00
Eli Uriegas
7a8fd6b0df Add more verbose error handling
* Adds logging to error messages in debug mode as pointed out in PR #249,
while also improving the debug message.
2016-12-30 13:48:17 -06:00
Eli Uriegas
3ada6f358c Merge pull request #197 from r0fls/178
convert header values to strings
2016-12-30 12:17:29 -06:00
Eli Uriegas
f1c2854358 Merge branch 'master' into 178 2016-12-30 12:15:08 -06:00
Eli Uriegas
87559a34f8 Include more explicit loop for headers conversion
Also merges master changes into this PR for this branch
2016-12-30 12:13:16 -06:00
Eli Uriegas
9586351f37 Merge pull request #243 from dutradda/add_remove_route_method
created methods to remove a route from api/router
2016-12-30 09:39:57 -06:00
Diogo
0f6ed642da created methods to remove a route from api/router 2016-12-30 07:36:57 -02:00
Diogo Dutra
6d1d4ade19 add a flag to skip SIGINT and SIGTERM signals registration 2016-12-29 19:35:41 -02:00
Eli Uriegas
73a57e1105 Merge pull request #252 from AntonDnepr/misprints
Small docs improvements
2016-12-29 11:49:55 -06:00
Anton Zhyrney
e7314d1775 fix misprints&renaming 2016-12-29 19:22:11 +02:00
38elements
ee8f8c2930 Merge branch 'master' into protocol 2016-12-29 16:44:15 +09:00
38elements
64e0e2d19f Improve custom_protocol.md 2016-12-29 16:41:04 +09:00
38elements
6bb4dae5e0 Fix format in custom_protocol.md 2016-12-29 13:25:04 +09:00
38elements
83e9d08853 Add document for custom protocol 2016-12-29 13:11:27 +09:00
Eli Uriegas
7dfa62516c Merge pull request #238 from r0fls/73
stop multiple worker server without sleep loop; issue #73
2016-12-28 18:05:06 -06:00
Jeong YunWon
15e7d8ab2e Handle hooks parameters in more debuggable way
1. not list() -> callable()
The args of hooking parameters of Sanic have to be callables.
For wrong parameters, errors will be generated from:
```
    listeners += args
```

By checking just list type, the raised error will be associated
with `[args]` instead of `args`, which is not given by users.
With this patch, the raised error will be associated with `args`.
Then users can notice their argument was neither callable nor list
in the easier way.

2. Function -> Functions in document
Regarding the parameter as a list is harmless to the user code.
But unawareness of its type can be list can limit the potent of
the user code.
2016-12-28 18:14:57 +09:00
Raphael Deem
a4f77984b7 stop multiple worker server without sleep loop; issue #73 2016-12-26 14:51:16 -08:00
38elements
39b279f0f2 Improve examples/custom_protocol.py 2016-12-26 23:54:59 +09:00
38elements
ac44900fc4 Add test and example for custom protocol 2016-12-26 23:41:10 +09:00
Sean Parsons
548458c3e0 Added test for new token property on request object. 2016-12-26 06:48:53 -05:00
Sean Parsons
986b0aa106 Added token property to request object. 2016-12-26 06:41:41 -05:00
Hyunjun Kim
01b42fb399 Allow Sanic-inherited application 2016-12-26 20:37:16 +09:00
Eli Uriegas
f74d44152a Merge pull request #234 from seemethere/update_tests_to_use_tox
Change travis job to use tox
2016-12-25 19:10:36 -08:00
Eli Uriegas
1557854755 Update to make flake8 actually work 2016-12-25 19:05:11 -08:00
Eli Uriegas
56d6c2a929 Change travis job to use tox 2016-12-25 18:55:25 -08:00
Eli Uriegas
2d4512cd1c Merge branch 'master' into improved_config 2016-12-25 15:26:33 -08:00
Eli Uriegas
5402e6d3a6 Merge pull request #212 from r0fls/176
allow overriding logging basicConfig settings
2016-12-25 09:13:51 -08:00
Cadel Watson
52c59e7133 Fix all docstring errors.
When generating documentation with sphinx-apidoc, there are currently
many docstring errors, mostly minor. This commit fixes all errors.
2016-12-25 20:43:45 +11:00
Cadel Watson
7654c2f902 Use Sphinx for documentation.
This commit creates configuration files and an index page for
documentation using Sphinx. The recommonmark package is used to enable
Markdown support for Sphinx, using the Common Mark specification. This
means that the current documentation doesn't need to be rewritten.
2016-12-25 20:24:34 +11:00
Raphael Deem
be9eca2d63 use try/except 2016-12-24 23:05:03 -08:00
Sean Parsons
d5ad5e46da Update response docstrings to be explicit on whats returned. 2016-12-25 01:24:17 -05:00
Sean Parsons
a486fb99a9 Updated json function docstrings to be more consistent. 2016-12-25 01:06:40 -05:00
Sean Parsons
2b10860c32 Added docstrings to sanic.response.py for issue 41 2016-12-25 01:05:26 -05:00
Sean Parsons
a03f216f42 Added additional docstrings to blueprints.py 2016-12-25 00:47:51 -05:00
Raphael Deem
7d7cbaacf1 header format function 2016-12-24 20:56:13 -08:00
Raphael Deem
00b5a496dd type -> isinstance 2016-12-24 20:56:13 -08:00
Raphael Deem
7e6c92dc52 convert header values to strings 2016-12-24 20:56:13 -08:00
38elements
2d05243c4a Refactor arguments of run function 2016-12-24 22:49:48 +09:00
38elements
39211f8fbd Refactor arguments of serve function 2016-12-24 11:40:07 +09:00
Raphael Deem
32ea45d403 allow overriding logging.basicConfig 2016-12-23 16:17:34 -08:00
Stefano Palazzo
a73a7d1e7b Make it possible to disable the logo by subclassing Config 2016-12-23 11:42:00 +01:00
38elements
c657c531b4 Customizable protocol 2016-12-23 00:13:38 +09:00
Tim Mundt
ef9edfd160 added documentation for configuration 2016-12-17 20:20:07 +01:00
Tim Mundt
234a7925c6 restored accidentally degraded doc string 2016-12-17 19:24:41 +01:00
Tim Mundt
a550b5c112 added tests and small fixes for config 2016-12-16 18:46:07 +01:00
Tim Mundt
04798cbf5b added methods to load config from a file 2016-12-16 17:05:09 +01:00
167 changed files with 16389 additions and 2533 deletions

32
.appveyor.yml Normal file
View File

@@ -0,0 +1,32 @@
version: "{branch}.{build}"
environment:
matrix:
- TOXENV: py35-no-ext
PYTHON: "C:\\Python35-x64"
PYTHON_VERSION: "3.5.x"
PYTHON_ARCH: "64"
- TOXENV: py36-no-ext
PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x"
PYTHON_ARCH: "64"
- TOXENV: py37-no-ext
PYTHON: "C:\\Python37-x64"
PYTHON_VERSION: "3.7.x"
PYTHON_ARCH: "64"
init: SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
install:
- pip install tox
build: off
test_script: tox
notifications:
- provider: Email
on_build_success: false
on_build_status_changed: false

View File

@@ -1,7 +1,7 @@
[run]
branch = True
source = sanic, tests
omit = site-packages
source = sanic
omit = site-packages, sanic/utils.py, sanic/__main__.py
[html]
directory = coverage
directory = coverage

25
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,25 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is, make sure to paste any exceptions and tracebacks.
**Code snippet**
Relevant source code, make sure to remove what is not necessary.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Environment (please complete the following information):**
- OS: [e.g. iOS]
- Version [e.g. 0.8.3]
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,16 @@
---
name: Feature request
about: Suggest an idea for Sanic
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or sample code about the feature request here.

13
.github/ISSUE_TEMPLATE/help-wanted.md vendored Normal file
View File

@@ -0,0 +1,13 @@
---
name: Help wanted
about: Do you need help? Try community.sanicframework.org
---
*DELETE ALL BEFORE POSTING*
*Post your HELP WANTED questions on [the community forum](https://community.sanicframework.org/)*.
Checkout the community forum before posting any question here.
We prefer if you put these kinds of questions here:
https://community.sanicframework.org/c/questions-and-help

8
.gitignore vendored
View File

@@ -1,11 +1,17 @@
*~
*.egg-info
*.egg
*.eggs
*.pyc
.coverage
.coverage.*
coverage
.tox
settings.py
*.pyc
.idea/*
.cache/*
.python-version
docs/_build/
docs/_api/
build/*
.DS_Store

View File

@@ -1,19 +1,41 @@
sudo: false
language: python
python:
- '3.5'
- '3.6'
cache:
directories:
- $HOME/.cache/pip
matrix:
include:
- env: TOX_ENV=py35
python: 3.5
- env: TOX_ENV=py35-no-ext
python: 3.5
- env: TOX_ENV=py36
python: 3.6
- env: TOX_ENV=py36-no-ext
python: 3.6
- env: TOX_ENV=py37
python: 3.7
dist: xenial
sudo: true
- env: TOX_ENV=py37-no-ext
python: 3.7
dist: xenial
sudo: true
- env: TOX_ENV=lint
python: 3.6
- env: TOX_ENV=check
python: 3.6
install:
- pip install -r requirements.txt
- pip install -r requirements-dev.txt
- python setup.py install
- pip install flake8
- pip install pytest
before_script: flake8 sanic
script: py.test -v tests
- pip install -U tox
- pip install codecov
script: travis_retry tox -e $TOX_ENV
after_success:
- codecov
deploy:
provider: pypi
user: channelcat
password:
secure: jH4+Di2/qcBwWVhI5/3NYd/JuDDgf5/cF85h+oQnAjgwP6me3th9RS0PHL2gjKJrmyRgwrW7a3eSAityo5sQSlBloQCNrtCE30rkDiwtgoIxDW72NR/nE8nUkS9Utgy87eS+3B4NrO7ag4GTqO5ET8SQ4/MCiQwyUQATLXj2s2eTpQvqJeZG6YgoeFAOYvlR580yznXoOwldWlkiymJiWSdR/01lthtWCi40sYC/QoU7psODJ/tPcsqgQtQKyUVsci7mKvp3Y8ImkoO/POM01jYNsS9qLh5pKTNCEYxtyzC77whenCNHn7WReVidd56g1ADosbNo4yY/1D3VAvwjUnkQ0SzdBQfT7IIzccEuC0j1NXKPN97OX0a6XzyUMYJ1XiU3juTJOPxdYBPbsDM3imQiwrOh1faIf0HCgNTN+Lxe5l8obCH7kffNcVUhs2zI0+2t4MS5tjb/OVuYD/TFn+bM33DqzLctTOK/pGn6xefzZcdzb191LPo99Lof+4fo6jNUpb0UmcBu5ZJzxh0lGe8FPIK3UAG/hrYDDgjx8s8RtUJjcEUQz0659XffYx7DLlgHO7cWyfjrHD3yrLzDbYr5mAS4FR+4D917V7UL+on4SsKHN00UuMGPguqSYo/xYyPLnJU5XK0du4MIpsNMB8TtrJOIewOOfD32+AisPQ8=
secure: h7oNDjA/ObDBGK7xt55SV0INHOclMJW/byxMrNxvCZ0JxiRk7WBNtWYt0WJjyf5lO/L0/sfgiAk0GIdFon57S24njSLPAq/a4ptkWZ68s2A+TaF6ezJSZvE9V8khivjoeub90TzfX6P5aukRja1CSxXKJm+v0V8hGE4CZGyCgEDvK3JqIakpXllSDl19DhVftCS/lQZD7AXrZlg1kZnPCMtB5IbCVR4L2bfrSJVNptBi2CqqxacY2MOLu+jv5FzJ2BGVIJ2zoIJS2T+JmGJzpiamF6y8Amv0667i9lg2DXWCtI3PsQzCmwa3F/ZsI+ohUAvJC5yvzP7SyTJyXifRBdJ9O137QkNAHFoJOOY3B4GSnTo8/boajKXEqGiV4h2EgwNjBaR0WJl0pB7HHUCBMkNRWqo6ACB8eCr04tXWXPvkGIc+wPjq960hsUZea1O31MuktYc9Ot6eiFqm7OKoItdi7LxCen1eTj93ePgkiEnVZ+p/04Hh1U7CX31UJMNu5kCvZPIANnAuDsS2SK7Qkr88OAuWL0wmrBcXKOcnVkJtZ5mzx8T54bI1RrSYtFDBLFfOPb0GucSziMBtQpE76qPEauVwIXBk3RnR8N57xBR/lvTaIk758tf+haO0llEO5rVls1zLNZ+VlTzXy7hX0OZbdopIAcCFBFWqWMAdXQc=
on:
tags: true
distributions: "sdist bdist_wheel"

View File

@@ -1,3 +1,80 @@
Version 0.8
-----------
0.8.3
- Changes:
- Ownership changed to org 'huge-success'
0.8.0
- Changes:
- Add Server-Sent Events extension (Innokenty Lebedev)
- Graceful handling of request_handler_task cancellation (Ashley Sommer)
- Sanitize URL before redirection (aveao)
- Add url_bytes to request (johndoe46)
- py37 support for travisci (yunstanford)
- Auto reloader support for OSX (garyo)
- Add UUID route support (Volodymyr Maksymiv)
- Add pausable response streams (Ashley Sommer)
- Add weakref to request slots (vopankov)
- remove ubuntu 12.04 from test fixture due to deprecation (yunstanford)
- Allow streaming handlers in add_route (kinware)
- use travis_retry for tox (Raphael Deem)
- update aiohttp version for test client (yunstanford)
- add redirect import for clarity (yingshaoxo)
- Update HTTP Entity headers (Arnulfo Solís)
- Add register_listener method (Stephan Fitzpatrick)
- Remove uvloop/ujson dependencies for Windows (abuckenheimer)
- Content-length header on 204/304 responses (Arnulfo Solís)
- Extend WebSocketProtocol arguments and add docs (Bob Olde Hampsink, yunstanford)
- Update development status from pre-alpha to beta (Maksim Anisenkov)
- KeepAlive Timout log level changed to debug (Arnulfo Solís)
- Pin pytest to 3.3.2 because of pytest-dev/pytest#3170 (Maksim Aniskenov)
- Install Python 3.5 and 3.6 on docker container for tests (Shahin Azad)
- Add support for blueprint groups and nesting (Elias Tarhini)
- Remove uvloop for windows setup (Aleksandr Kurlov)
- Auto Reload (Yaser Amari)
- Documentation updates/fixups (multiple contributors)
- Fixes:
- Fix: auto_reload in Linux (Ashley Sommer)
- Fix: broken tests for aiohttp >= 3.3.0 (Ashley Sommer)
- Fix: disable auto_reload by default on windows (abuckenheimer)
- Fix (1143): Turn off access log with gunicorn (hqy)
- Fix (1268): Support status code for file response (Cosmo Borsky)
- Fix (1266): Add content_type flag to Sanic.static (Cosmo Borsky)
- Fix: subprotocols parameter missing from add_websocket_route (ciscorn)
- Fix (1242): Responses for CI header (yunstanford)
- Fix (1237): add version constraint for websockets (yunstanford)
- Fix (1231): memory leak - always release resource (Phillip Xu)
- Fix (1221): make request truthy if transport exists (Raphael Deem)
- Fix failing tests for aiohttp>=3.1.0 (Ashley Sommer)
- Fix try_everything examples (PyManiacGR, kot83)
- Fix (1158): default to auto_reload in debug mode (Raphael Deem)
- Fix (1136): ErrorHandler.response handler call too restrictive (Julien Castiaux)
- Fix: raw requires bytes-like object (cloudship)
- Fix (1120): passing a list in to a route decorator's host arg (Timothy Ebiuwhe)
- Fix: Bug in multipart/form-data parser (DirkGuijt)
- Fix: Exception for missing parameter when value is null (NyanKiyoshi)
- Fix: Parameter check (Howie Hu)
- Fix (1089): Routing issue with named parameters and different methods (yunstanford)
- Fix (1085): Signal handling in multi-worker mode (yunstanford)
- Fix: single quote in readme.rst (Cosven)
- Fix: method typos (Dmitry Dygalo)
- Fix: log_response correct output for ip and port (Wibowo Arindrarto)
- Fix (1042): Exception Handling (Raphael Deem)
- Fix: Chinese URIs (Howie Hu)
- Fix (1079): timeout bug when self.transport is None (Raphael Deem)
- Fix (1074): fix strict_slashes when route has slash (Raphael Deem)
- Fix (1050): add samesite cookie to cookie keys (Raphael Deem)
- Fix (1065): allow add_task after server starts (Raphael Deem)
- Fix (1061): double quotes in unauthorized exception (Raphael Deem)
- Fix (1062): inject the app in add_task method (Raphael Deem)
- Fix: update environment.yml for readthedocs (Eli Uriegas)
- Fix: Cancel request task when response timeout is triggered (Jeong YunWon)
- Fix (1052): Method not allowed response for RFC7231 compliance (Raphael Deem)
- Fix: IPv6 Address and Socket Data Format (Dan Palmer)
Note: Changelog was unmaintained between 0.1 and 0.7
Version 0.1
-----------
- 0.1.7
@@ -5,18 +82,18 @@ Version 0.1
- 0.1.6
- Static files
- Lazy Cookie Loading
- 0.1.5
- 0.1.5
- Cookies
- Blueprint listeners and ordering
- Faster Router
- Fix: Incomplete file reads on medium+ sized post requests
- Breaking: after_start and before_stop now pass sanic as their first argument
- 0.1.4
- 0.1.4
- Multiprocessing
- 0.1.3
- Blueprint support
- Faster Response processing
- 0.1.1 - 0.1.2
- 0.1.1 - 0.1.2
- Struggling to update pypi via CI
- 0.1.0
- Released to public
- 0.1.0
- Released to public

74
CONDUCT.md Normal file
View File

@@ -0,0 +1,74 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at sanic-maintainers@googlegroups.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

72
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,72 @@
# Contributing
Thank you for your interest! Sanic is always looking for contributors. If you
don't feel comfortable contributing code, adding docstrings to the source files
is very appreciated.
We are committed to providing a friendly, safe and welcoming environment for all,
regardless of gender, sexual orientation, disability, ethnicity, religion,
or similar personal characteristic.
Our [code of conduct](./CONDUCT.md) sets the standards for behavior.
## Installation
To develop on sanic (and mainly to just run the tests) it is highly recommend to
install from sources.
So assume you have already cloned the repo and are in the working directory with
a virtual environment already set up, then run:
```bash
python setup.py develop && pip install -r requirements-dev.txt
```
## Running tests
To run the tests for sanic it is recommended to use tox like so:
```bash
tox
```
See it's that simple!
## Pull requests!
So the pull request approval rules are pretty simple:
1. All pull requests must pass unit tests.
2. All pull requests must be reviewed and approved by at least
one current collaborator on the project.
3. All pull requests must pass flake8 checks.
4. All pull requests must be consistent with the existing code.
5. If you decide to remove/change anything from any common interface
a deprecation message should accompany it.
6. If you implement a new feature you should have at least one unit
test to accompany it.
7. An example must be one of the following:
* Example of how to use Sanic
* Example of how to use Sanic extensions
* Example of how to use Sanic and asynchronous library
## Documentation
Sanic's documentation is built
using [sphinx](http://www.sphinx-doc.org/en/1.5.1/). Guides are written in
Markdown and can be found in the `docs` folder, while the module reference is
automatically generated using `sphinx-apidoc`.
To generate the documentation from scratch:
```bash
sphinx-apidoc -fo docs/_api/ sanic
sphinx-build -b html docs docs/_build
```
The HTML documentation will be created in the `docs/_build` folder.
## Warning
One of the main goals of Sanic is speed. Code that lowers the performance of
Sanic without significant gains in usability, security, or features may not be
merged. Please don't let this intimidate you! If you have any concerns about an
idea, open an issue for discussion and help.

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) [year] [fullname]
Copyright (c) 2016-present Channel Cat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.

7
MANIFEST.in Normal file
View File

@@ -0,0 +1,7 @@
include README.rst
include MANIFEST.in
include LICENSE
include setup.py
recursive-exclude * __pycache__
recursive-exclude * *.py[co]

4
Makefile Normal file
View File

@@ -0,0 +1,4 @@
test:
find . -name "*.pyc" -delete
docker build -t sanic/test-image -f docker/Dockerfile .
docker run -t sanic/test-image tox

View File

@@ -1,96 +0,0 @@
# Sanic
[![Join the chat at https://gitter.im/sanic-python/Lobby](https://badges.gitter.im/sanic-python/Lobby.svg)](https://gitter.im/sanic-python/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/channelcat/sanic.svg?branch=master)](https://travis-ci.org/channelcat/sanic)
[![PyPI](https://img.shields.io/pypi/v/sanic.svg)](https://pypi.python.org/pypi/sanic/)
[![PyPI](https://img.shields.io/pypi/pyversions/sanic.svg)](https://pypi.python.org/pypi/sanic/)
Sanic is a Flask-like Python 3.5+ web server that's written to go fast. It's based on the work done by the amazing folks at magicstack, and was inspired by this article: https://magic.io/blog/uvloop-blazing-fast-python-networking/.
On top of being Flask-like, Sanic supports async request handlers. This means you can use the new shiny async/await syntax from Python 3.5, making your code non-blocking and speedy.
## Benchmarks
All tests were run on an AWS medium instance running ubuntu, using 1 process. Each script delivered a small JSON response and was tested with wrk using 100 connections. Pypy was tested for Falcon and Flask but did not speed up requests.
| Server | Implementation | Requests/sec | Avg Latency |
| ------- | ------------------- | ------------:| -----------:|
| Sanic | Python 3.5 + uvloop | 33,342 | 2.96ms |
| Wheezy | gunicorn + meinheld | 20,244 | 4.94ms |
| Falcon | gunicorn + meinheld | 18,972 | 5.27ms |
| Bottle | gunicorn + meinheld | 13,596 | 7.36ms |
| Flask | gunicorn + meinheld | 4,988 | 20.08ms |
| Kyoukai | Python 3.5 + uvloop | 3,889 | 27.44ms |
| Aiohttp | Python 3.5 + uvloop | 2,979 | 33.42ms |
| Tornado | Python 3.5 | 2,138 | 46.66ms |
## Hello World
```python
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
```
## Installation
* `python -m pip install sanic`
## Documentation
* [Getting started](docs/getting_started.md)
* [Request Data](docs/request_data.md)
* [Routing](docs/routing.md)
* [Middleware](docs/middleware.md)
* [Exceptions](docs/exceptions.md)
* [Blueprints](docs/blueprints.md)
* [Class Based Views](docs/class_based_views.md)
* [Cookies](docs/cookies.md)
* [Static Files](docs/static_files.md)
* [Testing](docs/testing.md)
* [Deploying](docs/deploying.md)
* [Contributing](docs/contributing.md)
* [License](LICENSE)
## TODO:
* Streamed file processing
* File output
* Examples of integrations with 3rd-party modules
* RESTful router
## Limitations:
* No wheels for uvloop and httptools on Windows :(
## Final Thoughts:
▄▄▄▄▄
▀▀▀██████▄▄▄ _______________
▄▄▄▄▄ █████████▄ / \
▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Gotta go fast! |
▀▀█████▄▄ ▀██████▄██ | _________________/
▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
▀▀▀▄ ▀▀███ ▀ ▄▄
▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌
██▀▄▄▄██▀▄███▀ ▀▀████ ▄██
▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀
▌ ▐▀████▐███▒▒▒▒▒▐██▌
▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
▀▀█████████▀
▄▄██▀██████▀█
▄██▀ ▀▀▀ █
▄█ ▐▌
▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
▌ ▐ ▀▀▄▄▄▀
▀▀▄▄▀

103
README.rst Normal file
View File

@@ -0,0 +1,103 @@
Sanic
=====
|Join the chat at https://gitter.im/sanic-python/Lobby| |Build Status| |AppVeyor Build Status| |Documentation| |Codecov| |PyPI| |PyPI version| |Code style black|
Sanic is a Flask-like Python 3.5+ web server that's written to go fast. It's based on the work done by the amazing folks at magicstack, and was inspired by `this article <https://magic.io/blog/uvloop-blazing-fast-python-networking/>`_.
On top of being Flask-like, Sanic supports async request handlers. This means you can use the new shiny async/await syntax from Python 3.5, making your code non-blocking and speedy.
Sanic is developed `on GitHub <https://github.com/huge-success/sanic/>`_. We also have `a community discussion board <https://community.sanicframework.org/>`_. Contributions are welcome!
If you have a project that utilizes Sanic make sure to comment on the `issue <https://github.com/huge-success/sanic/issues/396>`_ that we use to track those projects!
Hello World Example
-------------------
.. code:: python
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route('/')
async def test(request):
return json({'hello': 'world'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Installation
------------
- ``pip install sanic``
To install sanic without uvloop or ujson using bash, you can provide either or both of these environmental variables
using any truthy string like `'y', 'yes', 't', 'true', 'on', '1'` and setting the NO_X to true will stop that features
installation.
- ``SANIC_NO_UVLOOP=true SANIC_NO_UJSON=true pip install sanic``
Documentation
-------------
`Documentation on Readthedocs <http://sanic.readthedocs.io/>`_.
.. |Join the chat at https://gitter.im/sanic-python/Lobby| image:: https://badges.gitter.im/sanic-python/Lobby.svg
:target: https://gitter.im/sanic-python/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
.. |Codecov| image:: https://codecov.io/gh/huge-success/sanic/branch/master/graph/badge.svg
:target: https://codecov.io/gh/huge-success/sanic
.. |Build Status| image:: https://travis-ci.org/huge-success/sanic.svg?branch=master
:target: https://travis-ci.org/huge-success/sanic
.. |AppVeyor Build Status| image:: https://ci.appveyor.com/api/projects/status/d8pt3ids0ynexi8c/branch/master?svg=true
:target: https://ci.appveyor.com/project/huge-success/sanic
.. |Documentation| image:: https://readthedocs.org/projects/sanic/badge/?version=latest
:target: http://sanic.readthedocs.io/en/latest/?badge=latest
.. |PyPI| image:: https://img.shields.io/pypi/v/sanic.svg
:target: https://pypi.python.org/pypi/sanic/
.. |PyPI version| image:: https://img.shields.io/pypi/pyversions/sanic.svg
:target: https://pypi.python.org/pypi/sanic/
.. |Code style black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black
Questions and Discussion
------------------------
`Ask a question or join the conversation <https://community.sanicframework.org/>`_.
Examples
--------
`Non-Core examples <https://github.com/huge-success/sanic/wiki/Examples/>`_. Examples of plugins and Sanic that are outside the scope of Sanic core.
`Extensions <https://github.com/huge-success/sanic/wiki/Extensions/>`_. Sanic extensions created by the community.
`Projects <https://github.com/huge-success/sanic/wiki/Projects/>`_. Sanic in production use.
Final Thoughts
--------------
::
▄▄▄▄▄
▀▀▀██████▄▄▄ _______________
▄▄▄▄▄ █████████▄ / \
▀▀▀▀█████▌ ▀▐▄ ▀▐█ | Gotta go fast! |
▀▀█████▄▄ ▀██████▄██ | _________________/
▀▄▄▄▄▄ ▀▀█▄▀█════█▀ |/
▀▀▀▄ ▀▀███ ▀ ▄▄
▄███▀▀██▄████████▄ ▄▀▀▀▀▀▀█▌
██▀▄▄▄██▀▄███▀ ▀▀████ ▄██
▄▀▀▀▄██▄▀▀▌████▒▒▒▒▒▒███ ▌▄▄▀
▌ ▐▀████▐███▒▒▒▒▒▐██▌
▀▄▄▄▄▀ ▀▀████▒▒▒▒▄██▀
▀▀█████████▀
▄▄██▀██████▀█
▄██▀ ▀▀▀ █
▄█ ▐▌
▄▄▄▄█▌ ▀█▄▄▄▄▀▀▄
▌ ▐ ▀▀▄▄▄▀
▀▀▄▄▀

28
docker/Dockerfile Normal file
View File

@@ -0,0 +1,28 @@
FROM alpine:3.7
RUN apk add --no-cache --update \
curl \
bash \
build-base \
ca-certificates \
git \
bzip2-dev \
linux-headers \
ncurses-dev \
openssl \
openssl-dev \
readline-dev \
sqlite-dev
RUN update-ca-certificates
RUN rm -rf /var/cache/apk/*
ENV PYENV_ROOT="/root/.pyenv"
ENV PATH="$PYENV_ROOT/bin:$PATH"
ADD . /app
WORKDIR /app
RUN /app/docker/bin/install_python.sh 3.5.4 3.6.4
ENTRYPOINT ["./docker/bin/entrypoint.sh"]

11
docker/bin/entrypoint.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
set -e
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
source /root/.pyenv/completions/pyenv.bash
pip install tox
exec $@

17
docker/bin/install_python.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
set -e
export CFLAGS='-O2'
export EXTRA_CFLAGS="-DTHREAD_STACK_SIZE=0x100000"
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
eval "$(pyenv init -)"
for ver in $@
do
pyenv install $ver
done
pyenv global $@
pip install --upgrade pip
pyenv rehash

225
docs/Makefile Normal file
View File

@@ -0,0 +1,225 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/aiographite.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/aiographite.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/aiographite"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/aiographite"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."

0
docs/_static/.gitkeep vendored Normal file
View File

View File

@@ -1,111 +0,0 @@
# Blueprints
Blueprints are objects that can be used for sub-routing within an application.
Instead of adding routes to the application object, blueprints define similar
methods for adding routes, which are then registered with the application in a
flexible and pluggable manner.
## Why?
Blueprints are especially useful for larger applications, where your application
logic can be broken down into several groups or areas of responsibility.
It is also useful for API versioning, where one blueprint may point at
`/v1/<routes>`, and another pointing at `/v2/<routes>`.
## My First Blueprint
The following shows a very simple blueprint that registers a handler-function at
the root `/` of your application.
Suppose you save this file as `my_blueprint.py`, this can be imported in your
main application later.
```python
from sanic.response import json
from sanic import Blueprint
bp = Blueprint('my_blueprint')
@bp.route('/')
async def bp_root(request):
return json({'my': 'blueprint'})
```
## Registering Blueprints
Blueprints must be registered with the application.
```python
from sanic import Sanic
from my_blueprint import bp
app = Sanic(__name__)
app.blueprint(bp)
app.run(host='0.0.0.0', port=8000, debug=True)
```
This will add the blueprint to the application and register any routes defined
by that blueprint.
In this example, the registered routes in the `app.router` will look like:
```python
[Route(handler=<function bp_root at 0x7f908382f9d8>, methods=None, pattern=re.compile('^/$'), parameters=[])]
```
## Middleware
Using blueprints allows you to also register middleware globally.
```python
@bp.middleware
async def halt_request(request):
print("I am a spy")
@bp.middleware('request')
async def halt_request(request):
return text('I halted the request')
@bp.middleware('response')
async def halt_response(request, response):
return text('I halted the response')
```
## Exceptions
Exceptions can also be applied exclusively to blueprints globally.
```python
@bp.exception(NotFound)
def ignore_404s(request, exception):
return text("Yep, I totally found the page: {}".format(request.url))
## Static files
Static files can also be served globally, under the blueprint prefix.
```python
bp.static('/folder/to/serve', '/web/path')
```
## Start and Stop
Blueprints and run functions during the start and stop process of the server.
If running in multiprocessor mode (more than 1 worker), these are triggered after the workers fork
Available events are:
* before_server_start - Executed before the server begins to accept connections
* after_server_start - Executed after the server begins to accept connections
* before_server_stop - Executed before the server stops accepting connections
* after_server_stop - Executed after the server is stopped and all requests are complete
```python
bp = Blueprint('my_blueprint')
@bp.listen('before_server_start')
async def setup_connection():
global database
database = mysql.connect(host='127.0.0.1'...)
@bp.listen('after_server_stop')
async def close_connection():
await database.close()
```

View File

@@ -1,45 +0,0 @@
# Class based views
Sanic has simple class based implementation. You should implement methods(get, post, put, patch, delete) for the class to every HTTP method you want to support. If someone tries to use a method that has not been implemented, there will be 405 response.
## Examples
```python
from sanic import Sanic
from sanic.views import HTTPMethodView
from sanic.response import text
app = Sanic('some_name')
class SimpleView(HTTPMethodView):
def get(self, request):
return text('I am get method')
def post(self, request):
return text('I am post method')
def put(self, request):
return text('I am put method')
def patch(self, request):
return text('I am patch method')
def delete(self, request):
return text('I am delete method')
app.add_route(SimpleView(), '/')
```
If you need any url params just mention them in method definition:
```python
class NameView(HTTPMethodView):
def get(self, request, name):
return text('Hello {}'.format(name))
app.add_route(NameView(), '/<name>')
```

154
docs/conf.py Normal file
View File

@@ -0,0 +1,154 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Sanic documentation build configuration file, created by
# sphinx-quickstart on Sun Dec 25 18:07:21 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
import os
import sys
# Add support for Markdown documentation using Recommonmark
from recommonmark.parser import CommonMarkParser
# Add support for auto-doc
from recommonmark.transform import AutoStructify
# Ensure that sanic is present in the path, to allow sphinx-apidoc to
# autogenerate documentation from docstrings
root_directory = os.path.dirname(os.getcwd())
sys.path.insert(0, root_directory)
import sanic
# -- General configuration ------------------------------------------------
extensions = ['sphinx.ext.autodoc', 'sphinxcontrib.asyncio']
templates_path = ['_templates']
# Enable support for both Restructured Text and Markdown
source_parsers = {'.md': CommonMarkParser}
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'Sanic'
copyright = '2016, Sanic contributors'
author = 'Sanic contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = sanic.__version__
# The full version, including alpha/beta/rc tags.
release = sanic.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
#
# modules.rst is generated by sphinx-apidoc but is unused. This suppresses
# a warning about it.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'modules.rst']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Sanicdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [(master_doc, 'Sanic.tex', 'Sanic Documentation',
'Sanic contributors', 'manual'), ]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, 'sanic', 'Sanic Documentation', [author], 1)]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Sanic', 'Sanic Documentation', author, 'Sanic',
'One line description of project.', 'Miscellaneous'),
]
# -- Options for Epub output ----------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Custom Settings -------------------------------------------------------
suppress_warnings = ['image.nonlocal_uri']
# app setup hook
def setup(app):
app.add_config_value('recommonmark_config', {
'enable_eval_rst': True,
'enable_auto_doc_ref': True,
}, True)
app.add_transform(AutoStructify)

View File

@@ -1,10 +0,0 @@
# How to contribute to Sanic
Thank you for your interest!
## Running tests
* `python -m pip install pytest`
* `python -m pytest tests`
## Warning
One of the main goals of Sanic is speed. Code that lowers the performance of Sanic without significant gains in usability, security, or features may not be merged.

View File

@@ -1,50 +0,0 @@
# Cookies
## Request
Request cookies can be accessed via the request.cookie dictionary
### Example
```python
from sanic import Sanic
from sanic.response import text
@app.route("/cookie")
async def test(request):
test_cookie = request.cookies.get('test')
return text("Test cookie set to: {}".format(test_cookie))
```
## Response
Response cookies can be set like dictionary values and
have the following parameters available:
* expires - datetime - Time for cookie to expire on the client's browser
* path - string - The Path attribute specifies the subset of URLs to
which this cookie applies
* comment - string - Cookie comment (metadata)
* domain - string - Specifies the domain for which the
cookie is valid. An explicitly specified domain must always
start with a dot.
* max-age - number - Number of seconds the cookie should live for
* secure - boolean - Specifies whether the cookie will only be sent via
HTTPS
* httponly - boolean - Specifies whether the cookie cannot be read
by javascript
### Example
```python
from sanic import Sanic
from sanic.response import text
@app.route("/cookie")
async def test(request):
response = text("There's a cookie up in this response")
response.cookies['test'] = 'It worked!'
response.cookies['test']['domain'] = '.gotta-go-fast.com'
response.cookies['test']['httponly'] = True
return response
```

View File

@@ -1,35 +0,0 @@
# Deploying
When it comes to deploying Sanic, there's not much to it, but there are
a few things to take note of.
## Workers
By default, Sanic listens in the main process using only 1 CPU core.
To crank up the juice, just specify the number of workers in the run
arguments like so:
```python
app.run(host='0.0.0.0', port=1337, workers=4)
```
Sanic will automatically spin up multiple processes and route
traffic between them. We recommend as many workers as you have
available cores.
## Running via Command
If you like using command line arguments, you can launch a sanic server
by executing the module. For example, if you initialized sanic as
app in a file named server.py, you could run the server like so:
`python -m sanic server.app --host=0.0.0.0 --port=1337 --workers=4`
With this way of running sanic, it is not necessary to run app.run in
your python file. If you do, just make sure you wrap it in name == main
like so:
```python
if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337, workers=4)
```

View File

@@ -1,28 +0,0 @@
# Exceptions
Exceptions can be thrown from within request handlers and will automatically be handled by Sanic. Exceptions take a message as their first argument, and can also take a status_code to be passed back in the HTTP response. Check sanic.exceptions for the full list of exceptions to throw.
## Throwing an exception
```python
from sanic import Sanic
from sanic.exceptions import ServerError
@app.route('/killme')
def i_am_ready_to_die(request):
raise ServerError("Something bad happened")
```
## Handling Exceptions
Just use the @exception decorator. The decorator expects a list of exceptions to handle as arguments. You can pass SanicException to catch them all! The exception handler must expect a request and exception object as arguments.
```python
from sanic import Sanic
from sanic.response import text
from sanic.exceptions import NotFound
@app.exception(NotFound)
def ignore_404s(request, exception):
return text("Yep, I totally found the page: {}".format(request.url))
```

View File

@@ -1,25 +0,0 @@
# Getting Started
Make sure you have pip and python 3.5 before starting
## Benchmarks
* Install Sanic
* `python3 -m pip install sanic`
* Edit main.py to include:
```python
from sanic import Sanic
from sanic.response import json
app = Sanic(__name__)
@app.route("/")
async def test(request):
return json({ "hello": "world" })
app.run(host="0.0.0.0", port=8000, debug=True)
```
* Run `python3 main.py`
You now have a working Sanic server! To continue on, check out:
* [Request Data](request_data.md)
* [Routing](routing.md)

43
docs/index.rst Normal file
View File

@@ -0,0 +1,43 @@
.. include:: sanic/index.rst
Guides
======
.. toctree::
:maxdepth: 2
sanic/getting_started
sanic/routing
sanic/request_data
sanic/response
sanic/static_files
sanic/exceptions
sanic/middleware
sanic/blueprints
sanic/websocket
sanic/config
sanic/cookies
sanic/decorators
sanic/streaming
sanic/class_based_views
sanic/custom_protocol
sanic/sockets
sanic/ssl
sanic/logging
sanic/versioning
sanic/debug_mode
sanic/testing
sanic/deploying
sanic/extensions
sanic/contributing
sanic/api_reference
Module Documentation
====================
.. toctree::
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

281
docs/make.bat Normal file
View File

@@ -0,0 +1,281 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. epub3 to make an epub3
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
echo. dummy to check syntax errors of document sources
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\aiographite.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\aiographite.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "epub3" (
%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
if "%1" == "dummy" (
%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
if errorlevel 1 exit /b 1
echo.
echo.Build finished. Dummy builder generates no files.
goto end
)
:end

View File

@@ -1,49 +0,0 @@
# Middleware
Middleware can be executed before or after requests. It is executed in the order it was registered. If middleware returns a response object, the request will stop processing and a response will be returned.
Middleware is registered via the middleware decorator, and can either be added as 'request' or 'response' middleware, based on the argument provided in the decorator. Response middleware receives both the request and the response as arguments.
## Examples
```python
app = Sanic(__name__)
@app.middleware
async def halt_request(request):
print("I am a spy")
@app.middleware('request')
async def halt_request(request):
return text('I halted the request')
@app.middleware('response')
async def halt_response(request, response):
return text('I halted the response')
@app.route('/')
async def handler(request):
return text('I would like to speak now please')
app.run(host="0.0.0.0", port=8000)
```
## Middleware chain
If you want to apply the middleware as a chain, applying more than one, is so easy. You only have to be aware that you do **not return** any response in your middleware:
```python
app = Sanic(__name__)
@app.middleware('response')
async def custom_banner(request, response):
response.headers["Server"] = "Fake-Server"
@app.middleware('response')
async def prevent_xss(request, response):
response.headers["x-xss-protection"] = "1; mode=block"
app.run(host="0.0.0.0", port=8000)
```
The above code will apply the two middlewares in order. First the middleware **custom_banner** will change the HTTP Response headers *Server* by *Fake-Server*, and the second middleware **prevent_xss** will add the HTTP Headers for prevent Cross-Site-Scripting (XSS) attacks.

View File

@@ -1,49 +0,0 @@
# Request Data
## Properties
The following request variables are accessible as properties:
`request.files` (dictionary of File objects) - List of files that have a name, body, and type
`request.json` (any) - JSON body
`request.args` (dict) - Query String variables. Use getlist to get multiple of the same name
`request.form` (dict) - Posted form variables. Use getlist to get multiple of the same name
`request.body` (bytes) - Posted raw body. To get the raw data, regardless of content type
See request.py for more information
## Examples
```python
from sanic import Sanic
from sanic.response import json, text
@app.route("/json")
def post_json(request):
return json({ "received": True, "message": request.json })
@app.route("/form")
def post_json(request):
return json({ "received": True, "form_data": request.form, "test": request.form.get('test') })
@app.route("/files")
def post_json(request):
test_file = request.files.get('test')
file_parameters = {
'body': test_file.body,
'name': test_file.name,
'type': test_file.type,
}
return json({ "received": True, "file_names": request.files.keys(), "test_file_parameters": file_parameters })
@app.route("/query_string")
def query_string(request):
return json({ "parsed": True, "args": request.args, "url": request.url, "query_string": request.query_string })
@app.route("/users", methods=["POST",])
def create_user(request):
return text("You are trying to create a user with the following POST: %s" % request.body)
```

View File

@@ -1,44 +0,0 @@
# Routing
Sanic comes with a basic router that supports request parameters. To specify a parameter, surround it with carrots like so: `<PARAM>`. Request parameters will be passed to the request handler functions as keyword arguments. To specify a type, add a :type after the parameter name, in the carrots. If the parameter does not match the type supplied, Sanic will throw a NotFound exception, resulting in a 404 page not found error.
## Examples
```python
from sanic import Sanic
from sanic.response import text
@app.route('/tag/<tag>')
async def tag_handler(request, tag):
return text('Tag - {}'.format(tag))
@app.route('/number/<integer_arg:int>')
async def integer_handler(request, integer_arg):
return text('Integer - {}'.format(integer_arg))
@app.route('/number/<number_arg:number>')
async def number_handler(request, number_arg):
return text('Number - {}'.format(number_arg))
@app.route('/person/<name:[A-z]>')
async def person_handler(request, name):
return text('Person - {}'.format(name))
@app.route('/folder/<folder_id:[A-z0-9]{0,4}>')
async def folder_handler(request, folder_id):
return text('Folder - {}'.format(folder_id))
async def handler1(request):
return text('OK')
app.add_route(handler1, '/test')
async def handler(request, name):
return text('Folder - {}'.format(name))
app.add_route(handler, '/folder/<name>')
async def person_handler(request, name):
return text('Person - {}'.format(name))
app.add_route(handler, '/person/<name:[A-z]>')
```

View File

@@ -0,0 +1,150 @@
API Reference
=============
Submodules
----------
sanic.app module
----------------
.. automodule:: sanic.app
:members:
:undoc-members:
:show-inheritance:
sanic.blueprints module
-----------------------
.. automodule:: sanic.blueprints
:members:
:undoc-members:
:show-inheritance:
sanic.config module
-------------------
.. automodule:: sanic.config
:members:
:undoc-members:
:show-inheritance:
sanic.constants module
----------------------
.. automodule:: sanic.constants
:members:
:undoc-members:
:show-inheritance:
sanic.cookies module
--------------------
.. automodule:: sanic.cookies
:members:
:undoc-members:
:show-inheritance:
sanic.exceptions module
-----------------------
.. automodule:: sanic.exceptions
:members:
:undoc-members:
:show-inheritance:
sanic.handlers module
---------------------
.. automodule:: sanic.handlers
:members:
:undoc-members:
:show-inheritance:
sanic.log module
----------------
.. automodule:: sanic.log
:members:
:undoc-members:
:show-inheritance:
sanic.request module
--------------------
.. automodule:: sanic.request
:members:
:undoc-members:
:show-inheritance:
sanic.response module
---------------------
.. automodule:: sanic.response
:members:
:undoc-members:
:show-inheritance:
sanic.router module
-------------------
.. automodule:: sanic.router
:members:
:undoc-members:
:show-inheritance:
sanic.server module
-------------------
.. automodule:: sanic.server
:members:
:undoc-members:
:show-inheritance:
sanic.static module
-------------------
.. automodule:: sanic.static
:members:
:undoc-members:
:show-inheritance:
sanic.testing module
--------------------
.. automodule:: sanic.testing
:members:
:undoc-members:
:show-inheritance:
sanic.views module
------------------
.. automodule:: sanic.views
:members:
:undoc-members:
:show-inheritance:
sanic.websocket module
----------------------
.. automodule:: sanic.websocket
:members:
:undoc-members:
:show-inheritance:
sanic.worker module
-------------------
.. automodule:: sanic.worker
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: sanic
:members:
:undoc-members:
:show-inheritance:

256
docs/sanic/blueprints.md Normal file
View File

@@ -0,0 +1,256 @@
# Blueprints
Blueprints are objects that can be used for sub-routing within an application.
Instead of adding routes to the application instance, blueprints define similar
methods for adding routes, which are then registered with the application in a
flexible and pluggable manner.
Blueprints are especially useful for larger applications, where your
application logic can be broken down into several groups or areas of
responsibility.
## My First Blueprint
The following shows a very simple blueprint that registers a handler-function at
the root `/` of your application.
Suppose you save this file as `my_blueprint.py`, which can be imported into your
main application later.
```python
from sanic.response import json
from sanic import Blueprint
bp = Blueprint('my_blueprint')
@bp.route('/')
async def bp_root(request):
return json({'my': 'blueprint'})
```
## Registering blueprints
Blueprints must be registered with the application.
```python
from sanic import Sanic
from my_blueprint import bp
app = Sanic(__name__)
app.blueprint(bp)
app.run(host='0.0.0.0', port=8000, debug=True)
```
This will add the blueprint to the application and register any routes defined
by that blueprint. In this example, the registered routes in the `app.router`
will look like:
```python
[Route(handler=<function bp_root at 0x7f908382f9d8>, methods=frozenset({'GET'}), pattern=re.compile('^/$'), parameters=[], name='my_blueprint.bp_root', uri='/')]
```
## Blueprint groups and nesting
Blueprints may also be registered as part of a list or tuple, where the registrar will recursively cycle through any sub-sequences of blueprints and register them accordingly. The `Blueprint.group` method is provided to simplify this process, allowing a 'mock' backend directory structure mimicking what's seen from the front end. Consider this (quite contrived) example:
```
api/
├──content/
│ ├──authors.py
│ ├──static.py
│ └──__init__.py
├──info.py
└──__init__.py
app.py
```
Initialization of this app's blueprint hierarchy could go as follows:
```python
# api/content/authors.py
from sanic import Blueprint
authors = Blueprint('content_authors', url_prefix='/authors')
```
```python
# api/content/static.py
from sanic import Blueprint
static = Blueprint('content_static', url_prefix='/static')
```
```python
# api/content/__init__.py
from sanic import Blueprint
from .static import static
from .authors import authors
content = Blueprint.group(static, authors, url_prefix='/content')
```
```python
# api/info.py
from sanic import Blueprint
info = Blueprint('info', url_prefix='/info')
```
```python
# api/__init__.py
from sanic import Blueprint
from .content import content
from .info import info
api = Blueprint.group(content, info, url_prefix='/api')
```
And registering these blueprints in `app.py` can now be done like so:
```python
# app.py
from sanic import Sanic
from .api import api
app = Sanic(__name__)
app.blueprint(api)
```
## Using blueprints
Blueprints have much the same functionality as an application instance.
### WebSocket routes
WebSocket handlers can be registered on a blueprint using the `@bp.websocket`
decorator or `bp.add_websocket_route` method.
### Middleware
Using blueprints allows you to also register middleware globally.
```python
@bp.middleware
async def print_on_request(request):
print("I am a spy")
@bp.middleware('request')
async def halt_request(request):
return text('I halted the request')
@bp.middleware('response')
async def halt_response(request, response):
return text('I halted the response')
```
### Exceptions
Exceptions can be applied exclusively to blueprints globally.
```python
@bp.exception(NotFound)
def ignore_404s(request, exception):
return text("Yep, I totally found the page: {}".format(request.url))
```
### Static files
Static files can be served globally, under the blueprint prefix.
```python
# suppose bp.name == 'bp'
bp.static('/web/path', '/folder/to/serve')
# also you can pass name parameter to it for url_for
bp.static('/web/path', '/folder/to/server', name='uploads')
app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/web/path/file.txt'
```
## Start and stop
Blueprints can run functions during the start and stop process of the server.
If running in multiprocessor mode (more than 1 worker), these are triggered
after the workers fork.
Available events are:
- `before_server_start`: Executed before the server begins to accept connections
- `after_server_start`: Executed after the server begins to accept connections
- `before_server_stop`: Executed before the server stops accepting connections
- `after_server_stop`: Executed after the server is stopped and all requests are complete
```python
bp = Blueprint('my_blueprint')
@bp.listener('before_server_start')
async def setup_connection(app, loop):
global database
database = mysql.connect(host='127.0.0.1'...)
@bp.listener('after_server_stop')
async def close_connection(app, loop):
await database.close()
```
## Use-case: API versioning
Blueprints can be very useful for API versioning, where one blueprint may point
at `/v1/<routes>`, and another pointing at `/v2/<routes>`.
When a blueprint is initialised, it can take an optional `url_prefix` argument,
which will be prepended to all routes defined on the blueprint. This feature
can be used to implement our API versioning scheme.
```python
# blueprints.py
from sanic.response import text
from sanic import Blueprint
blueprint_v1 = Blueprint('v1', url_prefix='/v1')
blueprint_v2 = Blueprint('v2', url_prefix='/v2')
@blueprint_v1.route('/')
async def api_v1_root(request):
return text('Welcome to version 1 of our documentation')
@blueprint_v2.route('/')
async def api_v2_root(request):
return text('Welcome to version 2 of our documentation')
```
When we register our blueprints on the app, the routes `/v1` and `/v2` will now
point to the individual blueprints, which allows the creation of *sub-sites*
for each API version.
```python
# main.py
from sanic import Sanic
from blueprints import blueprint_v1, blueprint_v2
app = Sanic(__name__)
app.blueprint(blueprint_v1, url_prefix='/v1')
app.blueprint(blueprint_v2, url_prefix='/v2')
app.run(host='0.0.0.0', port=8000, debug=True)
```
## URL Building with `url_for`
If you wish to generate a URL for a route inside of a blueprint, remember that the endpoint name
takes the format `<blueprint_name>.<handler_name>`. For example:
```python
@blueprint_v1.route('/')
async def root(request):
url = request.app.url_for('v1.post_handler', post_id=5) # --> '/v1/post/5'
return redirect(url)
@blueprint_v1.route('/post/<post_id>')
async def post_handler(request, post_id):
return text('Post {} in Blueprint V1'.format(post_id))
```

View File

@@ -0,0 +1,166 @@
# Class-Based Views
Class-based views are simply classes which implement response behaviour to
requests. They provide a way to compartmentalise handling of different HTTP
request types at the same endpoint. Rather than defining and decorating three
different handler functions, one for each of an endpoint's supported request
type, the endpoint can be assigned a class-based view.
## Defining views
A class-based view should subclass `HTTPMethodView`. You can then implement
class methods for every HTTP request type you want to support. If a request is
received that has no defined method, a `405: Method not allowed` response will
be generated.
To register a class-based view on an endpoint, the `app.add_route` method is
used. The first argument should be the defined class with the method `as_view`
invoked, and the second should be the URL endpoint.
The available methods are `get`, `post`, `put`, `patch`, and `delete`. A class
using all these methods would look like the following.
```python
from sanic import Sanic
from sanic.views import HTTPMethodView
from sanic.response import text
app = Sanic('some_name')
class SimpleView(HTTPMethodView):
def get(self, request):
return text('I am get method')
def post(self, request):
return text('I am post method')
def put(self, request):
return text('I am put method')
def patch(self, request):
return text('I am patch method')
def delete(self, request):
return text('I am delete method')
app.add_route(SimpleView.as_view(), '/')
```
You can also use `async` syntax.
```python
from sanic import Sanic
from sanic.views import HTTPMethodView
from sanic.response import text
app = Sanic('some_name')
class SimpleAsyncView(HTTPMethodView):
async def get(self, request):
return text('I am async get method')
app.add_route(SimpleAsyncView.as_view(), '/')
```
## URL parameters
If you need any URL parameters, as discussed in the routing guide, include them
in the method definition.
```python
class NameView(HTTPMethodView):
def get(self, request, name):
return text('Hello {}'.format(name))
app.add_route(NameView.as_view(), '/<name>')
```
## Decorators
If you want to add any decorators to the class, you can set the `decorators`
class variable. These will be applied to the class when `as_view` is called.
```python
class ViewWithDecorator(HTTPMethodView):
decorators = [some_decorator_here]
def get(self, request, name):
return text('Hello I have a decorator')
def post(self, request, name):
return text("Hello I also have a decorator")
app.add_route(ViewWithDecorator.as_view(), '/url')
```
But if you just want to decorate some functions and not all functions, you can do as follows:
```python
class ViewWithSomeDecorator(HTTPMethodView):
@staticmethod
@some_decorator_here
def get(request, name):
return text("Hello I have a decorator")
def post(self, request, name):
return text("Hello I don't have any decorators")
```
## URL Building
If you wish to build a URL for an HTTPMethodView, remember that the class name will be the endpoint
that you will pass into `url_for`. For example:
```python
@app.route('/')
def index(request):
url = app.url_for('SpecialClassView')
return redirect(url)
class SpecialClassView(HTTPMethodView):
def get(self, request):
return text('Hello from the Special Class View!')
app.add_route(SpecialClassView.as_view(), '/special_class_view')
```
## Using CompositionView
As an alternative to the `HTTPMethodView`, you can use `CompositionView` to
move handler functions outside of the view class.
Handler functions for each supported HTTP method are defined elsewhere in the
source, and then added to the view using the `CompositionView.add` method. The
first parameter is a list of HTTP methods to handle (e.g. `['GET', 'POST']`),
and the second is the handler function. The following example shows
`CompositionView` usage with both an external handler function and an inline
lambda:
```python
from sanic import Sanic
from sanic.views import CompositionView
from sanic.response import text
app = Sanic(__name__)
def get_handler(request):
return text('I am a get method')
view = CompositionView()
view.add(['GET'], get_handler)
view.add(['POST', 'PUT'], lambda request: text('I am a post/put method'))
# Use the new view to handle requests to the base URL
app.add_route(view, '/')
```
Note: currently you cannot build a URL for a CompositionView using `url_for`.

121
docs/sanic/config.md Normal file
View File

@@ -0,0 +1,121 @@
# 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.
## 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:
```
app = Sanic('myapp')
app.config.DB_NAME = 'appdb'
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:
```
db_settings = {
'DB_HOST': 'localhost',
'DB_NAME': 'appdb',
'DB_USER': 'appuser'
}
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.
## Loading Configuration
There are several ways how to load configuration.
### 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:
```python
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:
```python
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:
```
import myapp.default_settings
app = Sanic('myapp')
app.config.from_object(myapp.default_settings)
```
You could use a class or any other object as well.
### 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:
```
app = Sanic('myapp')
app.config.from_envvar('MYAPP_SETTINGS')
```
Then you can run your application with the `MYAPP_SETTINGS` environment variable set:
```
$ 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:
```
# config_file
DB_HOST = 'localhost'
DB_NAME = 'appdb'
DB_USER = 'appuser'
```
## Builtin Configuration Values
Out of the box there are just a few predefined values which can be overwritten when creating the application.
| Variable | Default | Description |
| ------------------------- | --------- | ------------------------------------------------------ |
| REQUEST_MAX_SIZE | 100000000 | How big a request may be (bytes) |
| REQUEST_TIMEOUT | 60 | How long a request can take to arrive (sec) |
| RESPONSE_TIMEOUT | 60 | How long a response can take to process (sec) |
| KEEP_ALIVE | True | Disables keep-alive when False |
| 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) |
| ACCESS_LOG | True | Disable or enable access log |
### 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.
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.
### What is Keep Alive? And what does the Keep Alive Timeout value do?
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.
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:
```
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
```

View File

@@ -0,0 +1,62 @@
# Contributing
Thank you for your interest! Sanic is always looking for contributors. If you
don't feel comfortable contributing code, adding docstrings to the source files
is very appreciated.
## Installation
To develop on sanic (and mainly to just run the tests) it is highly recommend to
install from sources.
So assume you have already cloned the repo and are in the working directory with
a virtual environment already set up, then run:
```bash
python setup.py develop && pip install -r requirements-dev.txt
```
## Running tests
To run the tests for sanic it is recommended to use tox like so:
```bash
tox
```
See it's that simple!
## Pull requests!
So the pull request approval rules are pretty simple:
* All pull requests must pass unit tests
* All pull requests must be reviewed and approved by at least
one current collaborator on the project
* All pull requests must pass flake8 checks
* If you decide to remove/change anything from any common interface
a deprecation message should accompany it.
* If you implement a new feature you should have at least one unit
test to accompany it.
## Documentation
Sanic's documentation is built
using [sphinx](http://www.sphinx-doc.org/en/1.5.1/). Guides are written in
Markdown and can be found in the `docs` folder, while the module reference is
automatically generated using `sphinx-apidoc`.
To generate the documentation from scratch:
```bash
sphinx-apidoc -fo docs/_api/ sanic
sphinx-build -b html docs docs/_build
```
The HTML documentation will be created in the `docs/_build` folder.
## Warning
One of the main goals of Sanic is speed. Code that lowers the performance of
Sanic without significant gains in usability, security, or features may not be
merged. Please don't let this intimidate you! If you have any concerns about an
idea, open an issue for discussion and help.

87
docs/sanic/cookies.rst Normal file
View File

@@ -0,0 +1,87 @@
Cookies
=======
Cookies are pieces of data which persist inside a user's browser. Sanic can
both read and write cookies, which are stored as key-value pairs.
.. warning::
Cookies can be freely altered by the client. Therefore you cannot just store
data such as login information in cookies as-is, as they can be freely altered
by the client. To ensure data you store in cookies is not forged or tampered
with by the client, use something like `itsdangerous`_ to cryptographically
sign the data.
Reading cookies
---------------
A user's cookies can be accessed via the ``Request`` object's ``cookies`` dictionary.
.. code-block:: python
from sanic.response import text
@app.route("/cookie")
async def test(request):
test_cookie = request.cookies.get('test')
return text("Test cookie set to: {}".format(test_cookie))
Writing cookies
---------------
When returning a response, cookies can be set on the ``Response`` object.
.. code-block:: python
from sanic.response import text
@app.route("/cookie")
async def test(request):
response = text("There's a cookie up in this response")
response.cookies['test'] = 'It worked!'
response.cookies['test']['domain'] = '.gotta-go-fast.com'
response.cookies['test']['httponly'] = True
return response
Deleting cookies
----------------
Cookies can be removed semantically or explicitly.
.. code-block:: python
from sanic.response import text
@app.route("/cookie")
async def test(request):
response = text("Time to eat some cookies muahaha")
# This cookie will be set to expire in 0 seconds
del response.cookies['kill_me']
# This cookie will self destruct in 5 seconds
response.cookies['short_life'] = 'Glad to be here'
response.cookies['short_life']['max-age'] = 5
del response.cookies['favorite_color']
# This cookie will remain unchanged
response.cookies['favorite_color'] = 'blue'
response.cookies['favorite_color'] = 'pink'
del response.cookies['favorite_color']
return response
Response cookies can be set like dictionary values and have the following
parameters available:
- ``expires`` (datetime): The time for the cookie to expire on the client's browser.
- ``path`` (string): The subset of URLs to which this cookie applies. Defaults to /.
- ``comment`` (string): A comment (metadata).
- ``domain`` (string): Specifies the domain for which the cookie is valid. An
explicitly specified domain must always start with a dot.
- ``max-age`` (number): Number of seconds the cookie should live for.
- ``secure`` (boolean): Specifies whether the cookie will only be sent via HTTPS.
- ``httponly`` (boolean): Specifies whether the cookie cannot be read by Javascript.
.. _itsdangerous: https://pythonhosted.org/itsdangerous/

View File

@@ -0,0 +1,72 @@
# 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)
```

53
docs/sanic/debug_mode.rst Normal file
View File

@@ -0,0 +1,53 @@
Debug Mode
=============
When enabling Sanic's debug mode, Sanic will provide a more verbose logging output
and by default will enable the Auto Reload feature.
.. warning::
Sanic's debug more will slow down the server's performance
and is therefore advised to enable it only in development environments.
Setting the debug mode
----------------------
By setting the ``debug`` mode a more verbose output from Sanic will be outputed
and the Automatic Reloader will be activated.
.. code-block:: python
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route('/')
async def hello_world(request):
return json({"hello": "world"})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, debug=True)
Manually setting auto reload
----------------------------
Sanic offers a way to enable or disable the Automatic Reloader manually,
the ``auto_reload`` argument will activate or deactivate the Automatic Reloader.
.. code-block:: python
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route('/')
async def hello_world(request):
return json({"hello": "world"})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, auto_reload=True)

39
docs/sanic/decorators.md Normal file
View File

@@ -0,0 +1,39 @@
# Handler Decorators
Since Sanic handlers are simple Python functions, you can apply decorators to them in a similar manner to Flask. A typical use case is when you want some code to run before a handler's code is executed.
## Authorization Decorator
Let's say you want to check that a user is authorized to access a particular endpoint. You can create a decorator that wraps a handler function, checks a request if the client is authorized to access a resource, and sends the appropriate response.
```python
from functools import wraps
from sanic.response import json
def authorized():
def decorator(f):
@wraps(f)
async def decorated_function(request, *args, **kwargs):
# run some method that checks the request
# for the client's authorization status
is_authorized = check_request_for_authorization_status(request)
if is_authorized:
# the user is authorized.
# run the handler method and return the response
response = await f(request, *args, **kwargs)
return response
else:
# the user is not authorized.
return json({'status': 'not_authorized'}, 403)
return decorated_function
return decorator
@app.route("/")
@authorized()
async def test(request):
return json({'status': 'authorized'})
```

78
docs/sanic/deploying.md Normal file
View File

@@ -0,0 +1,78 @@
# Deploying
Deploying Sanic is made simple by the inbuilt webserver. After defining an
instance of `sanic.Sanic`, we can call the `run` method with the following
keyword arguments:
- `host` *(default `"127.0.0.1"`)*: Address to host the server on.
- `port` *(default `8000`)*: Port to host the server on.
- `debug` *(default `False`)*: Enables debug output (slows server).
- `ssl` *(default `None`)*: `SSLContext` for SSL encryption of worker(s).
- `sock` *(default `None`)*: Socket for the server to accept connections from.
- `workers` *(default `1`)*: Number of worker processes to spawn.
- `loop` *(default `None`)*: An `asyncio`-compatible event loop. If none is
specified, Sanic creates its own event loop.
- `protocol` *(default `HttpProtocol`)*: Subclass
of
[asyncio.protocol](https://docs.python.org/3/library/asyncio-protocol.html#protocol-classes).
## Workers
By default, Sanic listens in the main process using only one CPU core. To crank
up the juice, just specify the number of workers in the `run` arguments.
```python
app.run(host='0.0.0.0', port=1337, workers=4)
```
Sanic will automatically spin up multiple processes and route traffic between
them. We recommend as many workers as you have available cores.
## Running via command
If you like using command line arguments, you can launch a Sanic server by
executing the module. For example, if you initialized Sanic as `app` in a file
named `server.py`, you could run the server like so:
`python -m sanic server.app --host=0.0.0.0 --port=1337 --workers=4`
With this way of running sanic, it is not necessary to invoke `app.run` in your
Python file. If you do, make sure you wrap it so that it only executes when
directly run by the interpreter.
```python
if __name__ == '__main__':
app.run(host='0.0.0.0', port=1337, workers=4)
```
## Running via Gunicorn
[Gunicorn](http://gunicorn.org/) Green Unicorn is a WSGI HTTP Server for UNIX.
Its a pre-fork worker model ported from Rubys Unicorn project.
In order to run Sanic application with Gunicorn, you need to use the special `sanic.worker.GunicornWorker`
for Gunicorn `worker-class` argument:
```
gunicorn myapp:app --bind 0.0.0.0:1337 --worker-class sanic.worker.GunicornWorker
```
If your application suffers from memory leaks, you can configure Gunicorn to gracefully restart a worker
after it has processed a given number of requests. This can be a convenient way to help limit the effects
of the memory leak.
See the [Gunicorn Docs](http://docs.gunicorn.org/en/latest/settings.html#max-requests) for more information.
## Asynchronous support
This is suitable if you *need* to share the sanic process with other applications, in particular the `loop`.
However be advised that this method does not support using multiple processes, and is not the preferred way
to run the app in general.
Here is an incomplete example (please see `run_async.py` in examples for something more practical):
```python
server = app.create_server(host="0.0.0.0", port=8000)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(server)
loop.run_forever()
```

88
docs/sanic/exceptions.md Normal file
View File

@@ -0,0 +1,88 @@
# Exceptions
Exceptions can be thrown from within request handlers and will automatically be
handled by Sanic. Exceptions take a message as their first argument, and can
also take a status code to be passed back in the HTTP response.
## Throwing an exception
To throw an exception, simply `raise` the relevant exception from the
`sanic.exceptions` module.
```python
from sanic.exceptions import ServerError
@app.route('/killme')
async def i_am_ready_to_die(request):
raise ServerError("Something bad happened", status_code=500)
```
You can also use the `abort` function with the appropriate status code:
```python
from sanic.exceptions import abort
from sanic.response import text
@app.route('/youshallnotpass')
async def no_no(request):
abort(401)
# this won't happen
text("OK")
```
## Handling exceptions
To override Sanic's default handling of an exception, the `@app.exception`
decorator is used. The decorator expects a list of exceptions to handle as
arguments. You can pass `SanicException` to catch them all! The decorated
exception handler function must take a `Request` and `Exception` object as
arguments.
```python
from sanic.response import text
from sanic.exceptions import NotFound
@app.exception(NotFound)
async def ignore_404s(request, exception):
return text("Yep, I totally found the page: {}".format(request.url))
```
You can also add an exception handler as such:
```python
from sanic import Sanic
async def server_error_handler(request, exception):
return text("Oops, server error", status=500)
app = Sanic()
app.error_handler.add(Exception, server_error_handler)
```
In some cases, you might want want to add some more error handling
functionality to what is provided by default. In that case, you
can subclass Sanic's default error handler as such:
```python
from sanic import Sanic
from sanic.handlers import ErrorHandler
class CustomErrorHandler(ErrorHandler):
def default(self, request, exception):
''' handles errors that have no error handlers assigned '''
# You custom error handling logic...
return super().default(request, exception)
app = Sanic()
app.error_handler = CustomErrorHandler()
```
## Useful exceptions
Some of the most useful exceptions are presented below:
- `NotFound`: called when a suitable route for the request isn't found.
- `ServerError`: called when something goes wrong inside the server. This
usually occurs if there is an exception raised in user code.
See the `sanic.exceptions` module for the full list of exceptions to throw.

36
docs/sanic/extensions.md Normal file
View File

@@ -0,0 +1,36 @@
# Extensions
A list of Sanic extensions created by the community.
- [Sanic-Plugins-Framework](https://github.com/ashleysommer/sanicpluginsframework): Library for easily creating and using Sanic plugins.
- [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.
- [Compress](https://github.com/subyraman/sanic_compress): Allows you to easily gzip Sanic responses. A port of Flask-Compress.
- [Jinja2](https://github.com/lixxu/sanic-jinja2): Support for Jinja2 template.
- [Sanic JWT](https://github.com/ahopkins/sanic-jwt): Authentication, JWT, and permission scoping for Sanic.
- [Sanic-JWT-Extended](https://github.com/devArtoria/Sanic-JWT-Extended): Provides extended JWT support for Sanic
- [OpenAPI/Swagger](https://github.com/channelcat/sanic-openapi): OpenAPI support, plus a Swagger UI.
- [Pagination](https://github.com/lixxu/python-paginate): Simple pagination support.
- [Motor](https://github.com/lixxu/sanic-motor): Simple motor wrapper.
- [Sanic CRUD](https://github.com/Typhon66/sanic_crud): CRUD REST API generation with peewee models.
- [UserAgent](https://github.com/lixxu/sanic-useragent): Add `user_agent` to request
- [Limiter](https://github.com/bohea/sanic-limiter): Rate limiting for sanic.
- [Sanic EnvConfig](https://github.com/jamesstidard/sanic-envconfig): Pull environment variables into your sanic config.
- [Babel](https://github.com/lixxu/sanic-babel): Adds i18n/l10n support to Sanic applications with the help of the
`Babel` library
- [Dispatch](https://github.com/ashleysommer/sanic-dispatcher): A dispatcher inspired by `DispatcherMiddleware` in werkzeug. Can act as a Sanic-to-WSGI adapter.
- [Sanic-OAuth](https://github.com/Sniedes722/Sanic-OAuth): OAuth Library for connecting to & creating your own token providers.
- [sanic-oauth](https://gitlab.com/SirEdvin/sanic-oauth): OAuth Library with many provider and OAuth1/OAuth2 support.
- [Sanic-nginx-docker-example](https://github.com/itielshwartz/sanic-nginx-docker-example): Simple and easy to use example of Sanic behined nginx using docker-compose.
- [sanic-graphql](https://github.com/graphql-python/sanic-graphql): GraphQL integration with Sanic
- [sanic-prometheus](https://github.com/dkruchinin/sanic-prometheus): Prometheus metrics for Sanic
- [Sanic-RestPlus](https://github.com/ashleysommer/sanic-restplus): A port of Flask-RestPlus for Sanic. Full-featured REST API with SwaggerUI generation.
- [sanic-transmute](https://github.com/yunstanford/sanic-transmute): A Sanic extension that generates APIs from python function and classes, and also generates Swagger UI/documentation automatically.
- [pytest-sanic](https://github.com/yunstanford/pytest-sanic): A pytest plugin for Sanic. It helps you to test your code asynchronously.
- [jinja2-sanic](https://github.com/yunstanford/jinja2-sanic): a jinja2 template renderer for Sanic.([Documentation](http://jinja2-sanic.readthedocs.io/en/latest/))
- [GINO](https://github.com/fantix/gino): An asyncio ORM on top of SQLAlchemy core, delivered with a Sanic extension. ([Documentation](https://python-gino.readthedocs.io/))
- [Sanic-Auth](https://github.com/pyx/sanic-auth): A minimal backend agnostic session-based user authentication mechanism for Sanic.
- [Sanic-CookieSession](https://github.com/pyx/sanic-cookiesession): A client-side only, cookie-based session, similar to the built-in session in Flask.
- [Sanic-WTF](https://github.com/pyx/sanic-wtf): Sanic-WTF makes using WTForms with Sanic and CSRF (Cross-Site Request Forgery) protection a little bit easier.
- [sanic-script](https://github.com/tim2anna/sanic-script): An extension for Sanic that adds support for writing commands to your application.
- [sanic-sse](https://github.com/inn0kenty/sanic_sse): [Server-Sent Events](https://en.wikipedia.org/wiki/Server-sent_events) implementation for Sanic.

View File

@@ -0,0 +1,40 @@
# Getting Started
Make sure you have both [pip](https://pip.pypa.io/en/stable/installing/) and at
least version 3.5 of Python before starting. Sanic uses the new `async`/`await`
syntax, so earlier versions of python won't work.
## 1. Install Sanic
```
python3 -m pip install sanic
```
## 2. Create a file called `main.py`
```python
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
```
## 3. Run the server
```
python3 main.py
```
## 4. Check your browser
Open the address `http://0.0.0.0:8000` in your web browser. You should see
the message *Hello world!*.
You now have a working Sanic server!

25
docs/sanic/index.rst Normal file
View File

@@ -0,0 +1,25 @@
Sanic
=================================
Sanic is a Flask-like Python 3.5+ web server that's written to go fast. It's based on the work done by the amazing folks at magicstack, and was inspired by `this article <https://magic.io/blog/uvloop-blazing-fast-python-networking/>`_.
On top of being Flask-like, Sanic supports async request handlers. This means you can use the new shiny async/await syntax from Python 3.5, making your code non-blocking and speedy.
Sanic is developed `on GitHub <https://github.com/channelcat/sanic/>`_. Contributions are welcome!
Sanic aspires to be simple
---------------------------
.. code:: python
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)

100
docs/sanic/logging.md Normal file
View File

@@ -0,0 +1,100 @@
# 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
```

147
docs/sanic/middleware.md Normal file
View File

@@ -0,0 +1,147 @@
# Middleware And Listeners
Middleware are functions which are executed before or after requests to the
server. They can be used to modify the *request to* or *response from*
user-defined handler functions.
Additionally, Sanic provides listeners which allow you to run code at various points of your application's lifecycle.
## Middleware
There are two types of middleware: request and response. Both are declared
using the `@app.middleware` decorator, with the decorator's parameter being a
string representing its type: `'request'` or `'response'`.
* Request middleware receives only the `request` as argument.
* Response middleware receives both the `request` and `response`.
The simplest middleware doesn't modify the request or response at all:
```
@app.middleware('request')
async def print_on_request(request):
print("I print when a request is received by the server")
@app.middleware('response')
async def print_on_response(request, response):
print("I print when a response is returned by the server")
```
## Modifying the request or response
Middleware can modify the request or response parameter it is given, *as long
as it does not return it*. The following example shows a practical use-case for
this.
```
app = Sanic(__name__)
@app.middleware('response')
async def custom_banner(request, response):
response.headers["Server"] = "Fake-Server"
@app.middleware('response')
async def prevent_xss(request, response):
response.headers["x-xss-protection"] = "1; mode=block"
app.run(host="0.0.0.0", port=8000)
```
The above code will apply the two middleware in order. First, the middleware
**custom_banner** will change the HTTP response header *Server* to
*Fake-Server*, and the second middleware **prevent_xss** will add the HTTP
header for preventing Cross-Site-Scripting (XSS) attacks. These two functions
are invoked *after* a user function returns a response.
## Responding early
If middleware returns a `HTTPResponse` object, the request will stop processing
and the response will be returned. If this occurs to a request before the
relevant user route handler is reached, the handler will never be called.
Returning a response will also prevent any further middleware from running.
```
@app.middleware('request')
async def halt_request(request):
return text('I halted the request')
@app.middleware('response')
async def halt_response(request, response):
return text('I halted the response')
```
## Listeners
If you want to execute startup/teardown code as your server starts or closes, you can use the following listeners:
- `before_server_start`
- `after_server_start`
- `before_server_stop`
- `after_server_stop`
These listeners are implemented as decorators on functions which accept the app object as well as the asyncio loop.
For example:
```
@app.listener('before_server_start')
async def setup_db(app, loop):
app.db = await db_setup()
@app.listener('after_server_start')
async def notify_server_started(app, loop):
print('Server successfully started!')
@app.listener('before_server_stop')
async def notify_server_stopping(app, loop):
print('Server shutting down!')
@app.listener('after_server_stop')
async def close_db(app, loop):
await app.db.close()
```
It's also possible to register a listener using the `register_listener` method.
This may be useful if you define your listeners in another module besides
the one you instantiate your app in.
```
app = Sanic()
async def setup_db(app, loop):
app.db = await db_setup()
app.register_listener(setup_db, 'before_server_start')
```
If you want to schedule a background task to run after the loop has started,
Sanic provides the `add_task` method to easily do so.
```
async def notify_server_started_after_five_seconds():
await asyncio.sleep(5)
print('Server successfully started!')
app.add_task(notify_server_started_after_five_seconds())
```
Sanic will attempt to automatically inject the app, passing it as an argument to the task:
```
async def notify_server_started_after_five_seconds(app):
await asyncio.sleep(5)
print(app.name)
app.add_task(notify_server_started_after_five_seconds)
```
Or you can pass the app explicitly for the same effect:
```
async def notify_server_started_after_five_seconds(app):
await asyncio.sleep(5)
print(app.name)
app.add_task(notify_server_started_after_five_seconds(app))
`

128
docs/sanic/request_data.md Normal file
View File

@@ -0,0 +1,128 @@
# Request Data
When an endpoint receives a HTTP request, the route function is passed a
`Request` object.
The following variables are accessible as properties on `Request` objects:
- `json` (any) - JSON body
```python
from sanic.response import json
@app.route("/json")
def post_json(request):
return json({ "received": True, "message": request.json })
```
- `args` (dict) - Query string variables. A query string is the section of a
URL that resembles `?key1=value1&key2=value2`. If that URL were to be parsed,
the `args` dictionary would look like `{'key1': ['value1'], 'key2': ['value2']}`.
The request's `query_string` variable holds the unparsed string value.
```python
from sanic.response import json
@app.route("/query_string")
def query_string(request):
return json({ "parsed": True, "args": request.args, "url": request.url, "query_string": request.query_string })
```
- `raw_args` (dict) - On many cases you would need to access the url arguments in
a less packed dictionary. For same previous URL `?key1=value1&key2=value2`, the
`raw_args` dictionary would look like `{'key1': 'value1', 'key2': 'value2'}`.
- `files` (dictionary of `File` objects) - List of files that have a name, body, and type
```python
from sanic.response import json
@app.route("/files")
def post_json(request):
test_file = request.files.get('test')
file_parameters = {
'body': test_file.body,
'name': test_file.name,
'type': test_file.type,
}
return json({ "received": True, "file_names": request.files.keys(), "test_file_parameters": file_parameters })
```
- `form` (dict) - Posted form variables.
```python
from sanic.response import json
@app.route("/form")
def post_json(request):
return json({ "received": True, "form_data": request.form, "test": request.form.get('test') })
```
- `body` (bytes) - Posted raw body. This property allows retrieval of the
request's raw data, regardless of content type.
```python
from sanic.response import text
@app.route("/users", methods=["POST",])
def create_user(request):
return text("You are trying to create a user with the following POST: %s" % request.body)
```
- `headers` (dict) - A case-insensitive dictionary that contains the request headers.
- `method` (str) - HTTP method of the request (ie `GET`, `POST`).
- `ip` (str) - IP address of the requester.
- `port` (str) - Port address of the requester.
- `socket` (tuple) - (IP, port) of the requester.
- `app` - a reference to the Sanic application object that is handling this request. This is useful when inside blueprints or other handlers in modules that do not have access to the global `app` object.
```python
from sanic.response import json
from sanic import Blueprint
bp = Blueprint('my_blueprint')
@bp.route('/')
async def bp_root(request):
if request.app.config['DEBUG']:
return json({'status': 'debug'})
else:
return json({'status': 'production'})
```
- `url`: The full URL of the request, ie: `http://localhost:8000/posts/1/?foo=bar`
- `scheme`: The URL scheme associated with the request: `http` or `https`
- `host`: The host associated with the request: `localhost:8080`
- `path`: The path of the request: `/posts/1/`
- `query_string`: The query string of the request: `foo=bar` or a blank string `''`
- `uri_template`: Template for matching route handler: `/posts/<id>/`
- `token`: The value of Authorization header: `Basic YWRtaW46YWRtaW4=`
## Accessing values using `get` and `getlist`
The request properties which return a dictionary actually return a subclass of
`dict` called `RequestParameters`. The key difference when using this object is
the distinction between the `get` and `getlist` methods.
- `get(key, default=None)` operates as normal, except that when the value of
the given key is a list, *only the first item is returned*.
- `getlist(key, default=None)` operates as normal, *returning the entire list*.
```python
from sanic.request import RequestParameters
args = RequestParameters()
args['titles'] = ['Post 1', 'Post 2']
args.get('titles') # => 'Post 1'
args.getlist('titles') # => ['Post 1', 'Post 2']
```

112
docs/sanic/response.md Normal file
View File

@@ -0,0 +1,112 @@
# Response
Use functions in `sanic.response` module to create responses.
## Plain Text
```python
from sanic import response
@app.route('/text')
def handle_request(request):
return response.text('Hello world!')
```
## HTML
```python
from sanic import response
@app.route('/html')
def handle_request(request):
return response.html('<p>Hello world!</p>')
```
## JSON
```python
from sanic import response
@app.route('/json')
def handle_request(request):
return response.json({'message': 'Hello world!'})
```
## File
```python
from sanic import response
@app.route('/file')
async def handle_request(request):
return await response.file('/srv/www/whatever.png')
```
## Streaming
```python
from sanic import response
@app.route("/streaming")
async def index(request):
async def streaming_fn(response):
response.write('foo')
response.write('bar')
return response.stream(streaming_fn, content_type='text/plain')
```
## File Streaming
For large files, a combination of File and Streaming above
```python
from sanic import response
@app.route('/big_file.png')
async def handle_request(request):
return await response.file_stream('/srv/www/whatever.png')
```
## Redirect
```python
from sanic import response
@app.route('/redirect')
def handle_request(request):
return response.redirect('/json')
```
## Raw
Response without encoding the body
```python
from sanic import response
@app.route('/raw')
def handle_request(request):
return response.raw(b'raw data')
```
## Modify headers or status
To modify headers or status code, pass the `headers` or `status` argument to those functions:
```python
from sanic import response
@app.route('/json')
def handle_request(request):
return response.json(
{'message': 'Hello world!'},
headers={'X-Served-By': 'sanic'},
status=200
)
```

335
docs/sanic/routing.md Normal file
View File

@@ -0,0 +1,335 @@
# Routing
Routing allows the user to specify handler functions for different URL endpoints.
A basic route looks like the following, where `app` is an instance of the
`Sanic` class:
```python
from sanic.response import json
@app.route("/")
async def test(request):
return json({ "hello": "world" })
```
When the url `http://server.url/` is accessed (the base url of the server), the
final `/` is matched by the router to the handler function, `test`, which then
returns a JSON object.
Sanic handler functions must be defined using the `async def` syntax, as they
are asynchronous functions.
## Request parameters
Sanic comes with a basic router that supports request parameters.
To specify a parameter, surround it with angle quotes like so: `<PARAM>`.
Request parameters will be passed to the route handler functions as keyword
arguments.
```python
from sanic.response import text
@app.route('/tag/<tag>')
async def tag_handler(request, tag):
return text('Tag - {}'.format(tag))
```
To specify a type for the parameter, add a `:type` after the parameter name,
inside the quotes. If the parameter does not match the specified type, Sanic
will throw a `NotFound` exception, resulting in a `404: Page not found` error
on the URL.
```python
from sanic.response import text
@app.route('/number/<integer_arg:int>')
async def integer_handler(request, integer_arg):
return text('Integer - {}'.format(integer_arg))
@app.route('/number/<number_arg:number>')
async def number_handler(request, number_arg):
return text('Number - {}'.format(number_arg))
@app.route('/person/<name:[A-z]+>')
async def person_handler(request, name):
return text('Person - {}'.format(name))
@app.route('/folder/<folder_id:[A-z0-9]{0,4}>')
async def folder_handler(request, folder_id):
return text('Folder - {}'.format(folder_id))
```
## HTTP request types
By default, a route defined on a URL will be available for only GET requests to that URL.
However, the `@app.route` decorator accepts an optional parameter, `methods`,
which allows the handler function to work with any of the HTTP methods in the list.
```python
from sanic.response import text
@app.route('/post', methods=['POST'])
async def post_handler(request):
return text('POST request - {}'.format(request.json))
@app.route('/get', methods=['GET'])
async def get_handler(request):
return text('GET request - {}'.format(request.args))
```
There is also an optional `host` argument (which can be a list or a string). This restricts a route to the host or hosts provided. If there is a also a route with no host, it will be the default.
```python
@app.route('/get', methods=['GET'], host='example.com')
async def get_handler(request):
return text('GET request - {}'.format(request.args))
# if the host header doesn't match example.com, this route will be used
@app.route('/get', methods=['GET'])
async def get_handler(request):
return text('GET request in default - {}'.format(request.args))
```
There are also shorthand method decorators:
```python
from sanic.response import text
@app.post('/post')
async def post_handler(request):
return text('POST request - {}'.format(request.json))
@app.get('/get')
async def get_handler(request):
return text('GET request - {}'.format(request.args))
```
## The `add_route` method
As we have seen, routes are often specified using the `@app.route` decorator.
However, this decorator is really just a wrapper for the `app.add_route`
method, which is used as follows:
```python
from sanic.response import text
# Define the handler functions
async def handler1(request):
return text('OK')
async def handler2(request, name):
return text('Folder - {}'.format(name))
async def person_handler2(request, name):
return text('Person - {}'.format(name))
# Add each handler function as a route
app.add_route(handler1, '/test')
app.add_route(handler2, '/folder/<name>')
app.add_route(person_handler2, '/person/<name:[A-z]>', methods=['GET'])
```
## URL building with `url_for`
Sanic provides a `url_for` method, to generate URLs based on the handler method name. This is useful if you want to avoid hardcoding url paths into your app; instead, you can just reference the handler name. For example:
```python
from sanic.response import redirect
@app.route('/')
async def index(request):
# generate a URL for the endpoint `post_handler`
url = app.url_for('post_handler', post_id=5)
# the URL is `/posts/5`, redirect to it
return redirect(url)
@app.route('/posts/<post_id>')
async def post_handler(request, post_id):
return text('Post - {}'.format(post_id))
```
Other things to keep in mind when using `url_for`:
- Keyword arguments passed to `url_for` that are not request parameters will be included in the URL's query string. For example:
```python
url = app.url_for('post_handler', post_id=5, arg_one='one', arg_two='two')
# /posts/5?arg_one=one&arg_two=two
```
- Multivalue argument can be passed to `url_for`. For example:
```python
url = app.url_for('post_handler', post_id=5, arg_one=['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:
```python
url = app.url_for('post_handler', post_id=5, arg_one='one', _anchor='anchor')
# /posts/5?arg_one=one#anchor
url = app.url_for('post_handler', post_id=5, arg_one='one', _external=True)
# //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
url = app.url_for('post_handler', post_id=5, arg_one='one', _scheme='http', _external=True)
# http://server/posts/5?arg_one=one
# when specifying _scheme, _external must be True
# you can pass all special arguments one time
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
```
- 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.
## WebSocket routes
Routes for the WebSocket protocol can be defined with the `@app.websocket`
decorator:
```python
@app.websocket('/feed')
async def feed(request, ws):
while True:
data = 'hello!'
print('Sending: ' + data)
await ws.send(data)
data = await ws.recv()
print('Received: ' + data)
```
Alternatively, the `app.add_websocket_route` method can be used instead of the
decorator:
```python
async def feed(request, ws):
pass
app.add_websocket_route(my_websocket_handler, '/feed')
```
Handlers for a WebSocket route are passed the request as first argument, and a
WebSocket protocol object as second argument. The protocol object has `send`
and `recv` methods to send and receive data respectively.
WebSocket support requires the [websockets](https://github.com/aaugustin/websockets)
package by Aymeric Augustin.
## About `strict_slashes`
You can make `routes` strict to trailing slash or not, it's configurable.
```python
# provide default strict_slashes value for all routes
app = Sanic('test_route_strict_slash', strict_slashes=True)
# you can also overwrite strict_slashes value for specific route
@app.get('/get', strict_slashes=False)
def handler(request):
return text('OK')
# It also works for blueprints
bp = Blueprint('test_bp_strict_slash', strict_slashes=True)
@bp.get('/bp/get', strict_slashes=False)
def handler(request):
return text('OK')
app.blueprint(bp)
```
## User defined route name
You can pass `name` to change the route name to avoid using the default name (`handler.__name__`).
```python
app = Sanic('test_named_route')
@app.get('/get', name='get_handler')
def handler(request):
return text('OK')
# then you need use `app.url_for('get_handler')`
# instead of # `app.url_for('handler')`
# It also works for blueprints
bp = Blueprint('test_named_bp')
@bp.get('/bp/get', name='get_handler')
def handler(request):
return text('OK')
app.blueprint(bp)
# then you need use `app.url_for('test_named_bp.get_handler')`
# instead of `app.url_for('test_named_bp.handler')`
# different names can be used for same url with different methods
@app.get('/test', name='route_test')
def handler(request):
return text('OK')
@app.post('/test', name='route_post')
def handler2(request):
return text('OK POST')
@app.put('/test', name='route_put')
def handler3(request):
return text('OK PUT')
# below url are the same, you can use any of them
# '/test'
app.url_for('route_test')
# app.url_for('route_post')
# app.url_for('route_put')
# for same handler name with different methods
# you need specify the name (it's url_for issue)
@app.get('/get')
def handler(request):
return text('OK')
@app.post('/post', name='post_handler')
def handler(request):
return text('OK')
# then
# app.url_for('handler') == '/get'
# app.url_for('post_handler') == '/post'
```
## Build URL for static files
You can use `url_for` for static file url building now.
If it's for file directly, `filename` can be ignored.
```python
app = Sanic('test_static')
app.static('/static', './static')
app.static('/uploads', './uploads', name='uploads')
app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png')
bp = Blueprint('bp', url_prefix='bp')
bp.static('/static', './static')
bp.static('/uploads', './uploads', name='uploads')
bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png')
app.blueprint(bp)
# then build the url
app.url_for('static', filename='file.txt') == '/static/file.txt'
app.url_for('static', name='static', filename='file.txt') == '/static/file.txt'
app.url_for('static', name='uploads', filename='file.txt') == '/uploads/file.txt'
app.url_for('static', name='best_png') == '/the_best.png'
# blueprint url building
app.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt'
app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/uploads/file.txt'
app.url_for('static', name='bp.best_png') == '/bp/static/the_best.png'
```

66
docs/sanic/sockets.rst Normal file
View File

@@ -0,0 +1,66 @@
Sockets
=======
Sanic can use the python
`socket module <https://docs.python.org/3/library/socket.html>`_ to accommodate
non IPv4 sockets.
IPv6 example:
.. code:: python
from sanic import Sanic
from sanic.response import json
import socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.bind(('::', 7777))
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(sock=sock)
to test IPv6 ``curl -g -6 "http://[::1]:7777/"``
UNIX socket example:
.. code:: python
import signal
import sys
import socket
import os
from sanic import Sanic
from sanic.response import json
server_socket = '/tmp/sanic.sock'
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(server_socket)
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
def signal_handler(sig, frame):
print('Exiting')
os.unlink(server_socket)
sys.exit(0)
if __name__ == "__main__":
app.run(sock=sock)
to test UNIX: ``curl -v --unix-socket /tmp/sanic.sock http://localhost/hello``

20
docs/sanic/ssl.rst Normal file
View File

@@ -0,0 +1,20 @@
SSL Example
-----------
Optionally pass in an SSLContext:
.. code:: python
import ssl
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain("/path/to/cert", keyfile="/path/to/keyfile")
app.run(host="0.0.0.0", port=8443, ssl=context)
You can also pass in the locations of a certificate and key as a dictionary:
.. code:: python
ssl = {'cert': "/path/to/cert", 'key': "/path/to/keyfile"}
app.run(host="0.0.0.0", port=8443, ssl=ssl)

View File

@@ -0,0 +1,83 @@
# Static Files
Static files and directories, such as an image file, are served by Sanic when
registered with the `app.static()` method. The method takes an endpoint URL and a
filename. The file specified will then be accessible via the given endpoint.
```python
from sanic import Sanic
from sanic.blueprints import Blueprint
app = Sanic(__name__)
# Serves files from the static folder to the URL /static
app.static('/static', './static')
# use url_for to build the url, name defaults to 'static' and can be ignored
app.url_for('static', filename='file.txt') == '/static/file.txt'
app.url_for('static', name='static', filename='file.txt') == '/static/file.txt'
# Serves the file /home/ubuntu/test.png when the URL /the_best.png
# is requested
app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png')
# you can use url_for to build the static file url
# you can ignore name and filename parameters if you don't define it
app.url_for('static', name='best_png') == '/the_best.png'
app.url_for('static', name='best_png', filename='any') == '/the_best.png'
# you need define the name for other static files
app.static('/another.png', '/home/ubuntu/another.png', name='another')
app.url_for('static', name='another') == '/another.png'
app.url_for('static', name='another', filename='any') == '/another.png'
# also, you can use static for blueprint
bp = Blueprint('bp', url_prefix='/bp')
bp.static('/static', './static')
# servers the file directly
bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png')
app.blueprint(bp)
app.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt'
app.url_for('static', name='bp.best_png') == '/bp/test_best.png'
app.run(host="0.0.0.0", port=8000)
```
> **Note:** Sanic does not provide directory index when you serve a static directory.
## Virtual Host
The `app.static()` method also support **virtual host**. You can serve your static files with spefic **virtual host** with `host` argument. For example:
```python
from sanic import Sanic
app = Sanic(__name__)
app.static('/static', './static')
app.static('/example_static', './example_static', host='www.example.com')
```
## Streaming Large File
In some cases, you might server large file(ex: videos, images, etc.) with Sanic. You can choose to use **streaming file** rather than download directly.
Here is an example:
```python
from sanic import Sanic
app = Sanic(__name__)
app.static('/large_video.mp4', '/home/ubuntu/large_video.mp4', stream_large_files=True)
```
When `stream_large_files` is `True`, Sanic will use `file_stream()` instead of `file()` to serve static files. This will use **1KB** as the default chunk size. And, if needed, you can also use a custom chunk size. For example:
```python
from sanic import Sanic
app = Sanic(__name__)
chunk_size = 1024 * 1024 * 8 # Set chunk size to 8KB
app.static('/large_video.mp4', '/home/ubuntu/large_video.mp4', stream_large_files=chunk_size)
```

106
docs/sanic/streaming.md Normal file
View File

@@ -0,0 +1,106 @@
# Streaming
## Request Streaming
Sanic allows you to get request data by stream, as below. When the request ends, `request.stream.get()` returns `None`. Only post, put and patch decorator have stream argument.
```python
from sanic import Sanic
from sanic.views import CompositionView
from sanic.views import HTTPMethodView
from sanic.views import stream as stream_decorator
from sanic.blueprints import Blueprint
from sanic.response import stream, text
bp = Blueprint('blueprint_request_stream')
app = Sanic('request_stream')
class SimpleView(HTTPMethodView):
@stream_decorator
async def post(self, request):
result = ''
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode('utf-8')
return text(result)
@app.post('/stream', stream=True)
async def handler(request):
async def streaming(response):
while True:
body = await request.stream.get()
if body is None:
break
body = body.decode('utf-8').replace('1', 'A')
await response.write(body)
return stream(streaming)
@bp.put('/bp_stream', stream=True)
async def bp_handler(request):
result = ''
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode('utf-8').replace('1', 'A')
return text(result)
async def post_handler(request):
result = ''
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode('utf-8')
return text(result)
app.blueprint(bp)
app.add_route(SimpleView.as_view(), '/method_view')
view = CompositionView()
view.add(['POST'], post_handler, stream=True)
app.add_route(view, '/composition_view')
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8000)
```
## Response Streaming
Sanic allows you to stream content to the client with the `stream` method. This method accepts a coroutine callback which is passed a `StreamingHTTPResponse` object that is written to. A simple example is like follows:
```python
from sanic import Sanic
from sanic.response import stream
app = Sanic(__name__)
@app.route("/")
async def test(request):
async def sample_streaming_fn(response):
await response.write('foo,')
await response.write('bar')
return stream(sample_streaming_fn, content_type='text/csv')
```
This is useful in situations where you want to stream content to the client that originates in an external service, like a database. For example, you can stream database records to the client with the asynchronous cursor that `asyncpg` provides:
```python
@app.route("/")
async def index(request):
async def stream_from_db(response):
conn = await asyncpg.connect(database='test')
async with conn.transaction():
async for record in conn.cursor('SELECT generate_series(0, 10)'):
await response.write(record[0])
return stream(stream_from_db)
```

127
docs/sanic/testing.md Normal file
View File

@@ -0,0 +1,127 @@
# Testing
Sanic endpoints can be tested locally using the `test_client` object, which
depends on the additional [aiohttp](https://aiohttp.readthedocs.io/en/stable/)
library.
The `test_client` exposes `get`, `post`, `put`, `delete`, `patch`, `head` and `options` methods
for you to run against your application. A simple example (using pytest) is like follows:
```python
# Import the Sanic app, usually created with Sanic(__name__)
from external_server import app
def test_index_returns_200():
request, response = app.test_client.get('/')
assert response.status == 200
def test_index_put_not_allowed():
request, response = app.test_client.put('/')
assert response.status == 405
```
Internally, each time you call one of the `test_client` methods, the Sanic app is run at `127.0.0.1:42101` and
your test request is executed against your application, using `aiohttp`.
The `test_client` methods accept the following arguments and keyword arguments:
- `uri` *(default `'/'`)* A string representing the URI to test.
- `gather_request` *(default `True`)* A boolean which determines whether the
original request will be returned by the function. If set to `True`, the
return value is a tuple of `(request, response)`, if `False` only the
response is returned.
- `server_kwargs` *(default `{}`) a dict of additional arguments to pass into `app.run` before the test request is run.
- `debug` *(default `False`)* A boolean which determines whether to run the server in debug mode.
The function further takes the `*request_args` and `**request_kwargs`, which are passed directly to the aiohttp ClientSession request.
For example, to supply data to a GET request, you would do the following:
```python
def test_get_request_includes_data():
params = {'key1': 'value1', 'key2': 'value2'}
request, response = app.test_client.get('/', params=params)
assert request.args.get('key1') == 'value1'
```
And to supply data to a JSON POST request:
```python
def test_post_json_request_includes_data():
data = {'key1': 'value1', 'key2': 'value2'}
request, response = app.test_client.post('/', data=json.dumps(data))
assert request.json.get('key1') == 'value1'
```
More information about
the available arguments to aiohttp can be found
[in the documentation for ClientSession](https://aiohttp.readthedocs.io/en/stable/client_reference.html#client-session).
## pytest-sanic
[pytest-sanic](https://github.com/yunstanford/pytest-sanic) is a pytest plugin, it helps you to test your code asynchronously.
Just write tests like,
```python
async def test_sanic_db_find_by_id(app):
"""
Let's assume that, in db we have,
{
"id": "123",
"name": "Kobe Bryant",
"team": "Lakers",
}
"""
doc = await app.db["players"].find_by_id("123")
assert doc.name == "Kobe Bryant"
assert doc.team == "Lakers"
```
[pytest-sanic](https://github.com/yunstanford/pytest-sanic) also provides some useful fixtures, like loop, unused_port,
test_server, test_client.
```python
@pytest.yield_fixture
def app():
app = Sanic("test_sanic_app")
@app.route("/test_get", methods=['GET'])
async def test_get(request):
return response.json({"GET": True})
@app.route("/test_post", methods=['POST'])
async def test_post(request):
return response.json({"POST": True})
yield app
@pytest.fixture
def test_cli(loop, app, test_client):
return loop.run_until_complete(test_client(app, protocol=WebSocketProtocol))
#########
# Tests #
#########
async def test_fixture_test_client_get(test_cli):
"""
GET request
"""
resp = await test_cli.get('/test_get')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"GET": True}
async def test_fixture_test_client_post(test_cli):
"""
POST request
"""
resp = await test_cli.post('/test_post')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"POST": True}
```

50
docs/sanic/versioning.md Normal file
View File

@@ -0,0 +1,50 @@
# Versioning
You can pass the `version` keyword to the route decorators, or to a blueprint initializer. It will result in the `v{version}` url prefix where `{version}` is the version number.
## Per route
You can pass a version number to the routes directly.
```python
from sanic import response
@app.route('/text', version=1)
def handle_request(request):
return response.text('Hello world! Version 1')
@app.route('/text', version=2)
def handle_request(request):
return response.text('Hello world! Version 2')
app.run(port=80)
```
Then with curl:
```bash
curl localhost/v1/text
curl localhost/v2/text
```
## Global blueprint version
You can also pass a version number to the blueprint, which will apply to all routes.
```python
from sanic import response
from sanic.blueprints import Blueprint
bp = Blueprint('test', version=1)
@bp.route('/html')
def handle_request(request):
return response.html('<p>Hello world!</p>')
```
Then with curl:
```bash
curl localhost/v1/html
```

52
docs/sanic/websocket.rst Normal file
View File

@@ -0,0 +1,52 @@
WebSocket
=========
Sanic supports websockets, to setup a WebSocket:
.. code:: python
from sanic import Sanic
from sanic.response import json
from sanic.websocket import WebSocketProtocol
app = Sanic()
@app.websocket('/feed')
async def feed(request, ws):
while True:
data = 'hello!'
print('Sending: ' + data)
await ws.send(data)
data = await ws.recv()
print('Received: ' + data)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, protocol=WebSocketProtocol)
Alternatively, the ``app.add_websocket_route`` method can be used instead of the
decorator:
.. code:: python
async def feed(request, ws):
pass
app.add_websocket_route(feed, '/feed')
Handlers for a WebSocket route are passed the request as first argument, and a
WebSocket protocol object as second argument. The protocol object has ``send``
and ``recv`` methods to send and receive data respectively.
You could setup your own WebSocket configuration through ``app.config``, like
.. code:: python
app.config.WEBSOCKET_MAX_SIZE = 2 ** 20
app.config.WEBSOCKET_MAX_QUEUE = 32
app.config.WEBSOCKET_READ_LIMIT = 2 ** 16
app.config.WEBSOCKET_WRITE_LIMIT = 2 ** 16
Find more in ``Configuration`` section.

View File

@@ -1,18 +0,0 @@
# Static Files
Both directories and files can be served by registering with static
## Example
```python
app = Sanic(__name__)
# Serves files from the static folder to the URL /static
app.static('/static', './static')
# Serves the file /home/ubuntu/test.png when the URL /the_best.png
# is requested
app.static('/the_best.png', '/home/ubuntu/test.png')
app.run(host="0.0.0.0", port=8000)
```

View File

@@ -1,51 +0,0 @@
# Testing
Sanic endpoints can be tested locally using the `sanic.utils` module, which
depends on the additional [aiohttp](https://aiohttp.readthedocs.io/en/stable/)
library. The `sanic_endpoint_test` function runs a local server, issues a
configurable request to an endpoint, and returns the result. It takes the
following arguments:
- `app` An instance of a Sanic app.
- `method` *(default `'get'`)* A string representing the HTTP method to use.
- `uri` *(default `'/'`)* A string representing the endpoint to test.
- `gather_request` *(default `True`)* A boolean which determines whether the
original request will be returned by the function. If set to `True`, the
return value is a tuple of `(request, response)`, if `False` only the
response is returned.
- `loop` *(default `None`)* The event loop to use.
- `debug` *(default `False`)* A boolean which determines whether to run the
server in debug mode.
The function further takes the `*request_args` and `**request_kwargs`, which
are passed directly to the aiohttp ClientSession request. For example, to
supply data with a GET request, `method` would be `get` and the keyword
argument `params={'value', 'key'}` would be supplied. More information about
the available arguments to aiohttp can be found
[in the documentation for ClientSession](https://aiohttp.readthedocs.io/en/stable/client_reference.html#client-session).
Below is a complete example of an endpoint test,
using [pytest](http://doc.pytest.org/en/latest/). The test checks that the
`/challenge` endpoint responds to a GET request with a supplied challenge
string.
```python
import pytest
import aiohttp
from sanic.utils import sanic_endpoint_test
# Import the Sanic app, usually created with Sanic(__name__)
from external_server import app
def test_endpoint_challenge():
# Create the challenge data
request_data = {'challenge': 'dummy_challenge'}
# Send the request to the endpoint, using the default `get` method
request, response = sanic_endpoint_test(app,
uri='/challenge',
params=request_data)
# Assert that the server responds with the challenge string
assert response.text == request_data['challenge']
```

21
environment.yml Normal file
View File

@@ -0,0 +1,21 @@
name: py35
dependencies:
- openssl=1.0.2g=0
- pip=8.1.1=py35_0
- python=3.5.1=0
- readline=6.2=2
- setuptools=20.3=py35_0
- sqlite=3.9.2=0
- tk=8.5.18=0
- wheel=0.29.0=py35_0
- xz=5.0.5=1
- zlib=1.2.8=0
- pip:
- uvloop>=0.5.3
- httptools>=0.0.10
- ujson>=1.35
- aiofiles>=0.3.0
- websockets>=6.0
- sphinxcontrib-asyncio>=0.2.0
- multidict>=4.0,<5.0
- https://github.com/channelcat/docutils-fork/zipball/master

View File

@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
import asyncio
from sanic import Sanic
app = Sanic()
async def notify_server_started_after_five_seconds():
await asyncio.sleep(5)
print('Server successfully started!')
app.add_task(notify_server_started_after_five_seconds())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)

View File

@@ -1,33 +0,0 @@
from sanic import Sanic
from sanic.response import json
import uvloop
import aiohttp
#Create an event loop manually so that we can use it for both sanic & aiohttp
loop = uvloop.new_event_loop()
app = Sanic(__name__)
async def fetch(session, url):
"""
Use session object to perform 'get' request on url
"""
async with session.get(url) as response:
return await response.json()
@app.route("/")
async def test(request):
"""
Download and serve example JSON
"""
url = "https://api.github.com/repos/channelcat/sanic"
async with aiohttp.ClientSession(loop=loop) as session:
response = await fetch(session, url)
return json(response)
app.run(host="0.0.0.0", port=8000, loop=loop)

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
from sanic import Sanic
from functools import wraps
from sanic.response import json
app = Sanic()
def check_request_for_authorization_status(request):
# Note: Define your check, for instance cookie, session.
flag = True
return flag
def authorized():
def decorator(f):
@wraps(f)
async def decorated_function(request, *args, **kwargs):
# run some method that checks the request
# for the client's authorization status
is_authorized = check_request_for_authorization_status(request)
if is_authorized:
# the user is authorized.
# run the handler method and return the response
response = await f(request, *args, **kwargs)
return response
else:
# the user is not authorized.
return json({'status': 'not_authorized'}, 403)
return decorated_function
return decorator
@app.route("/")
@authorized()
async def test(request):
return json({'status': 'authorized'})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)

View File

@@ -1,11 +1,10 @@
from sanic import Sanic
from sanic import Blueprint
from sanic.response import json, text
from sanic import Blueprint, Sanic
from sanic.response import file, json
app = Sanic(__name__)
blueprint = Blueprint('name', url_prefix='/my_blueprint')
blueprint2 = Blueprint('name', url_prefix='/my_blueprint2')
blueprint2 = Blueprint('name2', url_prefix='/my_blueprint2')
blueprint3 = Blueprint('name3', url_prefix='/my_blueprint3')
@blueprint.route('/foo')
@@ -18,7 +17,22 @@ async def foo2(request):
return json({'msg': 'hi from blueprint2'})
app.register_blueprint(blueprint)
app.register_blueprint(blueprint2)
@blueprint3.route('/foo')
async def index(request):
return await file('websocket.html')
@app.websocket('/feed')
async def foo3(request, ws):
while True:
data = 'hello!'
print('Sending: ' + data)
await ws.send(data)
data = await ws.recv()
print('Received: ' + data)
app.blueprint(blueprint)
app.blueprint(blueprint2)
app.blueprint(blueprint3)
app.run(host="0.0.0.0", port=8000, debug=True)

View File

@@ -1,41 +0,0 @@
"""
Example of caching using aiocache package. To run it you will need a Redis
instance running in localhost:6379.
Running this example you will see that the first call lasts 3 seconds and
the rest are instant because the value is retrieved from the Redis.
If you want more info about the package check
https://github.com/argaen/aiocache
"""
import asyncio
import aiocache
from sanic import Sanic
from sanic.response import json
from sanic.log import log
from aiocache import cached
from aiocache.serializers import JsonSerializer
app = Sanic(__name__)
aiocache.settings.set_defaults(
cache="aiocache.RedisCache"
)
@cached(key="my_custom_key", serializer=JsonSerializer())
async def expensive_call():
log.info("Expensive has been called")
await asyncio.sleep(3)
return {"test": True}
@app.route("/")
async def test(request):
log.info("Received GET /")
return json(await expensive_call())
app.run(host="0.0.0.0", port=8000, loop=asyncio.get_event_loop())

View File

@@ -1,39 +1,34 @@
"""
Example intercepting uncaught exceptions using Sanic's error handler framework.
This may be useful for developers wishing to use Sentry, Airbrake, etc.
or a custom system to log and monitor unexpected errors in production.
First we create our own class inheriting from Handler in sanic.exceptions,
and pass in an instance of it when we create our Sanic instance. Inside this
class' default handler, we can do anything including sending exceptions to
an external service.
"""
from sanic.handlers import ErrorHandler
from sanic.exceptions import SanicException
"""
Imports and code relevant for our CustomHandler class
(Ordinarily this would be in a separate file)
"""
from sanic.response import text
from sanic.exceptions import Handler, SanicException
class CustomHandler(Handler):
class CustomHandler(ErrorHandler):
def default(self, request, exception):
# Here, we have access to the exception object
# and can do anything with it (log, send to external service, etc)
# Some exceptions are trivial and built into Sanic (404s, etc)
if not issubclass(type(exception), SanicException):
if not isinstance(exception, SanicException):
print(exception)
# Then, we must finish handling the exception by returning
# our response to the client
# For this we can just call the super class' default handler
return super.default(self, request, exception)
return super().default(request, exception)
"""
@@ -42,19 +37,18 @@ server's error_handler to an instance of our CustomHandler
"""
from sanic import Sanic
from sanic.response import json
app = Sanic(__name__)
handler = CustomHandler(sanic=app)
handler = CustomHandler()
app.error_handler = handler
@app.route("/")
async def test(request):
# Here, something occurs which causes an unexpected exception
# This exception will flow to our custom handler.
x = 1 / 0
return json({"test": True})
raise SanicException('You Broke It!')
app.run(host="0.0.0.0", port=8000, debug=True)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, debug=True)

View File

@@ -1,18 +0,0 @@
## To use this example:
# curl -d '{"name": "John Doe"}' localhost:8000
from sanic import Sanic
from sanic.response import html
from jinja2 import Template
template = Template('Hello {{ name }}!')
app = Sanic(__name__)
@app.route('/')
async def test(request):
data = request.json
return html(template.render(**data))
app.run(host="0.0.0.0", port=8000)

View File

@@ -0,0 +1,38 @@
from sanic import Sanic
from sanic.response import json
import asyncio
import aiohttp
app = Sanic(__name__)
sem = None
@app.listener('before_server_start')
def init(sanic, loop):
global sem
concurrency_per_worker = 4
sem = asyncio.Semaphore(concurrency_per_worker, loop=loop)
async def bounded_fetch(session, url):
"""
Use session object to perform 'get' request on url
"""
async with sem, session.get(url) as response:
return await response.json()
@app.route("/")
async def test(request):
"""
Download and serve example JSON
"""
url = "https://api.github.com/repos/channelcat/sanic"
async with aiohttp.ClientSession() as session:
response = await bounded_fetch(session, url)
return json(response)
app.run(host="0.0.0.0", port=8000, workers=2)

View File

@@ -0,0 +1,86 @@
'''
Based on example from https://github.com/Skyscanner/aiotask-context
and `examples/{override_logging,run_async}.py`.
Needs https://github.com/Skyscanner/aiotask-context/tree/52efbc21e2e1def2d52abb9a8e951f3ce5e6f690 or newer
$ pip install git+https://github.com/Skyscanner/aiotask-context.git
'''
import asyncio
import uuid
import logging
from signal import signal, SIGINT
from sanic import Sanic
from sanic import response
import uvloop
import aiotask_context as context
log = logging.getLogger(__name__)
class RequestIdFilter(logging.Filter):
def filter(self, record):
record.request_id = context.get('X-Request-ID')
return True
LOG_SETTINGS = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'default',
'filters': ['requestid'],
},
},
'filters': {
'requestid': {
'()': RequestIdFilter,
},
},
'formatters': {
'default': {
'format': '%(asctime)s %(levelname)s %(name)s:%(lineno)d %(request_id)s | %(message)s',
},
},
'loggers': {
'': {
'level': 'DEBUG',
'handlers': ['console'],
'propagate': True
},
}
}
app = Sanic(__name__, log_config=LOG_SETTINGS)
@app.middleware('request')
async def set_request_id(request):
request_id = request.headers.get('X-Request-ID') or str(uuid.uuid4())
context.set("X-Request-ID", request_id)
@app.route("/")
async def test(request):
log.debug('X-Request-ID: %s', context.get('X-Request-ID'))
log.info('Hello from test!')
return response.json({"test": True})
if __name__ == '__main__':
asyncio.set_event_loop(uvloop.new_event_loop())
server = app.create_server(host="0.0.0.0", port=8000)
loop = asyncio.get_event_loop()
loop.set_task_factory(context.task_factory)
task = asyncio.ensure_future(server)
try:
loop.run_forever()
except:
loop.stop()

View File

@@ -0,0 +1,28 @@
"""
Modify header or status in response
"""
from sanic import Sanic
from sanic import response
app = Sanic(__name__)
@app.route('/')
def handle_request(request):
return response.json(
{'message': 'Hello world!'},
headers={'X-Served-By': 'sanic'},
status=200
)
@app.route('/unauthorized')
def handle_request(request):
return response.json(
{'message': 'You are not authorized'},
headers={'X-Served-By': 'sanic'},
status=404
)
app.run(host="0.0.0.0", port=8000, debug=True)

View File

@@ -0,0 +1,24 @@
from sanic import Sanic
from sanic import response
import logging
logging_format = "[%(asctime)s] %(process)d-%(levelname)s "
logging_format += "%(module)s::%(funcName)s():l%(lineno)d: "
logging_format += "%(message)s"
logging.basicConfig(
format=logging_format,
level=logging.DEBUG
)
log = logging.getLogger()
# Set logger to override default basicConfig
sanic = Sanic()
@sanic.route("/")
def test(request):
log.info("received request; responding with 'hey'")
return response.text("hey")
sanic.run(host="0.0.0.0", port=8000)

49
examples/pytest_xdist.py Normal file
View File

@@ -0,0 +1,49 @@
"""pytest-xdist example for sanic server
Install testing tools:
$ pip install pytest pytest-xdist
Run with xdist params:
$ pytest examples/pytest_xdist.py -n 8 # 8 workers
"""
import re
from sanic import Sanic
from sanic.response import text
from sanic.testing import PORT as PORT_BASE, SanicTestClient
import pytest
@pytest.fixture(scope="session")
def test_port(worker_id):
m = re.search(r'[0-9]+', worker_id)
if m:
num_id = m.group(0)
else:
num_id = 0
port = PORT_BASE + int(num_id)
return port
@pytest.fixture(scope="session")
def app():
app = Sanic()
@app.route('/')
async def index(request):
return text('OK')
return app
@pytest.fixture(scope="session")
def client(app, test_port):
return SanicTestClient(app, test_port)
@pytest.mark.parametrize('run_id', range(100))
def test_index(client, run_id):
request, response = client._sanic_endpoint_test('get', '/')
assert response.status == 200
assert response.text == 'OK'

View File

@@ -0,0 +1,18 @@
from sanic import Sanic
from sanic import response
app = Sanic(__name__)
@app.route('/')
def handle_request(request):
return response.redirect('/redirect')
@app.route('/redirect')
async def test(request):
return response.json({"Redirected": True})
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)

View File

@@ -0,0 +1,10 @@
import requests
# Warning: This is a heavy process.
data = ""
for i in range(1, 250000):
data += str(i)
r = requests.post('http://0.0.0.0:8000/stream', data=data)
print(r.text)

View File

@@ -0,0 +1,65 @@
from sanic import Sanic
from sanic.views import CompositionView
from sanic.views import HTTPMethodView
from sanic.views import stream as stream_decorator
from sanic.blueprints import Blueprint
from sanic.response import stream, text
bp = Blueprint('blueprint_request_stream')
app = Sanic('request_stream')
class SimpleView(HTTPMethodView):
@stream_decorator
async def post(self, request):
result = ''
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode('utf-8')
return text(result)
@app.post('/stream', stream=True)
async def handler(request):
async def streaming(response):
while True:
body = await request.stream.get()
if body is None:
break
body = body.decode('utf-8').replace('1', 'A')
await response.write(body)
return stream(streaming)
@bp.put('/bp_stream', stream=True)
async def bp_handler(request):
result = ''
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode('utf-8').replace('1', 'A')
return text(result)
async def post_handler(request):
result = ''
while True:
body = await request.stream.get()
if body is None:
break
result += body.decode('utf-8')
return text(result)
app.blueprint(bp)
app.add_route(SimpleView.as_view(), '/method_view')
view = CompositionView()
view.add(['POST'], post_handler, stream=True)
app.add_route(view, '/composition_view')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)

View File

@@ -1,6 +1,6 @@
from sanic import Sanic
import asyncio
from sanic.response import text
from sanic import Sanic
from sanic import response
from sanic.config import Config
from sanic.exceptions import RequestTimeout
@@ -11,11 +11,11 @@ app = Sanic(__name__)
@app.route('/')
async def test(request):
await asyncio.sleep(3)
return text('Hello, world!')
return response.text('Hello, world!')
@app.exception(RequestTimeout)
def timeout(request, exception):
return text('RequestTimeout from error_handler.', 408)
return response.text('RequestTimeout from error_handler.', 408)
app.run(host='0.0.0.0', port=8000)

22
examples/run_async.py Normal file
View File

@@ -0,0 +1,22 @@
from sanic import Sanic
from sanic import response
from signal import signal, SIGINT
import asyncio
import uvloop
app = Sanic(__name__)
@app.route("/")
async def test(request):
return response.json({"answer": "42"})
asyncio.set_event_loop(uvloop.new_event_loop())
server = app.create_server(host="0.0.0.0", port=8000)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(server)
signal(SIGINT, lambda s, f: loop.stop())
try:
loop.run_forever()
except:
loop.stop()

View File

@@ -1,65 +0,0 @@
""" To run this example you need additional aiopg package
"""
import os
import asyncio
import uvloop
import aiopg
from sanic import Sanic
from sanic.response import json
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
database_name = os.environ['DATABASE_NAME']
database_host = os.environ['DATABASE_HOST']
database_user = os.environ['DATABASE_USER']
database_password = os.environ['DATABASE_PASSWORD']
connection = 'postgres://{0}:{1}@{2}/{3}'.format(database_user,
database_password,
database_host,
database_name)
loop = asyncio.get_event_loop()
async def get_pool():
return await aiopg.create_pool(connection)
app = Sanic(name=__name__)
pool = loop.run_until_complete(get_pool())
async def prepare_db():
""" Let's create some table and add some data
"""
async with pool.acquire() as conn:
async with conn.cursor() as cur:
await cur.execute('DROP TABLE IF EXISTS sanic_polls')
await cur.execute("""CREATE TABLE sanic_polls (
id serial primary key,
question varchar(50),
pub_date timestamp
);""")
for i in range(0, 100):
await cur.execute("""INSERT INTO sanic_polls
(id, question, pub_date) VALUES ({}, {}, now())
""".format(i, i))
@app.route("/")
async def handle(request):
async with pool.acquire() as conn:
async with conn.cursor() as cur:
result = []
await cur.execute("SELECT question, pub_date FROM sanic_polls")
async for row in cur:
result.append({"question": row[0], "pub_date": row[1]})
return json({"polls": result})
if __name__ == '__main__':
loop.run_until_complete(prepare_db())
app.run(host='0.0.0.0', port=8000, loop=loop)

View File

@@ -1,73 +0,0 @@
""" To run this example you need additional aiopg package
"""
import os
import asyncio
import datetime
import uvloop
from aiopg.sa import create_engine
import sqlalchemy as sa
from sanic import Sanic
from sanic.response import json
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
database_name = os.environ['DATABASE_NAME']
database_host = os.environ['DATABASE_HOST']
database_user = os.environ['DATABASE_USER']
database_password = os.environ['DATABASE_PASSWORD']
connection = 'postgres://{0}:{1}@{2}/{3}'.format(database_user,
database_password,
database_host,
database_name)
loop = asyncio.get_event_loop()
metadata = sa.MetaData()
polls = sa.Table('sanic_polls', metadata,
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('question', sa.String(50)),
sa.Column("pub_date", sa.DateTime))
async def get_engine():
return await create_engine(connection)
app = Sanic(name=__name__)
engine = loop.run_until_complete(get_engine())
async def prepare_db():
""" Let's add some data
"""
async with engine.acquire() as conn:
await conn.execute('DROP TABLE IF EXISTS sanic_polls')
await conn.execute("""CREATE TABLE sanic_polls (
id serial primary key,
question varchar(50),
pub_date timestamp
);""")
for i in range(0, 100):
await conn.execute(
polls.insert().values(question=i,
pub_date=datetime.datetime.now())
)
@app.route("/")
async def handle(request):
async with engine.acquire() as conn:
result = []
async for row in conn.execute(polls.select()):
result.append({"question": row.question, "pub_date": row.pub_date})
return json({"polls": result})
if __name__ == '__main__':
loop.run_until_complete(prepare_db())
app.run(host='0.0.0.0', port=8000, loop=loop)

View File

@@ -1,80 +0,0 @@
## You need the following additional packages for this example
# aiopg
# peewee_async
# peewee
## sanic imports
from sanic import Sanic
from sanic.response import json
## peewee_async related imports
import uvloop
import peewee
from peewee_async import Manager, PostgresqlDatabase
# we instantiate a custom loop so we can pass it to our db manager
loop = uvloop.new_event_loop()
database = PostgresqlDatabase(database='test',
host='127.0.0.1',
user='postgres',
password='mysecretpassword')
objects = Manager(database, loop=loop)
## from peewee_async docs:
# Also theres no need to connect and re-connect before executing async queries
# with manager! Its all automatic. But you can run Manager.connect() or
# Manager.close() when you need it.
# let's create a simple key value store:
class KeyValue(peewee.Model):
key = peewee.CharField(max_length=40, unique=True)
text = peewee.TextField(default='')
class Meta:
database = database
# create table synchronously
KeyValue.create_table(True)
# OPTIONAL: close synchronous connection
database.close()
# OPTIONAL: disable any future syncronous calls
objects.database.allow_sync = False # this will raise AssertionError on ANY sync call
app = Sanic('peewee_example')
@app.route('/post/<key>/<value>')
async def post(request, key, value):
"""
Save get parameters to database
"""
obj = await objects.create(KeyValue, key=key, text=value)
return json({'object_id': obj.id})
@app.route('/get')
async def get(request):
"""
Load all objects from database
"""
all_objects = await objects.execute(KeyValue.select())
serialized_obj = []
for obj in all_objects:
serialized_obj.append({
'id': obj.id,
'key': obj.key,
'value': obj.text}
)
return json({'objects': serialized_obj})
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000, loop=loop)

View File

@@ -0,0 +1,42 @@
from sanic import Sanic
from sanic.views import HTTPMethodView
from sanic.response import text
app = Sanic('some_name')
class SimpleView(HTTPMethodView):
def get(self, request):
return text('I am get method')
def post(self, request):
return text('I am post method')
def put(self, request):
return text('I am put method')
def patch(self, request):
return text('I am patch method')
def delete(self, request):
return text('I am delete method')
class SimpleAsyncView(HTTPMethodView):
async def get(self, request):
return text('I am async get method')
async def post(self, request):
return text('I am async post method')
async def put(self, request):
return text('I am async put method')
app.add_route(SimpleView.as_view(), '/')
app.add_route(SimpleAsyncView.as_view(), '/async')
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, debug=True)

View File

@@ -1,12 +1,13 @@
from sanic import Sanic
from sanic.response import json
from sanic import response
app = Sanic(__name__)
@app.route("/")
async def test(request):
return json({"test": True})
return response.json({"test": True})
app.run(host="0.0.0.0", port=8000)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)

13
examples/teapot.py Normal file
View File

@@ -0,0 +1,13 @@
from sanic import Sanic
from sanic import response as res
app = Sanic(__name__)
@app.route("/")
async def test(req):
return res.text("I\'m a teapot", status=418)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)

View File

@@ -1,6 +1,8 @@
import os
from sanic import Sanic
from sanic.log import log
from sanic.response import json, text
from sanic.log import logger as log
from sanic import response
from sanic.exceptions import ServerError
app = Sanic(__name__)
@@ -8,37 +10,50 @@ app = Sanic(__name__)
@app.route("/")
async def test_async(request):
return json({"test": True})
return response.json({"test": True})
@app.route("/sync", methods=['GET', 'POST'])
def test_sync(request):
return json({"test": True})
return response.json({"test": True})
@app.route("/dynamic/<name>/<id:int>")
def test_params(request, name, id):
return text("yeehaww {} {}".format(name, id))
@app.route("/dynamic/<name>/<i:int>")
def test_params(request, name, i):
return response.text("yeehaww {} {}".format(name, i))
@app.route("/exception")
def exception(request):
raise ServerError("It's dead jim")
@app.route("/await")
async def test_await(request):
import asyncio
await asyncio.sleep(5)
return text("I'm feeling sleepy")
return response.text("I'm feeling sleepy")
@app.route("/file")
async def test_file(request):
return await response.file(os.path.abspath("setup.py"))
@app.route("/file_stream")
async def test_file_stream(request):
return await response.file_stream(os.path.abspath("setup.py"),
chunk_size=1024)
# ----------------------------------------------- #
# Exceptions
# ----------------------------------------------- #
@app.exception(ServerError)
async def test(request, exception):
return json({"exception": "{}".format(exception), "status": exception.status_code}, status=exception.status_code)
return response.json({"exception": "{}".format(exception), "status": exception.status_code},
status=exception.status_code)
# ----------------------------------------------- #
@@ -47,29 +62,43 @@ async def test(request, exception):
@app.route("/json")
def post_json(request):
return json({"received": True, "message": request.json})
return response.json({"received": True, "message": request.json})
@app.route("/form")
def post_json(request):
return json({"received": True, "form_data": request.form, "test": request.form.get('test')})
def post_form_json(request):
return response.json({"received": True, "form_data": request.form, "test": request.form.get('test')})
@app.route("/query_string")
def query_string(request):
return json({"parsed": True, "args": request.args, "url": request.url, "query_string": request.query_string})
return response.json({"parsed": True, "args": request.args, "url": request.url,
"query_string": request.query_string})
# ----------------------------------------------- #
# Run Server
# ----------------------------------------------- #
def after_start(loop):
@app.listener('before_server_start')
def before_start(app, loop):
log.info("SERVER STARTING")
@app.listener('after_server_start')
def after_start(app, loop):
log.info("OH OH OH OH OHHHHHHHH")
def before_stop(loop):
@app.listener('before_server_stop')
def before_stop(app, loop):
log.info("SERVER STOPPING")
@app.listener('after_server_stop')
def after_stop(app, loop):
log.info("TRIED EVERYTHING")
app.run(host="0.0.0.0", port=8000, debug=True, after_start=after_start, before_stop=before_stop)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, debug=True)

23
examples/unix_socket.py Normal file
View File

@@ -0,0 +1,23 @@
from sanic import Sanic
from sanic import response
import socket
import os
app = Sanic(__name__)
@app.route("/test")
async def test(request):
return response.text("OK")
if __name__ == '__main__':
server_address = './uds_socket'
# Make sure the socket does not already exist
try:
os.unlink(server_address)
except OSError:
if os.path.exists(server_address):
raise
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(server_address)
app.run(sock=sock)

View File

@@ -0,0 +1,20 @@
from sanic import Sanic
from sanic import response
app = Sanic(__name__)
@app.route('/')
async def index(request):
# generate a URL for the endpoint `post_handler`
url = app.url_for('post_handler', post_id=5)
# the URL is `/posts/5`, redirect to it
return response.redirect(url)
@app.route('/posts/<post_id>')
async def post_handler(request, post_id):
return response.text('Post - {}'.format(post_id))
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, debug=True)

39
examples/vhosts.py Normal file
View File

@@ -0,0 +1,39 @@
from sanic import response
from sanic import Sanic
from sanic.blueprints import Blueprint
# Usage
# curl -H "Host: example.com" localhost:8000
# curl -H "Host: sub.example.com" localhost:8000
# curl -H "Host: bp.example.com" localhost:8000/question
# curl -H "Host: bp.example.com" localhost:8000/answer
app = Sanic()
bp = Blueprint("bp", host="bp.example.com")
@app.route('/', host=["example.com",
"somethingelse.com",
"therestofyourdomains.com"])
async def hello(request):
return response.text("Some defaults")
@app.route('/', host="sub.example.com")
async def hello(request):
return response.text("42")
@bp.route("/question")
async def hello(request):
return response.text("What is the meaning of life?")
@bp.route("/answer")
async def hello(request):
return response.text("42")
app.blueprint(bp)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000)

29
examples/websocket.html Normal file
View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>WebSocket demo</title>
</head>
<body>
<script>
var ws = new WebSocket('ws://' + document.domain + ':' + location.port + '/feed'),
messages = document.createElement('ul');
ws.onmessage = function (event) {
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Received: ' + event.data);
message.appendChild(content);
messages.appendChild(message);
};
document.body.appendChild(messages);
window.setInterval(function() {
data = 'bye!'
ws.send(data);
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Sent: ' + data);
message.appendChild(content);
messages.appendChild(message);
}, 1000);
</script>
</body>
</html>

24
examples/websocket.py Normal file
View File

@@ -0,0 +1,24 @@
from sanic import Sanic
from sanic.response import file
app = Sanic(__name__)
@app.route('/')
async def index(request):
return await file('websocket.html')
@app.websocket('/feed')
async def feed(request, ws):
while True:
data = 'hello!'
print('Sending: ' + data)
await ws.send(data)
data = await ws.recv()
print('Received: ' + data)
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8000, debug=True)

2
pyproject.toml Normal file
View File

@@ -0,0 +1,2 @@
[tool.black]
line-length = 79

2
readthedocs.yml Normal file
View File

@@ -0,0 +1,2 @@
conda:
file: environment.yml

View File

@@ -1,14 +1,13 @@
httptools
ujson
uvloop
aiohttp
aiocache
pytest
coverage
tox
gunicorn
bottle
kyoukai
falcon
tornado
aiofiles
aiohttp>=2.3.0,<=3.2.1
chardet<=2.3.0
beautifulsoup4
coverage
httptools>=0.0.10
flake8
pytest==3.3.2
tox
ujson; sys_platform != "win32" and implementation_name == "cpython"
uvloop; sys_platform != "win32" and implementation_name == "cpython"
gunicorn
multidict>=4.0,<5.0

4
requirements-docs.txt Normal file
View File

@@ -0,0 +1,4 @@
sphinx
sphinx_rtd_theme
recommonmark
sphinxcontrib-asyncio

View File

@@ -1,5 +1,6 @@
httptools
ujson
uvloop
aiofiles
multidict
httptools>=0.0.10
ujson; sys_platform != "win32" and implementation_name == "cpython"
uvloop; sys_platform != "win32" and implementation_name == "cpython"
websockets>=6.0,<7.0
multidict>=4.0,<5.0

View File

@@ -1,6 +1,7 @@
from .sanic import Sanic
from .blueprints import Blueprint
from sanic.app import Sanic
from sanic.blueprints import Blueprint
__version__ = '0.1.9'
__all__ = ['Sanic', 'Blueprint']
__version__ = "18.12.0"
__all__ = ["Sanic", "Blueprint"]

View File

@@ -1,16 +1,23 @@
from argparse import ArgumentParser
from importlib import import_module
from .log import log
from .sanic import Sanic
from sanic.app import Sanic
from sanic.log import logger
if __name__ == "__main__":
parser = ArgumentParser(prog='sanic')
parser.add_argument('--host', dest='host', type=str, default='127.0.0.1')
parser.add_argument('--port', dest='port', type=int, default=8000)
parser.add_argument('--workers', dest='workers', type=int, default=1, )
parser.add_argument('--debug', dest='debug', action="store_true")
parser.add_argument('module')
parser = ArgumentParser(prog="sanic")
parser.add_argument("--host", dest="host", type=str, default="127.0.0.1")
parser.add_argument("--port", dest="port", type=int, default=8000)
parser.add_argument(
"--cert", dest="cert", type=str, help="location of certificate for SSL"
)
parser.add_argument(
"--key", dest="key", type=str, help="location of keyfile for SSL."
)
parser.add_argument("--workers", dest="workers", type=int, default=1)
parser.add_argument("--debug", dest="debug", action="store_true")
parser.add_argument("module")
args = parser.parse_args()
try:
@@ -20,17 +27,30 @@ if __name__ == "__main__":
module = import_module(module_name)
app = getattr(module, app_name, None)
if type(app) is not Sanic:
raise ValueError("Module is not a Sanic app, it is a {}. "
"Perhaps you meant {}.app?"
.format(type(app).__name__, args.module))
if not isinstance(app, Sanic):
raise ValueError(
"Module is not a Sanic app, it is a {}. "
"Perhaps you meant {}.app?".format(
type(app).__name__, args.module
)
)
if args.cert is not None or args.key is not None:
ssl = {"cert": args.cert, "key": args.key}
else:
ssl = None
app.run(host=args.host, port=args.port,
workers=args.workers, debug=args.debug)
except ImportError:
log.error("No module named {} found.\n"
" Example File: project/sanic_server.py -> app\n"
" Example Module: project.sanic_server.app"
.format(module_name))
except ValueError as e:
log.error("{}".format(e))
app.run(
host=args.host,
port=args.port,
workers=args.workers,
debug=args.debug,
ssl=ssl,
)
except ImportError as e:
logger.error(
"No module named {} found.\n"
" Example File: project/sanic_server.py -> app\n"
" Example Module: project.sanic_server.app".format(e.name)
)
except ValueError:
logger.exception("Failed to run app")

1122
sanic/app.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,117 +1,283 @@
from collections import defaultdict
from collections import defaultdict, namedtuple
from sanic.constants import HTTP_METHODS
from sanic.views import CompositionView
class BlueprintSetup:
"""
"""
def __init__(self, blueprint, app, options):
self.app = app
self.blueprint = blueprint
self.options = options
url_prefix = self.options.get('url_prefix')
if url_prefix is None:
url_prefix = self.blueprint.url_prefix
#: The prefix that should be used for all URLs defined on the
#: blueprint.
self.url_prefix = url_prefix
def add_route(self, handler, uri, methods):
"""
A helper method to register a handler to the application url routes.
"""
if self.url_prefix:
uri = self.url_prefix + uri
self.app.route(uri=uri, methods=methods)(handler)
def add_exception(self, handler, *args, **kwargs):
"""
Registers exceptions to sanic
"""
self.app.exception(*args, **kwargs)(handler)
def add_static(self, uri, file_or_directory, *args, **kwargs):
"""
Registers static files to sanic
"""
if self.url_prefix:
uri = self.url_prefix + uri
self.app.static(uri, file_or_directory, *args, **kwargs)
def add_middleware(self, middleware, *args, **kwargs):
"""
Registers middleware to sanic
"""
if args or kwargs:
self.app.middleware(*args, **kwargs)(middleware)
else:
self.app.middleware(middleware)
FutureRoute = namedtuple(
"FutureRoute",
[
"handler",
"uri",
"methods",
"host",
"strict_slashes",
"stream",
"version",
"name",
],
)
FutureListener = namedtuple(
"FutureListener", ["handler", "uri", "methods", "host"]
)
FutureMiddleware = namedtuple(
"FutureMiddleware", ["middleware", "args", "kwargs"]
)
FutureException = namedtuple("FutureException", ["handler", "args", "kwargs"])
FutureStatic = namedtuple(
"FutureStatic", ["uri", "file_or_directory", "args", "kwargs"]
)
class Blueprint:
def __init__(self, name, url_prefix=None):
"""
Creates a new blueprint
:param name: Unique name of the blueprint
def __init__(
self,
name,
url_prefix=None,
host=None,
version=None,
strict_slashes=False,
):
"""Create a new blueprint
:param name: unique name of the blueprint
:param url_prefix: URL to be prefixed before all route URLs
:param strict_slashes: strict to trailing slash
"""
self.name = name
self.url_prefix = url_prefix
self.deferred_functions = []
self.host = host
self.routes = []
self.websocket_routes = []
self.exceptions = []
self.listeners = defaultdict(list)
self.middlewares = []
self.statics = []
self.version = version
self.strict_slashes = strict_slashes
def record(self, func):
"""
Registers a callback function that is invoked when the blueprint is
registered on the application.
"""
self.deferred_functions.append(func)
@staticmethod
def group(*blueprints, url_prefix=""):
"""Create a list of blueprints, optionally
grouping them under a general URL prefix.
def make_setup_state(self, app, options):
:param blueprints: blueprints to be registered as a group
:param url_prefix: URL route to be prepended to all sub-prefixes
"""
"""
return BlueprintSetup(self, app, options)
def chain(nested):
"""itertools.chain() but leaves strings untouched"""
for i in nested:
if isinstance(i, (list, tuple)):
yield from chain(i)
else:
yield i
bps = []
for bp in chain(blueprints):
if bp.url_prefix is None:
bp.url_prefix = ""
bp.url_prefix = url_prefix + bp.url_prefix
bps.append(bp)
return bps
def register(self, app, options):
"""
"""
state = self.make_setup_state(app, options)
for deferred in self.deferred_functions:
deferred(state)
"""Register the blueprint to the sanic app."""
def route(self, uri, methods=None):
"""
url_prefix = options.get("url_prefix", self.url_prefix)
# Routes
for future in self.routes:
# attach the blueprint name to the handler so that it can be
# prefixed properly in the router
future.handler.__blueprintname__ = self.name
# Prepend the blueprint URI prefix if available
uri = url_prefix + future.uri if url_prefix else future.uri
version = future.version or self.version
app.route(
uri=uri[1:] if uri.startswith("//") else uri,
methods=future.methods,
host=future.host or self.host,
strict_slashes=future.strict_slashes,
stream=future.stream,
version=version,
name=future.name,
)(future.handler)
for future in self.websocket_routes:
# attach the blueprint name to the handler so that it can be
# prefixed properly in the router
future.handler.__blueprintname__ = self.name
# Prepend the blueprint URI prefix if available
uri = url_prefix + future.uri if url_prefix else future.uri
app.websocket(
uri=uri,
host=future.host or self.host,
strict_slashes=future.strict_slashes,
name=future.name,
)(future.handler)
# Middleware
for future in self.middlewares:
if future.args or future.kwargs:
app.register_middleware(
future.middleware, *future.args, **future.kwargs
)
else:
app.register_middleware(future.middleware)
# Exceptions
for future in self.exceptions:
app.exception(*future.args, **future.kwargs)(future.handler)
# Static Files
for future in self.statics:
# Prepend the blueprint URI prefix if available
uri = url_prefix + future.uri if url_prefix else future.uri
app.static(
uri, future.file_or_directory, *future.args, **future.kwargs
)
# Event listeners
for event, listeners in self.listeners.items():
for listener in listeners:
app.listener(event)(listener)
def route(
self,
uri,
methods=frozenset({"GET"}),
host=None,
strict_slashes=None,
stream=False,
version=None,
name=None,
):
"""Create a blueprint route from a decorated function.
:param uri: endpoint at which the route will be accessible.
:param methods: list of acceptable HTTP methods.
"""
if strict_slashes is None:
strict_slashes = self.strict_slashes
def decorator(handler):
self.record(lambda s: s.add_route(handler, uri, methods))
route = FutureRoute(
handler,
uri,
methods,
host,
strict_slashes,
stream,
version,
name,
)
self.routes.append(route)
return handler
return decorator
def add_route(self, handler, uri, methods=None):
def add_route(
self,
handler,
uri,
methods=frozenset({"GET"}),
host=None,
strict_slashes=None,
version=None,
name=None,
):
"""Create a blueprint route from a function.
:param handler: function for handling uri requests. Accepts function,
or class instance with a view_class method.
:param uri: endpoint at which the route will be accessible.
:param methods: list of acceptable HTTP methods.
:param host:
:param strict_slashes:
:param version:
:param name: user defined route name for url_for
:return: function or class instance
"""
# Handle HTTPMethodView differently
if hasattr(handler, "view_class"):
methods = set()
for method in HTTP_METHODS:
if getattr(handler.view_class, method.lower(), None):
methods.add(method)
if strict_slashes is None:
strict_slashes = self.strict_slashes
# handle composition view differently
if isinstance(handler, CompositionView):
methods = handler.handlers.keys()
self.route(
uri=uri,
methods=methods,
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
)(handler)
return handler
def websocket(
self, uri, host=None, strict_slashes=None, version=None, name=None
):
"""Create a blueprint websocket route from a decorated function.
:param uri: endpoint at which the route will be accessible.
"""
self.record(lambda s: s.add_route(handler, uri, methods))
if strict_slashes is None:
strict_slashes = self.strict_slashes
def decorator(handler):
route = FutureRoute(
handler, uri, [], host, strict_slashes, False, version, name
)
self.websocket_routes.append(route)
return handler
return decorator
def add_websocket_route(
self, handler, uri, host=None, version=None, name=None
):
"""Create a blueprint websocket route from a function.
:param handler: function for handling uri requests. Accepts function,
or class instance with a view_class method.
:param uri: endpoint at which the route will be accessible.
:return: function or class instance
"""
self.websocket(uri=uri, host=host, version=version, name=name)(handler)
return handler
def listener(self, event):
"""Create a listener from a decorated function.
:param event: Event to listen to.
"""
"""
def decorator(listener):
self.listeners[event].append(listener)
return listener
return decorator
def middleware(self, *args, **kwargs):
"""
"""
def register_middleware(middleware):
self.record(
lambda s: s.add_middleware(middleware, *args, **kwargs))
return middleware
"""Create a blueprint middleware from a decorated function."""
def register_middleware(_middleware):
future_middleware = FutureMiddleware(_middleware, args, kwargs)
self.middlewares.append(future_middleware)
return _middleware
# Detect which way this was called, @middleware or @middleware('AT')
if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
@@ -122,15 +288,135 @@ class Blueprint:
return register_middleware
def exception(self, *args, **kwargs):
"""
"""
"""Create a blueprint exception from a decorated function."""
def decorator(handler):
self.record(lambda s: s.add_exception(handler, *args, **kwargs))
exception = FutureException(handler, args, kwargs)
self.exceptions.append(exception)
return handler
return decorator
def static(self, uri, file_or_directory, *args, **kwargs):
"""Create a blueprint static route from a decorated function.
:param uri: endpoint at which the route will be accessible.
:param file_or_directory: Static asset.
"""
"""
self.record(
lambda s: s.add_static(uri, file_or_directory, *args, **kwargs))
name = kwargs.pop("name", "static")
if not name.startswith(self.name + "."):
name = "{}.{}".format(self.name, name)
kwargs.update(name=name)
strict_slashes = kwargs.get("strict_slashes")
if strict_slashes is None and self.strict_slashes is not None:
kwargs.update(strict_slashes=self.strict_slashes)
static = FutureStatic(uri, file_or_directory, args, kwargs)
self.statics.append(static)
# Shorthand method decorators
def get(
self, uri, host=None, strict_slashes=None, version=None, name=None
):
return self.route(
uri,
methods=["GET"],
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
)
def post(
self,
uri,
host=None,
strict_slashes=None,
stream=False,
version=None,
name=None,
):
return self.route(
uri,
methods=["POST"],
host=host,
strict_slashes=strict_slashes,
stream=stream,
version=version,
name=name,
)
def put(
self,
uri,
host=None,
strict_slashes=None,
stream=False,
version=None,
name=None,
):
return self.route(
uri,
methods=["PUT"],
host=host,
strict_slashes=strict_slashes,
stream=stream,
version=version,
name=name,
)
def head(
self, uri, host=None, strict_slashes=None, version=None, name=None
):
return self.route(
uri,
methods=["HEAD"],
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
)
def options(
self, uri, host=None, strict_slashes=None, version=None, name=None
):
return self.route(
uri,
methods=["OPTIONS"],
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
)
def patch(
self,
uri,
host=None,
strict_slashes=None,
stream=False,
version=None,
name=None,
):
return self.route(
uri,
methods=["PATCH"],
host=host,
strict_slashes=strict_slashes,
stream=stream,
version=version,
name=name,
)
def delete(
self, uri, host=None, strict_slashes=None, version=None, name=None
):
return self.route(
uri,
methods=["DELETE"],
host=host,
strict_slashes=strict_slashes,
version=version,
name=name,
)

Some files were not shown because too many files have changed in this diff Show More