Skip to content

Commit

Permalink
Update data model imports
Browse files Browse the repository at this point in the history
  • Loading branch information
NeonDaniel committed Nov 4, 2024
1 parent 5ead36c commit e6a33c9
Show file tree
Hide file tree
Showing 6 changed files with 9 additions and 305 deletions.
32 changes: 1 addition & 31 deletions neon_hana/schema/node_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,5 @@
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from uuid import uuid4

from pydantic import BaseModel, Field
from typing import Optional, Dict


class NodeSoftware(BaseModel):
operating_system: str = ""
os_version: str = ""
neon_packages: Optional[Dict[str, str]] = None


class NodeNetworking(BaseModel):
local_ip: str = "127.0.0.1"
public_ip: str = ""
mac_address: str = ""


class NodeLocation(BaseModel):
lat: Optional[float] = None
lon: Optional[float] = None
site_id: Optional[str] = None


class NodeData(BaseModel):
device_id: str = Field(default_factory=lambda: str(uuid4()))
device_name: str = ""
device_description: str = ""
platform: str = ""
networking: NodeNetworking = NodeNetworking()
software: NodeSoftware = NodeSoftware()
location: NodeLocation = NodeLocation()
from neon_data_models.models.client.node import *
131 changes: 2 additions & 129 deletions neon_hana/schema/node_v1.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2021 Neongecko.com Inc.
# Copyright 2008-2024 Neongecko.com Inc.
# BSD-3
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
Expand All @@ -24,131 +24,4 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from pydantic import BaseModel, Field
from typing import Optional, Dict, List, Literal
from neon_hana.schema.node_model import NodeData


class NodeInputContext(BaseModel):
node_data: Optional[NodeData] = Field(description="Node Data")


class AudioInputData(BaseModel):
audio_data: str = Field(description="base64-encoded audio")
lang: str = Field(description="BCP-47 language code")


class TextInputData(BaseModel):
text: str = Field(description="String text input")
lang: str = Field(description="BCP-47 language code")


class UtteranceInputData(BaseModel):
utterances: List[str] = Field(description="List of input utterance(s)")
lang: str = Field(description="BCP-47 language")


class KlatResponse(BaseModel):
sentence: str = Field(description="Text response")
audio: dict = {Field(description="Audio Gender",
type=Literal["male", "female"]):
Field(description="b64-encoded audio", type=str)}


class TtsResponse(KlatResponse):
translated: bool = Field(description="True if sentence was translated")
phonemes: List[str] = Field(description="List of phonemes")
genders: List[str] = Field(description="List of audio genders")


class KlatResponseData(BaseModel):
responses: dict = {Field(type=str,
description="BCP-47 language"): KlatResponse}


class NodeAudioInput(BaseModel):
msg_type: str = "neon.audio_input"
data: AudioInputData
context: NodeInputContext


class NodeTextInput(BaseModel):
msg_type: str = "recognizer_loop:utterance"
data: UtteranceInputData
context: NodeInputContext


class NodeGetStt(BaseModel):
msg_type: str = "neon.get_stt"
data: AudioInputData
context: NodeInputContext


class NodeGetTts(BaseModel):
msg_type: str = "neon.get_tts"
data: TextInputData
context: NodeInputContext


class NodeKlatResponse(BaseModel):
msg_type: str = "klat.response"
data: dict = {Field(type=str, description="BCP-47 language"): KlatResponse}
context: dict


class NodeAudioInputResponse(BaseModel):
msg_type: str = "neon.audio_input.response"
data: dict = {"parser_data": Field(description="Dict audio parser data",
type=dict),
"transcripts": Field(description="Transcribed text",
type=List[str]),
"skills_recv": Field(description="Skills service acknowledge",
type=bool)}
context: dict


class NodeGetSttResponse(BaseModel):
msg_type: str = "neon.get_stt.response"
data: dict = {"parser_data": Field(description="Dict audio parser data",
type=dict),
"transcripts": Field(description="Transcribed text",
type=List[str]),
"skills_recv": Field(description="Skills service acknowledge",
type=bool)}
context: dict


class NodeGetTtsResponse(BaseModel):
msg_type: str = "neon.get_tts.response"
data: KlatResponseData
context: dict


class CoreWWDetected(BaseModel):
msg_type: str = "neon.ww_detected"
data: dict
context: dict


class CoreIntentFailure(BaseModel):
msg_type: str = "complete.intent.failure"
data: dict
context: dict


class CoreErrorResponse(BaseModel):
msg_type: str = "klat.error"
data: dict
context: dict


class CoreClearData(BaseModel):
msg_type: str = "neon.clear_data"
data: dict
context: dict


class CoreAlertExpired(BaseModel):
msg_type: str = "neon.alert_expired"
data: dict
context: dict
from neon_data_models.models.api.node_v1 import *
141 changes: 1 addition & 140 deletions neon_hana/schema/user_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,143 +24,4 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import pytz
import datetime

from typing import Optional, List
from pydantic import BaseModel

from neon_users_service.models import User


class ProfileUser(BaseModel):
first_name: str = ""
middle_name: str = ""
last_name: str = ""
preferred_name: str = ""
full_name: str = ""
dob: str = "YYYY/MM/DD"
age: str = ""
email: str = ""
username: str = ""
password: str = ""
picture: str = ""
about: str = ""
phone: str = ""
phone_verified: bool = False
email_verified: bool = False


class ProfileBrands(BaseModel):
ignored_brands: dict = {}
favorite_brands: dict = {}
specially_requested: dict = {}


class ProfileSpeech(BaseModel):
stt_language: str = "en-us"
alt_languages: List[str] = ['en']
tts_language: str = "en-us"
tts_gender: str = "female"
neon_voice: Optional[str] = ''
secondary_tts_language: Optional[str] = ''
secondary_tts_gender: str = "male"
secondary_neon_voice: str = ''
speed_multiplier: float = 1.0


class ProfileUnits(BaseModel):
time: int = 12
# 12, 24
date: str = "MDY"
# MDY, YMD, YDM
measure: str = "imperial"
# imperial, metric


class ProfileLocation(BaseModel):
lat: Optional[float] = None
lng: Optional[float] = None
city: Optional[str] = None
state: Optional[str] = None
country: Optional[str] = None
tz: Optional[str] = None
utc: Optional[float] = None


class ProfileResponseMode(BaseModel):
speed_mode: str = "quick"
hesitation: bool = False
limit_dialog: bool = False


class ProfilePrivacy(BaseModel):
save_audio: bool = False
save_text: bool = False


class UserProfile(BaseModel):
user: ProfileUser = ProfileUser()
# brands: ProfileBrands
speech: ProfileSpeech = ProfileSpeech()
units: ProfileUnits = ProfileUnits()
location: ProfileLocation = ProfileLocation()
response_mode: ProfileResponseMode = ProfileResponseMode()
privacy: ProfilePrivacy = ProfilePrivacy()

@classmethod
def from_user_config(cls, user: User):
user_config = user.neon
today = datetime.date.today()
if user_config.user.dob:
dob = user_config.user.dob
age = today.year - dob.year - (
(today.month, today.day) < (dob.month, dob.day))
dob = dob.strftime("%Y/%m/%d")
else:
age = ""
dob = "YYYY/MM/DD"
full_name = " ".join((n for n in (user_config.user.first_name,
user_config.user.middle_name,
user_config.user.last_name) if n))
user = ProfileUser(about=user_config.user.about,
age=age, dob=dob,
email=user_config.user.email,
email_verified=user_config.user.email_verified,
first_name=user_config.user.first_name,
full_name=full_name,
last_name=user_config.user.last_name,
middle_name=user_config.user.middle_name,
password=user.password_hash or "",
phone=user_config.user.phone,
phone_verified=user_config.user.phone_verified,
picture=user_config.user.avatar_url,
preferred_name=user_config.user.preferred_name,
username=user.username
)
alt_stt = [lang.split('-')[0] for lang in
user_config.language.input_languages[1:]]
secondary_tts_lang = user_config.language.output_languages[1] if (
len(user_config.language.output_languages) > 1) else None
speech = ProfileSpeech(
alt_langs=alt_stt,
secondary_tts_gender=user_config.response_mode.tts_gender,
secondary_tts_language=secondary_tts_lang,
speed_multiplier=user_config.response_mode.tts_speed_multiplier,
stt_language=user_config.language.input_languages[0].split('-')[0],
tts_gender=user_config.response_mode.tts_gender,
tts_language=user_config.language.output_languages[0])
units = ProfileUnits(**user_config.units.model_dump())
utc_hours = (pytz.timezone(user_config.location.timezone or "UTC")
.utcoffset(datetime.datetime.now()).total_seconds() / 3600)
# TODO: Get city, state, country from lat/lon
location = ProfileLocation(lat=user_config.location.latitude,
lng=user_config.location.longitude,
tz=user_config.location.timezone,
utc=utc_hours)
response_mode = ProfileResponseMode(**user_config.response_mode.model_dump())
privacy = ProfilePrivacy(**user_config.privacy.model_dump())

return UserProfile(location=location, privacy=privacy,
response_mode=response_mode, speech=speech,
units=units, user=user)
from neon_data_models.models.user.neon_profile import *
4 changes: 2 additions & 2 deletions neon_hana/schema/user_requests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2021 Neongecko.com Inc.
# Copyright 2008-2024 Neongecko.com Inc.
# BSD-3
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
Expand All @@ -26,7 +26,7 @@

from pydantic import BaseModel

from neon_users_service.models import User
from neon_data_models.models.user.database import User


class GetUserRequest(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ token-throttler~=1.4
neon-mq-connector~=0.7
ovos-config~=0.0,>=0.0.12
ovos-utils~=0.0,>=0.0.38
neon-users-service@git+https://github.com/neongeckocom/neon-users-service@FEAT_InitialImplementation
neon-data-models
4 changes: 2 additions & 2 deletions tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from neon_hana.schema.user_profile import UserProfile

from neon_users_service.models import User
from neon_data_models.models.user import User


class TestUserProfile(TestCase):
Expand All @@ -13,6 +13,6 @@ def test_user_profile(self):

# Test from User
default_user = User(username="test_user")
profile = UserProfile.from_user_config(default_user)
profile = UserProfile.from_user_object(default_user)
self.assertIsInstance(profile, UserProfile)
self.assertEqual(default_user.username, profile.user.username)

0 comments on commit e6a33c9

Please sign in to comment.