Skip to content

Commit

Permalink
Merge pull request #104 from lsst-sqre/u/jsickcodes/v2-only-api
Browse files Browse the repository at this point in the history
Move root and auth endpoints out of v1 blueprint
  • Loading branch information
jonathansick authored Mar 14, 2022
2 parents cd1aab2 + be4009e commit 4e23e66
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 60 deletions.
2 changes: 1 addition & 1 deletion docs/auth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ Authentication - `/token`
#########################

.. autoflask:: keeper:flask_app
:endpoints: api.get_auth_token
:endpoints: apiroot.get_auth_token
2 changes: 0 additions & 2 deletions keeper/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
api = Blueprint("api", __name__)

from . import (
auth,
builds,
dashboards,
editions,
errorhandlers,
post_products_builds,
products,
queue,
root,
)
50 changes: 1 addition & 49 deletions keeper/api/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import datetime
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional

from pydantic import BaseModel, Field, HttpUrl, SecretStr, validator
from pydantic import BaseModel, Field, HttpUrl, validator

from keeper.editiontracking import EditionTrackingModes
from keeper.exceptions import ValidationError
Expand All @@ -28,54 +28,6 @@
from keeper.models import Build, Edition, Product


class AuthTokenResponse(BaseModel):
"""The auth token resource."""

token: SecretStr
"""Token string. Use this token in the basic auth "username" field."""

class Config:
json_encoders = {
SecretStr: lambda v: v.get_secret_value() if v else None,
}


class RootLinks(BaseModel):
"""Sub-resource containing links to APIs."""

self_url: HttpUrl
"""The URL of this resource."""

token: HttpUrl
"""The URL of the authorization endpoint to obtain a token."""

products: HttpUrl
"""The endpoint for the products listing."""


class RootData(BaseModel):
"""Sub-resource providing metadata about the service."""

server_version: str
"""The service vesion."""

documentation: HttpUrl
"""The URL of the service's documentation."""

message: str
"""Description of the service."""


class RootResponse(BaseModel):
"""The root endpoint resources provides metadata and links for the
service.
"""

data: RootData

links: RootLinks


class PresignedPostUrl(BaseModel):
"""An S3 presigned post URL and associated metadata."""

Expand Down
5 changes: 5 additions & 0 deletions keeper/apiroot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from flask import Blueprint

apiroot = Blueprint("apiroot", __name__)

from . import auth, root
55 changes: 55 additions & 0 deletions keeper/apiroot/_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Pydantic Models for the root API endpoints."""

from __future__ import annotations

from typing import Optional

from pydantic import BaseModel, HttpUrl, SecretStr


class AuthTokenResponse(BaseModel):
"""The auth token resource."""

token: SecretStr
"""Token string. Use this token in the basic auth "username" field."""

class Config:
json_encoders = {
SecretStr: lambda v: v.get_secret_value() if v else None,
}


class RootLinks(BaseModel):
"""Sub-resource containing links to APIs."""

self_url: HttpUrl
"""The URL of this resource."""

token: HttpUrl
"""The URL of the authorization endpoint to obtain a token."""

products: Optional[HttpUrl] = None
"""The endpoint for the products listing."""


class RootData(BaseModel):
"""Sub-resource providing metadata about the service."""

server_version: str
"""The service vesion."""

documentation: HttpUrl
"""The URL of the service's documentation."""

message: str
"""Description of the service."""


class RootResponse(BaseModel):
"""The root endpoint resources provides metadata and links for the
service.
"""

data: RootData

links: RootLinks
Empty file added keeper/apiroot/_urls.py
Empty file.
4 changes: 2 additions & 2 deletions keeper/api/auth.py → keeper/apiroot/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from flask import g
from flask_accept import accept_fallback

from keeper.api import api
from keeper.apiroot import apiroot
from keeper.auth import password_auth
from keeper.logutils import log_route

from ._models import AuthTokenResponse


@api.route("/token")
@apiroot.route("/token")
@accept_fallback
@log_route()
@password_auth.login_required
Expand Down
16 changes: 10 additions & 6 deletions keeper/api/root.py → keeper/apiroot/root.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""Root API route (GET /)."""

from flask import url_for
from flask import current_app, url_for
from flask_accept import accept_fallback

from keeper.api import api
from keeper.apiroot import apiroot
from keeper.logutils import log_route
from keeper.version import get_version

from ._models import RootData, RootLinks, RootResponse


@api.route("/", methods=["GET"])
@apiroot.route("/", methods=["GET"])
@accept_fallback
@log_route()
def get_root() -> str:
Expand All @@ -25,9 +25,13 @@ def get_root() -> str:
),
)
links = RootLinks(
self_url=url_for("api.get_root", _external=True),
token=url_for("api.get_auth_token", _external=True),
products=url_for("api.get_products", _external=True),
self_url=url_for("apiroot.get_root", _external=True),
token=url_for("apiroot.get_auth_token", _external=True),
products=(
url_for("api.get_products", _external=True)
if current_app.config["ENABLE_V1_API"]
else None
),
)
response = RootResponse(data=root_data, links=links)
return response.json(by_alias=True)
4 changes: 4 additions & 0 deletions keeper/appfactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def create_flask_app(profile: Optional[str] = None) -> Flask:
) # for sqlite; safe for other servers

# Register blueprints
from keeper.apiroot import apiroot as apiroot_blueprint

app.register_blueprint(apiroot_blueprint, url_prefix=None)

if app.config["ENABLE_V1_API"]:
from keeper.api import api as api_blueprint

Expand Down

0 comments on commit 4e23e66

Please sign in to comment.