Skip to content

Commit 4e23e66

Browse files
authored
Merge pull request #104 from lsst-sqre/u/jsickcodes/v2-only-api
Move root and auth endpoints out of v1 blueprint
2 parents cd1aab2 + be4009e commit 4e23e66

File tree

9 files changed

+78
-60
lines changed

9 files changed

+78
-60
lines changed

docs/auth.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ Authentication - `/token`
33
#########################
44

55
.. autoflask:: keeper:flask_app
6-
:endpoints: api.get_auth_token
6+
:endpoints: apiroot.get_auth_token

keeper/api/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
api = Blueprint("api", __name__)
44

55
from . import (
6-
auth,
76
builds,
87
dashboards,
98
editions,
109
errorhandlers,
1110
post_products_builds,
1211
products,
1312
queue,
14-
root,
1513
)

keeper/api/_models.py

+1-49
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import datetime
66
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional
77

8-
from pydantic import BaseModel, Field, HttpUrl, SecretStr, validator
8+
from pydantic import BaseModel, Field, HttpUrl, validator
99

1010
from keeper.editiontracking import EditionTrackingModes
1111
from keeper.exceptions import ValidationError
@@ -28,54 +28,6 @@
2828
from keeper.models import Build, Edition, Product
2929

3030

31-
class AuthTokenResponse(BaseModel):
32-
"""The auth token resource."""
33-
34-
token: SecretStr
35-
"""Token string. Use this token in the basic auth "username" field."""
36-
37-
class Config:
38-
json_encoders = {
39-
SecretStr: lambda v: v.get_secret_value() if v else None,
40-
}
41-
42-
43-
class RootLinks(BaseModel):
44-
"""Sub-resource containing links to APIs."""
45-
46-
self_url: HttpUrl
47-
"""The URL of this resource."""
48-
49-
token: HttpUrl
50-
"""The URL of the authorization endpoint to obtain a token."""
51-
52-
products: HttpUrl
53-
"""The endpoint for the products listing."""
54-
55-
56-
class RootData(BaseModel):
57-
"""Sub-resource providing metadata about the service."""
58-
59-
server_version: str
60-
"""The service vesion."""
61-
62-
documentation: HttpUrl
63-
"""The URL of the service's documentation."""
64-
65-
message: str
66-
"""Description of the service."""
67-
68-
69-
class RootResponse(BaseModel):
70-
"""The root endpoint resources provides metadata and links for the
71-
service.
72-
"""
73-
74-
data: RootData
75-
76-
links: RootLinks
77-
78-
7931
class PresignedPostUrl(BaseModel):
8032
"""An S3 presigned post URL and associated metadata."""
8133

keeper/apiroot/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from flask import Blueprint
2+
3+
apiroot = Blueprint("apiroot", __name__)
4+
5+
from . import auth, root

keeper/apiroot/_models.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Pydantic Models for the root API endpoints."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Optional
6+
7+
from pydantic import BaseModel, HttpUrl, SecretStr
8+
9+
10+
class AuthTokenResponse(BaseModel):
11+
"""The auth token resource."""
12+
13+
token: SecretStr
14+
"""Token string. Use this token in the basic auth "username" field."""
15+
16+
class Config:
17+
json_encoders = {
18+
SecretStr: lambda v: v.get_secret_value() if v else None,
19+
}
20+
21+
22+
class RootLinks(BaseModel):
23+
"""Sub-resource containing links to APIs."""
24+
25+
self_url: HttpUrl
26+
"""The URL of this resource."""
27+
28+
token: HttpUrl
29+
"""The URL of the authorization endpoint to obtain a token."""
30+
31+
products: Optional[HttpUrl] = None
32+
"""The endpoint for the products listing."""
33+
34+
35+
class RootData(BaseModel):
36+
"""Sub-resource providing metadata about the service."""
37+
38+
server_version: str
39+
"""The service vesion."""
40+
41+
documentation: HttpUrl
42+
"""The URL of the service's documentation."""
43+
44+
message: str
45+
"""Description of the service."""
46+
47+
48+
class RootResponse(BaseModel):
49+
"""The root endpoint resources provides metadata and links for the
50+
service.
51+
"""
52+
53+
data: RootData
54+
55+
links: RootLinks

keeper/apiroot/_urls.py

Whitespace-only changes.

keeper/api/auth.py keeper/apiroot/auth.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
from flask import g
66
from flask_accept import accept_fallback
77

8-
from keeper.api import api
8+
from keeper.apiroot import apiroot
99
from keeper.auth import password_auth
1010
from keeper.logutils import log_route
1111

1212
from ._models import AuthTokenResponse
1313

1414

15-
@api.route("/token")
15+
@apiroot.route("/token")
1616
@accept_fallback
1717
@log_route()
1818
@password_auth.login_required

keeper/api/root.py keeper/apiroot/root.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
"""Root API route (GET /)."""
22

3-
from flask import url_for
3+
from flask import current_app, url_for
44
from flask_accept import accept_fallback
55

6-
from keeper.api import api
6+
from keeper.apiroot import apiroot
77
from keeper.logutils import log_route
88
from keeper.version import get_version
99

1010
from ._models import RootData, RootLinks, RootResponse
1111

1212

13-
@api.route("/", methods=["GET"])
13+
@apiroot.route("/", methods=["GET"])
1414
@accept_fallback
1515
@log_route()
1616
def get_root() -> str:
@@ -25,9 +25,13 @@ def get_root() -> str:
2525
),
2626
)
2727
links = RootLinks(
28-
self_url=url_for("api.get_root", _external=True),
29-
token=url_for("api.get_auth_token", _external=True),
30-
products=url_for("api.get_products", _external=True),
28+
self_url=url_for("apiroot.get_root", _external=True),
29+
token=url_for("apiroot.get_auth_token", _external=True),
30+
products=(
31+
url_for("api.get_products", _external=True)
32+
if current_app.config["ENABLE_V1_API"]
33+
else None
34+
),
3135
)
3236
response = RootResponse(data=root_data, links=links)
3337
return response.json(by_alias=True)

keeper/appfactory.py

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def create_flask_app(profile: Optional[str] = None) -> Flask:
5757
) # for sqlite; safe for other servers
5858

5959
# Register blueprints
60+
from keeper.apiroot import apiroot as apiroot_blueprint
61+
62+
app.register_blueprint(apiroot_blueprint, url_prefix=None)
63+
6064
if app.config["ENABLE_V1_API"]:
6165
from keeper.api import api as api_blueprint
6266

0 commit comments

Comments
 (0)