├── .gitignore ├── README.md ├── project └── .gitkeep ├── requirements.txt └── slides ├── assets ├── autocompletion.png ├── create-item.png ├── curl-body-params.svg ├── curl-data-validation.svg ├── curl-header-params.svg ├── curl-path-params.svg ├── curl-query-params.svg ├── curl-simple.svg ├── dependency-injection.svg ├── fastapi-background-tasks.svg ├── fastapi-body-params.svg ├── fastapi-data-validation.svg ├── fastapi-docs.png ├── fastapi-expert.png ├── fastapi-header-params.svg ├── fastapi-path-params.svg ├── fastapi-query-params.svg ├── fastapi-redoc.png ├── fastapi-simple.svg ├── fastapi-websockets.svg ├── lets-deploy-in.jpg ├── marcelo.png └── q&a.jpeg ├── index.md └── src ├── 1_fastapi_features ├── background_tasks.py ├── body_params.py ├── header_params.py ├── main.py ├── path_params.py ├── query_params.py └── ws.py ├── 2_data_validation └── main.py ├── 3_dependency_injection └── main.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with FastAPI 2 | 3 | This repository contains the code for the workshop "Getting Started with FastAPI" presented on the [O'Reilly Live Event]. 4 | 5 | ## Slides 6 | 7 | To run the slides, you need to have [npm](https://www.npmjs.com/get-npm) installed. 8 | 9 | ```bash 10 | npm install -g @marp-team/marp-cli 11 | ``` 12 | 13 | Then, you can run the slides with: 14 | 15 | ```bash 16 | marp -s slides 17 | ``` 18 | 19 | [O'Reilly Live Event]: https://www.oreilly.com/live-events/getting-started-with-fastapi/0636920081396/ 20 | -------------------------------------------------------------------------------- /project/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/project/.gitkeep -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn 3 | -------------------------------------------------------------------------------- /slides/assets/autocompletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/autocompletion.png -------------------------------------------------------------------------------- /slides/assets/create-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/create-item.png -------------------------------------------------------------------------------- /slides/assets/fastapi-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/fastapi-docs.png -------------------------------------------------------------------------------- /slides/assets/fastapi-expert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/fastapi-expert.png -------------------------------------------------------------------------------- /slides/assets/fastapi-redoc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/fastapi-redoc.png -------------------------------------------------------------------------------- /slides/assets/lets-deploy-in.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/lets-deploy-in.jpg -------------------------------------------------------------------------------- /slides/assets/marcelo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/marcelo.png -------------------------------------------------------------------------------- /slides/assets/q&a.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kludex/fastapi-workshop/7832ac033651516e2319f1601d2ef0761fa068a8/slides/assets/q&a.jpeg -------------------------------------------------------------------------------- /slides/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | theme: gaia 3 | class: lead 4 | paginate: true 5 | backgroundColor: #fff 6 | backgroundImage: url('https://marp.app/assets/hero-background.svg') 7 | footer: "@marcelotryle" 8 | marp: true 9 | style: | 10 | .columns { 11 | display: grid; 12 | grid-template-columns: repeat(2, minmax(0, 1fr)); 13 | gap: 1rem; 14 | } 15 | --- 16 | 17 | # Getting Started with FastAPI 18 | 19 | ![bg:40% 80%](assets/marcelo.png) 20 | Marcelo Trylesinski 21 | 22 | --- 23 | 24 | # About me 25 | 26 | ![w:600](https://live.staticflickr.com/4458/37545736336_93f1591985_b.jpg) 27 | 28 | --- 29 | 30 | ## FastAPI Expert 31 | 32 | ![w:950 center](assets//fastapi-expert.png) 33 | 34 | --- 35 | 36 | ## OSS Maintainer 37 | 38 | ### Uvicorn 39 | 40 | ![w:450](https://raw.githubusercontent.com/tomchristie/uvicorn/master/docs/uvicorn.png) 41 | 42 | --- 43 | 44 | ## OSS Maintainer 45 | 46 | ### Starlette 47 | 48 | ![w:600](https://www.starlette.io/img/starlette.png) 49 | 50 | --- 51 | 52 | ## What is FastAPI? 53 | 54 | **FastAPI** is a modern web framework used to build APIs based on Python type hints. 55 | 56 | --- 57 | 58 | ## Why FastAPI? 59 | 60 | - Fast Development 61 | - Easy to learn 62 | - Intuitive 63 | - Fewer bugs 64 | 65 | --- 66 | 67 | # FastAPI Application 68 | 69 | ![w:500 center](assets/fastapi-simple.svg) 70 | 71 | ![w:500 center](assets/curl-simple.svg) 72 | 73 | [Run it yourself!](https://github.com/Kludex/fastapi-workshop/blob/main/slides/src/1_fastapi_features/main.py) 74 | 75 | --- 76 | 77 | ## Path Parameters 78 | 79 | ![w:500 center](assets/fastapi-path-params.svg) 80 | 81 | ![w:500 center](assets/curl-path-params.svg) 82 | 83 | [Run it yourself!](https://github.com/Kludex/fastapi-workshop/blob/main/slides/src/1_fastapi_features/path_params.py) 84 | 85 | --- 86 | 87 | ## Query Parameters 88 | 89 | ![w:500 center](assets/fastapi-query-params.svg) 90 | 91 | ![w:500 center](assets/curl-query-params.svg) 92 | 93 | [Run it yourself!](https://github.com/Kludex/fastapi-workshop/blob/main/slides/src/1_fastapi_features/query_params.py) 94 | 95 | --- 96 | 97 | ## Request Body 98 | 99 | ![w:400 center](assets/fastapi-body-params.svg) 100 | 101 | ![w:600 center](assets/curl-body-params.svg) 102 | 103 | [Run it yourself!](https://github.com/Kludex/fastapi-workshop/blob/main/slides/src/1_fastapi_features/body_params.py) 104 | 105 | --- 106 | 107 | ## Header Parameters 108 | 109 | ![w:500 center](assets/fastapi-header-params.svg) 110 | 111 | ![w:500 center](assets/curl-header-params.svg) 112 | 113 | [Run it yourself!](https://github.com/Kludex/fastapi-workshop/blob/main/slides/src/1_fastapi_features/header_params.py) 114 | 115 | --- 116 | 117 | ## Documentation (`/docs`) 118 | 119 | ![w:950 center](assets/fastapi-docs.png) 120 | 121 | --- 122 | 123 | ## Documentation (`/redoc`) 124 | 125 | ![w:1200 center](assets/fastapi-redoc.png) 126 | 127 | --- 128 | 129 | ## Data Validation 130 | 131 | ![w:700 center](assets/fastapi-data-validation.svg) 132 | 133 | --- 134 | 135 | ## Data Validation 136 | 137 | ![w:900 center](assets/curl-data-validation.svg) 138 | 139 | --- 140 | 141 | ## Data Validation (`/docs`) 142 | 143 | ![w:800 center](assets/create-item.png) 144 | 145 | --- 146 | 147 | ## Autocomplete 148 | 149 | ![w:800 center](assets/autocompletion.png) 150 | 151 | --- 152 | 153 | ## Dependency Injection 154 | 155 | 156 | ![w:800 center](assets/dependency-injection.svg) 157 | 158 | --- 159 | 160 | ## Background Tasks 161 | 162 | ![w:800 center](assets/fastapi-background-tasks.svg) 163 | 164 | [Run it yourself!](https://github.com/Kludex/fastapi-workshop/blob/main/slides/src/1_fastapi_features/background_tasks.py) 165 | 166 | --- 167 | 168 | ## WebSockets 169 | 170 | ![w:800 center](assets/fastapi-websockets.svg) 171 | 172 | --- 173 | 174 | # FastAPI Features 175 | 176 | https://fastapi.tiangolo.com/features/ 177 | 178 | --- 179 | 180 | ## Q&A 181 | 182 | ![w:500 center](assets/q&a.jpeg) 183 | 184 | --- 185 | 186 | ## Hands-on FastAPI 187 | 188 | --- 189 | 190 | ## The Project 191 | 192 | The project we are going to create is a simple API that allows us to create, read, update and delete items. 193 | 194 | 1. The items will have a name and a price. 195 | 2. We will store the items in a database. 196 | 3. We will be able to retrieve the items, create new items, update existing items and delete items. 197 | 4. We will be able to retrieve a single item with a specific name. 198 | 5. We will be able to retrieve only the items that cost less than a specific price. 199 | 200 | --- 201 | 202 | ## Create the Project 203 | 204 | Follow up on [FastAPI Workshop](https://github.com/Kludex/fastapi-workshop/). 205 | 206 | --- 207 | 208 | ## Exercise: Test the application 209 | 210 | --- 211 | 212 | ## Q&A 213 | 214 | ![w:500 center](assets/q&a.jpeg) 215 | 216 | --- 217 | 218 | ## Let's Deploy! 219 | 220 | ![bg:40% 80%](assets/lets-deploy-in.jpg) 221 | 222 | --- 223 | 224 | ## Let's Deploy! 225 | 226 | Install [Google Cloud SDK](https://cloud.google.com/sdk/docs/install-sdk) 227 | 228 | (If you are on Ubuntu: `snap install google-cloud-cli --classic`) 229 | 230 | --- 231 | 232 | ## Let's Deploy! 233 | 234 | Read [FastAPI documentation](https://fastapi.tiangolo.com/deployment/) about deployment 235 | 236 | --- 237 | 238 | ## Q&A 239 | 240 | ![w:500 center](assets/q&a.jpeg) 241 | 242 | --- 243 | 244 | ## How to proceed from here? 245 | 246 | Read the documentation: https://fastapi.tiangolo.com/ 247 | 248 | --- 249 | 250 | ## You can help the FastAPI Community 251 | 252 | 1. Answer issues 253 | 2. Join the Discord server 254 | 3. Help on underneath projects like Starlette and Pydantic 255 | 256 | --- 257 | 258 | ## Follow me 259 | 260 | - Twitter: https://twitter.com/marcelotryle 261 | - GitHub: https://github.com/kludex 262 | - LinkedIn: https://www.linkedin.com/in/marcelotryle/ 263 | 264 | --- 265 | 266 | ## Q&A 267 | 268 | ![w:500 center](assets/q&a.jpeg) 269 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/background_tasks.py: -------------------------------------------------------------------------------- 1 | from fastapi import BackgroundTasks, FastAPI 2 | 3 | app = FastAPI() 4 | 5 | 6 | def notify_user(): 7 | print("Sending email to user...") 8 | 9 | 10 | @app.get("/") 11 | async def home(background_tasks: BackgroundTasks): 12 | background_tasks.add_task(notify_user) 13 | return {"message": "Hello World"} 14 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/body_params.py: -------------------------------------------------------------------------------- 1 | """ 2 | This example shows how to use body parameters. 3 | 4 | To run this example, use the following command: 5 | 6 | uvicorn body_params:app --reload 7 | 8 | And then open your browser at http://localhost:8000/docs. 9 | """ 10 | 11 | from fastapi import FastAPI 12 | from pydantic import BaseModel 13 | 14 | app = FastAPI() 15 | 16 | 17 | class Item(BaseModel): 18 | name: str 19 | description: str 20 | 21 | 22 | @app.post("/items/") 23 | async def create_item(item: Item): 24 | return item 25 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/header_params.py: -------------------------------------------------------------------------------- 1 | """ 2 | This example shows how to use query parameters in FastAPI. 3 | 4 | Run the example with: 5 | 6 | uvicorn header_params:app --reload 7 | 8 | And then go to http://localhost:8000/?query=myquery 9 | """ 10 | 11 | from fastapi import FastAPI, Header 12 | 13 | app = FastAPI() 14 | 15 | 16 | @app.get("/") 17 | async def home(x_potato_header: str = Header(...)): 18 | return {"header": x_potato_header} 19 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a simple FastAPI application. 3 | 4 | You can run it with uvicorn: 5 | 6 | uvicorn main:app 7 | 8 | And then visit http://localhost:8000 in your browser. 9 | """ 10 | from fastapi import FastAPI 11 | 12 | app = FastAPI() 13 | 14 | 15 | @app.get("/") 16 | def home(): 17 | return {"Hello": "World"} 18 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/path_params.py: -------------------------------------------------------------------------------- 1 | """ 2 | This application uses path parameters. 3 | 4 | You can run it with uvicorn: 5 | 6 | uvicorn path_params:app 7 | 8 | And then visit http://localhost:8000/your_name in your browser. 9 | """ 10 | 11 | from fastapi import FastAPI 12 | 13 | app = FastAPI() 14 | 15 | 16 | @app.get("/{name}") 17 | def home(name: str): 18 | return {"Hello": name} 19 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/query_params.py: -------------------------------------------------------------------------------- 1 | """ 2 | This example shows how to use query parameters in FastAPI. 3 | 4 | Run the example with: 5 | 6 | uvicorn query_params:app --reload 7 | 8 | And then go to http://localhost:8000/?query=myquery 9 | """ 10 | 11 | from fastapi import FastAPI 12 | 13 | app = FastAPI() 14 | 15 | 16 | @app.get("/") 17 | async def home(query: str): 18 | return {"query": query} 19 | -------------------------------------------------------------------------------- /slides/src/1_fastapi_features/ws.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a simple example of a WebSocket endpoint. 3 | 4 | It accepts a WebSocket connection, sends a message, and then closes the connection. 5 | 6 | You can test it with the following command: 7 | 8 | uvicorn ws:app --reload 9 | 10 | And then using a WebSocket client like wscat: 11 | 12 | wscat -c ws://localhost:8000/ws 13 | """ 14 | 15 | from fastapi import FastAPI, WebSocket 16 | 17 | app = FastAPI() 18 | 19 | 20 | @app.websocket("/ws") 21 | async def websocket_endpoint(websocket: WebSocket): 22 | await websocket.accept() 23 | await websocket.send_text("Hello WebSocket!") 24 | await websocket.close() 25 | -------------------------------------------------------------------------------- /slides/src/2_data_validation/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is an application that uses data validation. 3 | """ 4 | from fastapi import FastAPI 5 | from pydantic import BaseModel 6 | 7 | app = FastAPI() 8 | 9 | 10 | class Item(BaseModel): 11 | name: str 12 | description: str 13 | price: float 14 | 15 | 16 | class ItemOutput(Item): 17 | item_id: int 18 | 19 | 20 | @app.post("/items/", response_model=ItemOutput) 21 | def create_item(item: Item): 22 | item.de # This line fails! 23 | return {"item_id": 42, **item.dict()} 24 | -------------------------------------------------------------------------------- /slides/src/3_dependency_injection/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is an application that uses dependency injection. 3 | 4 | You can run it with uvicorn: 5 | 6 | uvicorn main:app 7 | 8 | And then visit http://localhost:8000/items/42 in your browser. 9 | """ 10 | from fastapi import Depends, FastAPI 11 | 12 | app = FastAPI() 13 | 14 | 15 | class Session: 16 | def query(self, item_id: str): 17 | return {"name": "foo", "id": item_id} 18 | 19 | def close(self): 20 | ... 21 | 22 | 23 | def get_session(): 24 | session = Session() 25 | yield session 26 | session.close() 27 | 28 | 29 | @app.get("/items/{item_id}") 30 | async def read_item(item_id: str, session: Session = Depends(get_session)): 31 | return session.query(item_id=item_id) 32 | -------------------------------------------------------------------------------- /slides/src/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn 3 | sqlalchemy 4 | websockets 5 | 6 | flake8 7 | isort 8 | black 9 | mypy 10 | --------------------------------------------------------------------------------