Skip to content

Commit 77fe34e

Browse files
authored
Merge pull request #98 from tecladocode/develop
2 parents bd7d743 + d5d9827 commit 77fe34e

File tree

97 files changed

+1024
-691
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1024
-691
lines changed

.github/workflows/algolia-scraper.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Run Algolia Scraper
2+
3+
on:
4+
push:
5+
branches: ["master", "develop"]
6+
pull_request:
7+
branches: ["master", "develop"]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v2
17+
- uses: darrenjennings/algolia-docsearch-action@master
18+
with:
19+
algolia_application_id: "1BEGBIP9SH"
20+
algolia_api_key: ${{ secrets.ALGOLIA_API_KEY }}
21+
file: "docs/algolia.config.json"

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<div align="center">
88

9-
[![Udemy rating 4.6/5](https://img.shields.io/badge/udemy-4.6%2F5-brightgreen)](https://go.tecla.do/rest-apis-sale) ![GitHub last commit](https://img.shields.io/github/last-commit/tecladocode/rest-apis-flask-python/develop) ![Python 3.10](https://img.shields.io/badge/python-3.10-yellow) [![Discord](https://img.shields.io/discord/614395983807250433)](https://discord.gg/78Nvd3p) [![Twitter Follow](https://img.shields.io/twitter/follow/jslvtr?style=social) ](https://twitter.com/jslvtr)
9+
[![Udemy rating 4.6/5](https://img.shields.io/badge/udemy-4.6%2F5-brightgreen)](https://go.tecla.do/rest-apis-ebook) ![GitHub last commit](https://img.shields.io/github/last-commit/tecladocode/rest-apis-flask-python/develop) ![Python 3.10](https://img.shields.io/badge/python-3.10-yellow) [![Discord](https://img.shields.io/discord/614395983807250433)](https://discord.gg/78Nvd3p) [![Twitter Follow](https://img.shields.io/twitter/follow/jslvtr?style=social) ](https://twitter.com/jslvtr)
1010

1111
</div>
1212

@@ -16,7 +16,7 @@
1616

1717
## Getting started
1818

19-
Enrol in the course by going to [this link](https://go.tecla.do/rest-apis-sale).
19+
Enrol in the course by going to [this link](https://go.tecla.do/rest-apis-ebook).
2020

2121
Then you can come back here to download the repository. This repository contains the code that we develop in each section of the course.
2222

docs/algolia.config.json

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"index_name": "docusaurus-2",
3+
"start_urls": [
4+
"https://rest-apis-flask.teclado.com/"
5+
],
6+
"sitemap_urls": [
7+
"https://rest-apis-flask.teclado.com/sitemap.xml"
8+
],
9+
"sitemap_alternate_links": true,
10+
"stop_urls": [
11+
"/tests"
12+
],
13+
"selectors": {
14+
"lvl0": {
15+
"selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
16+
"type": "xpath",
17+
"global": true,
18+
"default_value": "Documentation"
19+
},
20+
"lvl1": "header h1",
21+
"lvl2": "article h2",
22+
"lvl3": "article h3",
23+
"lvl4": "article h4",
24+
"lvl5": "article h5, article td:first-child",
25+
"lvl6": "article h6",
26+
"text": "article p, article li, article td:last-child"
27+
},
28+
"strip_chars": " .,;:#",
29+
"custom_settings": {
30+
"separatorsToIndex": "_",
31+
"attributesForFaceting": [
32+
"language",
33+
"version",
34+
"type",
35+
"docusaurus_tag"
36+
],
37+
"attributesToRetrieve": [
38+
"hierarchy",
39+
"content",
40+
"anchor",
41+
"url",
42+
"url_without_anchor",
43+
"type"
44+
]
45+
},
46+
"conversation_id": [
47+
"833762294"
48+
]
49+
}

docs/docs-upcoming/11_celery_background_tasks/01_project_overview/README.md

-1
This file was deleted.

docs/docs-upcoming/11_celery_background_tasks/README.md

-1
This file was deleted.

docs/docs-upcoming/11_celery_background_tasks/_category_.json

-4
This file was deleted.

docs/docs/01_course_intro/01_curriculum_overview/README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ description: A brief description of the lecture goes here.
55

66
# Curriculum overview
77

8-
The curriculum overview goes here.
8+
import DocCategoryIndex from '@theme/DocCardList';
9+
import {useDocsSidebar} from '@docusaurus/theme-common/internal';
10+
11+
<DocCategoryIndex items={useDocsSidebar().items} />

docs/docs/01_course_intro/04_what_is_rest_api/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ An API client can be any device, such as a web app or a mobile app.
8484

8585
### Making an API for your own consumption
8686

87-
Make software companies make APIs that only they use (so they aren't fully public).
87+
Many software companies make APIs that only they use (so they aren't fully public).
8888

8989
Here's an example. You're making a multiplayer mobile game, and you need to store information about the moves that your character is making.
9090

@@ -109,7 +109,7 @@ REST APIs deal in resources, so every individual "thing" that can be named is a
109109
The main characteristics (or constraints) of a REST API are:
110110

111111
1. **Uniform interface**. Whichever way clients should access a certain resource should also be the way the access other resources. Clients should have a single way to retrieve resources.
112-
2. **Client-server**. Clients should know the endpoints of the API, but they should not be coupled to the development of the API. A client or a servevr may be swapped out for a different implementation without the other noticing.
112+
2. **Client-server**. Clients should know the endpoints of the API, but they should not be coupled to the development of the API. A client or a server may be swapped out for a different implementation without the other noticing.
113113
3. **Stateless**. The server (API) doesn't store anything about previous client requests. Each client request is treated as a brand new client. If the client needs the server to personalize the response, then the client must send the server whatever information the server needs in order to do so.
114114
4. **Cacheable**. The client or server must be able to cache the resources returned by the API. This is a very general constraint, but it's an important one.
115115
5. **Layered system**. REST APIs may be developed as multiple layers, where each layer interacts [only with the layer above and below it](https://excalidraw.com/#json=or3Umoigss4yIeuKg3cO8,qH6uDDCXc7DSjweqNvlmzw).
@@ -156,7 +156,7 @@ We'll deal with user authentication in a later section, but that's what the lock
156156
| `GET` | `/store` | Get a list of all stores. |
157157
| `POST` | `/store` | Create a store. |
158158
| `GET` | `/store/{id}` | Get a single store, given its unique id. |
159-
| `POST` | `/store/{id}` | Delete a store, given its unique id. |
159+
| `DELETE` | `/store/{id}` | Delete a store, given its unique id. |
160160

161161
### Items
162162

@@ -191,4 +191,4 @@ Then, over the following sections, we'll improve on this REST API. We'll add:
191191
- Add user authentication.
192192
- Add item tagging.
193193
- Add an admin panel so changing data manually is a bit easier.
194-
- And much more!
194+
- And much more!

docs/docs/01_course_intro/index.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ id: intro
44

55
# REST APIs with Flask and Python
66

7+
import VideoEmbed from "@site/src/components/VideoEmbed";
8+
9+
<div style={{ maxWidth: "720px", margin: "3rem auto", boxShadow: "0 5px 15px 0 rgba(0, 0, 0, 0.15)" }}>
10+
<VideoEmbed url="https://customer-zmitazl0ztnd2pvm.cloudflarestream.com/1c4db6119cf0c6e682a88a737af146eb/iframe?poster=https%3A%2F%2Fcustomer-zmitazl0ztnd2pvm.cloudflarestream.com%2F1c4db6119cf0c6e682a88a737af146eb%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600" />
11+
</div>
12+
713
Hi, and welcome!
814

915
REST APIs with Flask and Python is a complete course that teaches you how to develop complete, professional REST APIs using **Flask**, **PostgreSQL**, and **Docker**.

docs/docs/03_first_rest_api/01_project_overview/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ description: A first look at the project we'll build in this section.
55

66
# Overview of your first REST API
77

8+
import VideoEmbed from "@site/src/components/VideoEmbed";
9+
10+
<div style={{ maxWidth: "720px", margin: "3rem auto", boxShadow: "0 5px 15px 0 rgba(0, 0, 0, 0.15)" }}>
11+
<VideoEmbed url="https://customer-zmitazl0ztnd2pvm.cloudflarestream.com/cda9c0473bdc485a36905144f13f4d3f/iframe?poster=https%3A%2F%2Fcustomer-zmitazl0ztnd2pvm.cloudflarestream.com%2Fcda9c0473bdc485a36905144f13f4d3f%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600" />
12+
</div>
13+
814
In this section we'll make a simple REST API that allows us to:
915

1016
- Create stores, each with a `name` and a list of stocked `items`.
@@ -15,6 +21,10 @@ In this section we'll make a simple REST API that allows us to:
1521

1622
This is how the interaction will go!
1723

24+
:::tip Insomnia files
25+
Remember to get the Insomnia files for this section or for all sections [here](/insomnia-files/)!
26+
:::
27+
1828
## Create stores
1929

2030
Request:

docs/docs/03_first_rest_api/02_getting_set_up/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ description: Set up a Flask project and create the Flask app.
55

66
# Getting set up
77

8+
import VideoEmbed from "@site/src/components/VideoEmbed";
9+
10+
<div style={{ maxWidth: "720px", margin: "3rem auto", boxShadow: "0 5px 15px 0 rgba(0, 0, 0, 0.15)" }}>
11+
<VideoEmbed url="https://customer-zmitazl0ztnd2pvm.cloudflarestream.com/42b7de55034431b4c4c9420460f8df7d/iframe?poster=https%3A%2F%2Fcustomer-zmitazl0ztnd2pvm.cloudflarestream.com%2F42b7de55034431b4c4c9420460f8df7d%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600" />
12+
</div>
13+
814
Create a virtual environment and activate it.
915

1016
```

docs/docs/03_first_rest_api/03_first_rest_api_endpoint/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ description: Learn how to define a REST API endpoint using Flask.
55

66
# Your First REST API Endpoint
77

8+
import LockedVideoEmbed from "@site/src/components/LockedVideoEmbed";
9+
10+
<LockedVideoEmbed />
11+
812
Let's start off by defining where we'll store our data. In most REST APIs, you'd store your data in a database. For now, and for simplicity, we'll store it in a Python list.
913

1014
Later on we'll work on making this data dynamic. For now let's use some sample data.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"_type":"export","__export_format":4,"__export_date":"2022-11-09T15:36:47.360Z","__export_source":"insomnia.desktop.app:v2022.6.0","resources":[{"_id":"req_e15dafc098ac4a2198304d2aead2a5b9","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900815265,"created":1666123912423,"url":"http://127.0.0.1:5000/store/My Store/item","name":"/store/<name>/item Create item in store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"name\": \"Table\",\n\t\"price\": 17.99\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666124423081,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_8b9c03412d0e463fabe784d205f1d604","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666124528874,"created":1666124528874,"name":"Stores","description":"","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1666124528874,"_type":"request_group"},{"_id":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","parentId":null,"modified":1666991857781,"created":1666122928011,"name":"Section 3","description":"","scope":"collection","_type":"workspace"},{"_id":"req_697ca0714a3d4e94819411e3df0a2a17","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900846590,"created":1666124316888,"url":"http://127.0.0.1:5000/store/My store3/item","name":"/store/<name>/item","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666124423056,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_9451df3aae714e93a8ed529b3a1f99c2","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666124555354,"created":1666122990495,"url":"http://127.0.0.1:5000/store","name":"/store Get all store data","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666124423031,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_6363c8d4deb74b5bbccb1e2105277dac","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900812784,"created":1666124168137,"url":"http://127.0.0.1:5000/store/My store3","name":"/store/<name>","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1666124422956,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_0a9c4822679b4eae92dec7432fe144b8","parentId":"fld_8b9c03412d0e463fabe784d205f1d604","modified":1666900810115,"created":1666123651275,"url":"http://127.0.0.1:5000/store","name":"/store Create new store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"name\": \"My store3\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1666124422881,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_19db457230041d88ca9420d1b3c0f1f02bbcae93","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666122928025,"created":1666122928025,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1666122928025,"_type":"environment"},{"_id":"jar_19db457230041d88ca9420d1b3c0f1f02bbcae93","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666122928027,"created":1666122928027,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_c5b803a7c6514ff29573e26487d898d4","parentId":"wrk_6aa19b7d9ecd4f93a3602d257e54a163","modified":1666122928018,"created":1666122928018,"fileName":"Your First REST API","contents":"","contentType":"yaml","_type":"api_spec"}]}

docs/docs/05_flask_smorest/02_data_model_improvements/README.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,14 @@ CMD ["flask", "run", "--host", "0.0.0.0"]
8989
</Tabs>
9090
</div>
9191

92-
9392
## New files
9493

94+
:::tip Insomnia files
95+
Remember to get the Insomnia files for this section or for all sections [here](/insomnia-files/)!
96+
97+
There are two Insomnia files for this section: one for lectures 1-5 (before adding Docker), and one for the other lectures (after adding Docker).
98+
:::
99+
95100
Let's start off by creating a `requirements.txt` file with all our dependencies:
96101

97102
```txt title="requirements.txt"
@@ -245,6 +250,8 @@ def create_store():
245250
<TabItem value="new" label="create_store (new)">
246251

247252
```py title="app.py"
253+
import uuid
254+
248255
@app.post("/store")
249256
def create_store():
250257
store_data = request.get_json()
@@ -255,6 +262,8 @@ def create_store():
255262
return store
256263
```
257264

265+
Here we add a new import, [the `uuid` module](https://docs.python.org/3/library/uuid.html). We will be using it to create unique IDs for our stores and items instead of relying on the uniqueness of their names.
266+
258267
</TabItem>
259268
</Tabs>
260269
</div>

docs/docs/05_flask_smorest/07_marshmallow_schemas/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ItemSchema(Schema):
3737
id = fields.Str(dump_only=True)
3838
name = fields.Str(required=True)
3939
price = fields.Float(required=True)
40-
store_id = fields.Int(required=True)
40+
store_id = fields.Str(required=True)
4141
```
4242

4343
A couple of weird things maybe!

docs/docs/05_flask_smorest/07_marshmallow_schemas/end/schemas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ItemSchema(Schema):
55
id = fields.Str(dump_only=True)
66
name = fields.Str(required=True)
77
price = fields.Float(required=True)
8-
store_id = fields.Int(required=True)
8+
store_id = fields.Str(required=True)
99

1010

1111
class ItemUpdateSchema(Schema):

docs/docs/05_flask_smorest/08_validation_with_marshmallow/end/schemas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ItemSchema(Schema):
55
id = fields.Str(dump_only=True)
66
name = fields.Str(required=True)
77
price = fields.Float(required=True)
8-
store_id = fields.Int(required=True)
8+
store_id = fields.Str(required=True)
99

1010

1111
class ItemUpdateSchema(Schema):

docs/docs/05_flask_smorest/08_validation_with_marshmallow/start/schemas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ItemSchema(Schema):
55
id = fields.Str(dump_only=True)
66
name = fields.Str(required=True)
77
price = fields.Float(required=True)
8-
store_id = fields.Int(required=True)
8+
store_id = fields.Str(required=True)
99

1010

1111
class ItemUpdateSchema(Schema):

docs/docs/05_flask_smorest/09_decorating_responses/end/schemas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ItemSchema(Schema):
55
id = fields.Str(dump_only=True)
66
name = fields.Str(required=True)
77
price = fields.Float(required=True)
8-
store_id = fields.Int(required=True)
8+
store_id = fields.Str(required=True)
99

1010

1111
class ItemUpdateSchema(Schema):

docs/docs/05_flask_smorest/09_decorating_responses/start/schemas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ItemSchema(Schema):
55
id = fields.Str(dump_only=True)
66
name = fields.Str(required=True)
77
price = fields.Float(required=True)
8-
store_id = fields.Int(required=True)
8+
store_id = fields.Str(required=True)
99

1010

1111
class ItemUpdateSchema(Schema):

0 commit comments

Comments
 (0)