moriire commited on
Commit
014870a
1 Parent(s): 3c58d3e

auth added

Browse files
Dockerfile CHANGED
@@ -45,5 +45,5 @@ ENV HOME=/home/user \
45
  COPY --chown=user . $HOME
46
  #CMD ["python3", "-m", "app"]
47
  # Start the FastAPI app on port 7860, the default port expected by Spaces
48
- CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
49
  #ENTRYPOINT ["python3", "-m", "llama_cpp.server", "--hf_model_repo_id", "Qwen/Qwen1.5-0.5B-Chat-GGUF", "--model", "*q4_0.gguf", "--host", "0.0.0.0"]
 
45
  COPY --chown=user . $HOME
46
  #CMD ["python3", "-m", "app"]
47
  # Start the FastAPI app on port 7860, the default port expected by Spaces
48
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
49
  #ENTRYPOINT ["python3", "-m", "llama_cpp.server", "--hf_model_repo_id", "Qwen/Qwen1.5-0.5B-Chat-GGUF", "--model", "*q4_0.gguf", "--host", "0.0.0.0"]
__init__.py ADDED
File without changes
__pycache__/main.cpython-310.pyc ADDED
Binary file (625 Bytes). View file
 
app/__init__.py ADDED
File without changes
app/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (139 Bytes). View file
 
app/__pycache__/app.cpython-310.pyc ADDED
Binary file (1.68 kB). View file
 
app/__pycache__/auth.cpython-310.pyc ADDED
Binary file (1.68 kB). View file
 
app/__pycache__/config.cpython-310.pyc ADDED
Binary file (491 Bytes). View file
 
app/__pycache__/gtts.cpython-310.pyc ADDED
Binary file (2.36 kB). View file
 
app/__pycache__/main.cpython-310.pyc ADDED
Binary file (329 Bytes). View file
 
app/__pycache__/security.cpython-310.pyc ADDED
Binary file (582 Bytes). View file
 
app/auth.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timedelta
2
+ from typing import Optional
3
+
4
+ import jwt
5
+ from fastapi import HTTPException, Depends, status
6
+ from fastapi.security import OAuth2PasswordBearer
7
+ from sqlalchemy.orm import Session
8
+ from app.db.database import get_db
9
+ from app.models.user import User
10
+ from app.schemas.user import UserOut
11
+
12
+ SECRET_KEY = "supersecretkey"
13
+ ALGORITHM = "HS256"
14
+ ACCESS_TOKEN_EXPIRE_MINUTES = 30
15
+
16
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
17
+
18
+ def create_access_token(data: dict):
19
+ to_encode = data.copy()
20
+ expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
21
+ to_encode.update({"exp": expire})
22
+ encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
23
+ return encoded_jwt
24
+
25
+ def verify_access_token(token: str, db: Session):
26
+ try:
27
+ payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
28
+ user_id: str = payload.get("sub")
29
+ if user_id is None:
30
+ raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
31
+ user = db.query(User).filter(User.id == user_id).first()
32
+ if user is None:
33
+ raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
34
+ detail="User not found")
35
+ return user
36
+ except jwt.PyJWTError:
37
+ raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
38
+
39
+ def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
40
+ return verify_access_token(token, db)
app/config.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ #from pydantic import BaseSettings
2
+ from pydantic_settings import BaseSettings
3
+ class Settings(BaseSettings):
4
+ SECRET_KEY: str = "your_secret_key"
5
+ DATABASE_URL: str = "sqlite:///./app.db"
6
+
7
+ settings = Settings()
app/db/__pycache__/database.cpython-310.pyc ADDED
Binary file (783 Bytes). View file
 
app/db/database.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import create_engine
2
+ from sqlalchemy.orm import sessionmaker, declarative_base
3
+ from app.config import settings
4
+
5
+ DATABASE_URL = settings.DATABASE_URL
6
+
7
+ engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
8
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
9
+ Base = declarative_base()
10
+
11
+ def create_tables():
12
+ Base.metadata.create_all(bind=engine)
13
+
14
+ def get_db():
15
+ db = SessionLocal()
16
+ try:
17
+ yield db
18
+ finally:
19
+ db.close()
app/fapp.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import urllib.request
3
+ from llama_cpp import Llama
4
+ from fastapi import FastAPI
5
+
6
+ app = FastAPI(docs_url="/")
7
+
8
+ def download_file(file_link, filename):
9
+ # Checks if the file already exists before downloading
10
+ if not os.path.isfile(filename):
11
+ urllib.request.urlretrieve(file_link, filename)
12
+ print("File downloaded successfully.")
13
+ else:
14
+ print("File already exists.")
15
+
16
+
17
+ # Dowloading GGML model from HuggingFace
18
+ ggml_model_path = "https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/resolve/main/zephyr-7b-beta.Q4_0.gguf"
19
+ filename = "zephyr-7b-beta.Q4_0.gguf"
20
+
21
+ #download_file(ggml_model_path, filename)
22
+
23
+
24
+
25
+ llm = Llama(model_path="/home/mo/Desktop/web/oGBackend/qwen1_5-0_5b-chat-q2_k.gguf", n_ctx=512, n_batch=126, chat_format="llama")
26
+
27
+
28
+ def generate_text(
29
+ prompt="Who is the COlor of Apple?",
30
+ max_tokens=256,
31
+ temperature=0.7,
32
+ top_p=0.5,
33
+ echo=False,
34
+ stop=["#"],
35
+ ):
36
+ output = llm(
37
+ prompt,
38
+ max_tokens=max_tokens,
39
+ temperature=temperature,
40
+ top_p=top_p,
41
+ echo=echo,
42
+ stop=stop,
43
+ )
44
+ output_text = output["choices"][0]["text"]
45
+ return output_text
46
+
47
+
48
+ def generate_prompt_from_template(input):
49
+ chat_prompt_template = f"""<|im_start|>system
50
+ You are a helpful chatbot.<|im_end|>
51
+ <|im_start|>user
52
+ {input}<|im_end|>"""
53
+ return chat_prompt_template
54
+
55
+ @app.get("/generate")
56
+ def generate(text: str):
57
+ prompt = generate_prompt_from_template(text)
58
+
59
+ generate_text(
60
+ prompt,
61
+ max_tokens=356,
62
+ )
app/gtts.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import time
3
+
4
+ import speech_recognition as sr
5
+
6
+
7
+ def recognize_speech_from_mic(recognizer, microphone):
8
+ """Transcribe speech from recorded from `microphone`.
9
+
10
+ Returns a dictionary with three keys:
11
+ "success": a boolean indicating whether or not the API request was
12
+ successful
13
+ "error": `None` if no error occured, otherwise a string containing
14
+ an error message if the API could not be reached or
15
+ speech was unrecognizable
16
+ "transcription": `None` if speech could not be transcribed,
17
+ otherwise a string containing the transcribed text
18
+ """
19
+ # check that recognizer and microphone arguments are appropriate type
20
+ if not isinstance(recognizer, sr.Recognizer):
21
+ raise TypeError("`recognizer` must be `Recognizer` instance")
22
+
23
+ if not isinstance(microphone, sr.Microphone):
24
+ raise TypeError("`microphone` must be `Microphone` instance")
25
+
26
+ # adjust the recognizer sensitivity to ambient noise and record audio
27
+ # from the microphone
28
+ with microphone as source:
29
+ recognizer.adjust_for_ambient_noise(source)
30
+ audio = recognizer.listen(source)
31
+
32
+ # set up the response object
33
+ response = {
34
+ "success": True,
35
+ "error": None,
36
+ "transcription": None
37
+ }
38
+
39
+ # try recognizing the speech in the recording
40
+ # if a RequestError or UnknownValueError exception is caught,
41
+ # update the response object accordingly
42
+ try:
43
+ response["transcription"] = recognizer.recognize_google(audio)
44
+ except sr.RequestError:
45
+ # API was unreachable or unresponsive
46
+ response["success"] = False
47
+ response["error"] = "API unavailable"
48
+ except sr.UnknownValueError:
49
+ # speech was unintelligible
50
+ response["error"] = "Unable to recognize speech"
51
+
52
+ return response
53
+
54
+
55
+ if __name__ == "__main__":
56
+ # set the list of words, maxnumber of guesses, and prompt limit
57
+ WORDS = ["apple", "banana", "grape", "orange", "mango", "lemon"]
58
+ NUM_GUESSES = 3
59
+ PROMPT_LIMIT = 5
60
+
61
+ # create recognizer and mic instances
62
+ recognizer = sr.Recognizer()
63
+ microphone = sr.Microphone()
64
+
65
+ # get a random word from the list
66
+ word = random.choice(WORDS)
67
+
68
+ # format the instructions string
69
+ instructions = (
70
+ "I'm thinking of one of these words:\n"
71
+ "{words}\n"
72
+ "You have {n} tries to guess which one.\n"
73
+ ).format(words=', '.join(WORDS), n=NUM_GUESSES)
74
+
75
+ # show instructions and wait 3 seconds before starting the game
76
+ print(instructions)
77
+ time.sleep(3)
78
+
79
+ for i in range(NUM_GUESSES):
80
+ # get the guess from the user
81
+ # if a transcription is returned, break out of the loop and
82
+ # continue
83
+ # if no transcription returned and API request failed, break
84
+ # loop and continue
85
+ # if API request succeeded but no transcription was returned,
86
+ # re-prompt the user to say their guess again. Do this up
87
+ # to PROMPT_LIMIT times
88
+ for j in range(PROMPT_LIMIT):
89
+ print('Guess {}. Speak!'.format(i+1))
90
+ guess = recognize_speech_from_mic(recognizer, microphone)
91
+ if guess["transcription"]:
92
+ break
93
+ if not guess["success"]:
94
+ break
95
+ print("I didn't catch that. What did you say?\n")
96
+
97
+ # if there was an error, stop the game
98
+ if guess["error"]:
99
+ print("ERROR: {}".format(guess["error"]))
100
+ break
101
+
102
+ # show the user the transcription
103
+ print("You said: {}".format(guess["transcription"]))
104
+
105
+ # determine if guess is correct and if any attempts remain
106
+ guess_is_correct = guess["transcription"].lower() == word.lower()
107
+ user_has_more_attempts = i < NUM_GUESSES - 1
108
+
109
+ # determine if the user has won the game
110
+ # if not, repeat the loop if user has more attempts
111
+ # if no attempts left, the user loses the game
112
+ if guess_is_correct:
113
+ print("Correct! You win!".format(word))
114
+ break
115
+ elif user_has_more_attempts:
116
+ print("Incorrect. Try again.\n")
117
+ else:
118
+ print("Sorry, you lose!\nI was thinking of '{}'.".format(word))
119
+ break
app/hello.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import llama_cpp
2
+ model = llama_cpp.Llama(
3
+ model_path="/home/mo/Desktop/web/oGBackend/qwen1_5-0_5b-chat-q2_k.gguf",
4
+ chat_format="llama-2",
5
+ )
6
+ x = model.create_completion("Write a story about robotics?")
7
+ print(x)
app/models/__pycache__/user.cpython-310.pyc ADDED
Binary file (562 Bytes). View file
 
app/models/user.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Column, Integer, String
2
+ from app.db.database import Base
3
+
4
+ class User(Base):
5
+ __tablename__ = "users"
6
+
7
+ id = Column(Integer, primary_key=True, index=True)
8
+ username = Column(String, unique=True, index=True)
9
+ password = Column(String)
app/routers/__pycache__/llm.cpython-310.pyc ADDED
Binary file (3.62 kB). View file
 
app/routers/__pycache__/user.cpython-310.pyc ADDED
Binary file (1.59 kB). View file
 
app/routers/llm.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Depends, HTTPException, status
2
+ from sqlalchemy.orm import Session
3
+ from app.db.database import get_db
4
+ from app.models.user import User
5
+ from app.schemas.user import UserCreate, UserOut
6
+ from app.auth import create_access_token, get_current_user
7
+
8
+
9
+
10
+ import fastapi
11
+ from fastapi.responses import JSONResponse
12
+ from time import time
13
+ #from fastapi.middleware.cors import CORSMiddleware
14
+ import logging
15
+ import llama_cpp
16
+ import llama_cpp.llama_tokenizer
17
+ from pydantic import BaseModel
18
+
19
+
20
+
21
+
22
+
23
+ router = APIRouter(prefix="/llm", tags=["llm"])
24
+
25
+
26
+ class GenModel(BaseModel):
27
+ question: str
28
+ system: str = "You are a helpful medical AI chat assistant. Help as much as you can.Also continuously ask for possible symptoms in order to atat a conclusive ailment or sickness and possible solutions.Remember, response in English."
29
+ temperature: float = 0.8
30
+ seed: int = 101
31
+ mirostat_mode: int=2
32
+ mirostat_tau: float=4.0
33
+ mirostat_eta: float=1.1
34
+
35
+ class ChatModel(BaseModel):
36
+ question: list
37
+ system: str = "You are a helpful medical AI chat assistant. Help as much as you can.Also continuously ask for possible symptoms in order to atat a conclusive ailment or sickness and possible solutions.Remember, response in English."
38
+ temperature: float = 0.8
39
+ seed: int = 101
40
+ mirostat_mode: int=2
41
+ mirostat_tau: float=4.0
42
+ mirostat_eta: float=1.1
43
+ llm_chat = llama_cpp.Llama.from_pretrained(
44
+ repo_id="Qwen/Qwen1.5-0.5B-Chat-GGUF",
45
+ filename="*q4_0.gguf",
46
+ tokenizer=llama_cpp.llama_tokenizer.LlamaHFTokenizer.from_pretrained("Qwen/Qwen1.5-0.5B"),
47
+ verbose=False,
48
+ n_ctx=1024,
49
+ n_gpu_layers=0,
50
+ #chat_format="llama-2"
51
+ )
52
+ llm_generate = llama_cpp.Llama.from_pretrained(
53
+ repo_id="Qwen/Qwen1.5-0.5B-Chat-GGUF",
54
+ filename="*q4_0.gguf",
55
+ tokenizer=llama_cpp.llama_tokenizer.LlamaHFTokenizer.from_pretrained("Qwen/Qwen1.5-0.5B"),
56
+ verbose=False,
57
+ n_ctx=4096,
58
+ n_gpu_layers=0,
59
+ mirostat_mode=2,
60
+ mirostat_tau=4.0,
61
+ mirostat_eta=1.1
62
+ #chat_format="llama-2"
63
+ )
64
+ # Logger setup
65
+ logging.basicConfig(level=logging.INFO)
66
+ logger = logging.getLogger(__name__)
67
+
68
+
69
+
70
+
71
+ @router.get("/")
72
+ def index():
73
+ return fastapi.responses.RedirectResponse(url="/docs")
74
+
75
+ @router.get("/health")
76
+ def health():
77
+ return {"status": "ok"}
78
+
79
+ # Chat Completion API
80
+ @router.post("/chat/")
81
+ async def chat(chatm:ChatModel):
82
+ try:
83
+ st = time()
84
+ output = llm_chat.create_chat_completion(
85
+ messages = chatm.question,
86
+ temperature = chatm.temperature,
87
+ seed = chatm.seed,
88
+ #stream=True
89
+ )
90
+ #print(output)
91
+ et = time()
92
+ output["time"] = et - st
93
+ #messages.append({'role': "assistant", "content": output['choices'][0]['message']['content']})
94
+ #print(messages)
95
+ return output
96
+ except Exception as e:
97
+ logger.error(f"Error in /complete endpoint: {e}")
98
+ return JSONResponse(
99
+ status_code=500, content={"message": "Internal Server Error"}
100
+ )
101
+
102
+ # Chat Completion API
103
+ @router.post("/generate")
104
+ async def generate(gen:GenModel):
105
+ gen.system = "You are an helpful medical AI assistant."
106
+ gen.temperature = 0.5
107
+ gen.seed = 42
108
+ try:
109
+ st = time()
110
+ output = llm_generate.create_chat_completion(
111
+ messages=[
112
+ {"role": "system", "content": gen.system},
113
+ {"role": "user", "content": gen.question},
114
+ ],
115
+ temperature = gen.temperature,
116
+ seed= gen.seed,
117
+ #stream=True,
118
+ #echo=True
119
+ )
120
+ """
121
+ for chunk in output:
122
+ delta = chunk['choices'][0]['delta']
123
+ if 'role' in delta:
124
+ print(delta['role'], end=': ')
125
+ elif 'content' in delta:
126
+ print(delta['content'], end='')
127
+ #print(chunk)
128
+ """
129
+ et = time()
130
+ output["time"] = et - st
131
+ return output
132
+ except Exception as e:
133
+ logger.error(f"Error in /generate endpoint: {e}")
134
+ return JSONResponse(
135
+ status_code=500, content={"message": "Internal Server Error"}
136
+ )
app/routers/user.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Depends, HTTPException, status
2
+ from sqlalchemy.orm import Session
3
+ from app.db.database import get_db
4
+ from app.models.user import User
5
+ from app.schemas.user import UserCreate, UserOut
6
+ from app.auth import create_access_token, get_current_user
7
+
8
+ router = APIRouter(prefix="/user", tags=["user"])
9
+
10
+ @router.post("/register", response_model=UserOut)
11
+ def register(user: UserCreate, db: Session = Depends(get_db)):
12
+ existing_user = db.query(User).filter(User.username == user.username).first()
13
+ if existing_user:
14
+ raise HTTPException(status_code=400,
15
+ #status.HTTP_400_BAD_REQUEST,
16
+ detail="Username already taken")
17
+
18
+ hashed_password = user.password # Hashing is needed here
19
+ db_user = User(username=user.username, password=hashed_password)
20
+ db.add(db_user)
21
+ db.commit()
22
+ db.refresh(db_user)
23
+ return db_user
24
+
25
+ @router.post("/login")
26
+ def login(user: UserCreate, db: Session = Depends(get_db)):
27
+ db_user = db.query(User).filter(User.username == user.username).first()
28
+ if not db_user or db_user.password != user.password:
29
+ raise HTTPException(status_code=400,
30
+ #status.HTTP.400_BAD_REQUEST,
31
+ detail="Invalid credentials")
32
+
33
+ access_token = create_access_token(data={"sub": str(db_user.id)})
34
+ return {"access_token": access_token, "token_type": "bearer"}
35
+
36
+ @router.get("/me", response_model=UserOut)
37
+ def read_users_me(current_user: User = Depends(get_current_user)):
38
+ return current_user
app/schemas/__pycache__/user.cpython-310.pyc ADDED
Binary file (947 Bytes). View file
 
app/schemas/user.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ class UserInDB(BaseModel):
4
+ id: int
5
+ username: str
6
+ password: str
7
+
8
+ class UserCreate(BaseModel):
9
+ username: str
10
+ password: str
11
+
12
+ class UserOut(BaseModel):
13
+ id: int
14
+ username: str
15
+
16
+ class Config:
17
+ orm_mode = True
app/security.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from passlib.context import CryptContext
2
+
3
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
4
+
5
+ def hash_password(password: str):
6
+ return pwd_context.hash(password)
7
+
8
+ def verify_password(plain_password: str, hashed_password: str):
9
+ return pwd_context.verify(plain_password, hashed_password)
main.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ from fastapi import FastAPI
3
+ from app.routers import user
4
+ from app.db import database
5
+
6
+ app = FastAPI()
7
+
8
+ # Include user router
9
+ app.include_router(user.router)
10
+
11
+ # Create tables
12
+ database.create_tables()
13
+ """
14
+ from fastapi import FastAPI
15
+ from app.db import database # Base, engine
16
+ from app.routers import user, llm
17
+
18
+ #Base.metadata.create_all(bind=engine)
19
+
20
+ app = FastAPI(title="OpenGenAI",
21
+ description="Your Excellect AI Physician", docs_url="/")
22
+
23
+
24
+ app.include_router(llm.router)
25
+ app.include_router(user.router)
requirements.txt CHANGED
@@ -1,6 +1,56 @@
1
- fastapi
2
- uvicorn[standard]
3
- llama_cpp_python[server]==0.2.59
4
- huggingface-hub
5
- transformers
6
- tensorflow[and-cuda]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ annotated-types==0.6.0
2
+ anyio==4.3.0
3
+ certifi==2024.2.2
4
+ cffi==1.16.0
5
+ charset-normalizer==3.3.2
6
+ click==8.1.7
7
+ cryptography==42.0.5
8
+ diskcache==5.6.3
9
+ dnspython==2.6.1
10
+ email_validator==2.1.1
11
+ exceptiongroup==1.2.0
12
+ fastapi==0.110.1
13
+ filelock==3.13.4
14
+ fsspec==2024.3.1
15
+ greenlet==3.0.3
16
+ h11==0.14.0
17
+ httpcore==1.0.5
18
+ httptools==0.6.1
19
+ httpx==0.27.0
20
+ huggingface-hub==0.22.2
21
+ idna==3.7
22
+ itsdangerous==2.1.2
23
+ Jinja2==3.1.3
24
+ jwt==1.3.1
25
+ llama_cpp_python==0.2.61
26
+ MarkupSafe==2.1.5
27
+ numpy==1.26.4
28
+ orjson==3.10.0
29
+ packaging==24.0
30
+ passlib==1.7.4
31
+ pycparser==2.22
32
+ pydantic==2.7.0
33
+ pydantic-extra-types==2.6.0
34
+ pydantic-settings==2.2.1
35
+ pydantic_core==2.18.1
36
+ python-dotenv==1.0.1
37
+ python-multipart==0.0.9
38
+ PyYAML==6.0.1
39
+ regex==2023.12.25
40
+ requests==2.31.0
41
+ safetensors==0.4.2
42
+ sniffio==1.3.1
43
+ SQLAlchemy==2.0.29
44
+ starlette==0.37.2
45
+ tokenizers==0.15.2
46
+ tqdm==4.66.2
47
+ transformers==4.39.3
48
+ typing_extensions==4.11.0
49
+ ujson==5.9.0
50
+ urllib3==2.2.1
51
+ uvicorn==0.29.0
52
+ uvloop==0.19.0
53
+ watchfiles==0.21.0
54
+ websockets==12.0
55
+ tensorflow
56
+ pytorch