Skip to content

Commit f4d9cb2

Browse files
committed
add authentication guides
1 parent bf3995a commit f4d9cb2

File tree

15 files changed

+443
-2
lines changed

15 files changed

+443
-2
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,8 @@ cython_debug/
164164
requirements.txt
165165
generated
166166
tests/test_codegen.py
167+
.streamlit/*
168+
!.streamlit/config.yaml
169+
!.streamlit/secrets.toml.example
170+
playwright/.auth/*
171+
!playwright/.auth/.gitkeep

.streamlit/config.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
credentials:
2+
usernames:
3+
jsmith:
4+
5+
name: John Smith
6+
password: abc # To be replaced with hashed password
7+
rbriggs:
8+
9+
name: Rebecca Briggs
10+
password: def # To be replaced with hashed password
11+
cookie:
12+
expiry_days: 30
13+
key: random_signature_key # Must be string
14+
name: random_cookie_name
15+
preauthorized:
16+
emails:
17+

.streamlit/secrets.toml.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[auth]
2+
redirect_uri = "http://localhost:8501/oauth2callback"
3+
cookie_secret = "xxx"
4+
5+
[auth.microsoft]
6+
client_id = "your-client-id"
7+
client_secret = "your-client-secret"
8+
server_metadata_url = "https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration"

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
GIT_REVISION ?= $(shell git rev-parse --short HEAD)
33
GIT_TAG ?= $(shell git describe --tags --abbrev=0 --always | sed -e s/v//g)
44

5+
# Project
6+
SKIP_TEST ?= true
7+
58
.PHONY: help
69
help:
710
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
@@ -40,7 +43,7 @@ lint: ## lint
4043

4144
.PHONY: test
4245
test: ## run tests
43-
uv run pytest --capture=no -vv
46+
SKIP_TEST=$(SKIP_TEST) uv run pytest --capture=no -vv
4447

4548
.PHONY: ci-test
4649
ci-test: install-deps-dev format-check lint test ## run CI tests

compose.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
pgadmin:
3+
image: dpage/pgadmin4
4+
ports:
5+
- "8888:80"
6+
environment:
7+
PGADMIN_DEFAULT_EMAIL: [email protected]
8+
PGADMIN_DEFAULT_PASSWORD: very-strong-password
9+
PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION: "False"

docs/index.md

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ make install-deps-dev
1515

1616
- [[BUG] Host system is missing dependencies to run browsers (WSL2) #19100](https://github.com/microsoft/playwright/issues/19100)
1717

18-
## Guides
18+
## Fundamentals
1919

2020
To run some demos, please follow the instructions below.
2121

@@ -30,8 +30,78 @@ make show-trace
3030
make codegen
3131
```
3232

33+
## Guides
34+
35+
### Authentication
36+
37+
0. Run an application server
38+
39+
```shell
40+
docker compose up
41+
```
42+
43+
1. Run code generator and log in to the app manually.
44+
45+
```shell
46+
make codegen
47+
```
48+
49+
2. Update the generated codes for storing state via `context.storage_state()` method
50+
51+
3. Run the updated script named as `save_context.py`
52+
53+
```shell
54+
uv run scripts/save_context.py
55+
```
56+
57+
4. Run the following command to access to the app without logging in.
58+
59+
```shell
60+
uv run scripts/load_context.py
61+
```
62+
3363
## [Microsoft Playwright Testing](https://learn.microsoft.com/ja-jp/azure/playwright-testing/)
3464

3565
- [Get Started Sample](https://github.com/microsoft/playwright-testing-service/tree/main/samples/get-started)
3666

3767
## [Playwright MCP server](https://github.com/microsoft/playwright-mcp)
68+
69+
## Custom apps
70+
71+
### Credentials
72+
73+
Run the following command to set up the credentials for the application.
74+
75+
```shell
76+
# Run the application
77+
uv run streamlit run workshop_playwright_python/apps/streamlit_authentication.py
78+
```
79+
80+
To login, type your credentials described in [.streamlit/config.yaml](../.streamlit/config.yaml) and click the "Login" button. (e.g. `jsmith:abc`, `rbriggs:def`)
81+
82+
### OpenID Connect
83+
84+
To run a frontend application with authentication, you can refer to the following links.
85+
86+
- [User authentication and information](https://docs.streamlit.io/develop/concepts/connections/authentication)
87+
- [Use Microsoft Entra to authenticate users](https://docs.streamlit.io/develop/tutorials/authentication/microsoft)
88+
89+
For example, you can use the following file [.streamlit/secrets.toml](../.streamlit/secrets.toml.example) to set up authentication with Microsoft Entra ID.
90+
91+
```toml
92+
[auth]
93+
redirect_uri = "http://localhost:8501/oauth2callback"
94+
cookie_secret = "xxx"
95+
96+
[auth.microsoft]
97+
client_id = "your-client-id"
98+
client_secret = "your-client-secret"
99+
server_metadata_url = "https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration"
100+
```
101+
102+
Then, run the application using the following command:
103+
104+
```shell
105+
# Run the application
106+
uv run streamlit run workshop_playwright_python/apps/authentication.py
107+
```

playwright/.auth/.gitkeep

Whitespace-only changes.

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ description = "A GitHub template repository for Python"
55
readme = "README.md"
66
requires-python = ">=3.10"
77
dependencies = [
8+
"authlib>=1.5.2",
89
"playwright>=1.52.0",
910
"pytest-playwright>=0.7.0",
1011
"streamlit>=1.45.0",
12+
"streamlit-authenticator>=0.4.2",
1113
]
1214

1315
[project.optional-dependencies]

scripts/load_context.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from playwright.sync_api import Playwright, expect, sync_playwright
2+
3+
4+
def run(playwright: Playwright) -> None:
5+
browser = playwright.chromium.launch(headless=False)
6+
context = browser.new_context(
7+
storage_state="playwright/.auth/storage.json",
8+
)
9+
page = context.new_page()
10+
page.goto("http://localhost:8888/")
11+
12+
expect(page.get_by_role("heading", name="Feature rich | Maximises")).to_be_visible()
13+
14+
# ---------------------
15+
context.close()
16+
browser.close()
17+
18+
19+
with sync_playwright() as playwright:
20+
run(playwright)

scripts/save_context.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import json
2+
3+
from playwright.sync_api import Playwright, StorageState, sync_playwright
4+
5+
6+
def run(playwright: Playwright) -> None:
7+
browser = playwright.chromium.launch(headless=False)
8+
context = browser.new_context()
9+
page = context.new_page()
10+
page.goto("http://localhost:8888/")
11+
page.get_by_role("textbox", name="Email Address / Username").fill("[email protected]")
12+
page.get_by_role("textbox", name="Password").fill("very-strong-password")
13+
page.get_by_role("button", name="Login").click()
14+
15+
storage: StorageState = context.storage_state(path="playwright/.auth/storage.json")
16+
print(json.dumps(storage, indent=2))
17+
18+
# ---------------------
19+
context.close()
20+
browser.close()
21+
22+
23+
with sync_playwright() as playwright:
24+
run(playwright)

0 commit comments

Comments
 (0)