Build | |
---|---|
Docs | |
Package | |
Support | |
Stats |
Sanic is a Python 3.9+ web server and web framework that's written to go fast. It allows the usage of the async/await
syntax added in Python 3.5, which makes your code non-blocking and speedy.
Sanic is also ASGI compliant, so you can deploy it with an alternative ASGI webserver.
Source code on GitHub | Help and discussion board | User Guide | Chat on Discord
The project is maintained by the community, for the community. Contributions are welcome!
The goal of the project is to provide a simple way to get up and running a highly performant HTTP server that is easy to build, to expand, and ultimately to scale.
Check out open collective to learn more about helping to fund Sanic.
pip3 install sanic
Sanic makes use of
uvloop
andujson
to help with performance. If you do not want to use those packages, simply add an environmental variableSANIC_NO_UVLOOP=true
orSANIC_NO_UJSON=true
at install time.$ export SANIC_NO_UVLOOP=true $ export SANIC_NO_UJSON=true $ pip3 install --no-binary :all: sanicNote
If you are running on a clean install of Fedora 28 or above, please make sure you have the
redhat-rpm-config
package installed in case if you want to usesanic
withujson
dependency.from sanic import Sanic from sanic.response import json app = Sanic("my-hello-world-app") @app.route('/') async def test(request): return json({'hello': 'world'}) if __name__ == '__main__': app.run()Sanic can now be easily run using
sanic hello.app
.[2018-12-30 11:37:41 +0200] [13564] [INFO] Goin' Fast @ http://127.0.0.1:8000 [2018-12-30 11:37:41 +0200] [13564] [INFO] Starting worker [13564]And, we can verify it is working:
curl localhost:8000 -i
HTTP/1.1 200 OK Connection: keep-alive Keep-Alive: 5 Content-Length: 17 Content-Type: application/json {"hello":"world"}Now, let's go build something fast!
Minimum Python version is 3.8. If you need Python 3.7 support, please use v22.12LTS.
User Guide, Changelog, and API Documentation can be found at sanic.dev.
Ask a question or join the conversation.
We are always happy to have new contributions. We have marked issues good for anyone looking to get started, and welcome questions on the forums. Please take a look at our Contribution guidelines.
sanic's People
Forkers
psykzz seemethere n1ywb bikegriffith narzeja suzaku ph87 jpiasetz kolanos sm5art neuroradiology cclauss polarp rockystevejobs yuxiaqiao nareshku taeguk xavitorello techscientist mindflayer mountain3th guoyu07 mrccao rick-xu shivanikhosa nixiaocang satilew tanda517886160 npc7 0xcffec7bf howardyan93 simanto604newscred dotoca freylis rainyear alexyer vshangxiao houleitaidii mnpk tuannh99 leolujuyi melodya000 alihalabyah raj347 kylefrost kinguistar blakev benjamesbabala lau-jay dudisbrie oxbambooxo eyepea 8dspaces vromanov janusnic pathcl zhiruchen vuchau karec kpdb pcdinh montazze thuongdinh-agilityio christensonb swelham mythquan awesome-archive rogererens cporoske pablosajnovsky imbolc rohitkrai03 mechcoding eaglewei josphatowino akshbn ruchir594 speedcell4 amsb burningyu xinyvz lzydou jackfischer maksymdelta clenimar xiaosimao yinrongping andypau jxf211 atribecalledkwest cjhp1314 ariesw ryankung sharpek python3 dputtick argaen wushuyi guidiego darkdaresanic's Issues
Unable to start with multiple workers.
Using https://github.com/channelcat/sanic/blob/master/examples/simple_server.py adding
workers=4
to run fails. But works fine otherwise:2016-10-18 17:33:20,078: INFO: Goin' Fast @ http://0.0.0.0:8000 2016-10-18 17:33:20,078: INFO: Spinning up 4 workers... 2016-10-18 17:33:20,115: ERROR: Unable to start server: [Errno 22] Invalid argument 2016-10-18 17:33:20,126: ERROR: Unable to start server: [Errno 22] Invalid argument 2016-10-18 17:33:20,140: ERROR: Unable to start server: [Errno 22] Invalid argument 2016-10-18 17:33:20,150: ERROR: Unable to start server: [Errno 22] Invalid argument
Will try and debug more in a bit, but not sure what is going on yet.
Oh, and running the latest version from pip, have not pulled the latest git, if there has been a fix already.
asyncio signal handlers don't work on Windows
Sanic attempts to register signal handlers here:
https://github.com/channelcat/sanic/blob/master/sanic/server.py#L227But using the asyncio event loop (as is the fallback when uvloop can't be imported) does not implement signal handlers. See https://docs.python.org/3/library/asyncio-eventloops.html#windows where it states this, and the code at https://github.com/python/asyncio/blob/master/asyncio/events.py#L480
Commenting out the signal lines in sanic allows sanic to run on windows (yay) but then you can't Ctrl-C out of it, you must kill the python process
Multiple CPU Core Usage?
While sanic is super fast on a single process, it still leaves the other cores on the machine idle. I had hoped being 'flask like' it would drop into uWSGI just as easily but that does not appear to be the case in my experimentation. Attempting to use it as a drop in replacement to a flask app returns
TypeError: 'Sanic' object is not callable
I do not know if this is even feasible while still keeping the speed improvements, but compatibility with uWSGI, or some other method to fully utilize the CPU of a server would be extremely useful. If there is already a method of doing this, I was unable to find it in the examples or docs and additional information on the method would be extremely useful.
No request param in blueprint docs
@bp.route('/') async def bp_root(): return json({'my': 'blueprint'})
should be
@bp.route('/') async def bp_root(request): return json({'my': 'blueprint'})
Running tasks in background
Hey, awesome job!
I would like to know if it`s possible to run tasks in the background (the tasks of course must be async).For examples:
- I want a task that runs every 1 minute and do a REST request and save the results in global variables (so my REST endpoints will use that "cached" data)
- I want to read from kafka topic and save the latest result in a global variable (so my REST endpoints will use that "cached" data)
Is that possible and how do you recommend me to do that?
Thanks!Examples - SQLAlchemy
Create a new example of how to use SQLalchemy with Sanic. It can be a simple python file or an organized project in its own folder, whichever is easiest to understand and gets someone started on the right track.
Example of sqlalchemy + aiopg:
https://aiopg.readthedocs.io/en/stable/#sqlalchemy-and-aiopgMore research needs to be done on integration with other popular DBs - I'm not sure if this will up the difficulty so I tagged it as both beginner and intermediate.
Feedback on cache layer
Hi! really interesting project :).
I'm developing an asynchronous cache https://github.com/argaen/aiocache. The project is quite new but I'm looking for feedback and new use cases which will help to improve the interface and its usability.
I want the project to be really easy to integrate with other frameworks so I would really appreciate opinions on it :P.
Thanks a lot! :)
Unreachable code in sanic.py middleware
Unreachable code:
# sanic/sanic.py 76 # Detect which way this was called, @middleware or @middleware('AT') 77 if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): 78 return register_middleware(args[0]) 79 else: 80 attach_to = args[0] 81 return register_middleware 82 ################################## ENDS HERE 83 if isinstance(middleware, FunctionType): 84 middleware = Middleware(process_request=middleware) 85 86 return middleware
Gunicorn worker
Is there any way to mix sanic with gunicorn? Gunicorn has signals to increase/decrease workers and a bunch of other features that are useful in running a service in production.
Add web*socket* support
Maybe a plugin or a builtin support for websocket will be great.
Add Kyoukai comparisons
https://github.com/SunDwarf/Kyoukai โ uses asyncio + Ashpalt (and is also quite Flask-ish)
Handling redployments
Hiya,
One thing that's not clear to me from the documentation is how users should be expected to handle app redeployments (without dropping existing connections). Presumably you'd need to bring up the new servers on a different port, switch the load balancer, and then (gracefully) stop the existing server.
- Does sanic handle graceful redeployment without dropping connections?
- Have I misunderstood how app redeployment should be handled with sanic?
- Would this be worth documenting in the deployment section.
(Also related to #61 since graceful reloads are one of the benefits of running an application framework underneath a server such as gunicorn.)
Include script to run performance tests
Via
contributing.md
: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.
I'm afraid to make any "big" change attempts without knowing the exact way you're running the speed tests.
Add some more documentation in some of the source code?
Not too sure if this is planned, but figured it would help in terms of further contributions as the codebase continues to grow.
Content Type of JSON response should not have a charset
Content type of JSON is always utf-8, so
content_type="application/json; charset=utf-8")
should be
content_type="application/json")
Error: Overlong 2 byte UTF-8 sequence detected when encoding string
while
return json(doc)
,doc
is fetched from mongodb.Missing requirements for testing/dev
aiohttp and pytest is required for testing/development (
python -m pytest tests
), but they are not included in a development requirements.txt. #20 solves this.something pushed to the master broke latency
the speed dropped significantly to roughly 3k on my machine compared to 33k
Blueprint support
Add blueprint support, as it makes maintaining and separating larger applications much easier.
I'm currently working on a prototype implementing basic blueprint functionality. For now, only uri's (with blueprint url prefixes) will be supported, not handling blueprint specific static/template endpoints.
I aim to have a PR ready some time tomorrow, but I need to formulate some tests and documentation first.My current working example looks like this:
from sanic import Sanic from sanic import Blueprint from sanic.response import json, text app = Sanic(__name__) blueprint = Blueprint('name', url_prefix='/my_blueprint') blueprint2 = Blueprint('name2', url_prefix='/my_blueprint2') @blueprint.route('/foo') async def foo(request): return json({'msg': 'hi from blueprint'}) @blueprint2.route('/foo') async def foo2(request): return json({'msg': 'hi from blueprint2'}) app.register_blueprint(blueprint) app.register_blueprint(blueprint2) app.run(host="0.0.0.0", port=8000, debug=True)Yielding the following routes to the application:
/my_blueprint/foo /my_blueprint2/foo
201 should be recognized as a valid status code
STATUS_CODES dict in response.py should include 201 as CREATED.
Blueprint middleware applied globally
I was a little too hasty updating the blueprints documentation for middleware/exceptions, and just realized that middlewares and exceptions registered through a blueprint decorator are applied to all routes.
Is this intended behaviour? If so, then the the blueprint documentation must be updated once more.
Alternative behaviour: middleware registered on a blueprint, are only applied to routes for that blueprint.
Some considerations:
- should middleware applied to the app-object (instance of Sanic) also be applied to blueprint middleware?
- if so, how will ordering be handled?
Msgpack as an alternative to ujson
What do you think about msgpack as json lib? As I know it is faster than ujson.
https://gist.github.com/cactus/4073643
https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/
https://gist.github.com/msiedlarek/4985748#file-ujson_vs_msgpack-py(my results:
json: 32.72526153300714
ujson: 33.44454480899731
msgpack: 9.162779016012792)I think it will be great to replace ujson to msgpack or just move ujson to another level of abstraction to have ability to choose between msgpack or ujson or smth else.
Add benchmarking to Travis gate job?
Maybe we should add a simple benchmark to make sure that any changes added won't mess with the performance so that every pull request gets run against the same benchmark.
Serving Static Content
Sending binary files shouldn't be part of the project boiler plate, I think it should be included in the framework itself. This is a simplified version I made from Flask's
send_file
import os import mimetypes from sanic.response import HTTPResponse def sendfile(location, mimetype=None, add_etags=True): headers = {} filename = os.path.split(location)[-1] with open(location, 'rb') as ins_file: out_stream = ins_file.read() if add_etags: headers['ETag'] = '{}-{}-{}'.format( int(os.path.getmtime(location)), hex(os.path.getsize(location)), adler32(location.encode('utf-8')) & 0xffffffff) mimetype = mimetype or mimetypes.guess_type(filename)[0] or 'text/plain' return HTTPResponse(status=200, headers=headers, content_type=mimetype, body_bytes=out_stream)Add tornadoweb comparisons
TornadoWeb is a Python web framework and asynchronous networking library.
Sure on Py3
Cookie Support
Cookie support is needed for both requests and responses.
Request:
- Provide a cookie property with caching to self.parsed_cookies
- optimally, it should just be a dictionary of cookie keys to cookie values, to be used like:
cookie_value = request.cookies['cookie_name']Response:
- Interface could look like:
response.cookies['cookie_name'] = 'cookie_value' response.cookies.set(name='cookie_name', value='cookie_value', secure=True,\ http_only=True, domain='.my-domain.com', path='/my-path', \ expires=datetime.now(), max_age=timedelta(days=1))
- Ideally, this should update the Set-Cookies header of the response when cookies are set.
Add Bottle.py + Gunicorn comparisons?
When I see a lightweight framework like this, I compare it to something like Bottle before Flask. Would be nice to see how it compares with the rest of the frameworks up there.
Examples - Peewee Async
Create a new example of how to use peewee-async with Sanic. It can be a simple python file or an organized project in its own folder, whichever is easiest to understand and gets someone started on the right track.
Peewee-async docs:
https://peewee-async.readthedocs.io/en/latest/what's the unhashable url ?
I've read the source code of route part and find https://github.com/channelcat/sanic/blob/master/sanic/router.py#L82 , I wonder what's the unhashable url and if you can give an example :)
Configuration
I was hoping this would be a one for one replacement of Flask, but the configurations don't seem to line up and I can't find any documentation on configuration.
Any help would be appreciated. I am willing to help if I can.
Prioritizing TODOs
Noticed a fair amount of TODOs in the code, would be great to prioritize what needs to be done. Maybe ranking it in terms of difficulty as well for contributors who are at the beginner level all the way to expert?
thank you
There need a requirement of 'aiohttp' in requirements.txt
I think there need add a requirement of 'aiohttp' in requirements.txt.
Incompatible with windows
C:\Users\martijn>pip install https://github.com/channelcat/sanic/archive/master.zip Collecting https://github.com/channelcat/sanic/archive/master.zip Downloading https://github.com/channelcat/sanic/archive/master.zip | 30kB 364kB/s Collecting uvloop>=0.5.3 (from Sanic==0.1.0) Downloading uvloop-0.5.4.tar.gz (1.9MB) 100% |################################| 1.9MB 180kB/s Complete output from command python setup.py egg_info: Traceback (most recent call last): File "<string>", line 1, in <module> File "C:\Users\martijn\AppData\Local\Temp\pip-build-gylxe2o1\uvloop\setup.py", line 9, in <module> raise RuntimeError('uvloop does not support Windows at the moment') RuntimeError: uvloop does not support Windows at the moment ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in C:\Users\martijn\AppData\Local\Temp\pip-build-gylxe2o1\uvloop\
I know this is technically a uvloop issue, but since it affects this repo as well I suggest making an alternative for windows users
Failure to write request swallows problem
server.py, line 137-139:
If the response is malformed, Sanic will log an error (thankfully), but will not return any kind of response (simply killing the connection).Sanic should generate an exception that can be handled by the error handler, and ultimately return a 500.
Note that this can be generated by attempting to return a Flask-type tuple instead of a Sanic response object.
Templates support
What do you think about integrate templates (jinja2?) into sanic core? I think the popularity of django and flask largely depends on their ability to write and distribute independent apps, which contains its own routes, handlers, templates and static files. Sanic has all of this except of templates.
If you agree, I suggest the next api:
render_string('index.html', context) render('index.html', context) @app.context_processor @bp.context_processor @app.template('index.html') @bp.template('index.html')
Code is indented with tabs instead of spaces
Just wanted to comment on this because I wanted to contribute some documentation for sanic, but I just wanted to let you know all of your indentation right now is being done with tabs.
Instead of submitting a pull request for this though, and overwriting all the hard work you did to get this up and running, I thought I would submit an issue to allow you to fix it yourself.
It's as easy as running
:retab
in vim or if you are using pycharm it's as easy as reformatting.Or you could use something like sed.
I can still take care of it if you want just let me know.
Example of using async requests
I actually don't know if it requires a custom requests library or if it's something that can be done "natively" with sanic, but being able to do requests queries async would be awesome. Then you don't have to worry about blocking when doing a sloooow
requests.post(...)
.
Also, something I'm personally interested in, is the ability to use elasticsearch in an async matter.way too anonymous
@channelcat As you've left no identifying information about yourself for correspondence about sanic I have no choice but to write you here. I authored Yosai and would like to see how it could be used to secure sanic applications.
Subdomains in Blueprints
Can i use subdomain routing with blueprints? Basically i have more than two or three modules that i want to be on different subdomains using Blueprints. Below is the code for doing it in flask, but can i do something like this in sanic?
# -*- coding: utf-8 -*- from flask import Flask, Blueprint app = Flask(__name__) app.config.DEBUG = True www = Blueprint('www', 'www', subdomain='www') sub = Blueprint('sub', 'sub', subdomain='sub') @www.route('/') def www_hello(): return 'www.www_hello' @sub.route('/') def sub_hello(): return 'sub.sub_hello' app.register_blueprint(www) app.register_blueprint(sub) if __name__ == '__main__': app.run(host='127.0.0.1', port=8888, debug=True)Route parameters with dots or other punctuation not working
Hi, Thanks for the great work on Sanic!
I just started using it for a small project of mine. One bug which i ran into was its inability to parse parameters with punctuation in them, like so:@app.route('/entries/domain/<domain>') async def get_entries_for_domain(request, domain): ... GET http://0.0.0.0:8000/entries/domain/kernel.org Error: Requested URL /entries/domain/kernel.org not found
But at the same time fetching the
/entries/domain/kernel_org
endpoint works.
Any way to work around this?Document logging
Sanic doesn't have a logger like flask, so how to use logging in it
Consider allowing a string response to be inferred as `text(..)`
Instead of saying
return text(..)
in a route, allowreturn 'my text'
by inferring the response type inwrite_response
.sanic/server.py:
class HttpProtocol ... ... def write_response(self, response): try: keep_alive = self.parser.should_keep_alive() and not self.signal.stopped try: self.transport.write(response.output(self.request.version, keep_alive, self.request_timeout)) except AttributeError: # attempt to send the response as a text response if isinstance(response, str): response = text(response) self.transport.write(response.output(self.request.version, keep_alive, self.request_timeout)) else: raise if not keep_alive: self.transport.close() else: self.cleanup() except Exception as e: self.bail_out("Writing request failed, connection closed {}".format(e))Everyone uses uWSGI + Nginx not Gunicorn to go fast
Benchmarks should use uWSGI + Nginx.
Why not just wait() for the stop event to happen?
in: https://github.com/channelcat/sanic/blob/master/sanic/sanic.py#L257 you spin every 0.3 seconds checking if the event has been set, why not just wait on the event?
Expose the event loop as an optional parameter to `app.run(..)`
Since the event loop is created in
server.serve
it could be beneficial to expose passing a pre-allocated event loop that could be used before the server starts to enable database connections and such.Request argument as a global variable
I think it's a little long-winded.
in sanic:@app.route("/") async def test(request): return json({"test": True})in flask:
@app.route("/") def hello(): return "Hello World!"Since each function takes a request argument, why not set it as a global variable.
Could you tell me the reason why you don't do this๏ผthank youTravis CI?
Maybe a travis CI can be setup to automatically run tests on PR (including flake8 plz) and to also automate the submittal to PyPI.
Get into TechEmpower benchmarks
I think it'd be useful to have sanic in the TechEmpower benchmarks so that more users can discover it.
The instructions to get in are found here:
https://www.techempower.com/benchmarks/#section=codeAnd sample applications can be found here:
https://github.com/TechEmpower/FrameworkBenchmarksSwagger/OpenAPI Support
It would be nice to have Swagger/OpenAPI support. I'm not sure what the most intuitive way to implement this is.
Some examples, for inspiration:
- Flask-swagger - Uses YAML appended to docstring
- Connexion - Reads YAML swagger doc files and hosts a swagger UI
Recommend Projects
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
TensorFlow
An Open Source Machine Learning Framework for Everyone
Django
The Web framework for perfectionists with deadlines.
Laravel
A PHP framework for web artisans
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
Recommend Topics
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
web
Some thing interesting about web. New door for the world.
server
A server is a program made to process requests and deliver data to clients.
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Visualization
Some thing interesting about visualization, use data art
Game
Some thing interesting about game, make everyone happy.
Recommend Org
We are working to build community through open source technology. NB: members must have two-factor auth.
Microsoft
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba
Alibaba Open Source for everyone
D3
Data-Driven Documents codes.
Tencent
China tencent open source team.