Skip to content

Commit 00dfce2

Browse files
authored
Merge branch 'master' into python-getter-setter
2 parents 00c7a13 + e99fde1 commit 00dfce2

File tree

130 files changed

+5122
-6518
lines changed

Some content is hidden

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

130 files changed

+5122
-6518
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Python REST APIs With Flask, Connexion, and SQLAlchemy – Part 1
2+
3+
This repository holds the code for part one of the Real Python [Python REST APIs With Flask, Connexion, and SQLAlchemy](https://realpython.com/flask-connexion-rest-api) tutorial series.
4+
5+
## Real Python Flask REST API – Part 1
6+
7+
You should first create a virtual environment:
8+
9+
```console
10+
$ python -m venv venv
11+
$ source venv/bin/activate
12+
```
13+
14+
Install the pinned dependencies from `requirements.txt`:
15+
16+
```console
17+
(venv) $ python -m pip install -r requirements.txt
18+
```
19+
20+
Then, navigate into the `rp_flask_api/` folder and start the development web server:
21+
22+
```console
23+
(venv) $ cd rp_flask_api
24+
(venv) $ python app.py
25+
```
26+
27+
To see your home page, visit `http://127.0.0.1:8000`. You can find the Swagger UI API documentation on `http://127.0.0.1:8000/api/ui`.
28+
29+
## Flask Starter
30+
31+
You can find the _Flask Starter_ files in the `flask_starter/` folder.
32+
33+
To use the _Flask Starter_, copy the `flask_starter/` folder and rename it to your Flask project name. Open the terminal inside of your project folder, and create a virtual environment:
34+
35+
```console
36+
$ python -m venv venv
37+
$ source venv/bin/activate
38+
```
39+
40+
You can then install Flask with `pip`:
41+
42+
```console
43+
(venv) $ python -m pip install flask
44+
```
45+
46+
You can start your Flask development server by running `app.py` as a script:
47+
48+
```console
49+
(venv) $ python app.py
50+
```
51+
52+
To see your home page, visit `http://127.0.0.1:8000`.
53+
54+
## Author
55+
56+
- **Philipp Acsany**, E-mail: [[email protected]]([email protected])
57+
58+
## License
59+
60+
Distributed under the MIT license. See [`LICENSE`](../LICENSE) for more information.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from flask import Flask, render_template
2+
3+
app = Flask(__name__)
4+
5+
6+
@app.route("/")
7+
def home():
8+
return render_template("home.html")
9+
10+
11+
if __name__ == "__main__":
12+
app.run(host="0.0.0.0", port=8000, debug=True)

flask-connexion-rest/version_2/templates/home.html renamed to flask-connexion-rest-part-1/flask_starter/templates/home.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
5-
<title>Application Home Page</title>
5+
<title>RP Flask REST API</title>
66
</head>
77
<body>
8-
<h2>
9-
Hello World!
10-
</h2>
8+
<h1>
9+
Hello, World!
10+
</h1>
1111
</body>
12-
</html>
12+
</html>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
attrs==22.1.0
2+
certifi==2022.9.24
3+
charset-normalizer==2.1.1
4+
click==8.1.3
5+
clickclick==20.10.2
6+
connexion==2.14.1
7+
Flask==2.2.2
8+
idna==3.4
9+
inflection==0.5.1
10+
itsdangerous==2.1.2
11+
Jinja2==3.1.2
12+
jsonschema==4.16.0
13+
MarkupSafe==2.1.1
14+
packaging==21.3
15+
pyparsing==3.0.9
16+
pyrsistent==0.19.1
17+
PyYAML==6.0
18+
requests==2.28.1
19+
swagger-ui-bundle==0.0.9
20+
urllib3==1.26.12
21+
Werkzeug==2.2.2
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import connexion
2+
from flask import render_template
3+
4+
app = connexion.App(__name__, specification_dir="./")
5+
app.add_api("swagger.yml")
6+
7+
8+
@app.route("/")
9+
def home():
10+
return render_template("home.html")
11+
12+
13+
if __name__ == "__main__":
14+
app.run(host="0.0.0.0", port=8000, debug=True)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from datetime import datetime
2+
3+
from flask import abort, make_response
4+
5+
6+
def get_timestamp():
7+
return datetime.now().strftime(("%Y-%m-%d %H:%M:%S"))
8+
9+
10+
PEOPLE = {
11+
"Fairy": {
12+
"fname": "Tooth",
13+
"lname": "Fairy",
14+
"timestamp": get_timestamp(),
15+
},
16+
"Ruprecht": {
17+
"fname": "Knecht",
18+
"lname": "Ruprecht",
19+
"timestamp": get_timestamp(),
20+
},
21+
"Bunny": {
22+
"fname": "Easter",
23+
"lname": "Bunny",
24+
"timestamp": get_timestamp(),
25+
},
26+
}
27+
28+
29+
def read_all():
30+
return list(PEOPLE.values())
31+
32+
33+
def create(person):
34+
lname = person.get("lname")
35+
fname = person.get("fname", "")
36+
37+
if lname and lname not in PEOPLE:
38+
PEOPLE[lname] = {
39+
"lname": lname,
40+
"fname": fname,
41+
"timestamp": get_timestamp(),
42+
}
43+
return PEOPLE[lname], 201
44+
else:
45+
abort(406, f"Person with last name {lname} already exists")
46+
47+
48+
def read_one(lname):
49+
if lname in PEOPLE:
50+
return PEOPLE[lname]
51+
else:
52+
abort(404, f"Person with last name {lname} not found")
53+
54+
55+
def update(lname, person):
56+
if lname in PEOPLE:
57+
PEOPLE[lname]["fname"] = person.get("fname", PEOPLE[lname]["fname"])
58+
PEOPLE[lname]["timestamp"] = get_timestamp()
59+
return PEOPLE[lname]
60+
else:
61+
abort(404, f"Person with last name {lname} not found")
62+
63+
64+
def delete(lname):
65+
if lname in PEOPLE:
66+
del PEOPLE[lname]
67+
return make_response(f"{lname} successfully deleted", 200)
68+
else:
69+
abort(404, f"Person with last name {lname} not found")
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
openapi: 3.0.0
2+
info:
3+
title: "RP Flask REST API"
4+
description: "An API about people and notes"
5+
version: "1.0.0"
6+
7+
servers:
8+
- url: "/api"
9+
10+
components:
11+
schemas:
12+
Person:
13+
type: "object"
14+
required:
15+
- lname
16+
properties:
17+
fname:
18+
type: "string"
19+
lname:
20+
type: "string"
21+
parameters:
22+
lname:
23+
name: "lname"
24+
description: "Last name of the person to get"
25+
in: path
26+
required: True
27+
schema:
28+
type: "string"
29+
30+
paths:
31+
/people:
32+
get:
33+
operationId: "people.read_all"
34+
tags:
35+
- "People"
36+
summary: "Read the list of people"
37+
responses:
38+
"200":
39+
description: "Successfully read people list"
40+
post:
41+
operationId: "people.create"
42+
tags:
43+
- People
44+
summary: "Create a person"
45+
requestBody:
46+
description: "Person to create"
47+
required: True
48+
content:
49+
application/json:
50+
schema:
51+
x-body-name: "person"
52+
$ref: "#/components/schemas/Person"
53+
responses:
54+
"201":
55+
description: "Successfully created person"
56+
/people/{lname}:
57+
get:
58+
operationId: "people.read_one"
59+
tags:
60+
- People
61+
summary: "Read one person"
62+
parameters:
63+
- $ref: "#/components/parameters/lname"
64+
responses:
65+
"200":
66+
description: "Successfully read person"
67+
put:
68+
tags:
69+
- People
70+
operationId: "people.update"
71+
summary: "Update a person"
72+
parameters:
73+
- $ref: "#/components/parameters/lname"
74+
responses:
75+
"200":
76+
description: "Successfully updated person"
77+
requestBody:
78+
content:
79+
application/json:
80+
schema:
81+
x-body-name: "person"
82+
$ref: "#/components/schemas/Person"
83+
delete:
84+
tags:
85+
- People
86+
operationId: "people.delete"
87+
summary: "Delete a person"
88+
parameters:
89+
- $ref: "#/components/parameters/lname"
90+
responses:
91+
"204":
92+
description: "Successfully deleted person"

flask-connexion-rest/version_3/templates/home.html renamed to flask-connexion-rest-part-1/rp_flask_api/templates/home.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
5-
<title>Application Home Page</title>
5+
<title>RP Flask REST API</title>
66
</head>
77
<body>
8-
<h2>
9-
Hello World!
10-
</h2>
8+
<h1>
9+
Hello, World!
10+
</h1>
1111
</body>
12-
</html>
12+
</html>
Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,70 @@
1-
This folder contains the bonus material & example projects for our upcoming part 2 of [Building and Documenting Python REST APIs With Flask and Connexion](https://realpython.com/flask-connexion-rest-api/) on Real Python.
1+
# Python REST APIs With Flask, Connexion, and SQLAlchemy – Part 2
2+
3+
This repository holds the code for part two of the Real Python [Python REST APIs With Flask, Connexion, and SQLAlchemy](https://realpython.com/flask-connexion-rest-api-part-2) tutorial series.
4+
5+
## Real Python Flask REST API – Part 2
6+
7+
You should first create a virtual environment:
8+
9+
```console
10+
$ python -m venv venv
11+
$ source venv/bin/activate
12+
```
13+
14+
Install the pinned dependencies from `requirements.txt`:
15+
16+
```console
17+
(venv) $ python -m pip install -r requirements.txt
18+
```
19+
20+
Then, navigate into the `rp_flask_api/` folder:
21+
22+
```console
23+
(venv) $ cd rp_flask_api
24+
(venv) $ python app.py
25+
```
26+
27+
To see your home page, visit `http://127.0.0.1:8000`. You can find the Swagger UI API documentation on `http://127.0.0.1:8000/api/ui`.
28+
29+
### Optional: Build the Database
30+
31+
You can build a SQLite database with content by following the commands below.
32+
33+
Navigate inside the `rp_flask_api/`, enter the [Python interactive shell](https://realpython.com/interacting-with-python/) and run the commands below:
34+
35+
```pycon
36+
>>> import sqlite3
37+
>>> conn = sqlite3.connect("people.db")
38+
>>> columns = [
39+
... "id INTEGER PRIMARY KEY",
40+
... "lname VARCHAR UNIQUE",
41+
... "fname VARCHAR",
42+
... "timestamp DATETIME",
43+
... ]
44+
>>> create_table_cmd = f"CREATE TABLE person ({','.join(columns)})"
45+
>>> conn.execute(create_table_cmd)
46+
>>> people = [
47+
... "1, 'Fairy', 'Sugar', '2022-10-08 09:15:10'",
48+
... "2, 'Ruprecht', 'Knecht', '2022-10-08 09:15:13'",
49+
... "3, 'Bunny', 'Easter', '2022-10-08 09:15:27'",
50+
... ]
51+
>>> for person_data in people:
52+
... insert_cmd = f"INSERT INTO person VALUES ({person_data})"
53+
... conn.execute(insert_cmd)
54+
...
55+
<sqlite3.Cursor object at 0x104ac4dc0>
56+
<sqlite3.Cursor object at 0x104ac4f40>
57+
<sqlite3.Cursor object at 0x104ac4fc0>
58+
59+
>>> conn.commit()
60+
```
61+
62+
This will create a database named `people.db` that you can use with your project.
63+
64+
## Author
65+
66+
- **Philipp Acsany**, E-mail: [[email protected]]([email protected])
67+
68+
## License
69+
70+
Distributed under the MIT license. See [`LICENSE`](../LICENSE) for more information.

0 commit comments

Comments
 (0)