Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b8f6879

Browse files
Starter code for chapter 7, databases.
1 parent c257c6b commit b8f6879

37 files changed

+1109
-0
lines changed

‎code/ch7-databases/data/package.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Package:
2+
3+
def __init__(self,
4+
package_name: str,
5+
summary: str,
6+
description: str,
7+
home_page: str,
8+
lic: str,
9+
author_name: str,
10+
maintainers: list = None,
11+
):
12+
if maintainers is None:
13+
maintainers = []
14+
self.maintainers = maintainers
15+
self.author_name = author_name
16+
self.license = lic
17+
self.home_page = home_page
18+
self.description = description
19+
self.summary = summary
20+
self.package_name = package_name
21+
self.id = package_name

‎code/ch7-databases/data/release.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import datetime
2+
3+
4+
class Release:
5+
6+
def __init__(self, version: str, created_date: datetime.datetime):
7+
self.version = version
8+
self.created_date = created_date

‎code/ch7-databases/data/user.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import datetime
2+
3+
4+
class User:
5+
6+
def __init__(self, name, email, hashed_password):
7+
self.id = 1
8+
self.name = name
9+
self.email = email
10+
self.hash_password = hashed_password
11+
self.created_date = None
12+
self.profile_image_url = ""
13+
self.last_login: datetime.datetime = None
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import hashlib
2+
from typing import Optional
3+
4+
from fastapi import Request
5+
from fastapi import Response
6+
7+
from infrastructure.num_convert import try_int
8+
9+
auth_cookie_name = 'pypi_account'
10+
11+
12+
def set_auth(response: Response, user_id: int):
13+
hash_val = __hash_text(str(user_id))
14+
val = "{}:{}".format(user_id, hash_val)
15+
response.set_cookie(auth_cookie_name, val, secure=False, httponly=True, samesite='Lax')
16+
17+
18+
def __hash_text(text: str) -> str:
19+
text = 'salty__' + text + '__text'
20+
return hashlib.sha512(text.encode('utf-8')).hexdigest()
21+
22+
23+
def get_user_id_via_auth_cookie(request: Request) -> Optional[int]:
24+
if auth_cookie_name not in request.cookies:
25+
return None
26+
27+
val = request.cookies[auth_cookie_name]
28+
parts = val.split(':')
29+
if len(parts) != 2:
30+
return None
31+
32+
user_id = parts[0]
33+
hash_val = parts[1]
34+
hash_val_check = __hash_text(user_id)
35+
if hash_val != hash_val_check:
36+
print("Warning: Hash mismatch, invalid cookie value")
37+
return None
38+
39+
return try_int(user_id)
40+
41+
42+
def logout(response: Response):
43+
response.delete_cookie(auth_cookie_name)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def try_int(text) -> int:
2+
try:
3+
return int(text)
4+
except:
5+
return 0

‎code/ch7-databases/main.py‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import fastapi
2+
import fastapi_chameleon
3+
import uvicorn
4+
from starlette.staticfiles import StaticFiles
5+
6+
from views import account
7+
from views import home
8+
from views import packages
9+
10+
app = fastapi.FastAPI()
11+
12+
13+
def main():
14+
configure(dev_mode=True)
15+
uvicorn.run(app, host='127.0.0.1', port=8000, debug=True)
16+
17+
18+
def configure(dev_mode: bool):
19+
configure_templates(dev_mode)
20+
configure_routes()
21+
22+
23+
def configure_templates(dev_mode: bool):
24+
fastapi_chameleon.global_init('templates', auto_reload=dev_mode)
25+
26+
27+
def configure_routes():
28+
app.mount('/static', StaticFiles(directory='static'), name='static')
29+
app.include_router(home.router)
30+
app.include_router(account.router)
31+
app.include_router(packages.router)
32+
33+
34+
if __name__ == '__main__':
35+
main()
36+
else:
37+
configure(dev_mode=False)

‎code/ch7-databases/placeholder.txt‎

Whitespace-only changes.

‎code/ch7-databases/requirements.txt‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fastapi
2+
uvicorn
3+
aiofiles
4+
python-multipart
5+
6+
git+https://github.com/mikeckennedy/fastapi-chameleon
7+
8+
starlette
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import datetime
2+
from typing import List, Optional
3+
4+
from data.package import Package
5+
from data.release import Release
6+
7+
8+
def release_count() -> int:
9+
return 2_234_847
10+
11+
12+
def package_count() -> int:
13+
return 274_000
14+
15+
16+
def latest_packages(limit: int = 5) -> List:
17+
return [
18+
{'id': 'fastapi', 'summary': "A great web framework"},
19+
{'id': 'uvicorn', 'summary': "Your favorite ASGI server"},
20+
{'id': 'httpx', 'summary': "Requests for an async world"},
21+
][:limit]
22+
23+
24+
def get_package_by_id(package_name: str) -> Optional[Package]:
25+
package = Package(
26+
package_name, "This is the summary", "Full details here!",
27+
"https://fastapi.tiangolo.com/", "MIT", "Sebastián Ramírez"
28+
)
29+
return package
30+
31+
32+
def get_latest_release_for_package(package_name: str) -> Optional[Release]:
33+
return Release("1.2.0", datetime.datetime.now())
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from typing import Optional
2+
3+
from data.user import User
4+
5+
6+
def user_count() -> int:
7+
return 73_874
8+
9+
10+
def create_account(name: str, email: str, password: str) -> User:
11+
return User(name, email, 'abc')
12+
13+
14+
def login_user(email: str, password: str) -> Optional[User]:
15+
if password == 'abc':
16+
return User("test user", email, 'abc')
17+
18+
return None

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /