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
Branches
Tags
1 merge request!69correct typing and fix a bug
Pipeline #84082 passed
"""The product block that describes a site subscription."""
import re
from typing import Optional
from orchestrator.domain.base import ProductBlockModel
from orchestrator.types import SubscriptionLifecycle, strEnum
from pydantic import ConstrainedStr
from gso.schemas.types import LatitudeCoordinate, LongitudeCoordinate
class SiteTier(strEnum):
......@@ -20,15 +20,6 @@ class SiteTier(strEnum):
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"):
"""A site that's currently inactive, see {class}`SiteBlock`."""
......@@ -36,8 +27,8 @@ class SiteBlockInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INIT
site_city: Optional[str] = None
site_country: Optional[str] = None
site_country_code: Optional[str] = None
site_latitude: Optional[SnmpCoordinate] = None
site_longitude: Optional[SnmpCoordinate] = None
site_latitude: Optional[LatitudeCoordinate] = None
site_longitude: Optional[LongitudeCoordinate] = None
site_internal_id: Optional[int] = None
site_bgp_community_id: Optional[int] = None
site_tier: Optional[SiteTier] = None
......@@ -51,8 +42,8 @@ class SiteBlockProvisioning(SiteBlockInactive, lifecycle=[SubscriptionLifecycle.
site_city: Optional[str] = None
site_country: Optional[str] = None
site_country_code: Optional[str] = None
site_latitude: Optional[SnmpCoordinate] = None
site_longitude: Optional[SnmpCoordinate] = None
site_latitude: Optional[LatitudeCoordinate] = None
site_longitude: Optional[LongitudeCoordinate] = None
site_internal_id: Optional[int] = None
site_bgp_community_id: Optional[int] = None
site_tier: Optional[SiteTier] = None
......@@ -72,9 +63,9 @@ class SiteBlock(SiteBlockProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE])
site_country_code: str
"""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."""
site_latitude: SnmpCoordinate
site_latitude: LatitudeCoordinate
"""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."""
site_internal_id: int
"""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
from pydantic import validator
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.schemas.types import LatitudeCoordinate, LongitudeCoordinate
from gso.workflows.utils import customer_selector
......@@ -26,8 +26,8 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: # noqa: C
site_city: str
site_country: str
site_country_code: str
site_latitude: str
site_longitude: str
site_latitude: LatitudeCoordinate
site_longitude: LongitudeCoordinate
site_bgp_community_id: int
site_internal_id: int
site_tier: site_pb.SiteTier
......@@ -41,26 +41,6 @@ def initial_input_form_generator(product_name: str) -> FormGenerator: # noqa: C
except LookupError:
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)
def ts_address_must_be_valid(cls, ts_address: str) -> str | NoReturn:
try:
......@@ -91,8 +71,8 @@ def initialize_subscription(
site_city: str,
site_country: str,
site_country_code: str,
site_latitude: SnmpCoordinate,
site_longitude: SnmpCoordinate,
site_latitude: LatitudeCoordinate,
site_longitude: LongitudeCoordinate,
site_bgp_community_id: int,
site_internal_id: int,
site_ts_address: str,
......@@ -102,8 +82,8 @@ def initialize_subscription(
subscription.site.site_city = site_city
subscription.site.site_country = site_country
subscription.site.site_country_code = site_country_code
subscription.site.site_latitude = site_longitude
subscription.site.site_longitude = site_latitude
subscription.site.site_latitude = site_latitude
subscription.site.site_longitude = site_longitude
subscription.site.site_bgp_community_id = site_bgp_community_id
subscription.site.site_internal_id = site_internal_id
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