forked from React-Group/interstellar_ai
		
	Backend and frontend tweaks #16
					 9 changed files with 181 additions and 55 deletions
				
			
		| 
						 | 
					@ -3,7 +3,6 @@ import React, { useEffect, useRef, useState } from "react";
 | 
				
			||||||
import ConversationFrontend from "../components/ConversationFrontend";
 | 
					import ConversationFrontend from "../components/ConversationFrontend";
 | 
				
			||||||
import InputFrontend from "../components/InputFrontend";
 | 
					import InputFrontend from "../components/InputFrontend";
 | 
				
			||||||
import axios from "axios";
 | 
					import axios from "axios";
 | 
				
			||||||
import { log } from 'console';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const InputOutputBackend: React.FC = () => {
 | 
					const InputOutputBackend: React.FC = () => {
 | 
				
			||||||
  type Message = {
 | 
					  type Message = {
 | 
				
			||||||
| 
						 | 
					@ -16,6 +15,7 @@ const InputOutputBackend: React.FC = () => {
 | 
				
			||||||
  const getWorkerRef = useRef<Worker | null>(null)
 | 
					  const getWorkerRef = useRef<Worker | null>(null)
 | 
				
			||||||
  const [messages, setMessages] = useState<Message[]>([{role:"assistant", content:"Hello! How can I help you?"}])
 | 
					  const [messages, setMessages] = useState<Message[]>([{role:"assistant", content:"Hello! How can I help you?"}])
 | 
				
			||||||
  const [liveMessage, setLiveMessage] = useState("")
 | 
					  const [liveMessage, setLiveMessage] = useState("")
 | 
				
			||||||
 | 
					  const [inputDisabled, setInputDisabled] = useState(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  console.log(messages);
 | 
					  console.log(messages);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -37,8 +37,10 @@ const InputOutputBackend: React.FC = () => {
 | 
				
			||||||
    postWorkerRef.current.onmessage = (event) => {
 | 
					    postWorkerRef.current.onmessage = (event) => {
 | 
				
			||||||
      const status = event.data.status
 | 
					      const status = event.data.status
 | 
				
			||||||
      if (status == 200) {
 | 
					      if (status == 200) {
 | 
				
			||||||
 | 
					        setInputDisabled(false)
 | 
				
			||||||
        endGetWorker()
 | 
					        endGetWorker()
 | 
				
			||||||
      } else if (status == 500) {
 | 
					      } else if (status == 500) {
 | 
				
			||||||
 | 
					        setInputDisabled(false)
 | 
				
			||||||
        if (getWorkerRef.current) {
 | 
					        if (getWorkerRef.current) {
 | 
				
			||||||
          addMessage("assistant", "There was an Error with the AI response")
 | 
					          addMessage("assistant", "There was an Error with the AI response")
 | 
				
			||||||
          getWorkerRef.current.postMessage("terminate")
 | 
					          getWorkerRef.current.postMessage("terminate")
 | 
				
			||||||
| 
						 | 
					@ -86,11 +88,15 @@ const InputOutputBackend: React.FC = () => {
 | 
				
			||||||
    if (getWorkerRef.current) {
 | 
					    if (getWorkerRef.current) {
 | 
				
			||||||
      getWorkerRef.current.postMessage({action:"terminate"})
 | 
					      getWorkerRef.current.postMessage({action:"terminate"})
 | 
				
			||||||
      getWorkerRef.current.terminate()
 | 
					      getWorkerRef.current.terminate()
 | 
				
			||||||
 | 
					      getWorkerRef.current = null
 | 
				
			||||||
      console.log(messages);
 | 
					      console.log(messages);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const editLastMessage = (newContent: string) => {
 | 
					  const editLastMessage = (newContent: string) => {
 | 
				
			||||||
 | 
					    if (newContent == "") {
 | 
				
			||||||
 | 
					      newContent = "Generating answer..."
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  setMessages((prevMessages) => {
 | 
					  setMessages((prevMessages) => {
 | 
				
			||||||
    const updatedMessages = prevMessages.slice(); // Create a shallow copy of the current messages
 | 
					    const updatedMessages = prevMessages.slice(); // Create a shallow copy of the current messages
 | 
				
			||||||
    if (updatedMessages.length > 0) {
 | 
					    if (updatedMessages.length > 0) {
 | 
				
			||||||
| 
						 | 
					@ -109,11 +115,16 @@ const InputOutputBackend: React.FC = () => {
 | 
				
			||||||
    setMessages(previous => [...previous,{role,content}])
 | 
					    setMessages(previous => [...previous,{role,content}])
 | 
				
			||||||
  }  
 | 
					  }  
 | 
				
			||||||
  const handleSendClick = (inputValue: string) => {
 | 
					  const handleSendClick = (inputValue: string) => {
 | 
				
			||||||
    if (postWorkerRef.current) {
 | 
					    if (inputValue != "") {
 | 
				
			||||||
      addMessage("user", inputValue)
 | 
					      if (!inputDisabled) {
 | 
				
			||||||
      console.log("input:",inputValue);
 | 
					        setInputDisabled(true)
 | 
				
			||||||
      postWorkerRef.current.postMessage({messages:[...messages, { role: "user", content: inputValue }], ai_model:"phi3.5", access_token:accessToken})
 | 
					        if (postWorkerRef.current) {
 | 
				
			||||||
      startGetWorker()
 | 
					          addMessage("user", inputValue)
 | 
				
			||||||
 | 
					          console.log("input:",inputValue);
 | 
				
			||||||
 | 
					          postWorkerRef.current.postMessage({messages:[...messages, { role: "user", content: inputValue }], ai_model:"phi3.5", access_token:accessToken})
 | 
				
			||||||
 | 
					          startGetWorker()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,6 +156,7 @@ const InputOutputBackend: React.FC = () => {
 | 
				
			||||||
        message=""
 | 
					        message=""
 | 
				
			||||||
        onSendClick={handleSendClick}
 | 
					        onSendClick={handleSendClick}
 | 
				
			||||||
        onMicClick={handleMicClick}
 | 
					        onMicClick={handleMicClick}
 | 
				
			||||||
 | 
					        inputDisabled={inputDisabled}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,6 @@ const fetchData = () => {
 | 
				
			||||||
        .catch(error => {
 | 
					        .catch(error => {
 | 
				
			||||||
            console.log('Error fetching data:', error);
 | 
					            console.log('Error fetching data:', error);
 | 
				
			||||||
            postMessage({error:"failed fetching data"})
 | 
					            postMessage({error:"failed fetching data"})
 | 
				
			||||||
        
 | 
					            setTimeout(() => fetchData(),1000)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import axios from "axios";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onmessage = (e) => {
 | 
					onmessage = (e) => {
 | 
				
			||||||
    const { messages = [{ role: "assistant", content: "Hello! How can I help you?" }], ai_model = "phi3.5", access_token } = e.data
 | 
					    const { messages = [{ role: "assistant", content: "Hello! How can I help you?" }], ai_model = "phi3.5", access_token } = e.data
 | 
				
			||||||
    messages.unshift({ role: "system", content: "You are a Helpful assistant" })
 | 
					    messages.unshift({ role: "system", content: "You are a Helpful assistant. you give short answers" })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const Message = {
 | 
					    const Message = {
 | 
				
			||||||
        messages: messages,
 | 
					        messages: messages,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
// Header.tsx
 | 
					// Header.tsx
 | 
				
			||||||
import React from 'react';
 | 
					import React, { useState } from 'react';
 | 
				
			||||||
import Login from './Login';
 | 
					import Login from './Login';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface HeaderProps {
 | 
					interface HeaderProps {
 | 
				
			||||||
| 
						 | 
					@ -11,29 +11,32 @@ interface HeaderProps {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Header: React.FC<HeaderProps> = ({ onViewChange, showDivs, toggleDivs, showHistoryModelsToggle, showToggle }) => {
 | 
					const Header: React.FC<HeaderProps> = ({ onViewChange, showDivs, toggleDivs, showHistoryModelsToggle, showToggle }) => {
 | 
				
			||||||
 | 
					  const [menuOpen, setMenuOpen] = useState(false)
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  const toggleMenu = () => {
 | 
				
			||||||
 | 
					    setMenuOpen(!menuOpen)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <header>
 | 
					      <header>
 | 
				
			||||||
        <ul>
 | 
					        <div className={`hamburger ${menuOpen ? "open" : ""}`} onClick={toggleMenu}>
 | 
				
			||||||
          <li>
 | 
					          <span></span>
 | 
				
			||||||
            <button onClick={() => onViewChange('AI')} className="header-button header-logo">
 | 
					          <span></span>
 | 
				
			||||||
              <img src="/img/logo.png" alt="logo" className="header-logo" />
 | 
					          <span></span>
 | 
				
			||||||
            </button>
 | 
					        </div>
 | 
				
			||||||
          </li>
 | 
					        <nav className={`nav-links ${menuOpen ? "active":""}`}>
 | 
				
			||||||
          <li>
 | 
					            <button onClick={() => onViewChange('FAQ')} className="nav-btn">FAQ</button>
 | 
				
			||||||
            <button onClick={() => onViewChange('FAQ')} className="header-button">FAQ</button>
 | 
					            <button onClick={() => onViewChange('Documentation')} className="nav-btn">Documentation</button>
 | 
				
			||||||
          </li>
 | 
					            {showToggle && showHistoryModelsToggle && (
 | 
				
			||||||
          <li>
 | 
					              <button onClick={toggleDivs} className="nav-btn">
 | 
				
			||||||
            <button onClick={() => onViewChange('Documentation')} className="header-button">Documentation</button>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          {showToggle && showHistoryModelsToggle && (
 | 
					 | 
				
			||||||
            <li>
 | 
					 | 
				
			||||||
              <button onClick={toggleDivs} className="header-button">
 | 
					 | 
				
			||||||
                {showDivs ? 'Hide History/Models' : 'Show History/Models'}
 | 
					                {showDivs ? 'Hide History/Models' : 'Show History/Models'}
 | 
				
			||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
            </li>
 | 
					            )}
 | 
				
			||||||
          )}
 | 
					          </nav>
 | 
				
			||||||
        </ul>
 | 
					          {/* <button onClick={() => onViewChange('AI')} className="header-button header-logo">
 | 
				
			||||||
 | 
					            <img src="/img/logo.png" alt="logo" className="header-logo" />
 | 
				
			||||||
 | 
					          </button> */}
 | 
				
			||||||
      <Login />
 | 
					      <Login />
 | 
				
			||||||
      </header>
 | 
					      </header>
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,21 +4,25 @@ interface InputProps {
 | 
				
			||||||
  message: string;
 | 
					  message: string;
 | 
				
			||||||
  onSendClick: (message: string) => void;
 | 
					  onSendClick: (message: string) => void;
 | 
				
			||||||
  onMicClick: () => void;
 | 
					  onMicClick: () => void;
 | 
				
			||||||
 | 
					  inputDisabled:boolean
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
 | 
					const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
 | 
				
			||||||
  ({ message, onSendClick, onMicClick }, ref: ForwardedRef<HTMLDivElement>) => {
 | 
					  ({ message, onSendClick, onMicClick, inputDisabled }, ref: ForwardedRef<HTMLDivElement>) => {
 | 
				
			||||||
    const [inputValue, setInputValue] = useState('');
 | 
					    const [inputValue, setInputValue] = useState('');
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
 | 
					    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
 | 
				
			||||||
      setInputValue(e.target.value);
 | 
					      setInputValue(e.target.value);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
 | 
					    const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
 | 
				
			||||||
      if (event.key === 'Enter') {
 | 
					      if (!inputDisabled) {
 | 
				
			||||||
        onSendClick(inputValue); // Call the function passed via props
 | 
					        if (event.key === 'Enter') {
 | 
				
			||||||
        setInputValue(''); // Optionally clear input after submission
 | 
					          onSendClick(inputValue); // Call the function passed via props
 | 
				
			||||||
        event.preventDefault(); // Prevent default action (e.g., form submission)
 | 
					          setInputValue(''); // Optionally clear input after submission
 | 
				
			||||||
 | 
					          event.preventDefault(); // Prevent default action (e.g., form submission)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +36,7 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>(
 | 
				
			||||||
          onChange={handleInputChange}
 | 
					          onChange={handleInputChange}
 | 
				
			||||||
          onKeyDown={handleKeyDown}
 | 
					          onKeyDown={handleKeyDown}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <button type="button" onClick={() => onSendClick(inputValue)}>
 | 
					        <button type="button" onClick={() => onSendClick(inputValue)} disabled={inputDisabled?true:false}>
 | 
				
			||||||
          <img src="/img/send.svg" alt="send" />
 | 
					          <img src="/img/send.svg" alt="send" />
 | 
				
			||||||
        </button>
 | 
					        </button>
 | 
				
			||||||
        <button type="button" onClick={onMicClick}>
 | 
					        <button type="button" onClick={onMicClick}>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,29 +10,84 @@ header {
 | 
				
			||||||
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
 | 
					    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
 | 
				
			||||||
    z-index: 1000;
 | 
					    z-index: 1000;
 | 
				
			||||||
    font-family: var(--font-family);
 | 
					    font-family: var(--font-family);
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: space-between;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
header li {
 | 
					.nav-links{
 | 
				
			||||||
    display: inline-block;
 | 
					    display: flex;
 | 
				
			||||||
    margin: 0 15px;
 | 
					    gap: 15px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
header img {
 | 
					.nav-btn{
 | 
				
			||||||
    height: 2em;
 | 
					    background: transparent;
 | 
				
			||||||
    vertical-align: middle;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
header a, 
 | 
					 | 
				
			||||||
header li button {
 | 
					 | 
				
			||||||
    color: var(--header-text-color); /* Use the new header text color */
 | 
					 | 
				
			||||||
    text-decoration: none;
 | 
					 | 
				
			||||||
    transition: color 0.3s;
 | 
					 | 
				
			||||||
    border: none;
 | 
					    border: none;
 | 
				
			||||||
    background-color: transparent;
 | 
					    cursor: pointer;
 | 
				
			||||||
    font-size: 1em;
 | 
					    /* color */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
header a:hover,
 | 
					.nav-btn:hover{
 | 
				
			||||||
header li button:hover {
 | 
					    /* color */
 | 
				
			||||||
    color: var(--input-button-color); /* Keep the hover color */
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hamburger{
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hamburger span{
 | 
				
			||||||
 | 
					    width: 25px;
 | 
				
			||||||
 | 
					    height: 3px;
 | 
				
			||||||
 | 
					    background-color: var(--header-text-color);
 | 
				
			||||||
 | 
					    margin: 4px;
 | 
				
			||||||
 | 
					    transition: 0.3s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hamburger.open span:nth-child(1){
 | 
				
			||||||
 | 
					    transform: rotate(45deg) translate(5px, 5px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hamburger.open span:nth-child(2){
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hamburger.open span:nth-child(3){
 | 
				
			||||||
 | 
					    transform: rotate(-45deg) translate(5px, -5px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.header-button{
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.header-button img{
 | 
				
			||||||
 | 
					    height: 8vh;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@media (max-width:768px) {
 | 
				
			||||||
 | 
					    .nav-links{
 | 
				
			||||||
 | 
					        display: none;
 | 
				
			||||||
 | 
					        position: absolute;
 | 
				
			||||||
 | 
					        top: 60px;
 | 
				
			||||||
 | 
					        right: 0;
 | 
				
			||||||
 | 
					        /* background color */
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        flex-direction: column;
 | 
				
			||||||
 | 
					        align-items: flex-start;
 | 
				
			||||||
 | 
					        padding: 10px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .nav-links.active{
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .nav-btn{
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        text-align: center;
 | 
				
			||||||
 | 
					        padding: 10px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .hamburger{
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								py/api.py
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								py/api.py
									
										
									
									
									
								
							| 
						 | 
					@ -4,16 +4,18 @@ import secrets
 | 
				
			||||||
import threading
 | 
					import threading
 | 
				
			||||||
from ai import AI
 | 
					from ai import AI
 | 
				
			||||||
from db import DB
 | 
					from db import DB
 | 
				
			||||||
 | 
					from weather import Weather
 | 
				
			||||||
from voice import VoiceRecognition
 | 
					from voice import VoiceRecognition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class API:
 | 
					class API:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        self.crypt_size = 1
 | 
					        self.crypt_size = 4096
 | 
				
			||||||
        self.app = Flask(__name__)
 | 
					        self.app = Flask(__name__)
 | 
				
			||||||
        self.ai_response = {}
 | 
					        self.ai_response = {}
 | 
				
			||||||
        self.ai = AI()
 | 
					        self.ai = AI()
 | 
				
			||||||
        self.db = DB()
 | 
					        self.db = DB()
 | 
				
			||||||
 | 
					        self.weather = Weather()
 | 
				
			||||||
        self.voice = VoiceRecognition()
 | 
					        self.voice = VoiceRecognition()
 | 
				
			||||||
        self.db.load_database()
 | 
					        self.db.load_database()
 | 
				
			||||||
        self.ai_response_lock = threading.Lock()
 | 
					        self.ai_response_lock = threading.Lock()
 | 
				
			||||||
| 
						 | 
					@ -23,8 +25,12 @@ class API:
 | 
				
			||||||
        @self.app.route('/interstellar_ai/api/ai_create', methods=['GET'])
 | 
					        @self.app.route('/interstellar_ai/api/ai_create', methods=['GET'])
 | 
				
			||||||
        def create_ai():
 | 
					        def create_ai():
 | 
				
			||||||
            access_token = secrets.token_urlsafe(self.crypt_size)
 | 
					            access_token = secrets.token_urlsafe(self.crypt_size)
 | 
				
			||||||
            self.ai_response[access_token] = ""
 | 
					
 | 
				
			||||||
            return jsonify({'status': 200, 'access_token': access_token})
 | 
					            if access_token not in self.ai_response:
 | 
				
			||||||
 | 
					                self.ai_response[access_token] = ""
 | 
				
			||||||
 | 
					                return jsonify({'status': 200, 'access_token': access_token})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return jsonify({'status': 401, 'error': 'An error occurred, please try again.'})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @self.app.route('/interstellar_ai/api/ai_send', methods=['POST'])
 | 
					        @self.app.route('/interstellar_ai/api/ai_send', methods=['POST'])
 | 
				
			||||||
        def send_ai():
 | 
					        def send_ai():
 | 
				
			||||||
| 
						 | 
					@ -99,6 +105,12 @@ class API:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return jsonify({'status': 401, 'response': "Invalid type"})
 | 
					            return jsonify({'status': 401, 'response': "Invalid type"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @self.app.route('/interstellar_ai/api/weather', methods=['POST'])
 | 
				
			||||||
 | 
					        def get_weather():
 | 
				
			||||||
 | 
					            unit_type = request.args.get('unit_type')
 | 
				
			||||||
 | 
					            city = request.args.get('city')
 | 
				
			||||||
 | 
					            return jsonify({'status': 200, 'response': self.weather.getweather(unit_type, city)})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.app.run(debug=True, host='0.0.0.0', port=5000)
 | 
					        self.app.run(debug=True, host='0.0.0.0', port=5000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,3 +9,4 @@ SpeechRecognition
 | 
				
			||||||
PocketSphinx
 | 
					PocketSphinx
 | 
				
			||||||
google-cloud-speech
 | 
					google-cloud-speech
 | 
				
			||||||
google-generativeai
 | 
					google-generativeai
 | 
				
			||||||
 | 
					python-weather
 | 
				
			||||||
							
								
								
									
										39
									
								
								py/weather.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								py/weather.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					import python_weather
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Weather:
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    async def getweather(unit_type, city):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if unit_type == "imperial":
 | 
				
			||||||
 | 
					            unit_type = python_weather.IMPERIAL
 | 
				
			||||||
 | 
					        elif unit_type == "metric":
 | 
				
			||||||
 | 
					            unit_type = python_weather.METRIC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async with python_weather.Client(unit=unit_type) as client:
 | 
				
			||||||
 | 
					            weather = await client.get(city)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            data = {
 | 
				
			||||||
 | 
					                'temperature': weather.temperature,
 | 
				
			||||||
 | 
					                'humidity': weather.humidity,
 | 
				
			||||||
 | 
					                'unit': weather.unit,
 | 
				
			||||||
 | 
					                'datetime': weather.datetime,
 | 
				
			||||||
 | 
					                'coordinates': weather.coordinates,
 | 
				
			||||||
 | 
					                'country': weather.country,
 | 
				
			||||||
 | 
					                'daily_forecasts': weather.daily_forecasts,
 | 
				
			||||||
 | 
					                'description': weather.description,
 | 
				
			||||||
 | 
					                'feels_like': weather.feels_like,
 | 
				
			||||||
 | 
					                'kind': weather.kind,
 | 
				
			||||||
 | 
					                'local_population': weather.local_population,
 | 
				
			||||||
 | 
					                'locale': weather.locale,
 | 
				
			||||||
 | 
					                'location': weather.location,
 | 
				
			||||||
 | 
					                'precipitation': weather.precipitation,
 | 
				
			||||||
 | 
					                'pressure': weather.pressure,
 | 
				
			||||||
 | 
					                'region': weather.region,
 | 
				
			||||||
 | 
					                'ultraviolet': weather.ultraviolet,
 | 
				
			||||||
 | 
					                'visibility': weather.visibility,
 | 
				
			||||||
 | 
					                'wind_direction': weather.wind_direction,
 | 
				
			||||||
 | 
					                'wind_speed': weather.wind_speed,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return data
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue