Skip to content
Snippets Groups Projects
Commit 303acc40 authored by Mohammad Torkashvand's avatar Mohammad Torkashvand
Browse files

correct typing and fix a bug

parent 643926ad
No related branches found
No related tags found
1 merge request!69correct typing and fix a bug
Pipeline #84082 passed
"""The product block that describes a site subscription.""" """The product block that describes a site subscription."""
import re
from typing import Optional from typing import Optional
from orchestrator.domain.base import ProductBlockModel from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle, strEnum from orchestrator.types import SubscriptionLifecycle, strEnum
from pydantic import ConstrainedStr
from gso.schemas.types import LatitudeCoordinate, LongitudeCoordinate
class SiteTier(strEnum): class SiteTier(strEnum):
...@@ -20,15 +20,6 @@ class SiteTier(strEnum): ...@@ -20,15 +20,6 @@ class SiteTier(strEnum):
TIER4 = 4 TIER4 = 4
class SnmpCoordinate(ConstrainedStr):
"""An {term}`SNMP` coordinate, modeled as a constrained string.
The coordinate must match the format of `1.35`, `-123.456`, etc.
"""
regex = re.compile(r"^-?\d{1,3}\.\d+$")
class SiteBlockInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="SiteBlock"): class SiteBlockInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INITIAL], product_block_name="SiteBlock"):
"""A site that's currently inactive, see {class}`SiteBlock`.""" """A site that's currently inactive, see {class}`SiteBlock`."""
...@@ -36,8 +27,8 @@ class SiteBlockInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INIT ...@@ -36,8 +27,8 @@ class SiteBlockInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INIT
site_city: Optional[str] = None site_city: Optional[str] = None
site_country: Optional[str] = None site_country: Optional[str] = None
site_country_code: Optional[str] = None site_country_code: Optional[str] = None
site_latitude: Optional[SnmpCoordinate] = None site_latitude: Optional[LatitudeCoordinate] = None
site_longitude: Optional[SnmpCoordinate] = None site_longitude: Optional[LongitudeCoordinate] = None
site_internal_id: Optional[int] = None site_internal_id: Optional[int] = None
site_bgp_community_id: Optional[int] = None site_bgp_community_id: Optional[int] = None
site_tier: Optional[SiteTier] = None site_tier: Optional[SiteTier] = None
...@@ -51,8 +42,8 @@ class SiteBlockProvisioning(SiteBlockInactive, lifecycle=[SubscriptionLifecycle. ...@@ -51,8 +42,8 @@ class SiteBlockProvisioning(SiteBlockInactive, lifecycle=[SubscriptionLifecycle.
site_city: Optional[str] = None site_city: Optional[str] = None
site_country: Optional[str] = None site_country: Optional[str] = None
site_country_code: Optional[str] = None site_country_code: Optional[str] = None
site_latitude: Optional[SnmpCoordinate] = None site_latitude: Optional[LatitudeCoordinate] = None
site_longitude: Optional[SnmpCoordinate] = None site_longitude: Optional[LongitudeCoordinate] = None
site_internal_id: Optional[int] = None site_internal_id: Optional[int] = None
site_bgp_community_id: Optional[int] = None site_bgp_community_id: Optional[int] = None
site_tier: Optional[SiteTier] = None site_tier: Optional[SiteTier] = None
...@@ -72,9 +63,9 @@ class SiteBlock(SiteBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]) ...@@ -72,9 +63,9 @@ class SiteBlock(SiteBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE])
site_country_code: str site_country_code: str
"""The code of the corresponding country. This is also used for the {term}`FQDN`, following the example given for """The code of the corresponding country. This is also used for the {term}`FQDN`, following the example given for
the site name, the country code would end up in the Y position.""" the site name, the country code would end up in the Y position."""
site_latitude: SnmpCoordinate site_latitude: LatitudeCoordinate
"""The latitude of the site, used for {term}`SNMP` purposes.""" """The latitude of the site, used for {term}`SNMP` purposes."""
site_longitude: SnmpCoordinate site_longitude: LongitudeCoordinate
"""Similar to the latitude, the longitude of a site.""" """Similar to the latitude, the longitude of a site."""
site_internal_id: int site_internal_id: int
"""The internal ID used within GÉANT to denote a site.""" """The internal ID used within GÉANT to denote a site."""
......
import re
from typing import Union
from pydantic import ConstrainedStr
class LatitudeCoordinate(ConstrainedStr):
"""A latitude coordinate, modeled as a constrained string.
The coordinate must match the format conforming to the latitude
range of `-`90 to +90 degrees. It can be a floating-point number or an integer.
Valid examples: 40.7128, -74.0060, 90, -90, 0
"""
regex = re.compile(r"^-?([1-8]?\d(\.\d+)?|90(\.0+)?)$")
@classmethod
def validate(cls, value: Union[str]) -> Union[str]:
if not cls.regex.match(value):
raise ValueError("Invalid latitude coordinate. Valid examples: '40.7128', '-74.0060', '90', '-90', '0'.")
return value
class LongitudeCoordinate(ConstrainedStr):
"""A longitude coordinate, modeled as a constrained string.
The coordinate must match the format conforming to the longitude
range of `-`180 to 180 degrees. It can be a floating point number or an integer.
Valid examples: 40.7128, -74.0060, 180, -180, 0
"""
regex = re.compile(r"^-?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$")
@classmethod
def validate(cls, value: Union[str]) -> Union[str]:
if not cls.regex.match(value):
raise ValueError("Invalid longitude coordinate. Valid examples: '40.7128', '-74.0060', '180', '-180'")
return value
...@@ -11,8 +11,8 @@ from orchestrator.workflows.utils import wrap_create_initial_input_form ...@@ -11,8 +11,8 @@ from orchestrator.workflows.utils import wrap_create_initial_input_form
from pydantic import validator from pydantic import validator
from gso.products.product_blocks import site as site_pb from gso.products.product_blocks import site as site_pb
from gso.products.product_blocks.site import SnmpCoordinate
from gso.products.product_types import site from gso.products.product_types import site
from gso.schemas.types import LatitudeCoordinate, LongitudeCoordinate
from gso.workflows.utils import customer_selector from gso.workflows.utils import customer_selector
...@@ -26,8 +26,8 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: # noqa: C ...@@ -26,8 +26,8 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: # noqa: C
site_city: str site_city: str
site_country: str site_country: str
site_country_code: str site_country_code: str
site_latitude: str site_latitude: LatitudeCoordinate
site_longitude: str site_longitude: LongitudeCoordinate
site_bgp_community_id: int site_bgp_community_id: int
site_internal_id: int site_internal_id: int
site_tier: site_pb.SiteTier site_tier: site_pb.SiteTier
...@@ -41,26 +41,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: # noqa: C ...@@ -41,26 +41,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: # noqa: C
except LookupError: except LookupError:
raise ValueError("Invalid or non-existent country code, it must be in ISO 3166-1 alpha-2 format.") raise ValueError("Invalid or non-existent country code, it must be in ISO 3166-1 alpha-2 format.")
@validator("site_latitude", allow_reuse=True)
def latitude_must_be_valid(cls, latitude: str) -> str | NoReturn:
def _is_valid_latitude(degree: float) -> bool:
return -90 <= degree <= 90
if _is_valid_latitude(float(latitude)):
return latitude
raise ValueError("Entered latitude is not a valid value, must be between -90.0° and 90.0°.")
@validator("site_longitude", allow_reuse=True)
def longitude_must_be_valid(cls, longitude: str) -> str | NoReturn:
def _is_valid_longitude(degree: float) -> bool:
return -180 <= degree <= 180
if _is_valid_longitude(float(longitude)):
return longitude
raise ValueError("Entered longitude is not a valid value, must be between -180.0° and 180.0°.")
@validator("site_ts_address", allow_reuse=True) @validator("site_ts_address", allow_reuse=True)
def ts_address_must_be_valid(cls, ts_address: str) -> str | NoReturn: def ts_address_must_be_valid(cls, ts_address: str) -> str | NoReturn:
try: try:
...@@ -91,8 +71,8 @@ def initialize_subscription( ...@@ -91,8 +71,8 @@ def initialize_subscription(
site_city: str, site_city: str,
site_country: str, site_country: str,
site_country_code: str, site_country_code: str,
site_latitude: SnmpCoordinate, site_latitude: LatitudeCoordinate,
site_longitude: SnmpCoordinate, site_longitude: LongitudeCoordinate,
site_bgp_community_id: int, site_bgp_community_id: int,
site_internal_id: int, site_internal_id: int,
site_ts_address: str, site_ts_address: str,
...@@ -102,8 +82,8 @@ def initialize_subscription( ...@@ -102,8 +82,8 @@ def initialize_subscription(
subscription.site.site_city = site_city subscription.site.site_city = site_city
subscription.site.site_country = site_country subscription.site.site_country = site_country
subscription.site.site_country_code = site_country_code subscription.site.site_country_code = site_country_code
subscription.site.site_latitude = site_longitude subscription.site.site_latitude = site_latitude
subscription.site.site_longitude = site_latitude subscription.site.site_longitude = site_longitude
subscription.site.site_bgp_community_id = site_bgp_community_id subscription.site.site_bgp_community_id = site_bgp_community_id
subscription.site.site_internal_id = site_internal_id subscription.site.site_internal_id = site_internal_id
subscription.site.site_tier = site_tier subscription.site.site_tier = site_tier
......
import pytest
from gso.schemas.types import LatitudeCoordinate, LongitudeCoordinate
@pytest.mark.parametrize(
"input_value, is_valid",
[
("40.7128", True),
("-74.0060", True),
("90", True),
("-90", True),
("0", True),
("45.6", True),
("91", False),
("-91", False),
("180", False),
("-180", False),
("abc", False),
("90.1", False),
],
)
def test_latitude(input_value, is_valid):
if is_valid:
assert LatitudeCoordinate.validate(input_value) == input_value
else:
with pytest.raises(ValueError) as excinfo:
LatitudeCoordinate.validate(input_value)
assert "Invalid latitude coordinate" in str(excinfo.value)
@pytest.mark.parametrize(
"input_value, is_valid",
[
("40.7128", True),
("-74.0060", True),
("180", True),
("-180", True),
("0", True),
("90.1", True),
("181", False),
("-181", False),
("200", False),
("-200", False),
("abc", False),
("90a", False),
],
)
def test_longitude(input_value, is_valid):
if is_valid:
assert LongitudeCoordinate.validate(input_value) == input_value
else:
with pytest.raises(ValueError) as excinfo:
LongitudeCoordinate.validate(input_value)
assert "Invalid longitude coordinate" in str(excinfo.value)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment