Shipmaster1 commited on
Commit
943312d
·
verified ·
1 Parent(s): 2bfdab6

Upload 9 files

Browse files
Files changed (9) hide show
  1. .env.sample +1 -1
  2. .gitattributes +35 -35
  3. .gitignore +161 -160
  4. Dockerfile +1 -1
  5. README.md +200 -200
  6. app.py +1 -1
  7. chainlit.md +3 -3
  8. pyproject.toml +14 -14
  9. uv.lock +85 -59
.env.sample CHANGED
@@ -1 +1 @@
1
- OPENAI_API_KEY=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
 
1
+ OPENAI_API_KEY=###
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore CHANGED
@@ -1,160 +1,161 @@
1
- # Byte-compiled / optimized / DLL files
2
- __pycache__/
3
- *.py[cod]
4
- *$py.class
5
-
6
- # C extensions
7
- *.so
8
-
9
- # Distribution / packaging
10
- .Python
11
- build/
12
- develop-eggs/
13
- dist/
14
- downloads/
15
- eggs/
16
- .eggs/
17
- lib/
18
- lib64/
19
- parts/
20
- sdist/
21
- var/
22
- wheels/
23
- share/python-wheels/
24
- *.egg-info/
25
- .installed.cfg
26
- *.egg
27
- MANIFEST
28
-
29
- # PyInstaller
30
- # Usually these files are written by a python script from a template
31
- # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
- *.manifest
33
- *.spec
34
-
35
- # Installer logs
36
- pip-log.txt
37
- pip-delete-this-directory.txt
38
-
39
- # Unit test / coverage reports
40
- htmlcov/
41
- .tox/
42
- .nox/
43
- .coverage
44
- .coverage.*
45
- .cache
46
- nosetests.xml
47
- coverage.xml
48
- *.cover
49
- *.py,cover
50
- .hypothesis/
51
- .pytest_cache/
52
- cover/
53
-
54
- # Translations
55
- *.mo
56
- *.pot
57
-
58
- # Django stuff:
59
- *.log
60
- local_settings.py
61
- db.sqlite3
62
- db.sqlite3-journal
63
-
64
- # Flask stuff:
65
- instance/
66
- .webassets-cache
67
-
68
- # Scrapy stuff:
69
- .scrapy
70
-
71
- # Sphinx documentation
72
- docs/_build/
73
-
74
- # PyBuilder
75
- .pybuilder/
76
- target/
77
-
78
- # Jupyter Notebook
79
- .ipynb_checkpoints
80
-
81
- # IPython
82
- profile_default/
83
- ipython_config.py
84
-
85
- # pyenv
86
- # For a library or package, you might want to ignore these files since the code is
87
- # intended to run in multiple environments; otherwise, check them in:
88
- # .python-version
89
-
90
- # pipenv
91
- # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
- # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
- # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
- # install all needed dependencies.
95
- #Pipfile.lock
96
-
97
- # poetry
98
- # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
- # This is especially recommended for binary packages to ensure reproducibility, and is more
100
- # commonly ignored for libraries.
101
- # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
- #poetry.lock
103
-
104
- # pdm
105
- # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
- #pdm.lock
107
- # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
- # in version control.
109
- # https://pdm.fming.dev/#use-with-ide
110
- .pdm.toml
111
-
112
- # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113
- __pypackages__/
114
-
115
- # Celery stuff
116
- celerybeat-schedule
117
- celerybeat.pid
118
-
119
- # SageMath parsed files
120
- *.sage.py
121
-
122
- # Environments
123
- .env
124
- .venv
125
- env/
126
- venv/
127
- ENV/
128
- env.bak/
129
- venv.bak/
130
-
131
- # Spyder project settings
132
- .spyderproject
133
- .spyproject
134
-
135
- # Rope project settings
136
- .ropeproject
137
-
138
- # mkdocs documentation
139
- /site
140
-
141
- # mypy
142
- .mypy_cache/
143
- .dmypy.json
144
- dmypy.json
145
-
146
- # Pyre type checker
147
- .pyre/
148
-
149
- # pytype static type analyzer
150
- .pytype/
151
-
152
- # Cython debug symbols
153
- cython_debug/
154
-
155
- # PyCharm
156
- # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157
- # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158
- # and can be added to the global gitignore or merged into this file. For a more nuclear
159
- # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
- #.idea/
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+ .chainlit/
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ .pybuilder/
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ # For a library or package, you might want to ignore these files since the code is
88
+ # intended to run in multiple environments; otherwise, check them in:
89
+ # .python-version
90
+
91
+ # pipenv
92
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
94
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
95
+ # install all needed dependencies.
96
+ #Pipfile.lock
97
+
98
+ # poetry
99
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
100
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
101
+ # commonly ignored for libraries.
102
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
103
+ #poetry.lock
104
+
105
+ # pdm
106
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
107
+ #pdm.lock
108
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
109
+ # in version control.
110
+ # https://pdm.fming.dev/#use-with-ide
111
+ .pdm.toml
112
+
113
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
114
+ __pypackages__/
115
+
116
+ # Celery stuff
117
+ celerybeat-schedule
118
+ celerybeat.pid
119
+
120
+ # SageMath parsed files
121
+ *.sage.py
122
+
123
+ # Environments
124
+ .env
125
+ .venv
126
+ env/
127
+ venv/
128
+ ENV/
129
+ env.bak/
130
+ venv.bak/
131
+
132
+ # Spyder project settings
133
+ .spyderproject
134
+ .spyproject
135
+
136
+ # Rope project settings
137
+ .ropeproject
138
+
139
+ # mkdocs documentation
140
+ /site
141
+
142
+ # mypy
143
+ .mypy_cache/
144
+ .dmypy.json
145
+ dmypy.json
146
+
147
+ # Pyre type checker
148
+ .pyre/
149
+
150
+ # pytype static type analyzer
151
+ .pytype/
152
+
153
+ # Cython debug symbols
154
+ cython_debug/
155
+
156
+ # PyCharm
157
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
158
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
159
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
160
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
161
+ #.idea/
Dockerfile CHANGED
@@ -39,4 +39,4 @@ RUN uv sync
39
  EXPOSE 7860
40
 
41
  # Run the app
42
- CMD ["uv", "run", "chainlit", "run", "app.py", "--host", "0.0.0.0", "--port", "7860"]
 
39
  EXPOSE 7860
40
 
41
  # Run the app
42
+ CMD ["uv", "run", "chainlit", "run", "app.py", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,200 +1,200 @@
1
- ---
2
- title: BeyondChatGPT Demo
3
- emoji: 📉
4
- colorFrom: pink
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- app_port: 7860
9
- ---
10
-
11
- <p align = "center" draggable=”false” ><img src="https://github.com/AI-Maker-Space/LLM-Dev-101/assets/37101144/d1343317-fa2f-41e1-8af1-1dbb18399719"
12
- width="200px"
13
- height="auto"/>
14
- </p>
15
-
16
-
17
- ## <h1 align="center" id="heading">:wave: Welcome to Beyond ChatGPT!!</h1>
18
-
19
- For a step-by-step YouTube video walkthrough, watch this! [Deploying Chainlit app on Hugging Face](https://www.youtube.com/live/pRbbZcL0NMI?si=NAYhMZ_suAY84f06&t=2119)
20
-
21
- ![Beyond ChatGPT: Build Your First LLM Application](https://github.com/AI-Maker-Space/Beyond-ChatGPT/assets/48775140/cb7a74b8-28af-4d12-a008-8f5a51d47b4c)
22
-
23
- ## 🤖 Your First LLM App
24
-
25
- > If you need an introduction to `git`, or information on how to set up API keys for the tools we'll be using in this repository - check out our [Interactive Dev Environment for LLM Development](https://github.com/AI-Maker-Space/Interactive-Dev-Environment-for-LLM-Development/tree/main) which has everything you'd need to get started in this repository!
26
-
27
- In this repository, we'll walk you through the steps to create a Large Language Model (LLM) application using Chainlit, then containerize it using Docker, and finally deploy it on Huggingface Spaces.
28
-
29
- Are you ready? Let's get started!
30
-
31
- <details>
32
- <summary>🖥️ Accessing "gpt-3.5-turbo" (ChatGPT) like a developer</summary>
33
-
34
- 1. Head to [this notebook](https://colab.research.google.com/drive/1mOzbgf4a2SP5qQj33ZxTz2a01-5eXqk2?usp=sharing) and follow along with the instructions!
35
-
36
- 2. Complete the notebook and try out your own system/assistant messages!
37
-
38
- That's it! Head to the next step and start building your application!
39
-
40
- </details>
41
-
42
-
43
- <details>
44
- <summary>🏗️ Building Your First LLM App</summary>
45
-
46
- 1. Clone [this](https://github.com/AI-Maker-Space/Beyond-ChatGPT/tree/main) repo.
47
-
48
- ``` bash
49
- git clone https://github.com/AI-Maker-Space/Beyond-ChatGPT.git
50
- ```
51
-
52
- 2. Navigate inside this repo
53
- ``` bash
54
- cd Beyond-ChatGPT
55
- ```
56
-
57
- 3. Create a virtual environment and install dependencies.
58
- ``` bash
59
- # Create a virtual environment
60
- uv venv
61
-
62
- # Activate the virtual environment
63
- # On macOS/Linux:
64
- source .venv/bin/activate
65
- # On Windows:
66
- # .venv\Scripts\activate
67
-
68
- # Install dependencies from pyproject.toml
69
- uv sync
70
- ```
71
-
72
- 4. Open your `.env` file. Replace the `###` in your `.env` file with your OpenAI Key and save the file.
73
- ``` bash
74
- OPENAI_API_KEY=sk-###
75
- ```
76
-
77
- 5. Let's try deploying it locally. Make sure you're in the activated virtual environment. Run the app using Chainlit. This may take a minute to run.
78
- ``` bash
79
- uv run chainlit run app.py -w
80
- ```
81
-
82
- <p align = "center" draggable="false">
83
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/54bcccf9-12e2-4cef-ab53-585c1e2b0fb5">
84
- </p>
85
-
86
- Great work! Let's see if we can interact with our chatbot.
87
-
88
- <p align = "center" draggable="false">
89
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/854e4435-1dee-438a-9146-7174b39f7c61">
90
- </p>
91
-
92
- Awesome! Time to throw it into a docker container and prepare it for shipping!
93
- </details>
94
-
95
-
96
-
97
- <details>
98
- <summary>🐳 Containerizing our App</summary>
99
-
100
- 1. Let's build the Docker image. We'll tag our image as `llm-app` using the `-t` parameter. The `.` at the end means we want all of the files in our current directory to be added to our image. Note that our Dockerfile is set up to use uv for dependency management and will install all the packages defined in our pyproject.toml file.
101
-
102
- ``` bash
103
- docker build -t llm-app .
104
- ```
105
-
106
- 2. Run and test the Docker image locally using the `run` command. The `-p`parameter connects our **host port #** to the left of the `:` to our **container port #** on the right.
107
-
108
- ``` bash
109
- docker run -p 7860:7860 llm-app
110
- ```
111
-
112
- 3. Visit http://localhost:7860 in your browser to see if the app runs correctly.
113
-
114
- <p align = "center" draggable="false">
115
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/2c764f25-09a0-431b-8d28-32246e0ca1b7">
116
- </p>
117
-
118
- Great! Time to ship!
119
- </details>
120
-
121
-
122
- <details>
123
- <summary>🚀 Deploying Your First LLM App</summary>
124
-
125
- 1. Let's create a new Huggingface Space. Navigate to [Huggingface](https://huggingface.co) and click on your profile picture on the top right. Then click on `New Space`.
126
-
127
- <p align = "center" draggable=”false”>
128
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/f0656408-28b8-4876-9887-8f0c4b882bae">
129
- </p>
130
-
131
- 2. Setup your space as shown below:
132
-
133
- - Owner: Your username
134
- - Space Name: `llm-app`
135
- - License: `Openrail`
136
- - Select the Space SDK: `Docker`
137
- - Docker Template: `Blank`
138
- - Space Hardware: `CPU basic - 2 vCPU - 16 GB - Free`
139
- - Repo type: `Public`
140
-
141
- <p align = "center" draggable=”false”>
142
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/8f16afd1-6b46-4d9f-b642-8fefe355c5c9">
143
- </p>
144
-
145
- 3. You should see something like this. We're now ready to send our files to our Huggingface Space. After cloning, move your files to this repo and push it along with your docker file. You DO NOT need to create a Dockerfile. Make sure NOT TO push your `.env` file. This should automatically be ignored.
146
-
147
- <p align = "center" draggable=”false”>
148
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/cbf366e2-7613-4223-932a-72c67a73f9c6">
149
- </p>
150
-
151
- 4. After pushing all files, navigate to the settings in the top right to add your OpenAI API key.
152
-
153
- <p align = "center" draggable=”false”>
154
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/a1123a6f-abdd-4f76-bea4-39acf9928762">
155
- </p>
156
-
157
- 5. Scroll down to `Variables and secrets` and click on `New secret` on the top right.
158
-
159
- <p align = "center" draggable=”false”>
160
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/a8a4a25d-752b-4036-b572-93381370c2db">
161
- </p>
162
-
163
- 6. Set the name to `OPENAI_API_KEY` and add your OpenAI key under `Value`. Click save.
164
-
165
- <p align = "center" draggable=”false”>
166
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/0a897538-1779-48ff-bcb4-486af30f7a14">
167
- </p>
168
-
169
- 7. To ensure your key is being used, we recommend you `Restart this Space`.
170
-
171
- <p align = "center" draggable=”false”>
172
- <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/fb1d83af-6ebe-4676-8bf5-b6d88f07c583">
173
- </p>
174
-
175
- 8. Congratulations! You just deployed your first LLM! 🚀🚀🚀 Get on linkedin and post your results and experience! Make sure to tag us at #AIMakerspace !
176
-
177
- Here's a template to get your post started!
178
-
179
- ```
180
- 🚀🎉 Exciting News! 🎉🚀
181
-
182
- 🏗️ Today, I'm thrilled to announce that I've successfully built and shipped my first-ever LLM using the powerful combination of Chainlit, Docker, and the OpenAI API! 🖥️
183
-
184
- Check it out 👇
185
- [LINK TO APP]
186
-
187
- A big shoutout to the @**AI Makerspace** for all making this possible. Couldn't have done it without the incredible community there. 🤗🙏
188
-
189
- Looking forward to building with the community! 🙌✨ Here's to many more creations ahead! 🥂🎉
190
-
191
- Who else is diving into the world of AI? Let's connect! 🌐💡
192
-
193
- #FirstLLM #Chainlit #Docker #OpenAI #AIMakerspace
194
- ```
195
-
196
- </details>
197
-
198
- <p></p>
199
-
200
- ### That's it for now! And so it begins.... :)
 
1
+ ---
2
+ title: BeyondChatGPT Demo
3
+ emoji: 📉
4
+ colorFrom: pink
5
+ colorTo: yellow
6
+ sdk: docker
7
+ pinned: false
8
+ app_port: 7860
9
+ ---
10
+
11
+ <p align = "center" draggable=”false” ><img src="https://github.com/AI-Maker-Space/LLM-Dev-101/assets/37101144/d1343317-fa2f-41e1-8af1-1dbb18399719"
12
+ width="200px"
13
+ height="auto"/>
14
+ </p>
15
+
16
+
17
+ ## <h1 align="center" id="heading">:wave: Welcome to Beyond ChatGPT!!</h1>
18
+
19
+ For a step-by-step YouTube video walkthrough, watch this! [Deploying Chainlit app on Hugging Face](https://www.youtube.com/live/pRbbZcL0NMI?si=NAYhMZ_suAY84f06&t=2119)
20
+
21
+ ![Beyond ChatGPT: Build Your First LLM Application](https://github.com/AI-Maker-Space/Beyond-ChatGPT/assets/48775140/cb7a74b8-28af-4d12-a008-8f5a51d47b4c)
22
+
23
+ ## 🤖 Your First LLM App
24
+
25
+ > If you need an introduction to `git`, or information on how to set up API keys for the tools we'll be using in this repository - check out our [Interactive Dev Environment for LLM Development](https://github.com/AI-Maker-Space/Interactive-Dev-Environment-for-LLM-Development/tree/main) which has everything you'd need to get started in this repository!
26
+
27
+ In this repository, we'll walk you through the steps to create a Large Language Model (LLM) application using Chainlit, then containerize it using Docker, and finally deploy it on Huggingface Spaces.
28
+
29
+ Are you ready? Let's get started!
30
+
31
+ <details>
32
+ <summary>🖥️ Accessing "gpt-3.5-turbo" (ChatGPT) like a developer</summary>
33
+
34
+ 1. Head to [this notebook](https://colab.research.google.com/drive/1mOzbgf4a2SP5qQj33ZxTz2a01-5eXqk2?usp=sharing) and follow along with the instructions!
35
+
36
+ 2. Complete the notebook and try out your own system/assistant messages!
37
+
38
+ That's it! Head to the next step and start building your application!
39
+
40
+ </details>
41
+
42
+
43
+ <details>
44
+ <summary>🏗️ Building Your First LLM App</summary>
45
+
46
+ 1. Clone [this](https://github.com/AI-Maker-Space/Beyond-ChatGPT/tree/main) repo.
47
+
48
+ ``` bash
49
+ git clone https://github.com/AI-Maker-Space/Beyond-ChatGPT.git
50
+ ```
51
+
52
+ 2. Navigate inside this repo
53
+ ``` bash
54
+ cd Beyond-ChatGPT
55
+ ```
56
+
57
+ 3. Create a virtual environment and install dependencies.
58
+ ``` bash
59
+ # Create a virtual environment
60
+ uv venv
61
+
62
+ # Activate the virtual environment
63
+ # On macOS/Linux:
64
+ source .venv/bin/activate
65
+ # On Windows:
66
+ # .venv\Scripts\activate
67
+
68
+ # Install dependencies from pyproject.toml
69
+ uv sync
70
+ ```
71
+
72
+ 4. Open your `.env` file. Replace the `###` in your `.env` file with your OpenAI Key and save the file.
73
+ ``` bash
74
+ OPENAI_API_KEY=sk-###
75
+ ```
76
+
77
+ 5. Let's try deploying it locally. Make sure you're in the activated virtual environment. Run the app using Chainlit. This may take a minute to run.
78
+ ``` bash
79
+ uv run chainlit run app.py -w
80
+ ```
81
+
82
+ <p align = "center" draggable="false">
83
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/54bcccf9-12e2-4cef-ab53-585c1e2b0fb5">
84
+ </p>
85
+
86
+ Great work! Let's see if we can interact with our chatbot.
87
+
88
+ <p align = "center" draggable="false">
89
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/854e4435-1dee-438a-9146-7174b39f7c61">
90
+ </p>
91
+
92
+ Awesome! Time to throw it into a docker container and prepare it for shipping!
93
+ </details>
94
+
95
+
96
+
97
+ <details>
98
+ <summary>🐳 Containerizing our App</summary>
99
+
100
+ 1. Let's build the Docker image. We'll tag our image as `llm-app` using the `-t` parameter. The `.` at the end means we want all of the files in our current directory to be added to our image. Note that our Dockerfile is set up to use uv for dependency management and will install all the packages defined in our pyproject.toml file.
101
+
102
+ ``` bash
103
+ docker build -t llm-app .
104
+ ```
105
+
106
+ 2. Run and test the Docker image locally using the `run` command. The `-p`parameter connects our **host port #** to the left of the `:` to our **container port #** on the right.
107
+
108
+ ``` bash
109
+ docker run -p 7860:7860 llm-app
110
+ ```
111
+
112
+ 3. Visit http://localhost:7860 in your browser to see if the app runs correctly.
113
+
114
+ <p align = "center" draggable="false">
115
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/2c764f25-09a0-431b-8d28-32246e0ca1b7">
116
+ </p>
117
+
118
+ Great! Time to ship!
119
+ </details>
120
+
121
+
122
+ <details>
123
+ <summary>🚀 Deploying Your First LLM App</summary>
124
+
125
+ 1. Let's create a new Huggingface Space. Navigate to [Huggingface](https://huggingface.co) and click on your profile picture on the top right. Then click on `New Space`.
126
+
127
+ <p align = "center" draggable=”false”>
128
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/f0656408-28b8-4876-9887-8f0c4b882bae">
129
+ </p>
130
+
131
+ 2. Setup your space as shown below:
132
+
133
+ - Owner: Your username
134
+ - Space Name: `llm-app`
135
+ - License: `Openrail`
136
+ - Select the Space SDK: `Docker`
137
+ - Docker Template: `Blank`
138
+ - Space Hardware: `CPU basic - 2 vCPU - 16 GB - Free`
139
+ - Repo type: `Public`
140
+
141
+ <p align = "center" draggable=”false”>
142
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/8f16afd1-6b46-4d9f-b642-8fefe355c5c9">
143
+ </p>
144
+
145
+ 3. You should see something like this. We're now ready to send our files to our Huggingface Space. After cloning, move your files to this repo and push it along with your docker file. You DO NOT need to create a Dockerfile. Make sure NOT TO push your `.env` file. This should automatically be ignored.
146
+
147
+ <p align = "center" draggable=”false”>
148
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/cbf366e2-7613-4223-932a-72c67a73f9c6">
149
+ </p>
150
+
151
+ 4. After pushing all files, navigate to the settings in the top right to add your OpenAI API key.
152
+
153
+ <p align = "center" draggable=”false”>
154
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/a1123a6f-abdd-4f76-bea4-39acf9928762">
155
+ </p>
156
+
157
+ 5. Scroll down to `Variables and secrets` and click on `New secret` on the top right.
158
+
159
+ <p align = "center" draggable=”false”>
160
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/a8a4a25d-752b-4036-b572-93381370c2db">
161
+ </p>
162
+
163
+ 6. Set the name to `OPENAI_API_KEY` and add your OpenAI key under `Value`. Click save.
164
+
165
+ <p align = "center" draggable=”false”>
166
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/0a897538-1779-48ff-bcb4-486af30f7a14">
167
+ </p>
168
+
169
+ 7. To ensure your key is being used, we recommend you `Restart this Space`.
170
+
171
+ <p align = "center" draggable=”false”>
172
+ <img src="https://github.com/AI-Maker-Space/LLMOps-Dev-101/assets/37101144/fb1d83af-6ebe-4676-8bf5-b6d88f07c583">
173
+ </p>
174
+
175
+ 8. Congratulations! You just deployed your first LLM! 🚀🚀🚀 Get on linkedin and post your results and experience! Make sure to tag us at #AIMakerspace !
176
+
177
+ Here's a template to get your post started!
178
+
179
+ ```
180
+ 🚀🎉 Exciting News! 🎉🚀
181
+
182
+ 🏗️ Today, I'm thrilled to announce that I've successfully built and shipped my first-ever LLM using the powerful combination of Chainlit, Docker, and the OpenAI API! 🖥️
183
+
184
+ Check it out 👇
185
+ [LINK TO APP]
186
+
187
+ A big shoutout to the @**AI Makerspace** for all making this possible. Couldn't have done it without the incredible community there. 🤗🙏
188
+
189
+ Looking forward to building with the community! 🙌✨ Here's to many more creations ahead! 🥂🎉
190
+
191
+ Who else is diving into the world of AI? Let's connect! 🌐💡
192
+
193
+ #FirstLLM #Chainlit #Docker #OpenAI #AIMakerspace
194
+ ```
195
+
196
+ </details>
197
+
198
+ <p></p>
199
+
200
+ ### That's it for now! And so it begins.... :)
app.py CHANGED
@@ -77,4 +77,4 @@ async def main(message: cl.Message):
77
  msg.prompt = prompt
78
 
79
  # Send and close the message stream
80
- await msg.send()
 
77
  msg.prompt = prompt
78
 
79
  # Send and close the message stream
80
+ await msg.send()
chainlit.md CHANGED
@@ -1,3 +1,3 @@
1
- # Beyond ChatGPT
2
-
3
- This Chainlit app was created following instructions from [this repository!](https://github.com/AI-Maker-Space/Beyond-ChatGPT)
 
1
+ # Beyond ChatGPT
2
+
3
+ This Chainlit app was created following instructions from [this repository!](https://github.com/AI-Maker-Space/Beyond-ChatGPT)
pyproject.toml CHANGED
@@ -1,14 +1,14 @@
1
- [project]
2
- name = "beyond-chatgpt"
3
- version = "0.1.0"
4
- description = "Add your description here"
5
- readme = "README.md"
6
- requires-python = ">=3.13"
7
- dependencies = [
8
- "chainlit==2.2.1",
9
- "cohere==4.37",
10
- "openai==1.3.5",
11
- "pydantic==2.10.1",
12
- "python-dotenv==1.0.0",
13
- "tiktoken==0.5.1",
14
- ]
 
1
+ [project]
2
+ name = "beyond-chatgpt"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.13"
7
+ dependencies = [
8
+ "chainlit==0.7.700",
9
+ "cohere==4.37",
10
+ "openai==1.3.5",
11
+ "pydantic==2.10.1",
12
+ "python-dotenv==1.0.0",
13
+ "tiktoken==0.5.1",
14
+ ]
uv.lock CHANGED
@@ -1,5 +1,4 @@
1
  version = 1
2
- revision = 1
3
  requires-python = ">=3.13"
4
 
5
  [[package]]
@@ -89,14 +88,14 @@ wheels = [
89
 
90
  [[package]]
91
  name = "asyncer"
92
- version = "0.0.7"
93
  source = { registry = "https://pypi.org/simple" }
94
  dependencies = [
95
  { name = "anyio" },
96
  ]
97
- sdist = { url = "https://files.pythonhosted.org/packages/39/29/245ba9fa5769a1e3226c1157aedb372fe9dab28c4e1dcf6911d84d3a5e04/asyncer-0.0.7.tar.gz", hash = "sha256:d5e563fb0f56eb87b97257984703658a4f5bbdb52ff851b3e8ed864cc200b1d2", size = 14437 }
98
  wheels = [
99
- { url = "https://files.pythonhosted.org/packages/3e/4b/40a1dc52fc26695b1e80a9e67dfb0fe7e6ddc57bbc5b61348e40c0045abb/asyncer-0.0.7-py3-none-any.whl", hash = "sha256:f0d579d4f67c4ead52ede3a45c854f462cae569058a8a6a68a4ebccac1c335d8", size = 8476 },
100
  ]
101
 
102
  [[package]]
@@ -132,7 +131,7 @@ dependencies = [
132
 
133
  [package.metadata]
134
  requires-dist = [
135
- { name = "chainlit", specifier = "==2.2.1" },
136
  { name = "cohere", specifier = "==4.37" },
137
  { name = "openai", specifier = "==1.3.5" },
138
  { name = "pydantic", specifier = "==2.10.1" },
@@ -160,7 +159,7 @@ wheels = [
160
 
161
  [[package]]
162
  name = "chainlit"
163
- version = "2.2.1"
164
  source = { registry = "https://pypi.org/simple" }
165
  dependencies = [
166
  { name = "aiofiles" },
@@ -168,27 +167,26 @@ dependencies = [
168
  { name = "click" },
169
  { name = "dataclasses-json" },
170
  { name = "fastapi" },
 
171
  { name = "filetype" },
172
  { name = "httpx" },
173
  { name = "lazify" },
174
- { name = "literalai" },
175
  { name = "nest-asyncio" },
176
  { name = "packaging" },
177
  { name = "pydantic" },
178
  { name = "pyjwt" },
179
  { name = "python-dotenv" },
 
180
  { name = "python-multipart" },
181
- { name = "python-socketio" },
182
- { name = "starlette" },
183
  { name = "syncer" },
184
  { name = "tomli" },
185
  { name = "uptrace" },
186
  { name = "uvicorn" },
187
  { name = "watchfiles" },
188
  ]
189
- sdist = { url = "https://files.pythonhosted.org/packages/5a/0d/19f66ced254c35cd0595ba064402a15c2ca3d3fba2a75f7ea75b52619871/chainlit-2.2.1.tar.gz", hash = "sha256:45bfc5721f7b0766a3b9ef748478ec1043cfdcb9edc78e23a89db489335f10e9", size = 9473105 }
190
  wheels = [
191
- { url = "https://files.pythonhosted.org/packages/b8/ef/4408863d8110462bea8ee971a9f747ceeaafe3aa0404f0d7e85d6b06bb1c/chainlit-2.2.1-py3-none-any.whl", hash = "sha256:c2cc7d84386073899164b960371a9c046f175a9659763189cb9f1130b544b694", size = 9623188 },
192
  ]
193
 
194
  [[package]]
@@ -213,21 +211,12 @@ wheels = [
213
  { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
214
  ]
215
 
216
- [[package]]
217
- name = "chevron"
218
- version = "0.14.0"
219
- source = { registry = "https://pypi.org/simple" }
220
- sdist = { url = "https://files.pythonhosted.org/packages/15/1f/ca74b65b19798895d63a6e92874162f44233467c9e7c1ed8afd19016ebe9/chevron-0.14.0.tar.gz", hash = "sha256:87613aafdf6d77b6a90ff073165a61ae5086e21ad49057aa0e53681601800ebf", size = 11440 }
221
- wheels = [
222
- { url = "https://files.pythonhosted.org/packages/52/93/342cc62a70ab727e093ed98e02a725d85b746345f05d2b5e5034649f4ec8/chevron-0.14.0-py3-none-any.whl", hash = "sha256:fbf996a709f8da2e745ef763f482ce2d311aa817d287593a5b990d6d6e4f0443", size = 11595 },
223
- ]
224
-
225
  [[package]]
226
  name = "click"
227
  version = "8.1.8"
228
  source = { registry = "https://pypi.org/simple" }
229
  dependencies = [
230
- { name = "colorama", marker = "sys_platform == 'win32'" },
231
  ]
232
  sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
233
  wheels = [
@@ -262,15 +251,15 @@ wheels = [
262
 
263
  [[package]]
264
  name = "dataclasses-json"
265
- version = "0.6.7"
266
  source = { registry = "https://pypi.org/simple" }
267
  dependencies = [
268
  { name = "marshmallow" },
269
  { name = "typing-inspect" },
270
  ]
271
- sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227 }
272
  wheels = [
273
- { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686 },
274
  ]
275
 
276
  [[package]]
@@ -296,16 +285,29 @@ wheels = [
296
 
297
  [[package]]
298
  name = "fastapi"
299
- version = "0.115.12"
300
  source = { registry = "https://pypi.org/simple" }
301
  dependencies = [
302
  { name = "pydantic" },
303
  { name = "starlette" },
304
  { name = "typing-extensions" },
305
  ]
306
- sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236 }
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  wheels = [
308
- { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164 },
309
  ]
310
 
311
  [[package]]
@@ -396,30 +398,32 @@ wheels = [
396
 
397
  [[package]]
398
  name = "httpcore"
399
- version = "1.0.7"
400
  source = { registry = "https://pypi.org/simple" }
401
  dependencies = [
 
402
  { name = "certifi" },
403
  { name = "h11" },
 
404
  ]
405
- sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
406
  wheels = [
407
- { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
408
  ]
409
 
410
  [[package]]
411
  name = "httpx"
412
- version = "0.28.1"
413
  source = { registry = "https://pypi.org/simple" }
414
  dependencies = [
415
- { name = "anyio" },
416
  { name = "certifi" },
417
  { name = "httpcore" },
418
  { name = "idna" },
 
419
  ]
420
- sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
421
  wheels = [
422
- { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
423
  ]
424
 
425
  [[package]]
@@ -452,18 +456,6 @@ wheels = [
452
  { url = "https://files.pythonhosted.org/packages/03/a5/866b44697cee47d1cae429ed370281d937ad4439f71af82a6baaa139d26a/Lazify-0.4.0-py2.py3-none-any.whl", hash = "sha256:c2c17a7a33e9406897e3f66fde4cd3f84716218d580330e5af10cfe5a0cd195a", size = 3107 },
453
  ]
454
 
455
- [[package]]
456
- name = "literalai"
457
- version = "0.1.103"
458
- source = { registry = "https://pypi.org/simple" }
459
- dependencies = [
460
- { name = "chevron" },
461
- { name = "httpx" },
462
- { name = "packaging" },
463
- { name = "pydantic" },
464
- ]
465
- sdist = { url = "https://files.pythonhosted.org/packages/fc/fc/628b39e31b368aacbca51721ba7a66a4d140e9be916a0c7396664fdaed7a/literalai-0.1.103.tar.gz", hash = "sha256:060e86e63c0f53041a737b2183354ac092ee8cd9faec817dc95df639bb263a7d", size = 62540 }
466
-
467
  [[package]]
468
  name = "marshmallow"
469
  version = "3.26.1"
@@ -680,11 +672,11 @@ wheels = [
680
 
681
  [[package]]
682
  name = "packaging"
683
- version = "24.2"
684
  source = { registry = "https://pypi.org/simple" }
685
- sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
686
  wheels = [
687
- { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
688
  ]
689
 
690
  [[package]]
@@ -811,13 +803,27 @@ wheels = [
811
  { url = "https://files.pythonhosted.org/packages/07/8f/978a0b913e3f8ad33a9a2fe204d32efe3d1ee34ecb1f2829c1cfbdd92082/python_engineio-4.11.2-py3-none-any.whl", hash = "sha256:f0971ac4c65accc489154fe12efd88f53ca8caf04754c46a66e85f5102ef22ad", size = 59239 },
812
  ]
813
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814
  [[package]]
815
  name = "python-multipart"
816
- version = "0.0.18"
817
  source = { registry = "https://pypi.org/simple" }
818
- sdist = { url = "https://files.pythonhosted.org/packages/b4/86/b6b38677dec2e2e7898fc5b6f7e42c2d011919a92d25339451892f27b89c/python_multipart-0.0.18.tar.gz", hash = "sha256:7a68db60c8bfb82e460637fa4750727b45af1d5e2ed215593f917f64694d34fe", size = 36622 }
819
  wheels = [
820
- { url = "https://files.pythonhosted.org/packages/13/6b/b60f47101ba2cac66b4a83246630e68ae9bbe2e614cbae5f4465f46dee13/python_multipart-0.0.18-py3-none-any.whl", hash = "sha256:efe91480f485f6a361427a541db4796f9e1591afc0fb8e7a4ba06bfbc6708996", size = 24389 },
821
  ]
822
 
823
  [[package]]
@@ -894,14 +900,14 @@ wheels = [
894
 
895
  [[package]]
896
  name = "starlette"
897
- version = "0.41.3"
898
  source = { registry = "https://pypi.org/simple" }
899
  dependencies = [
900
  { name = "anyio" },
901
  ]
902
- sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 }
903
  wheels = [
904
- { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 },
905
  ]
906
 
907
  [[package]]
@@ -944,7 +950,7 @@ name = "tqdm"
944
  version = "4.67.1"
945
  source = { registry = "https://pypi.org/simple" }
946
  dependencies = [
947
- { name = "colorama", marker = "sys_platform == 'win32'" },
948
  ]
949
  sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
950
  wheels = [
@@ -999,15 +1005,15 @@ wheels = [
999
 
1000
  [[package]]
1001
  name = "uvicorn"
1002
- version = "0.34.0"
1003
  source = { registry = "https://pypi.org/simple" }
1004
  dependencies = [
1005
  { name = "click" },
1006
  { name = "h11" },
1007
  ]
1008
- sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 }
1009
  wheels = [
1010
- { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 },
1011
  ]
1012
 
1013
  [[package]]
@@ -1034,6 +1040,26 @@ wheels = [
1034
  { url = "https://files.pythonhosted.org/packages/3f/82/45dddf4f5bf8b73ba27382cebb2bb3c0ee922c7ef77d936b86276aa39dca/watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c", size = 265344 },
1035
  ]
1036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
  [[package]]
1038
  name = "wrapt"
1039
  version = "1.17.2"
 
1
  version = 1
 
2
  requires-python = ">=3.13"
3
 
4
  [[package]]
 
88
 
89
  [[package]]
90
  name = "asyncer"
91
+ version = "0.0.2"
92
  source = { registry = "https://pypi.org/simple" }
93
  dependencies = [
94
  { name = "anyio" },
95
  ]
96
+ sdist = { url = "https://files.pythonhosted.org/packages/72/fc/de575dfcb41355123d20c492a46bccbe3613f92b7283818c35698543abb3/asyncer-0.0.2.tar.gz", hash = "sha256:d546c85f3626ebbaf06bb4395db49761c902a61a6ac802b1a74133cab4f7f433", size = 8814 }
97
  wheels = [
98
+ { url = "https://files.pythonhosted.org/packages/01/61/92a12d4a53f4b88178c36209188ba2478ca51862210edb5d22c9236a9c34/asyncer-0.0.2-py3-none-any.whl", hash = "sha256:46e0e1423ce21588350ad425875e81795280b9e1f517e8a389de940b86c348bd", size = 8298 },
99
  ]
100
 
101
  [[package]]
 
131
 
132
  [package.metadata]
133
  requires-dist = [
134
+ { name = "chainlit", specifier = "==0.7.700" },
135
  { name = "cohere", specifier = "==4.37" },
136
  { name = "openai", specifier = "==1.3.5" },
137
  { name = "pydantic", specifier = "==2.10.1" },
 
159
 
160
  [[package]]
161
  name = "chainlit"
162
+ version = "0.7.700"
163
  source = { registry = "https://pypi.org/simple" }
164
  dependencies = [
165
  { name = "aiofiles" },
 
167
  { name = "click" },
168
  { name = "dataclasses-json" },
169
  { name = "fastapi" },
170
+ { name = "fastapi-socketio" },
171
  { name = "filetype" },
172
  { name = "httpx" },
173
  { name = "lazify" },
 
174
  { name = "nest-asyncio" },
175
  { name = "packaging" },
176
  { name = "pydantic" },
177
  { name = "pyjwt" },
178
  { name = "python-dotenv" },
179
+ { name = "python-graphql-client" },
180
  { name = "python-multipart" },
 
 
181
  { name = "syncer" },
182
  { name = "tomli" },
183
  { name = "uptrace" },
184
  { name = "uvicorn" },
185
  { name = "watchfiles" },
186
  ]
187
+ sdist = { url = "https://files.pythonhosted.org/packages/1b/fd/7adae964158519c7b6487d3c2b0f47bfc775abdfde53ef25f9bf702b715f/chainlit-0.7.700.tar.gz", hash = "sha256:edad61d08e04f4639a5fdd015b2d5b8a6ba7f656ecb95fb5ef69443451cfeb5f", size = 2197735 }
188
  wheels = [
189
+ { url = "https://files.pythonhosted.org/packages/ec/84/005208b695511497dd06b886cda8fae9c89ac0aabbac169732050be0d35b/chainlit-0.7.700-py3-none-any.whl", hash = "sha256:a42c42e0e74ae94907ec4c7fabf4338f2f707d154c6b97c4df6f42cea162036e", size = 2217871 },
190
  ]
191
 
192
  [[package]]
 
211
  { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
212
  ]
213
 
 
 
 
 
 
 
 
 
 
214
  [[package]]
215
  name = "click"
216
  version = "8.1.8"
217
  source = { registry = "https://pypi.org/simple" }
218
  dependencies = [
219
+ { name = "colorama", marker = "platform_system == 'Windows'" },
220
  ]
221
  sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
222
  wheels = [
 
251
 
252
  [[package]]
253
  name = "dataclasses-json"
254
+ version = "0.5.14"
255
  source = { registry = "https://pypi.org/simple" }
256
  dependencies = [
257
  { name = "marshmallow" },
258
  { name = "typing-inspect" },
259
  ]
260
+ sdist = { url = "https://files.pythonhosted.org/packages/92/30/43b04314b64fbd4562216721bfbf95022922c57e0340809b99f5e049d8ea/dataclasses_json-0.5.14.tar.gz", hash = "sha256:d82896a94c992ffaf689cd1fafc180164e2abdd415b8f94a7f78586af5886236", size = 29334 }
261
  wheels = [
262
+ { url = "https://files.pythonhosted.org/packages/97/5f/e7cc90f36152810cab08b6c9c1125e8bcb9d76f8b3018d101b5f877b386c/dataclasses_json-0.5.14-py3-none-any.whl", hash = "sha256:5ec6fed642adb1dbdb4182badb01e0861badfd8fda82e3b67f44b2d1e9d10d21", size = 26297 },
263
  ]
264
 
265
  [[package]]
 
285
 
286
  [[package]]
287
  name = "fastapi"
288
+ version = "0.100.1"
289
  source = { registry = "https://pypi.org/simple" }
290
  dependencies = [
291
  { name = "pydantic" },
292
  { name = "starlette" },
293
  { name = "typing-extensions" },
294
  ]
295
+ sdist = { url = "https://files.pythonhosted.org/packages/b2/72/6af07ac2417c6c8bf13069cac3673a5e4628247c62316b0f65a2eaea15c3/fastapi-0.100.1.tar.gz", hash = "sha256:522700d7a469e4a973d92321ab93312448fbe20fca9c8da97effc7e7bc56df23", size = 10494927 }
296
+ wheels = [
297
+ { url = "https://files.pythonhosted.org/packages/66/23/5db1adf057fc47f6575c4f317b98882a9312f59a7ec555ae38ca854aef42/fastapi-0.100.1-py3-none-any.whl", hash = "sha256:ec6dd52bfc4eff3063cfcd0713b43c87640fefb2687bbbe3d8a08d94049cdf32", size = 65754 },
298
+ ]
299
+
300
+ [[package]]
301
+ name = "fastapi-socketio"
302
+ version = "0.0.10"
303
+ source = { registry = "https://pypi.org/simple" }
304
+ dependencies = [
305
+ { name = "fastapi" },
306
+ { name = "python-socketio" },
307
+ ]
308
+ sdist = { url = "https://files.pythonhosted.org/packages/e1/14/dde9633af2168f1929447c7d8a8947e9371dfca37d58c72d8c1ad686db75/fastapi-socketio-0.0.10.tar.gz", hash = "sha256:202f9b319f010001cbd1114ec92a0d9eb5f5ca9316eae5fd41a6088da0812727", size = 7156 }
309
  wheels = [
310
+ { url = "https://files.pythonhosted.org/packages/b5/49/50fe1f72b10c1902fc057e5810f51bffc94c5cab416cf9f16358e71b021a/fastapi_socketio-0.0.10-py3-none-any.whl", hash = "sha256:11c2bfa3f25d786bd860ed13c892472e86bfeba85e7a0bec4f922ae5e4d8650f", size = 7412 },
311
  ]
312
 
313
  [[package]]
 
398
 
399
  [[package]]
400
  name = "httpcore"
401
+ version = "0.17.3"
402
  source = { registry = "https://pypi.org/simple" }
403
  dependencies = [
404
+ { name = "anyio" },
405
  { name = "certifi" },
406
  { name = "h11" },
407
+ { name = "sniffio" },
408
  ]
409
+ sdist = { url = "https://files.pythonhosted.org/packages/63/ad/c98ecdbfe04417e71e143bf2f2fb29128e4787d78d1cedba21bd250c7e7a/httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888", size = 62676 }
410
  wheels = [
411
+ { url = "https://files.pythonhosted.org/packages/94/2c/2bde7ff8dd2064395555220cbf7cba79991172bf5315a07eb3ac7688d9f1/httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87", size = 74513 },
412
  ]
413
 
414
  [[package]]
415
  name = "httpx"
416
+ version = "0.24.1"
417
  source = { registry = "https://pypi.org/simple" }
418
  dependencies = [
 
419
  { name = "certifi" },
420
  { name = "httpcore" },
421
  { name = "idna" },
422
+ { name = "sniffio" },
423
  ]
424
+ sdist = { url = "https://files.pythonhosted.org/packages/f8/2a/114d454cb77657dbf6a293e69390b96318930ace9cd96b51b99682493276/httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd", size = 81858 }
425
  wheels = [
426
+ { url = "https://files.pythonhosted.org/packages/ec/91/e41f64f03d2a13aee7e8c819d82ee3aa7cdc484d18c0ae859742597d5aa0/httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd", size = 75377 },
427
  ]
428
 
429
  [[package]]
 
456
  { url = "https://files.pythonhosted.org/packages/03/a5/866b44697cee47d1cae429ed370281d937ad4439f71af82a6baaa139d26a/Lazify-0.4.0-py2.py3-none-any.whl", hash = "sha256:c2c17a7a33e9406897e3f66fde4cd3f84716218d580330e5af10cfe5a0cd195a", size = 3107 },
457
  ]
458
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  [[package]]
460
  name = "marshmallow"
461
  version = "3.26.1"
 
672
 
673
  [[package]]
674
  name = "packaging"
675
+ version = "23.2"
676
  source = { registry = "https://pypi.org/simple" }
677
+ sdist = { url = "https://files.pythonhosted.org/packages/fb/2b/9b9c33ffed44ee921d0967086d653047286054117d584f1b1a7c22ceaf7b/packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", size = 146714 }
678
  wheels = [
679
+ { url = "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7", size = 53011 },
680
  ]
681
 
682
  [[package]]
 
803
  { url = "https://files.pythonhosted.org/packages/07/8f/978a0b913e3f8ad33a9a2fe204d32efe3d1ee34ecb1f2829c1cfbdd92082/python_engineio-4.11.2-py3-none-any.whl", hash = "sha256:f0971ac4c65accc489154fe12efd88f53ca8caf04754c46a66e85f5102ef22ad", size = 59239 },
804
  ]
805
 
806
+ [[package]]
807
+ name = "python-graphql-client"
808
+ version = "0.4.3"
809
+ source = { registry = "https://pypi.org/simple" }
810
+ dependencies = [
811
+ { name = "aiohttp" },
812
+ { name = "requests" },
813
+ { name = "websockets" },
814
+ ]
815
+ sdist = { url = "https://files.pythonhosted.org/packages/04/bf/6ebd129e957c3fd8ea1c36ae03cbd68e2342ec2bea7010d5379bd363da06/python_graphql_client-0.4.3.tar.gz", hash = "sha256:fdbd03115dde8776db02e60414b83b018d7d95e5752d6d5fabf21c99265f5b9d", size = 4140 }
816
+ wheels = [
817
+ { url = "https://files.pythonhosted.org/packages/94/23/20e60e8ce635aaef99962e3d1d0f0b3e0e9632e1bd0aeb6b6cb8436a1fa3/python_graphql_client-0.4.3-py3-none-any.whl", hash = "sha256:c5eb996702acf46110b352f61819c46065ea4f4f106158535cd471e66490b25e", size = 4945 },
818
+ ]
819
+
820
  [[package]]
821
  name = "python-multipart"
822
+ version = "0.0.6"
823
  source = { registry = "https://pypi.org/simple" }
824
+ sdist = { url = "https://files.pythonhosted.org/packages/2d/23/abcfad10c3348cb6358400f8adbc21b523bbc6c954494fd0974428068672/python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132", size = 31024 }
825
  wheels = [
826
+ { url = "https://files.pythonhosted.org/packages/b4/ff/b1e11d8bffb5e0e1b6d27f402eeedbeb9be6df2cdbc09356a1ae49806dbf/python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18", size = 45711 },
827
  ]
828
 
829
  [[package]]
 
900
 
901
  [[package]]
902
  name = "starlette"
903
+ version = "0.27.0"
904
  source = { registry = "https://pypi.org/simple" }
905
  dependencies = [
906
  { name = "anyio" },
907
  ]
908
+ sdist = { url = "https://files.pythonhosted.org/packages/06/68/559bed5484e746f1ab2ebbe22312f2c25ec62e4b534916d41a8c21147bf8/starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", size = 51394 }
909
  wheels = [
910
+ { url = "https://files.pythonhosted.org/packages/58/f8/e2cca22387965584a409795913b774235752be4176d276714e15e1a58884/starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91", size = 66978 },
911
  ]
912
 
913
  [[package]]
 
950
  version = "4.67.1"
951
  source = { registry = "https://pypi.org/simple" }
952
  dependencies = [
953
+ { name = "colorama", marker = "platform_system == 'Windows'" },
954
  ]
955
  sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 }
956
  wheels = [
 
1005
 
1006
  [[package]]
1007
  name = "uvicorn"
1008
+ version = "0.23.2"
1009
  source = { registry = "https://pypi.org/simple" }
1010
  dependencies = [
1011
  { name = "click" },
1012
  { name = "h11" },
1013
  ]
1014
+ sdist = { url = "https://files.pythonhosted.org/packages/4c/b3/aa7eb8367959623eef0527f876e371f1ac5770a3b31d3d6db34337b795e6/uvicorn-0.23.2.tar.gz", hash = "sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a", size = 40034 }
1015
  wheels = [
1016
+ { url = "https://files.pythonhosted.org/packages/79/96/b0882a1c3f7ef3dd86879e041212ae5b62b4bd352320889231cc735a8e8f/uvicorn-0.23.2-py3-none-any.whl", hash = "sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53", size = 59544 },
1017
  ]
1018
 
1019
  [[package]]
 
1040
  { url = "https://files.pythonhosted.org/packages/3f/82/45dddf4f5bf8b73ba27382cebb2bb3c0ee922c7ef77d936b86276aa39dca/watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c", size = 265344 },
1041
  ]
1042
 
1043
+ [[package]]
1044
+ name = "websockets"
1045
+ version = "15.0.1"
1046
+ source = { registry = "https://pypi.org/simple" }
1047
+ sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016 }
1048
+ wheels = [
1049
+ { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440 },
1050
+ { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098 },
1051
+ { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329 },
1052
+ { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111 },
1053
+ { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054 },
1054
+ { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496 },
1055
+ { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829 },
1056
+ { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217 },
1057
+ { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195 },
1058
+ { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393 },
1059
+ { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837 },
1060
+ { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 },
1061
+ ]
1062
+
1063
  [[package]]
1064
  name = "wrapt"
1065
  version = "1.17.2"