Skip to content

Commit

Permalink
Chapter 10
Browse files Browse the repository at this point in the history
Signed-off-by: Julio Jimenez <julio@julioj.com>
  • Loading branch information
juliojimenez committed Feb 25, 2024
1 parent 7c03f9b commit 2b09134
Show file tree
Hide file tree
Showing 19 changed files with 1,237 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ Each example runs on a different port. Run multiple examples simultaneously and
- [Integrating Using Callbacks](./chapter-9/4-integrating-using-callbacks)
- [Integrating Using Events](./chapter-9/5-integrating-using-events)

### Chapter 10

- [Our First JSON Endpoint: Listing All Contacts](./chapter-10/1-listing-all-contacts)

## Support

Python 3.11+
Expand Down
154 changes: 154 additions & 0 deletions chapter-10/1-listing-all-contacts/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
from contacts_model import Contact, Archiver
from flask import Flask, flash, redirect, render_template, request, send_file
from typing import Any
from werkzeug.wrappers import response

Contact.load_db()

app: Flask = Flask(__name__)

app.secret_key = b"it is over"


@app.route("/")
def index() -> response.Response:
return redirect("/contacts")


@app.route("/contacts")
def contacts() -> str:
search: str | None = request.args.get("q")
page: int = int(request.args.get("page", 1))
if search is not None:
contacts_set: list = Contact.search(search)
if request.headers.get("HX-Trigger") == "search":
return render_template("rows.html", contacts=contacts_set)
else:
contacts_set = Contact.all(page)
return render_template(
"index.html", contacts=contacts_set, page=page, archiver=Archiver.get()
)


@app.route("/contacts/count")
def contacts_count() -> str:
count: int = Contact.count()
return f"({str(count)} total Contacts)"


@app.route("/contacts/new", methods=["GET"])
def contacts_new_get() -> str:
return render_template("new.html", contact=Contact())


@app.route("/contacts/new", methods=["POST"])
def contacts_new() -> response.Response | str:
c: Contact = Contact(
None,
request.form["first_name"],
request.form["last_name"],
request.form["phone"],
request.form["email"],
)
if c.save():
flash("Created New Contact!")
return redirect("/contacts")
else:
return render_template("new.html", contact=c)


@app.route("/contacts/<contact_id>")
def contacts_view(contact_id: int = 0) -> str:
contact: Any | None = Contact.find(contact_id)
return render_template("show.html", contact=contact)


@app.route("/contacts/<contact_id>/edit", methods=["GET"])
def contacts_edit_get(contact_id: int = 0) -> str:
contact: Any | None = Contact.find(contact_id)
return render_template("edit.html", contact=contact)


@app.route("/contacts/<contact_id>/edit", methods=["POST"])
def contacts_edit_post(contact_id: int = 0) -> response.Response | str:
c: Any = Contact.find(contact_id)
c.update(
request.form["first_name"],
request.form["last_name"],
request.form["phone"],
request.form["email"],
)
if c.save():
flash("Updated Contact!")
return redirect("/contacts/" + str(contact_id))
else:
return render_template("edit.html", contact=c)


@app.route("/contacts/<contact_id>/email", methods=["GET"])
def contacts_email_get(contact_id=0) -> response.Response | str:
c: Any = Contact.find(contact_id)
c.email = request.args.get("email")
c.validate()
return c.errors.get("email") or ""


@app.route("/contacts/<contact_id>", methods=["DELETE"])
def contacts_delete(contact_id: int = 0) -> response.Response | str:
contact: Any | None = Contact.find(contact_id)
if contact is not None:
contact.delete()
if request.headers.get("HX-Trigger") == "delete-btn":
flash("Deleted Contact!")
return redirect("/contacts", 303)
else:
return ""


@app.route("/contacts/", methods=["DELETE"])
def contacts_delete_all() -> str:
contact_ids: list = list(map(int, request.form.getlist("selected_contact_ids")))
for contact_id in contact_ids:
contact: Any | None = Contact.find(contact_id)
if contact is not None:
contact.delete()
flash("Deleted Contacts!")
contacts_set: list = Contact.all()
return render_template("index.html", contacts=contacts_set, page=1)


@app.route("/contacts/archive", methods=["POST"])
def start_archive() -> str:
archiver = Archiver.get()
archiver.run()
return render_template("archive_ui.html", archiver=archiver)


@app.route("/contacts/archive", methods=["GET"])
def archive_status() -> str:
archiver = Archiver.get()
return render_template("archive_ui.html", archiver=archiver)


@app.route("/contacts/archive/file", methods=["GET"])
def archive_content() -> response.Response:
manager = Archiver.get()
return send_file(manager.archive_file(), "archive.json", as_attachment=True)


@app.route("/contacts/archive", methods=["DELETE"])
def reset_archive() -> str:
archiver = Archiver.get()
archiver.reset()
return render_template("archive_ui.html", archiver=archiver)


@app.route("/api/v1/contacts", methods=["GET"])
def json_contacts() -> dict:
contacts_set: list = Contact.all()
contacts_dicts: list = [c.__dict__ for c in contacts_set]
return {"contacts": contacts_dicts}


if __name__ == "__main__":
app.run(port=5061)
162 changes: 162 additions & 0 deletions chapter-10/1-listing-all-contacts/contacts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
[
{
"id": 2,
"first": "Carson",
"last": "Gross",
"phone": "123-456-7890",
"email": "carson@example.comz",
"errors": {}
},
{
"id": 3,
"first": "",
"last": "",
"phone": "",
"email": "joe@example2.com",
"errors": {}
},
{
"id": 5,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe@example.com",
"errors": {}
},
{
"id": 6,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe1@example.com",
"errors": {}
},
{
"id": 7,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe2@example.com",
"errors": {}
},
{
"id": 8,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe3@example.com",
"errors": {}
},
{
"id": 9,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe4@example.com",
"errors": {}
},
{
"id": 10,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe5@example.com",
"errors": {}
},
{
"id": 11,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe6@example.com",
"errors": {}
},
{
"id": 12,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe7@example.com",
"errors": {}
},
{
"id": 13,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe8@example.com",
"errors": {}
},
{
"id": 14,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe9@example.com",
"errors": {}
},
{
"id": 15,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe10@example.com",
"errors": {}
},
{
"id": 16,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe11@example.com",
"errors": {}
},
{
"id": 17,
"first": "Joe",
"last": "Blow",
"phone": "123-456-7890",
"email": "joe12@example.com",
"errors": {}
},
{
"id": 18,
"first": null,
"last": null,
"phone": null,
"email": "restexample1@example.com",
"errors": {}
},
{
"id": 19,
"first": null,
"last": null,
"phone": null,
"email": "restexample2@example.com",
"errors": {}
},
{
"id": 20,
"first": null,
"last": null,
"phone": null,
"email": "restexample3@example.com",
"errors": {}
},
{
"id": 21,
"first": null,
"last": null,
"phone": null,
"email": "restexample4@example.com",
"errors": {}
},
{
"id": 22,
"first": null,
"last": null,
"phone": null,
"email": "restexample5@example.com",
"errors": {}
}
]
Loading

0 comments on commit 2b09134

Please sign in to comment.