ionosphere commited on
Commit
582fc9e
·
1 Parent(s): 16bb9f9
Files changed (5) hide show
  1. .gitignore +162 -0
  2. HOW_TO.md +17 -0
  3. app.py +113 -71
  4. images/agir.png +0 -0
  5. requirements.txt +261 -13
.gitignore ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .idea/
2
+ ### Python template
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+ cover/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ .pybuilder/
78
+ target/
79
+
80
+ # Jupyter Notebook
81
+ .ipynb_checkpoints
82
+
83
+ # IPython
84
+ profile_default/
85
+ ipython_config.py
86
+
87
+ # pyenv
88
+ # For a library or package, you might want to ignore these files since the code is
89
+ # intended to run in multiple environments; otherwise, check them in:
90
+ # .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # poetry
100
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
101
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
102
+ # commonly ignored for libraries.
103
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
104
+ #poetry.lock
105
+
106
+ # pdm
107
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
108
+ #pdm.lock
109
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
110
+ # in version control.
111
+ # https://pdm.fming.dev/#use-with-ide
112
+ .pdm.toml
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ env/
128
+ venv/
129
+ ENV/
130
+ env.bak/
131
+ venv.bak/
132
+
133
+ # Spyder project settings
134
+ .spyderproject
135
+ .spyproject
136
+
137
+ # Rope project settings
138
+ .ropeproject
139
+
140
+ # mkdocs documentation
141
+ /site
142
+
143
+ # mypy
144
+ .mypy_cache/
145
+ .dmypy.json
146
+ dmypy.json
147
+
148
+ # Pyre type checker
149
+ .pyre/
150
+
151
+ # pytype static type analyzer
152
+ .pytype/
153
+
154
+ # Cython debug symbols
155
+ cython_debug/
156
+
157
+ # PyCharm
158
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
161
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
+ #.idea/
HOW_TO.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # INSTALLING
2
+
3
+ > Clone the project in a local folder 'viti'
4
+
5
+ > Go to the project folder
6
+
7
+ `python -m venv .venv`
8
+
9
+ `source .venv/bin/activate`
10
+
11
+ `pip install -r requirements.txt`
12
+
13
+ Test the installation
14
+
15
+ `streamlit run app.py`
16
+
17
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,78 +1,120 @@
1
  import os
 
2
  import time
3
  from pathlib import Path
4
-
5
  import numpy as np
6
  import streamlit as st
7
- import leafmap.foliumap as leafmap
8
- from faiss import IndexFlatL2
9
- from mistralai.client import MistralClient
10
- from mistralai.models.chat_completion import ChatMessage
11
- from pypdf import PdfReader
12
-
13
- @st.cache_resource
14
- def get_client():
15
- """Returns a cached instance of the MistralClient."""
16
- api_key = os.environ["MISTRAL_API_KEY"]
17
- return MistralClient(api_key=api_key)
18
-
19
-
20
- CLIENT: MistralClient = get_client()
21
-
22
- PROMPT = """
23
- An excerpt from a document is given below.
24
-
25
- ---------------------
26
- {context}
27
- ---------------------
28
-
29
- Given the document excerpt, answer the following query.
30
- If the context does not provide enough information, decline to answer.
31
- Do not output anything that can't be answered from the context.
32
-
33
- Query: {query}
34
- Answer:
35
- """
36
-
37
- def app():
38
- st.title("Search Basemaps")
39
- st.markdown(
40
- """
41
- This app is a demonstration of searching and loading basemaps from [xyzservices](https://github.com/geopandas/xyzservices) and [Quick Map Services (QMS)](https://github.com/nextgis/quickmapservices). Selecting from 1000+ basemaps with a few clicks.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  """
43
- )
44
-
45
- with st.expander("See demo"):
46
- st.image("https://i.imgur.com/0SkUhZh.gif")
47
-
48
- row1_col1, row1_col2 = st.columns([3, 1])
49
- width = 800
50
- height = 600
51
- tiles = None
52
-
53
- with row1_col2:
54
-
55
- checkbox = st.checkbox("Search Quick Map Services (QMS)")
56
- keyword = st.text_input("Enter a keyword to search and press Enter:")
57
- empty = st.empty()
58
-
59
- if keyword:
60
- options = leafmap.search_xyz_services(keyword=keyword)
61
- if checkbox:
62
- qms = leafmap.search_qms(keyword=keyword)
63
- if qms is not None:
64
- options = options + qms
65
-
66
- tiles = empty.multiselect("Select XYZ tiles to add to the map:", options)
67
-
68
- with row1_col1:
69
- m = leafmap.Map()
70
-
71
- if tiles is not None:
72
- for tile in tiles:
73
- m.add_xyz_service(tile)
74
-
75
- m.to_streamlit(height=height)
76
-
77
 
78
- app()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+ import json
3
  import time
4
  from pathlib import Path
5
+ from dotenv import load_dotenv
6
  import numpy as np
7
  import streamlit as st
8
+ from mistralai import Mistral, UserMessage
9
+ import json
10
+ import faiss
11
+
12
+ # load .env in local dev
13
+ load_dotenv()
14
+
15
+ title = "Simulateur IA Viti"
16
+ description = "Demonstrateur Viti"
17
+ LOGO = "images/agir.png"
18
+ form_help ="Vous pouvez compléter les informations ci-dessous pour personnaliser votre expérience"
19
+ placeholder = (
20
+ "Vous pouvez me posez une question sur la transmission de votre domaine, appuyer sur Entrée pour valider"
21
+ )
22
+ placeholder_url = "Récupérer les données de ce lien."
23
+ llm_model = "open-mixtral-8x7b"
24
+
25
+ env_api_key = os.environ.get("MISTRAL_API_KEY")
26
+ query_engine = None
27
+
28
+ # Define LLMs
29
+ client = Mistral(api_key=env_api_key)
30
+
31
+ st.title(title)
32
+
33
+ st.caption(placeholder)
34
+ st.logo(LOGO)
35
+ st.sidebar.markdown(form_help)
36
+ age = st.sidebar.text_input("Votre age", type="default")
37
+
38
+ def load_json(rep:str):
39
+ f = open(rep, encoding='UTF-8')
40
+ return json.load(f)
41
+
42
+ def split_chunk(data, chunk_size):
43
+ data_str = [json.dumps(entry) for entry in data]
44
+ chunk_size = chunk_size
45
+ chunks = [data_str[i:i + chunk_size] for i in range(0, len(data_str), chunk_size)]
46
+ print(f"Nb. chunks = {len(chunks)}")
47
+ return chunks
48
+
49
+ def get_text_embedding(input):
50
+ embeddings_batch_response = client.embeddings(
51
+ model='mistral-embed',
52
+ input=input
53
+ )
54
+ return embeddings_batch_response.data[0].embedding
55
+
56
+ def load_vector_db(text_embedded):
57
+ d = text_embedded.shape[1]
58
+ index = faiss.IndexFlatL2(d)
59
+ index.add(text_embedded)
60
+ return index
61
+
62
+ def find_similar_chunk(index, question_embeddings, chunks):
63
+ D, I = index.search(question_embeddings, k=2) # distance, index
64
+ return [chunks[i] for i in I.tolist()[0]]
65
+
66
+ def prompt_chat(retrieved_chunk, question):
67
+ return f"""
68
+ Les informations contextuelles sont les suivantes.
69
+ ---------------------
70
+ {retrieved_chunk}
71
+ ---------------------
72
+ Compte tenu des informations contextuelles et sans connaissances préalables,
73
+ réponds en français à la question suivante de manière concise.
74
+ Utilise des listes pour plus de lisibilité.
75
+ Question: {question}
76
+ Réponse:
77
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
+ # Chargement des données
80
+ # data = load_json('catalogue_2024.json')
81
+ # chunks = split_chunk(data, 3)
82
+ # text_embeddings = np.load("catalogue_embeddings.npy")
83
+ # index = load_vector_db(text_embeddings)
84
+
85
+ if "messages" not in st.session_state:
86
+ st.session_state["messages"] = [{"role": "assistant", "content": "Comment puis-je vous aider?"}]
87
+ st.session_state["History"] = []
88
+ st.session_state.History.append({"role": "assitant", "content": "Comment puis-je vous aider?"})
89
+
90
+ for msg in st.session_state.messages:
91
+ st.chat_message(msg["role"]).write(msg["content"])
92
+
93
+ if prompt := st.chat_input():
94
+ # question_embeddings = np.array([get_text_embedding(prompt)])
95
+ # retrieved_chunk = find_similar_chunk(index, question_embeddings, chunks)
96
+ # p = prompt_chat(retrieved_chunk=retrieved_chunk, question=prompt)
97
+
98
+ st.session_state.messages.append({"role": "user", "content": prompt})
99
+ # st.session_state.History.append({"role": "user", "content": p})
100
+ st.chat_message("user").write(prompt)
101
+
102
+ with st.chat_message("assistant"):
103
+ message_placeholder = st.empty()
104
+ full_response = ""
105
+ chat_response = client.chat.complete(
106
+ model=llm_model,
107
+ messages=st.session_state.messages[1:]
108
+ )
109
+
110
+ print(chat_response.choices[0])
111
+
112
+ for choice in chat_response.choices:
113
+ print(choice)
114
+ full_response += (choice.message.content or "")
115
+ message_placeholder.markdown(full_response + "|")
116
+
117
+ message_placeholder.markdown(full_response)
118
+
119
+ st.session_state.History.append({"role": "assistant", "content": full_response})
120
+ st.session_state.messages.append({"role": "assistant", "content": full_response})
images/agir.png ADDED
requirements.txt CHANGED
@@ -1,13 +1,261 @@
1
- streamlit
2
- faiss-cpu
3
- pypdf
4
- mistralai
5
- fiona
6
- folium #==0.13.0
7
- geopandas
8
- leafmap>=0.35.2
9
- streamlit-folium
10
- owslib
11
- palettable
12
- plotly
13
- git+https://github.com/giswqs/geemap
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohappyeyeballs==2.4.0
2
+ aiohttp==3.10.5
3
+ aiosignal==1.3.1
4
+ altair==5.4.1
5
+ annotated-types==0.7.0
6
+ anyio==4.5.0
7
+ anywidget==0.9.13
8
+ asgiref==3.8.1
9
+ asttokens==2.4.1
10
+ async-timeout==4.0.3
11
+ attrs==24.2.0
12
+ backoff==2.2.1
13
+ bcrypt==4.2.0
14
+ beautifulsoup4==4.12.3
15
+ blinker==1.8.2
16
+ bqplot==0.12.43
17
+ branca==0.7.2
18
+ build==1.2.2
19
+ cachetools==5.5.0
20
+ certifi==2024.8.30
21
+ charset-normalizer==3.3.2
22
+ chroma-hnswlib==0.7.6
23
+ chromadb==0.5.7
24
+ chromedriver-autoinstaller==0.6.4
25
+ click==8.1.7
26
+ click-plugins==1.1.1
27
+ cligj==0.7.2
28
+ coloredlogs==15.0.1
29
+ colour==0.1.5
30
+ comm==0.2.2
31
+ contourpy==1.3.0
32
+ cssselect==1.2.0
33
+ cycler==0.12.1
34
+ dataclasses-json==0.6.7
35
+ decorator==5.1.1
36
+ Deprecated==1.2.14
37
+ dirtyjson==1.0.8
38
+ distro==1.9.0
39
+ duckdb==1.1.0
40
+ earthengine-api==1.1.0
41
+ eerepr==0.0.4
42
+ eval_type_backport==0.2.0
43
+ exceptiongroup==1.2.2
44
+ executing==2.1.0
45
+ faiss-cpu==1.8.0.post1
46
+ fastapi==0.115.0
47
+ feedfinder2==0.0.4
48
+ feedparser==6.0.11
49
+ filelock==3.16.1
50
+ fiona==1.10.1
51
+ flatbuffers==24.3.25
52
+ folium==0.17.0
53
+ fonttools==4.53.1
54
+ frozenlist==1.4.1
55
+ fsspec==2024.9.0
56
+ future==1.0.0
57
+ gdown==5.2.0
58
+ geemap @ git+https://github.com/giswqs/geemap@1adb1a53b5bbb716199637e096f105ca8c727657
59
+ geocoder==1.38.1
60
+ geojson==3.1.0
61
+ geopandas==1.0.1
62
+ gitdb==4.0.11
63
+ GitPython==3.1.43
64
+ google-api-core==2.19.2
65
+ google-api-python-client==2.146.0
66
+ google-auth==2.34.0
67
+ google-auth-httplib2==0.2.0
68
+ google-cloud-core==2.4.1
69
+ google-cloud-storage==2.18.2
70
+ google-crc32c==1.6.0
71
+ google-resumable-media==2.7.2
72
+ googleapis-common-protos==1.65.0
73
+ greenlet==3.0.3
74
+ grpcio==1.66.1
75
+ h11==0.14.0
76
+ html2text==2024.2.26
77
+ httpcore==1.0.5
78
+ httplib2==0.22.0
79
+ httptools==0.6.1
80
+ httpx==0.27.2
81
+ huggingface-hub==0.25.0
82
+ humanfriendly==10.0
83
+ idna==3.10
84
+ importlib_metadata==8.4.0
85
+ importlib_resources==6.4.5
86
+ ipyevents==2.0.2
87
+ ipyfilechooser==0.6.0
88
+ ipyleaflet==0.19.2
89
+ ipython==8.27.0
90
+ ipytree==0.2.2
91
+ ipyvue==1.11.1
92
+ ipyvuetify==1.10.0
93
+ ipywidgets==8.1.5
94
+ jedi==0.19.1
95
+ jieba3k==0.35.1
96
+ Jinja2==3.1.4
97
+ jiter==0.5.0
98
+ joblib==1.4.2
99
+ jsonpath-python==1.0.6
100
+ jsonschema==4.23.0
101
+ jsonschema-specifications==2023.12.1
102
+ jupyter-leaflet==0.19.2
103
+ jupyterlab_widgets==3.0.13
104
+ kiwisolver==1.4.7
105
+ kubernetes==30.1.0
106
+ leafmap==0.37.3
107
+ llama-cloud==0.0.17
108
+ llama-index==0.11.10
109
+ llama-index-agent-openai==0.3.3
110
+ llama-index-cli==0.3.1
111
+ llama-index-core==0.11.10
112
+ llama-index-embeddings-mistralai==0.2.0
113
+ llama-index-embeddings-openai==0.2.5
114
+ llama-index-indices-managed-llama-cloud==0.3.1
115
+ llama-index-legacy==0.9.48.post3
116
+ llama-index-llms-mistralai==0.2.5
117
+ llama-index-llms-openai==0.2.9
118
+ llama-index-multi-modal-llms-openai==0.2.1
119
+ llama-index-program-openai==0.2.0
120
+ llama-index-question-gen-openai==0.2.0
121
+ llama-index-readers-file==0.2.1
122
+ llama-index-readers-llama-parse==0.3.0
123
+ llama-index-readers-web==0.2.2
124
+ llama-index-vector-stores-chroma==0.2.0
125
+ llama-parse==0.5.5
126
+ lxml==5.3.0
127
+ markdown-it-py==3.0.0
128
+ MarkupSafe==2.1.5
129
+ marshmallow==3.22.0
130
+ matplotlib==3.9.2
131
+ matplotlib-inline==0.1.7
132
+ mdurl==0.1.2
133
+ mistralai==1.1.0
134
+ mmh3==5.0.0
135
+ monotonic==1.6
136
+ mpmath==1.3.0
137
+ multidict==6.1.0
138
+ mypy-extensions==1.0.0
139
+ narwhals==1.8.1
140
+ nest-asyncio==1.6.0
141
+ networkx==3.3
142
+ newspaper3k==0.2.8
143
+ nltk==3.9.1
144
+ numpy==1.26.4
145
+ oauthlib==3.2.2
146
+ onnxruntime==1.19.2
147
+ openai==1.46.0
148
+ opentelemetry-api==1.27.0
149
+ opentelemetry-exporter-otlp-proto-common==1.27.0
150
+ opentelemetry-exporter-otlp-proto-grpc==1.27.0
151
+ opentelemetry-instrumentation==0.48b0
152
+ opentelemetry-instrumentation-asgi==0.48b0
153
+ opentelemetry-instrumentation-fastapi==0.48b0
154
+ opentelemetry-proto==1.27.0
155
+ opentelemetry-sdk==1.27.0
156
+ opentelemetry-semantic-conventions==0.48b0
157
+ opentelemetry-util-http==0.48b0
158
+ orjson==3.10.7
159
+ outcome==1.3.0.post0
160
+ overrides==7.7.0
161
+ OWSLib==0.31.0
162
+ packaging==24.1
163
+ palettable==3.3.3
164
+ pandas==2.2.2
165
+ parso==0.8.4
166
+ pexpect==4.9.0
167
+ pillow==10.4.0
168
+ playwright==1.47.0
169
+ plotly==5.24.1
170
+ posthog==3.6.6
171
+ prompt_toolkit==3.0.47
172
+ proto-plus==1.24.0
173
+ protobuf==4.25.5
174
+ psygnal==0.11.1
175
+ ptyprocess==0.7.0
176
+ pure_eval==0.2.3
177
+ pyarrow==17.0.0
178
+ pyasn1==0.6.1
179
+ pyasn1_modules==0.4.1
180
+ pydantic==2.9.2
181
+ pydantic_core==2.23.4
182
+ pydeck==0.9.1
183
+ pyee==12.0.0
184
+ Pygments==2.18.0
185
+ pyogrio==0.9.0
186
+ pyparsing==3.1.4
187
+ pypdf==4.3.1
188
+ pyperclip==1.9.0
189
+ PyPika==0.48.9
190
+ pyproj==3.6.1
191
+ pyproject_hooks==1.1.0
192
+ pyshp==2.3.1
193
+ PySocks==1.7.1
194
+ pystac==1.10.1
195
+ pystac-client==0.8.3
196
+ python-box==7.2.0
197
+ python-dateutil==2.8.2
198
+ python-dotenv==1.0.1
199
+ pytz==2024.2
200
+ PyYAML==6.0.2
201
+ ratelim==0.1.6
202
+ referencing==0.35.1
203
+ regex==2024.9.11
204
+ requests==2.32.3
205
+ requests-file==2.1.0
206
+ requests-oauthlib==2.0.0
207
+ rich==13.8.1
208
+ rpds-py==0.20.0
209
+ rsa==4.9
210
+ scooby==0.10.0
211
+ selenium==4.24.0
212
+ sgmllib3k==1.0.0
213
+ shapely==2.0.6
214
+ shellingham==1.5.4
215
+ six==1.16.0
216
+ smmap==5.0.1
217
+ sniffio==1.3.1
218
+ sortedcontainers==2.4.0
219
+ soupsieve==2.6
220
+ spider-client==0.0.27
221
+ SQLAlchemy==2.0.35
222
+ stack-data==0.6.3
223
+ starlette==0.38.5
224
+ streamlit==1.38.0
225
+ streamlit_folium==0.22.1
226
+ striprtf==0.0.26
227
+ sympy==1.13.3
228
+ tenacity==8.5.0
229
+ tiktoken==0.7.0
230
+ tinysegmenter==0.3
231
+ tldextract==5.1.2
232
+ tokenizers==0.20.0
233
+ toml==0.10.2
234
+ tomli==2.0.1
235
+ tornado==6.4.1
236
+ tqdm==4.66.5
237
+ traitlets==5.14.3
238
+ traittypes==0.2.1
239
+ trio==0.26.2
240
+ trio-websocket==0.11.1
241
+ typer==0.12.5
242
+ typing-inspect==0.9.0
243
+ typing_extensions==4.12.2
244
+ tzdata==2024.1
245
+ uritemplate==4.1.1
246
+ urllib3==2.2.3
247
+ uvicorn==0.30.6
248
+ uvloop==0.20.0
249
+ watchdog==4.0.2
250
+ watchfiles==0.24.0
251
+ wcwidth==0.2.13
252
+ websocket-client==1.8.0
253
+ websockets==13.0.1
254
+ whitebox==2.3.5
255
+ whiteboxgui==2.3.0
256
+ widgetsnbextension==4.0.13
257
+ wrapt==1.16.0
258
+ wsproto==1.2.0
259
+ xyzservices==2024.9.0
260
+ yarl==1.11.1
261
+ zipp==3.20.2