Skip to content

Commit d8eff19

Browse files
committed
fastapi wrapper with auth example
1 parent ebe9ebc commit d8eff19

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"CS_SERVER": "localhost",
3+
"CS_DOMAIN": "Global",
4+
"QUALI_API_PORT": 9000
5+
}

quali_api/fast-api-proxy/main.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import json
2+
import uvicorn as uvicorn
3+
4+
from fastapi import Depends, FastAPI, HTTPException
5+
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
6+
from dataclasses import dataclass
7+
from quali_api import QualiAPIHandler
8+
9+
app = FastAPI()
10+
11+
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
12+
13+
14+
@dataclass
15+
class CloudshellConfig:
16+
server: str
17+
domain: str
18+
port: str
19+
20+
21+
def _get_config():
22+
with open("config.json") as f:
23+
data = json.load(f)
24+
return CloudshellConfig(server=data["CS_SERVER"],
25+
domain=data["CS_DOMAIN"],
26+
port=data["QUALI_API_PORT"])
27+
28+
29+
config = _get_config()
30+
quali_api = QualiAPIHandler(host=config.server, port=config.port)
31+
32+
33+
@app.post("/token")
34+
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
35+
user_name = form_data.username
36+
password = form_data.password
37+
if not user_name and password:
38+
raise HTTPException(status_code=400,
39+
detail="Must provide user and password")
40+
response = quali_api.login(user_name=user_name, password=password, domain=config.domain)
41+
if not response.ok:
42+
raise HTTPException(status_code=response.status_code,
43+
detail=response.reason)
44+
token = quali_api.get_token_from_login(response)
45+
return {"access_token": token, "token_type": "bearer"}
46+
47+
48+
@app.get("/suites")
49+
async def read_users_me(token: str = Depends(oauth2_scheme)):
50+
return quali_api.get_available_suites(token)
51+
52+
53+
if __name__ == "__main__":
54+
uvicorn.run(app, host="0.0.0.0", port=7000)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import json
2+
3+
import requests
4+
from requests import Response
5+
6+
7+
class QualiAPIHandler:
8+
def __init__(self, host, port=9000):
9+
self._base_url = f"http://{host}:{port}/Api"
10+
11+
def login(self, user_name: str = None, password: str = None, domain: str = "Global") -> Response:
12+
headers = {"username": user_name, "password": password, "domain": domain}
13+
return requests.put(f"{self._base_url}/Auth/Login", headers)
14+
15+
@staticmethod
16+
def get_token_from_login(response: Response):
17+
return response.text[1:-1]
18+
19+
@staticmethod
20+
def _prep_auth_header(token):
21+
return f"Basic {token}"
22+
23+
def get_available_suites(self, token) -> dict:
24+
response = requests.get(self._base_url + "/Scheduling/SuiteTemplates",
25+
headers={"Authorization": self._prep_auth_header(token)})
26+
if not response.ok:
27+
response.raise_for_status()
28+
return response.json()
29+
30+
31+
if __name__ == "__main__":
32+
# sanity test
33+
api = QualiAPIHandler("localhost")
34+
token = api.login(user_name="admin", password="admin", domain="Global")
35+
suites = api.get_available_suites(token)
36+
print(json.dumps(suites, indent=4))
37+
pass
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
python-multipart
2+
fastapi
3+
uvicorn
4+
requests

0 commit comments

Comments
 (0)