Untuk mengantisipasi dimulainya kursus " Pengembang Python. Profesional ", kami telah menyiapkan terjemahan tradisional dari artikel yang bermanfaat.
Halo semuanya, dalam artikel ini saya akan berbicara tentang membuat proyek asinkron sederhana pada kerangka kerja Sanic.
pengantar
Sanic β Flask - - Python 10 , . async/await, Python 3.5, .
β HTTP-, , .
, , , .
: github. .
Python3.6+
pipenv ( )
PostgreSQL ( , MySQL SQLite)
secure β , cookie - Python.
sanic-envconfig β , Sanic.
databases β Python, SQLAlchemy Core PostgreSQL, MySQL SQLite.
Pipfile.
pipenv β--βpython python3.6 , pipenv.
pipenv install sanic secure environs sanic-envconfig:
pipenv install databases[postgresql]postgresql, mysql, sqlite.
, .
βββ .env
βββ Pipfile
βββ Pipfile.lock
βββ setup.py
βββ project
βββ __init__.py
βββ __main__.py
βββ main.py
βββ middlewares.py
βββ routes.py
βββ settings.py
βββ tables.py setup.py, project .
from setuptools import setup
setup(
name='project',
)β¦
pipenv install -e . .env , .
_main_.py , project .
pipenv run python -m project main.py
from project.main import init
init() . init main.py.
from sanic import Sanic
app = Sanic(__name__)
def init():
app.run(host='0.0.0.0', port=8000, debug=True) app Sanic, , , debug.
β¦
pipenv run python -m project
Sanic . http://0.0.0.0:8000, :
Error: Requested URL / not found
, . .
. .env, Sanic.
.env
DEBUG=True
HOST=0.0.0.0
POST=8000β¦
from sanic import Sanic
from environs import Env
from project.settings import Settings
app = Sanic(__name__)
def init():
env = Env()
env.read_env()
app.config.from_object(Settings)
app.run(
host=app.config.HOST,
port=app.config.PORT,
debug=app.config.DEBUG,
auto_reload=app.config.DEBUG,
)settings.py
from sanic_envconfig import EnvConfig
class Settings(EnvConfig):
DEBUG: bool = True
HOST: str = '0.0.0.0'
PORT: int = 8000 , auto_reload, .
.
, .
databases asyncpg, PostgreSQL. . .

afterserverstart
afterserverstop
main.py
from sanic import Sanic
from databases import Database
from environs import Env
from project.settings import Settings
app = Sanic(__name__)
def setup_database():
app.db = Database(app.config.DB_URL)
@app.listener('after_server_start')
async def connect_to_db(*args, **kwargs):
await app.db.connect()
@app.listener('after_server_stop')
async def disconnect_from_db(*args, **kwargs):
await app.db.disconnect()
def init():
env = Env()
env.read_env()
app.config.from_object(Settings)
setup_database()
app.run(
host=app.config.HOST,
port=app.config.PORT,
debug=app.config.DEBUG,
auto_reload=app.config.DEBUG,
)-. DB_URL .
.env
DEBUG=True
HOST=0.0.0.0
POST=8000
DB_URL=postgresql://postgres:postgres@localhost/postgressettings.py:
from sanic_envconfig import EnvConfig
class Settings(EnvConfig):
DEBUG: bool = True
HOST: str = '0.0.0.0'
PORT: int = 8000
DB_URL: str = '', DB_URL . app.db. .
, SQL-.
tables.py SQLAlchemy.
import sqlalchemy
metadata = sqlalchemy.MetaData()
books = sqlalchemy.Table(
'books',
metadata,
sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
sqlalchemy.Column('title', sqlalchemy.String(length=100)),
sqlalchemy.Column('author', sqlalchemy.String(length=60)),
), books . Alembic β , SQLAlchemy Python.
SQLAlchemy. .
# Executing many
query = books.insert()
values = [
{"title": "No Highway", "author": "Nevil Shute"},
{"title": "The Daffodil", "author": "SkyH. E. Bates"},
]
await app.db.execute_many(query, values)
# Fetching multiple rows
query = books.select()
rows = await app.db.fetch_all(query)
# Fetch single row
query = books.select()
row = await app.db.fetch_one(query). routes.py books.
from sanic.response import json
from project.tables import books
def setup_routes(app):
@app.route("/books")
async def book_list(request):
query = books.select()
rows = await request.app.db.fetch_all(query)
return json({
'books': [{row['title']: row['author']} for row in rows]
}) , , init setup_routes.
from project.routes import setup_routes
app = Sanic(__name__)
def init():
...
app.config.from_object(Settings)
setup_database()
setup_routes(app)
...β¦
$ curl localhost:8000/books
{"books":[{"No Highway":"Nevil Shute"},{"The Daffodil":"SkyH. E. Bates"}]}Middleware
, -?
$ curl -I localhost:8000
Connection: keep-alive
Keep-Alive: 5
Content-Length: 32
Content-Type: text/plain; charset=utf-8, . , X-XSS-Protection, Strict-Transport-Security .. secure.
middlewares.py
from secure import SecureHeaders
secure_headers = SecureHeaders()
def setup_middlewares(app):
@app.middleware('response')
async def set_secure_headers(request, response):
secure_headers.sanic(response)middleware main.py:
from project.middlewares import setup_middlewares
app = Sanic(__name__)
def init():
...
app.config.from_object(Settings)
setup_database()
setup_routes(app)
setup_middlewares(app)
...:
$ curl -I localhost:8000/books
Connection: keep-alive
Keep-Alive: 5
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
Pragma: no-cache
Expires: 0
Cache-control: no-cache, no-store, must-revalidate, max-age=0
Content-Length: 32
Content-Type: text/plain; charset=utf-8. " Python C: Python " .