decentralized and customizable links page on top of atproto ligo.at
atproto link-in-bio python uv

use flask `session`

+20 -20
+1
.gitignore
··· 1 .venv 2 *.pyc
··· 1 + .env 2 .venv 3 *.pyc
+19 -20
src/main.py
··· 2 from atproto.exceptions import AtProtocolError 3 from atproto_client.models import ComAtprotoRepoCreateRecord 4 from atproto_client.models.app.bsky.actor.defs import ProfileViewDetailed 5 - from flask import Flask, make_response, redirect, render_template, request 6 from urllib import request as http_request 7 import json 8 9 app = Flask(__name__) 10 pdss: dict[str, str] = {} 11 dids: dict[str, str] = {} 12 links: dict[str, list[dict[str, str]]] = {} ··· 45 46 @app.get("/login") 47 def page_login(): 48 - if "session" in request.cookies: 49 return redirect("/editor") 50 return render_template("login.html") 51 52 53 @app.get("/editor") 54 def page_editor(): 55 - session = request.cookies.get("session") 56 - if session is None or not session: 57 return redirect("/login") 58 client = Client() 59 profile: ProfileViewDetailed | None 60 try: 61 - profile = client.login(session_string=session) 62 except AtProtocolError: 63 - r = make_response(redirect("/login", 303)) 64 - r.delete_cookie("session") 65 - return r 66 67 pds = resolve_pds_from_did(profile.did) 68 if not pds: ··· 81 82 @app.post("/editor/profile") 83 def post_editor_profile(): 84 - session = request.cookies.get("session") 85 - if session is None or not session: 86 return redirect("/login", 303) 87 client = Client() 88 - profile = client.login(session_string=session) 89 90 display_name = request.form.get("displayName") 91 description = request.form.get("description") or "" ··· 109 110 @app.post("/editor/links") 111 def post_editor_links(): 112 - session = request.cookies.get("session") 113 - if session is None or not session: 114 return redirect("/login", 303) 115 client = Client() 116 - profile = client.login(session_string=session) 117 118 links: list[dict[str, str]] = [] 119 urls = request.form.getlist("link-url") ··· 255 256 @app.route("/auth/logout") 257 def auth_logout(): 258 - r = make_response(redirect("/")) 259 - r.delete_cookie("session") 260 - return r 261 262 263 @app.post("/auth/login") ··· 275 session_string = client.export_session_string() 276 except AtProtocolError: 277 return redirect("/login", 303) 278 - r = make_response(redirect("/editor", code=303)) 279 - r.set_cookie("session", session_string) 280 - return r
··· 2 from atproto.exceptions import AtProtocolError 3 from atproto_client.models import ComAtprotoRepoCreateRecord 4 from atproto_client.models.app.bsky.actor.defs import ProfileViewDetailed 5 + from flask import Flask, session, redirect, render_template, request 6 from urllib import request as http_request 7 import json 8 9 app = Flask(__name__) 10 + _ = app.config.from_prefixed_env() 11 + 12 pdss: dict[str, str] = {} 13 dids: dict[str, str] = {} 14 links: dict[str, list[dict[str, str]]] = {} ··· 47 48 @app.get("/login") 49 def page_login(): 50 + if "session" in session: 51 return redirect("/editor") 52 return render_template("login.html") 53 54 55 @app.get("/editor") 56 def page_editor(): 57 + sess: str | None = session.get("session") 58 + if sess is None or not sess: 59 return redirect("/login") 60 client = Client() 61 profile: ProfileViewDetailed | None 62 try: 63 + profile = client.login(session_string=sess) 64 except AtProtocolError: 65 + session.clear() 66 + return redirect("/login", 303) 67 68 pds = resolve_pds_from_did(profile.did) 69 if not pds: ··· 82 83 @app.post("/editor/profile") 84 def post_editor_profile(): 85 + sess: str | None = session.get("session") 86 + if sess is None or not sess: 87 return redirect("/login", 303) 88 client = Client() 89 + profile = client.login(session_string=sess) 90 91 display_name = request.form.get("displayName") 92 description = request.form.get("description") or "" ··· 110 111 @app.post("/editor/links") 112 def post_editor_links(): 113 + sess: str | None = session.get("session") 114 + if sess is None or not sess: 115 return redirect("/login", 303) 116 client = Client() 117 + profile = client.login(session_string=sess) 118 119 links: list[dict[str, str]] = [] 120 urls = request.form.getlist("link-url") ··· 256 257 @app.route("/auth/logout") 258 def auth_logout(): 259 + session.clear() 260 + return redirect("/") 261 262 263 @app.post("/auth/login") ··· 275 session_string = client.export_session_string() 276 except AtProtocolError: 277 return redirect("/login", 303) 278 + session["session"] = session_string 279 + return redirect("/editor", code=303)