Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions src/ssvc/api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,7 @@
from fastapi.responses import RedirectResponse

import ssvc # noqa: F401
from ssvc.api.routers import (
decision_point,
decision_points,
decision_table,
decision_tables,
keys,
namespaces,
objects,
types,
versions,
)
from ssvc.api.v1 import router as router_v1
from ssvc.registry.base import (
get_registry,
)
Expand All @@ -54,15 +44,8 @@
"email": "[email protected]",
},
)
app.include_router(decision_point.router)
app.include_router(decision_points.router)
app.include_router(decision_table.router)
app.include_router(decision_tables.router)
app.include_router(types.router)
app.include_router(namespaces.router)
app.include_router(keys.router)
app.include_router(versions.router)
app.include_router(objects.router)

app.include_router(router_v1)


# root should redirect to docs
Expand Down
24 changes: 24 additions & 0 deletions src/ssvc/api/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python
"""
API version 1 router for SSVC
"""
# Copyright (c) 2025 Carnegie Mellon University.
# NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE
# ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS" BASIS.
# CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT
# NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR
# MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE
# OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE
# ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM
# PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
# Licensed under a MIT (SEI)-style license, please see LICENSE or contact
# [email protected] for full terms.
# [DISTRIBUTION STATEMENT A] This material has been approved for
# public release and unlimited distribution. Please see Copyright notice
# for non-US Government use and distribution.
# This Software includes and/or makes use of Third-Party Software each
# subject to its own license.
# DM24-0278

from ssvc.api.v1.routers.v1_router import router_v1 as router # noqa: F401
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@

from pydantic import RootModel, model_validator

from ssvc.api.response_models._type_defs import (DecisionPointDictType, DecisionPointValuesListType,
DecisionTableDictType, KeyDictType, NamespaceDictType, StringsListType,
TypesDictType, VersionDictType)
from ssvc.api.v1.response_models._type_defs import (
DecisionPointDictType,
DecisionPointValuesListType,
DecisionTableDictType,
KeyDictType,
NamespaceDictType,
StringsListType,
TypesDictType,
VersionDictType,
)
from ssvc.decision_points.base import DecisionPoint, DecisionPointValue
from ssvc.decision_tables.base import DecisionTable

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from fastapi import APIRouter

from ssvc.api.helpers import _404_on_none
from ssvc.api.response_models import (
from ssvc.api.v1.response_models import (
DecisionPointDictResponse,
DecisionPointDictType,
DecisionPointValueListResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from fastapi import APIRouter

from ssvc.api.helpers import _404_on_none
from ssvc.api.response_models import (
from ssvc.api.v1.response_models import (
DecisionTableDictResponse,
DecisionTableDictType,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from fastapi import APIRouter

from ssvc.api.helpers import _404_on_none
from ssvc.api.response_models import (
from ssvc.api.v1.response_models import (
KeyDictResponse,
ListOfStringsResponse,
StringsListType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
from fastapi import APIRouter

from ssvc.api.helpers import _404_on_none
from ssvc.api.response_models import (ListOfStringsResponse, NamespaceDictResponse, NamespaceDictType, StringsListType)
from ssvc.api.v1.response_models import (
ListOfStringsResponse,
NamespaceDictResponse,
NamespaceDictType,
StringsListType,
)
from ssvc.registry.base import get_registry, lookup_objtype

router = APIRouter(
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

from fastapi import APIRouter

from ssvc.api.response_models import (
from ssvc.api.v1.response_models import (
ListOfStringsResponse,
StringsListType,
TypesDictResponse,
)
from ssvc.api.response_models._type_defs import TypesDictType
from ssvc.api.v1.response_models._type_defs import TypesDictType
from ssvc.registry.base import get_registry

r = get_registry()
Expand Down
56 changes: 56 additions & 0 deletions src/ssvc/api/v1/routers/v1_router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python
"""
API version 1 router for SSVC
"""
# Copyright (c) 2025 Carnegie Mellon University.
# NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE
# ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS" BASIS.
# CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT
# NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR
# MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE
# OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE
# ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM
# PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
# Licensed under a MIT (SEI)-style license, please see LICENSE or contact
# [email protected] for full terms.
# [DISTRIBUTION STATEMENT A] This material has been approved for
# public release and unlimited distribution. Please see Copyright notice
# for non-US Government use and distribution.
# This Software includes and/or makes use of Third-Party Software each
# subject to its own license.
# DM24-0278
from fastapi import APIRouter

from ssvc.api.v1.routers import (
decision_point,
decision_table,
decision_tables,
objects,
)
from ssvc.api.v1.routers import (
decision_points,
keys,
namespaces,
types,
versions,
)

router_v1 = APIRouter(prefix="/v1", tags=["v1"])
router_v1.include_router(decision_point.router)
router_v1.include_router(decision_points.router)
router_v1.include_router(decision_table.router)
router_v1.include_router(decision_tables.router)
router_v1.include_router(types.router)
router_v1.include_router(namespaces.router)
router_v1.include_router(keys.router)
router_v1.include_router(versions.router)
router_v1.include_router(objects.router)


def main():
pass


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from fastapi import APIRouter

from ssvc.api.helpers import _404_on_none
from ssvc.api.response_models import (
from ssvc.api.v1.response_models import (
ListOfStringsResponse,
StringsListType,
VersionDictResponse,
Expand Down
2 changes: 1 addition & 1 deletion src/test/api/routers/test_decision_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from fastapi import HTTPException
from fastapi.testclient import TestClient

from ssvc.api.routers import decision_point
from ssvc.api.v1.routers import decision_point
from ssvc.decision_points.base import DecisionPoint, DecisionPointValue
from ssvc.registry.base import SsvcObjectRegistry

Expand Down
18 changes: 9 additions & 9 deletions src/test/api/routers/test_decision_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from fastapi import FastAPI
from fastapi.testclient import TestClient

from ssvc.api.routers import decision_points
from ssvc.api.v1.routers import decision_points
from ssvc.decision_points.base import DecisionPoint, DecisionPointValue


Expand Down Expand Up @@ -52,7 +52,7 @@ def setUp(self):
),
)

@patch("ssvc.api.routers.decision_points.lookup_objtype")
@patch("ssvc.api.v1.routers.decision_points.lookup_objtype")
def test_get_all_decision_points_success(self, mock_lookup):
dp = self.dp
result_mock = MagicMock()
Expand All @@ -66,13 +66,13 @@ def test_get_all_decision_points_success(self, mock_lookup):
self.assertEqual(response.status_code, 200)
self.assertIn(dp.id, response.json())

@patch("ssvc.api.routers.decision_points.lookup_objtype")
@patch("ssvc.api.v1.routers.decision_points.lookup_objtype")
def test_get_all_decision_points_not_found(self, mock_lookup):
mock_lookup.return_value = None
response = self.client.get("/decision_points/")
self.assertEqual(response.status_code, 404)

@patch("ssvc.api.routers.decision_points.lookup_namespace")
@patch("ssvc.api.v1.routers.decision_points.lookup_namespace")
def test_get_all_decision_points_for_namespace_success(self, mock_lookup):
dp = self.dp
result_mock = MagicMock()
Expand All @@ -84,15 +84,15 @@ def test_get_all_decision_points_for_namespace_success(self, mock_lookup):
self.assertEqual(response.status_code, 200)
self.assertIn(dp.id, response.json())

@patch("ssvc.api.routers.decision_points.lookup_namespace")
@patch("ssvc.api.v1.routers.decision_points.lookup_namespace")
def test_get_all_decision_points_for_namespace_not_found(
self, mock_lookup
):
mock_lookup.return_value = None
response = self.client.get("/decision_points/ns1")
self.assertEqual(response.status_code, 404)

@patch("ssvc.api.routers.decision_points.lookup_key")
@patch("ssvc.api.v1.routers.decision_points.lookup_key")
def test_get_all_versions_of_decision_points_for_key_success(
self, mock_lookup
):
Expand All @@ -104,15 +104,15 @@ def test_get_all_versions_of_decision_points_for_key_success(
self.assertEqual(response.status_code, 200)
self.assertIn(dp.id, response.json())

@patch("ssvc.api.routers.decision_points.lookup_key")
@patch("ssvc.api.v1.routers.decision_points.lookup_key")
def test_get_all_versions_of_decision_points_for_key_not_found(
self, mock_lookup
):
mock_lookup.return_value = None
response = self.client.get("/decision_points/ns1/key1")
self.assertEqual(response.status_code, 404)

@patch("ssvc.api.routers.decision_points.lookup_latest")
@patch("ssvc.api.v1.routers.decision_points.lookup_latest")
def test_get_latest_decision_point_for_key_success(self, mock_lookup):
dp = self.dp
mock_lookup.return_value = dp
Expand All @@ -123,7 +123,7 @@ def test_get_latest_decision_point_for_key_success(self, mock_lookup):
self.assertEqual(response.json()["version"], dp.version)
self.assertEqual(response.json()["name"], dp.name)

@patch("ssvc.api.routers.decision_points.lookup_latest")
@patch("ssvc.api.v1.routers.decision_points.lookup_latest")
def test_get_latest_decision_point_for_key_not_found(self, mock_lookup):
mock_lookup.return_value = None
response = self.client.get("/decision_points/ns1/key1/latest")
Expand Down
2 changes: 1 addition & 1 deletion src/test/api/routers/test_decision_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from fastapi import HTTPException
from fastapi.testclient import TestClient

from ssvc.api.routers import decision_table
from ssvc.api.v1.routers import decision_table
from ssvc.decision_points.base import DecisionPoint, DecisionPointValue
from ssvc.decision_tables.base import DecisionTable
from ssvc.registry.base import SsvcObjectRegistry
Expand Down
18 changes: 9 additions & 9 deletions src/test/api/routers/test_decision_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from fastapi import FastAPI
from fastapi.testclient import TestClient

from ssvc.api.routers import decision_tables
from ssvc.api.v1.routers import decision_tables
from ssvc.decision_points.base import DecisionPoint, DecisionPointValue
from ssvc.decision_tables.base import DecisionTable
from ssvc.registry.base import SsvcObjectRegistry
Expand Down Expand Up @@ -81,7 +81,7 @@ def setUp(self):
registered=False,
)

@patch("ssvc.api.routers.decision_tables.lookup_objtype")
@patch("ssvc.api.v1.routers.decision_tables.lookup_objtype")
def test_get_all_decision_tables_success(self, mock_lookup):
result_mock = MagicMock()
result_mock.namespaces = {
Expand All @@ -98,13 +98,13 @@ def test_get_all_decision_tables_success(self, mock_lookup):
self.assertEqual(response.status_code, 200)
self.assertIn(self.dt.id, response.json())

@patch("ssvc.api.routers.decision_tables.lookup_objtype")
@patch("ssvc.api.v1.routers.decision_tables.lookup_objtype")
def test_get_all_decision_tables_not_found(self, mock_lookup):
mock_lookup.return_value = None
response = self.client.get("/decision_tables/")
self.assertEqual(response.status_code, 404)

@patch("ssvc.api.routers.decision_tables.lookup_namespace")
@patch("ssvc.api.v1.routers.decision_tables.lookup_namespace")
def test_get_decision_tables_for_namespace_success(self, mock_lookup):
ns_mock = MagicMock()
ns_mock.keys = {
Expand All @@ -117,13 +117,13 @@ def test_get_decision_tables_for_namespace_success(self, mock_lookup):
self.assertEqual(response.status_code, 200)
self.assertIn(self.dt.id, response.json())

@patch("ssvc.api.routers.decision_tables.lookup_namespace")
@patch("ssvc.api.v1.routers.decision_tables.lookup_namespace")
def test_get_decision_tables_for_namespace_not_found(self, mock_lookup):
mock_lookup.return_value = None
response = self.client.get(f"/decision_tables/{self.dt.namespace}")
self.assertEqual(response.status_code, 404)

@patch("ssvc.api.routers.decision_tables.lookup_key")
@patch("ssvc.api.v1.routers.decision_tables.lookup_key")
def test_get_decision_tables_for_key_success(self, mock_lookup):
key_mock = MagicMock()
key_mock.versions = {self.dt.version: MagicMock(obj=self.dt)}
Expand All @@ -134,15 +134,15 @@ def test_get_decision_tables_for_key_success(self, mock_lookup):
self.assertEqual(response.status_code, 200)
self.assertIn(self.dt.id, response.json())

@patch("ssvc.api.routers.decision_tables.lookup_key")
@patch("ssvc.api.v1.routers.decision_tables.lookup_key")
def test_get_decision_tables_for_key_not_found(self, mock_lookup):
mock_lookup.return_value = None
response = self.client.get(
f"/decision_tables/{self.dt.namespace}/{self.dt.key}"
)
self.assertEqual(response.status_code, 404)

@patch("ssvc.api.routers.decision_tables.lookup_latest")
@patch("ssvc.api.v1.routers.decision_tables.lookup_latest")
def test_get_latest_decision_table_for_key_success(self, mock_lookup):
latest_dt = self.dt
mock_lookup.return_value = latest_dt
Expand All @@ -155,7 +155,7 @@ def test_get_latest_decision_table_for_key_success(self, mock_lookup):
self.assertEqual(response.json()["version"], latest_dt.version)
self.assertEqual(response.json()["name"], latest_dt.name)

@patch("ssvc.api.routers.decision_tables.lookup_latest")
@patch("ssvc.api.v1.routers.decision_tables.lookup_latest")
def test_get_latest_decision_table_for_key_not_found(self, mock_lookup):
mock_lookup.return_value = None
response = self.client.get(f"/decision_tables/test/key1/latest")
Expand Down
Loading