Browse Source

Add events docs and tests (#99)

pull/100/head
Sebastián Ramírez 6 years ago
committed by GitHub
parent
commit
834723cf2c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. 16
      docs/src/events/tutorial001.py
  3. 14
      docs/src/events/tutorial002.py
  4. 43
      docs/tutorial/events.md
  5. 1
      mkdocs.yml
  6. 0
      tests/test_tutorial/test_events/__init__.py
  7. 79
      tests/test_tutorial/test_events/test_tutorial001.py
  8. 34
      tests/test_tutorial/test_events/test_tutorial002.py

1
.gitignore

@ -11,3 +11,4 @@ site
coverage.xml
.netlify
test.db
log.txt

16
docs/src/events/tutorial001.py

@ -0,0 +1,16 @@
from fastapi import FastAPI
app = FastAPI()
items = {}
@app.on_event("startup")
async def startup_event():
items["foo"] = {"name": "Fighters"}
items["bar"] = {"name": "Tenders"}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
return items[item_id]

14
docs/src/events/tutorial002.py

@ -0,0 +1,14 @@
from fastapi import FastAPI
app = FastAPI()
@app.on_event("shutdown")
def startup_event():
with open("log.txt", mode="a") as log:
log.write("Application shutdown")
@app.get("/items/")
async def read_items():
return [{"name": "Foo"}]

43
docs/tutorial/events.md

@ -0,0 +1,43 @@
You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down.
These functions can be declared with `async def` or normal `def`.
## `startup` event
To add a function that should be run before the application starts, declare it with the event `"startup"`:
```Python hl_lines="8"
{!./src/events/tutorial001.py!}
```
In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
You can add more than one event handler function.
And your application won't start receiving requests until all the `startup` event handlers have completed.
## `shutdown` event
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
```Python hl_lines="6"
{!./src/events/tutorial002.py!}
```
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
!!! info
In the `open()` function, the `mode="a"` means "append", so, the line will be added after whatever is on that file, without overwriting the previous contents.
!!! tip
Notice that in this case we are using a standard Python `open()` function that interacts with a file.
So, it involves I/O (input/output), that requires "waiting" for things to be written to disk.
But `open()` doesn't use `async` and `await`.
So, we declare the event handler function with standard `def` instead of `async def`.
!!! info
You can read more about these event handlers in <a href="https://www.starlette.io/events/" target="_blank">Starlette's Events' docs</a>.

1
mkdocs.yml

@ -63,6 +63,7 @@ nav:
- Application Configuration: 'tutorial/application-configuration.md'
- GraphQL: 'tutorial/graphql.md'
- WebSockets: 'tutorial/websockets.md'
- 'Events: startup - shutdown': 'tutorial/events.md'
- Debugging: 'tutorial/debugging.md'
- Concurrency and async / await: 'async.md'
- Deployment: 'deployment.md'

0
tests/test_tutorial/test_events/__init__.py

79
tests/test_tutorial/test_events/test_tutorial001.py

@ -0,0 +1,79 @@
from starlette.testclient import TestClient
from events.tutorial001 import app
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "Fast API", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Read Item Get",
"operationId": "read_item_items__item_id__get",
"parameters": [
{
"required": True,
"schema": {"title": "Item_Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
}
},
"components": {
"schemas": {
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {"type": "string"},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
}
},
}
def test_events():
with TestClient(app) as client:
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
response = client.get("/items/foo")
assert response.status_code == 200
assert response.json() == {"name": "Fighters"}

34
tests/test_tutorial/test_events/test_tutorial002.py

@ -0,0 +1,34 @@
from starlette.testclient import TestClient
from events.tutorial002 import app
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "Fast API", "version": "0.1.0"},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Items Get",
"operationId": "read_items_items__get",
}
}
},
}
def test_events():
with TestClient(app) as client:
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
response = client.get("/items/")
assert response.status_code == 200
assert response.json() == [{"name": "Foo"}]
with open("log.txt") as log:
assert "Application shutdown" in log.read()
Loading…
Cancel
Save