Skip to content

Commit dca54be

Browse files
committed
async bs
1 parent 3444319 commit dca54be

File tree

5 files changed

+222
-29
lines changed

5 files changed

+222
-29
lines changed

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.13
1+
3.12

hello.py

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,44 @@
1-
from models.com.nokia.eda.interfaces.v1alpha1 import Interface, Member, SpecModel, Metadata
1+
import asyncio
2+
3+
from models.com.nokia.eda.interfaces.v1alpha1 import (
4+
Interface,
5+
Member,
6+
Metadata,
7+
SpecModel,
8+
)
9+
from src import auth
10+
11+
12+
async def get_api_token():
13+
client_secret = await auth.get_client_secret()
14+
access_token = await auth.get_access_token(client_secret)
15+
print(f"Access Token: {access_token}")
16+
217

318
def main():
4-
iface = Interface(
5-
apiVersion="interfaces.eda.nokia.com/v1alpha1",
6-
kind="Interface",
7-
metadata=Metadata(
8-
name="test",
9-
namespace="clab-vlan",
10-
labels={"app": "test"},
11-
),
12-
spec=SpecModel(
13-
description="This is a test interface",
14-
enabled=True,
15-
members=[
16-
Member(
17-
node="leaf1",
18-
interface="ethernet-1-1",
19-
)
20-
]
21-
)
22-
)
23-
print(iface.model_dump_json(indent=2))
19+
# Run the asynchronous function
20+
asyncio.run(get_api_token())
21+
22+
# iface = Interface(
23+
# apiVersion="interfaces.eda.nokia.com/v1alpha1",
24+
# kind="Interface",
25+
# metadata=Metadata(
26+
# name="test",
27+
# namespace="clab-vlan",
28+
# labels={"app": "test"},
29+
# ),
30+
# spec=SpecModel(
31+
# description="This is a test interface",
32+
# enabled=True,
33+
# members=[
34+
# Member(
35+
# node="leaf1",
36+
# interface="ethernet-1-1",
37+
# )
38+
# ]
39+
# )
40+
# )
41+
# print(iface.model_dump_json(indent=2))
2442

2543

2644
if __name__ == "__main__":

pyproject.toml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
[project]
22
name = "openapi-example-python"
33
version = "0.1.0"
4-
description = "Add your description here"
4+
description = "Working with EDA OpenAPI specification"
55
readme = "README.md"
6-
requires-python = ">=3.13"
7-
dependencies = [
8-
"pydantic>=2.10.5",
9-
]
6+
requires-python = "~=3.12"
7+
dependencies = ["httpx==0.28.1", "pydantic==2.10.5"]

src/auth.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import httpx
2+
3+
# Keycloak configuration
4+
EDA_API_URL = "https://devbox.panda-cobra.ts.net"
5+
EDA_VERSION = "v24.12.1"
6+
KC_KEYCLOAK_URL = f"{EDA_API_URL}/core/httpproxy/v1/keycloak/"
7+
KC_REALM = "master"
8+
KC_CLIENT_ID = "admin-cli"
9+
KC_USERNAME = "admin"
10+
KC_PASSWORD = "admin"
11+
EDA_REALM = "eda"
12+
API_CLIENT_ID = "eda"
13+
14+
# Step 1: Get an access token
15+
token_url = f"{KC_KEYCLOAK_URL}/realms/{KC_REALM}/protocol/openid-connect/token"
16+
token_data = {
17+
"grant_type": "password",
18+
"client_id": KC_CLIENT_ID,
19+
"username": KC_USERNAME,
20+
"password": KC_PASSWORD,
21+
}
22+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
23+
24+
25+
async def get_client_secret() -> str:
26+
async with httpx.AsyncClient(verify=False) as client:
27+
# Fetch access token
28+
token_response = await client.post(token_url, data=token_data, headers=headers)
29+
token_response.raise_for_status()
30+
access_token = token_response.json()["access_token"]
31+
32+
# Step 2: Fetch the `eda` client ID and secret
33+
admin_api_url = f"{KC_KEYCLOAK_URL}/admin/realms/{EDA_REALM}/clients"
34+
auth_headers = {
35+
"Authorization": f"Bearer {access_token}",
36+
"Content-Type": "application/json",
37+
}
38+
39+
# Fetch clients
40+
clients_response = await client.get(admin_api_url, headers=auth_headers)
41+
clients_response.raise_for_status()
42+
clients = clients_response.json()
43+
44+
# Find the `eda` client
45+
eda_client = next(
46+
(client for client in clients if client["clientId"] == API_CLIENT_ID), None
47+
)
48+
49+
if not eda_client:
50+
raise Exception("Client `eda` not found in realm `eda-realm`")
51+
52+
# Fetch the client secret
53+
client_id = eda_client["id"]
54+
client_secret_url = f"{admin_api_url}/{client_id}/client-secret"
55+
secret_response = await client.get(client_secret_url, headers=auth_headers)
56+
secret_response.raise_for_status()
57+
client_secret = secret_response.json()["value"]
58+
59+
return client_secret
60+
61+
62+
async def get_access_token(client_secret: str) -> str:
63+
token_endpoint = (
64+
f"{KC_KEYCLOAK_URL}/realms/{EDA_REALM}/protocol/openid-connect/token"
65+
)
66+
67+
token_data = {
68+
"client_id": API_CLIENT_ID,
69+
"grant_type": "password",
70+
"scope": "openid",
71+
"username": "admin",
72+
"password": "admin",
73+
"client_secret": client_secret,
74+
}
75+
76+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
77+
78+
async with httpx.AsyncClient(verify=False) as client:
79+
response = await client.post(token_endpoint, data=token_data, headers=headers)
80+
response.raise_for_status()
81+
return response.json()["access_token"]

uv.lock

Lines changed: 98 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)