Jaume commited on
Commit
ee6d38b
·
1 Parent(s): 1024ec8

refactoring

Browse files
.gitattributes CHANGED
@@ -34,3 +34,4 @@ saved_model/**/* 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
36
  *.png 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
36
  *.png filter=lfs diff=lfs merge=lfs -text
37
+ *.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -10,16 +10,32 @@ pinned: true
10
  license: mit
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
  ## Running the app
17
 
18
  ```bash
19
- poetry install
20
  poetry run gradio app.py
21
  ```
22
 
 
 
23
  Update the requirements.txt file with the following command:
24
  ```bash
25
  poetry export --without-hashes --without dev -f requirements.txt -o requirements.txt
 
10
  license: mit
11
  ---
12
 
13
+ # Write4All
14
 
15
+ In a world where diversity and inclusivity are essential, crafting content that resonates with everyone can be a challenge. With ✅ Write4All I hope making the world more inclusive, one word and image at a time.
16
+
17
+ ## Requirements
18
+
19
+ - Python 3.10+
20
+ - Poetry
21
+ - Gemini API key
22
+
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install poetry
28
+ ```
29
 
30
  ## Running the app
31
 
32
  ```bash
33
+ export GEMINI_API_KEY=your_api_key_here
34
  poetry run gradio app.py
35
  ```
36
 
37
+ ## Development
38
+ Huggingface spaces require the `requirements.txt` file to be updated with the latest dependencies.
39
  Update the requirements.txt file with the following command:
40
  ```bash
41
  poetry export --without-hashes --without dev -f requirements.txt -o requirements.txt
app.py CHANGED
@@ -1,130 +1,7 @@
1
  import re
2
- import os
3
  import gradio as gr
4
- import json
5
- from functools import cache
6
-
7
- import google.generativeai as genai
8
-
9
-
10
- try:
11
- from dotenv import load_dotenv
12
-
13
- load_dotenv()
14
- except:
15
- pass
16
-
17
- generation_config = {
18
- "temperature": 0.9, # Temperature of the sampling distribution
19
- "top_p": 1, # Probability of sampling from the top p tokens
20
- "top_k": 1, # Number of top tokens to sample from
21
- "max_output_tokens": 2048,
22
- }
23
-
24
- safety_settings = [
25
- {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
26
- {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
27
- {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
28
- {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_ONLY_HIGH"},
29
- ]
30
-
31
- genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
32
-
33
- text_model = genai.GenerativeModel(
34
- model_name="gemini-1.0-pro",
35
- generation_config=generation_config,
36
- safety_settings=safety_settings,
37
- )
38
- vision_model = genai.GenerativeModel(
39
- "gemini-pro-vision",
40
- generation_config=generation_config,
41
- safety_settings=safety_settings,
42
- )
43
-
44
-
45
- @cache
46
- def get_file(path: str) -> str:
47
- with open(path) as f:
48
- return f.read()
49
-
50
-
51
- def fix_json(json_str: str) -> str:
52
- template = get_file("templates/prompt_json_fix.txt")
53
- prompt = template.format(json=json_str)
54
- response = text_model.generate_content(prompt).text
55
- return response.split("```json")[1].split("```")[0]
56
-
57
-
58
- def get_json_content(response: str) -> dict:
59
- print(response)
60
- if "```json" not in response:
61
- return []
62
- raw_json = response.split("```json")[1].split("```")[0]
63
- try:
64
- return json.loads(raw_json)
65
- except json.JSONDecodeError as e:
66
- print(e)
67
- new_json = fix_json(raw_json)
68
- print(new_json)
69
- return json.loads(new_json)
70
-
71
-
72
- def review_text(text: str) -> list[dict]:
73
- template = get_file("templates/prompt_v1.txt")
74
- try:
75
- response = text_model.generate_content(template.format(text=text)).text
76
- except ValueError as e:
77
- print(e)
78
- raise ValueError(
79
- f"Error while getting answer from the model, make sure the content isn't offensive or dangerous."
80
- )
81
- return get_json_content(response)
82
-
83
-
84
- def review_image(image) -> list[dict]:
85
- prompt = get_file("templates/prompt_image_v1.txt")
86
- try:
87
- response = vision_model.generate_content([prompt, image]).text
88
- except ValueError as e:
89
- print(e)
90
- message = "Error while getting answer from the model, make sure the content isn't offensive or dangerous. Please try again or change the prompt."
91
- gr.Error(message)
92
- raise ValueError(message)
93
- return response
94
-
95
-
96
- def html_title(title: str) -> str:
97
- return f"<h1>{title}</h1>"
98
-
99
-
100
- def apply_review(text: str, review: list[dict]) -> str:
101
- output = ""
102
- review = sorted(review, key=lambda x: x["start_char"])
103
- last_end = 0
104
- for entity in review:
105
- starts = [
106
- m.start() + last_end
107
- for m in re.finditer(entity["term"].lower(), text[last_end:].lower())
108
- ]
109
- if len(starts) > 0:
110
- start = starts[0]
111
- end = start + len(entity["term"])
112
- output += text[last_end:start]
113
- output += get_file("templates/correction.html").format(
114
- term=text[start:end], fix=entity["fix"], kind=entity["type"]
115
- )
116
- last_end = end
117
- output += text[last_end:]
118
- return f"<pre style='white-space: pre-wrap;'>{output}</pre>"
119
-
120
-
121
- def review_table_summary(review: list[dict]) -> str:
122
- table = "<table><tr><th>Term</th><th>Fix</th><th>Type</th><th>Reason</th></tr>"
123
- for entity in review:
124
- table += f"<tr><td>{entity['term']}</td><td>{entity['fix']}</td><td>{entity['type']}</td><td>{entity.get('reason', '-')}</td></tr>"
125
- table += "</table>"
126
- return table
127
 
 
128
 
129
  def format_entities(text: str, review: list[dict]) -> list[dict]:
130
  entities = []
@@ -146,41 +23,45 @@ def format_entities(text: str, review: list[dict]) -> list[dict]:
146
  return entities
147
 
148
 
149
- def process_text(text):
150
- review = review_text(text)
151
- if len(review) == 0:
152
- return html_title("No issues found in the text 🎉🎉🎉")
153
- return (
154
- html_title("Reviewed text")
155
- + apply_review(text, review)
156
- + html_title("Explanation")
157
- + review_table_summary(review)
158
- )
159
-
160
-
161
- def process_image(image):
162
- print(image)
163
- return review_image(image)
164
-
165
-
166
  text_ui = gr.Interface(
167
  fn=process_text,
168
- inputs=["text"],
 
 
 
 
 
 
 
 
169
  outputs=[gr.HTML(label="Revision")],
170
  examples=[
171
- "The whitelist is incomplete.",
172
- "There's not enough manpower to deliver the project",
173
- "This has never happened in the history of mankind!",
174
- "El hombre desciende del mono.",
175
- "Els homes són animals",
176
  ],
177
  )
178
 
179
  image_ui = gr.Interface(
180
  fn=process_image,
181
- inputs=gr.Image(sources=["upload", "clipboard"], type="pil"),
 
 
 
 
 
 
 
 
182
  outputs=["markdown"],
183
- examples=["static/images/CEOs.png", "static/images/meat_grid.png"],
 
 
 
 
 
184
  )
185
 
186
  with gr.Blocks() as demo:
 
1
  import re
 
2
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ from review import process_text, process_image, get_file
5
 
6
  def format_entities(text: str, review: list[dict]) -> list[dict]:
7
  entities = []
 
23
  return entities
24
 
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  text_ui = gr.Interface(
27
  fn=process_text,
28
+ inputs=[
29
+ gr.Dropdown(
30
+ ["Gemini 1.0 Pro", "Gemini 1.5 Pro (latest)"],
31
+ label="Model",
32
+ value="Gemini 1.0 Pro",
33
+ scale=1,
34
+ ),
35
+ gr.Textbox(lines=5, label="Text", scale=4),
36
+ ],
37
  outputs=[gr.HTML(label="Revision")],
38
  examples=[
39
+ ["Gemini 1.0 Pro", "The whitelist is incomplete."],
40
+ ["Gemini 1.0 Pro", "There's not enough manpower to deliver the project"],
41
+ ["Gemini 1.0 Pro", "This has never happened in the history of mankind!"],
42
+ ["Gemini 1.0 Pro", "El hombre desciende del mono."],
43
+ ["Gemini 1.0 Pro", "Els homes són animals"],
44
  ],
45
  )
46
 
47
  image_ui = gr.Interface(
48
  fn=process_image,
49
+ inputs=[
50
+ gr.Dropdown(
51
+ ["Gemini 1.0 Pro Vision", "Gemini 1.5 Pro (latest)"],
52
+ label="Model",
53
+ value="Gemini 1.0 Pro Vision",
54
+ scale=1,
55
+ ),
56
+ gr.Image(sources=["upload", "clipboard"], type="pil"),
57
+ ],
58
  outputs=["markdown"],
59
+ examples=[
60
+ ["Gemini 1.0 Pro Vision", "static/images/CEOs.png"],
61
+ ["Gemini 1.0 Pro Vision", "static/images/meat_grid.png"],
62
+ ["Gemini 1.0 Pro Vision", "static/images/elephants.png"],
63
+ ["Gemini 1.0 Pro Vision", "static/images/crosses.png"],
64
+ ],
65
  )
66
 
67
  with gr.Blocks() as demo:
notebooks/examples.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
poetry.lock CHANGED
@@ -69,6 +69,35 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin
69
  test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
70
  trio = ["trio (>=0.23)"]
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  [[package]]
73
  name = "attrs"
74
  version = "23.2.0"
@@ -110,6 +139,70 @@ files = [
110
  {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
111
  ]
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  [[package]]
114
  name = "charset-normalizer"
115
  version = "3.3.2"
@@ -234,6 +327,23 @@ files = [
234
  {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
235
  ]
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  [[package]]
238
  name = "contourpy"
239
  version = "1.2.1"
@@ -312,6 +422,48 @@ files = [
312
  docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
313
  tests = ["pytest", "pytest-cov", "pytest-xdist"]
314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  [[package]]
316
  name = "exceptiongroup"
317
  version = "1.2.0"
@@ -326,6 +478,20 @@ files = [
326
  [package.extras]
327
  test = ["pytest (>=6)"]
328
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  [[package]]
330
  name = "fastapi"
331
  version = "0.110.1"
@@ -839,6 +1005,117 @@ files = [
839
  docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
840
  testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"]
841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
842
  [[package]]
843
  name = "jinja2"
844
  version = "3.1.3"
@@ -891,6 +1168,59 @@ files = [
891
  [package.dependencies]
892
  referencing = ">=0.31.0"
893
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
894
  [[package]]
895
  name = "kiwisolver"
896
  version = "1.4.5"
@@ -1145,6 +1475,20 @@ pillow = ">=8"
1145
  pyparsing = ">=2.3.1"
1146
  python-dateutil = ">=2.7"
1147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1148
  [[package]]
1149
  name = "mdurl"
1150
  version = "0.1.2"
@@ -1156,6 +1500,17 @@ files = [
1156
  {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
1157
  ]
1158
 
 
 
 
 
 
 
 
 
 
 
 
1159
  [[package]]
1160
  name = "numpy"
1161
  version = "1.26.4"
@@ -1345,6 +1700,35 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d
1345
  test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
1346
  xml = ["lxml (>=4.9.2)"]
1347
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1348
  [[package]]
1349
  name = "pillow"
1350
  version = "10.3.0"
@@ -1431,6 +1815,35 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa
1431
  typing = ["typing-extensions"]
1432
  xmp = ["defusedxml"]
1433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1434
  [[package]]
1435
  name = "proto-plus"
1436
  version = "1.23.0"
@@ -1468,6 +1881,59 @@ files = [
1468
  {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"},
1469
  ]
1470
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1471
  [[package]]
1472
  name = "pyasn1"
1473
  version = "0.6.0"
@@ -1493,6 +1959,17 @@ files = [
1493
  [package.dependencies]
1494
  pyasn1 = ">=0.4.6,<0.7.0"
1495
 
 
 
 
 
 
 
 
 
 
 
 
1496
  [[package]]
1497
  name = "pydantic"
1498
  version = "2.6.4"
@@ -1696,6 +2173,29 @@ files = [
1696
  {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
1697
  ]
1698
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1699
  [[package]]
1700
  name = "pyyaml"
1701
  version = "6.0.1"
@@ -1755,6 +2255,111 @@ files = [
1755
  {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
1756
  ]
1757
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1758
  [[package]]
1759
  name = "referencing"
1760
  version = "0.34.0"
@@ -2005,6 +2610,25 @@ files = [
2005
  {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
2006
  ]
2007
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2008
  [[package]]
2009
  name = "starlette"
2010
  version = "0.37.2"
@@ -2044,6 +2668,26 @@ files = [
2044
  {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"},
2045
  ]
2046
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2047
  [[package]]
2048
  name = "tqdm"
2049
  version = "4.66.2"
@@ -2064,6 +2708,21 @@ notebook = ["ipywidgets (>=6)"]
2064
  slack = ["slack-sdk"]
2065
  telegram = ["requests"]
2066
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2067
  [[package]]
2068
  name = "typer"
2069
  version = "0.12.0"
@@ -2172,6 +2831,17 @@ typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
2172
  [package.extras]
2173
  standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
2174
 
 
 
 
 
 
 
 
 
 
 
 
2175
  [[package]]
2176
  name = "websockets"
2177
  version = "11.0.3"
@@ -2251,7 +2921,18 @@ files = [
2251
  {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"},
2252
  ]
2253
 
 
 
 
 
 
 
 
 
 
 
 
2254
  [metadata]
2255
  lock-version = "2.0"
2256
  python-versions = "^3.10"
2257
- content-hash = "33d8960ca2a2c2dacc1c34ccd5b1a781a1a3350d1670829e0fbc5aa193bf4bc2"
 
69
  test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
70
  trio = ["trio (>=0.23)"]
71
 
72
+ [[package]]
73
+ name = "appnope"
74
+ version = "0.1.4"
75
+ description = "Disable App Nap on macOS >= 10.9"
76
+ optional = false
77
+ python-versions = ">=3.6"
78
+ files = [
79
+ {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"},
80
+ {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"},
81
+ ]
82
+
83
+ [[package]]
84
+ name = "asttokens"
85
+ version = "2.4.1"
86
+ description = "Annotate AST trees with source code positions"
87
+ optional = false
88
+ python-versions = "*"
89
+ files = [
90
+ {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"},
91
+ {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"},
92
+ ]
93
+
94
+ [package.dependencies]
95
+ six = ">=1.12.0"
96
+
97
+ [package.extras]
98
+ astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"]
99
+ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"]
100
+
101
  [[package]]
102
  name = "attrs"
103
  version = "23.2.0"
 
139
  {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
140
  ]
141
 
142
+ [[package]]
143
+ name = "cffi"
144
+ version = "1.16.0"
145
+ description = "Foreign Function Interface for Python calling C code."
146
+ optional = false
147
+ python-versions = ">=3.8"
148
+ files = [
149
+ {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
150
+ {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
151
+ {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
152
+ {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
153
+ {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
154
+ {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
155
+ {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
156
+ {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
157
+ {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
158
+ {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
159
+ {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
160
+ {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
161
+ {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
162
+ {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
163
+ {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
164
+ {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
165
+ {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
166
+ {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
167
+ {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
168
+ {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
169
+ {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
170
+ {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
171
+ {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
172
+ {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
173
+ {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
174
+ {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
175
+ {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
176
+ {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
177
+ {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
178
+ {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
179
+ {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
180
+ {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
181
+ {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"},
182
+ {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"},
183
+ {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"},
184
+ {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"},
185
+ {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"},
186
+ {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"},
187
+ {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"},
188
+ {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"},
189
+ {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
190
+ {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
191
+ {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
192
+ {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
193
+ {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
194
+ {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
195
+ {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
196
+ {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
197
+ {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
198
+ {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
199
+ {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
200
+ {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
201
+ ]
202
+
203
+ [package.dependencies]
204
+ pycparser = "*"
205
+
206
  [[package]]
207
  name = "charset-normalizer"
208
  version = "3.3.2"
 
327
  {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
328
  ]
329
 
330
+ [[package]]
331
+ name = "comm"
332
+ version = "0.2.2"
333
+ description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc."
334
+ optional = false
335
+ python-versions = ">=3.8"
336
+ files = [
337
+ {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"},
338
+ {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"},
339
+ ]
340
+
341
+ [package.dependencies]
342
+ traitlets = ">=4"
343
+
344
+ [package.extras]
345
+ test = ["pytest"]
346
+
347
  [[package]]
348
  name = "contourpy"
349
  version = "1.2.1"
 
422
  docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
423
  tests = ["pytest", "pytest-cov", "pytest-xdist"]
424
 
425
+ [[package]]
426
+ name = "debugpy"
427
+ version = "1.8.1"
428
+ description = "An implementation of the Debug Adapter Protocol for Python"
429
+ optional = false
430
+ python-versions = ">=3.8"
431
+ files = [
432
+ {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"},
433
+ {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"},
434
+ {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"},
435
+ {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"},
436
+ {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"},
437
+ {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"},
438
+ {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"},
439
+ {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"},
440
+ {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"},
441
+ {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"},
442
+ {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"},
443
+ {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"},
444
+ {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"},
445
+ {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"},
446
+ {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"},
447
+ {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"},
448
+ {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"},
449
+ {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"},
450
+ {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"},
451
+ {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"},
452
+ {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"},
453
+ {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"},
454
+ ]
455
+
456
+ [[package]]
457
+ name = "decorator"
458
+ version = "5.1.1"
459
+ description = "Decorators for Humans"
460
+ optional = false
461
+ python-versions = ">=3.5"
462
+ files = [
463
+ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
464
+ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
465
+ ]
466
+
467
  [[package]]
468
  name = "exceptiongroup"
469
  version = "1.2.0"
 
478
  [package.extras]
479
  test = ["pytest (>=6)"]
480
 
481
+ [[package]]
482
+ name = "executing"
483
+ version = "2.0.1"
484
+ description = "Get the currently executing AST node of a frame, and other information"
485
+ optional = false
486
+ python-versions = ">=3.5"
487
+ files = [
488
+ {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"},
489
+ {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"},
490
+ ]
491
+
492
+ [package.extras]
493
+ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"]
494
+
495
  [[package]]
496
  name = "fastapi"
497
  version = "0.110.1"
 
1005
  docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
1006
  testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"]
1007
 
1008
+ [[package]]
1009
+ name = "ipykernel"
1010
+ version = "6.29.4"
1011
+ description = "IPython Kernel for Jupyter"
1012
+ optional = false
1013
+ python-versions = ">=3.8"
1014
+ files = [
1015
+ {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"},
1016
+ {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"},
1017
+ ]
1018
+
1019
+ [package.dependencies]
1020
+ appnope = {version = "*", markers = "platform_system == \"Darwin\""}
1021
+ comm = ">=0.1.1"
1022
+ debugpy = ">=1.6.5"
1023
+ ipython = ">=7.23.1"
1024
+ jupyter-client = ">=6.1.12"
1025
+ jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
1026
+ matplotlib-inline = ">=0.1"
1027
+ nest-asyncio = "*"
1028
+ packaging = "*"
1029
+ psutil = "*"
1030
+ pyzmq = ">=24"
1031
+ tornado = ">=6.1"
1032
+ traitlets = ">=5.4.0"
1033
+
1034
+ [package.extras]
1035
+ cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"]
1036
+ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"]
1037
+ pyqt5 = ["pyqt5"]
1038
+ pyside6 = ["pyside6"]
1039
+ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"]
1040
+
1041
+ [[package]]
1042
+ name = "ipython"
1043
+ version = "8.23.0"
1044
+ description = "IPython: Productive Interactive Computing"
1045
+ optional = false
1046
+ python-versions = ">=3.10"
1047
+ files = [
1048
+ {file = "ipython-8.23.0-py3-none-any.whl", hash = "sha256:07232af52a5ba146dc3372c7bf52a0f890a23edf38d77caef8d53f9cdc2584c1"},
1049
+ {file = "ipython-8.23.0.tar.gz", hash = "sha256:7468edaf4f6de3e1b912e57f66c241e6fd3c7099f2ec2136e239e142e800274d"},
1050
+ ]
1051
+
1052
+ [package.dependencies]
1053
+ colorama = {version = "*", markers = "sys_platform == \"win32\""}
1054
+ decorator = "*"
1055
+ exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
1056
+ jedi = ">=0.16"
1057
+ matplotlib-inline = "*"
1058
+ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
1059
+ prompt-toolkit = ">=3.0.41,<3.1.0"
1060
+ pygments = ">=2.4.0"
1061
+ stack-data = "*"
1062
+ traitlets = ">=5.13.0"
1063
+ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
1064
+
1065
+ [package.extras]
1066
+ all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"]
1067
+ black = ["black"]
1068
+ doc = ["docrepr", "exceptiongroup", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "stack-data", "typing-extensions"]
1069
+ kernel = ["ipykernel"]
1070
+ matplotlib = ["matplotlib"]
1071
+ nbconvert = ["nbconvert"]
1072
+ nbformat = ["nbformat"]
1073
+ notebook = ["ipywidgets", "notebook"]
1074
+ parallel = ["ipyparallel"]
1075
+ qtconsole = ["qtconsole"]
1076
+ test = ["pickleshare", "pytest (<8)", "pytest-asyncio (<0.22)", "testpath"]
1077
+ test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"]
1078
+
1079
+ [[package]]
1080
+ name = "ipywidgets"
1081
+ version = "8.1.2"
1082
+ description = "Jupyter interactive widgets"
1083
+ optional = false
1084
+ python-versions = ">=3.7"
1085
+ files = [
1086
+ {file = "ipywidgets-8.1.2-py3-none-any.whl", hash = "sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60"},
1087
+ {file = "ipywidgets-8.1.2.tar.gz", hash = "sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9"},
1088
+ ]
1089
+
1090
+ [package.dependencies]
1091
+ comm = ">=0.1.3"
1092
+ ipython = ">=6.1.0"
1093
+ jupyterlab-widgets = ">=3.0.10,<3.1.0"
1094
+ traitlets = ">=4.3.1"
1095
+ widgetsnbextension = ">=4.0.10,<4.1.0"
1096
+
1097
+ [package.extras]
1098
+ test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"]
1099
+
1100
+ [[package]]
1101
+ name = "jedi"
1102
+ version = "0.19.1"
1103
+ description = "An autocompletion tool for Python that can be used for text editors."
1104
+ optional = false
1105
+ python-versions = ">=3.6"
1106
+ files = [
1107
+ {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"},
1108
+ {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"},
1109
+ ]
1110
+
1111
+ [package.dependencies]
1112
+ parso = ">=0.8.3,<0.9.0"
1113
+
1114
+ [package.extras]
1115
+ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"]
1116
+ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
1117
+ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"]
1118
+
1119
  [[package]]
1120
  name = "jinja2"
1121
  version = "3.1.3"
 
1168
  [package.dependencies]
1169
  referencing = ">=0.31.0"
1170
 
1171
+ [[package]]
1172
+ name = "jupyter-client"
1173
+ version = "8.6.1"
1174
+ description = "Jupyter protocol implementation and client libraries"
1175
+ optional = false
1176
+ python-versions = ">=3.8"
1177
+ files = [
1178
+ {file = "jupyter_client-8.6.1-py3-none-any.whl", hash = "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f"},
1179
+ {file = "jupyter_client-8.6.1.tar.gz", hash = "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f"},
1180
+ ]
1181
+
1182
+ [package.dependencies]
1183
+ jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
1184
+ python-dateutil = ">=2.8.2"
1185
+ pyzmq = ">=23.0"
1186
+ tornado = ">=6.2"
1187
+ traitlets = ">=5.3"
1188
+
1189
+ [package.extras]
1190
+ docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
1191
+ test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"]
1192
+
1193
+ [[package]]
1194
+ name = "jupyter-core"
1195
+ version = "5.7.2"
1196
+ description = "Jupyter core package. A base package on which Jupyter projects rely."
1197
+ optional = false
1198
+ python-versions = ">=3.8"
1199
+ files = [
1200
+ {file = "jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409"},
1201
+ {file = "jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9"},
1202
+ ]
1203
+
1204
+ [package.dependencies]
1205
+ platformdirs = ">=2.5"
1206
+ pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""}
1207
+ traitlets = ">=5.3"
1208
+
1209
+ [package.extras]
1210
+ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"]
1211
+ test = ["ipykernel", "pre-commit", "pytest (<8)", "pytest-cov", "pytest-timeout"]
1212
+
1213
+ [[package]]
1214
+ name = "jupyterlab-widgets"
1215
+ version = "3.0.10"
1216
+ description = "Jupyter interactive widgets for JupyterLab"
1217
+ optional = false
1218
+ python-versions = ">=3.7"
1219
+ files = [
1220
+ {file = "jupyterlab_widgets-3.0.10-py3-none-any.whl", hash = "sha256:dd61f3ae7a5a7f80299e14585ce6cf3d6925a96c9103c978eda293197730cb64"},
1221
+ {file = "jupyterlab_widgets-3.0.10.tar.gz", hash = "sha256:04f2ac04976727e4f9d0fa91cdc2f1ab860f965e504c29dbd6a65c882c9d04c0"},
1222
+ ]
1223
+
1224
  [[package]]
1225
  name = "kiwisolver"
1226
  version = "1.4.5"
 
1475
  pyparsing = ">=2.3.1"
1476
  python-dateutil = ">=2.7"
1477
 
1478
+ [[package]]
1479
+ name = "matplotlib-inline"
1480
+ version = "0.1.6"
1481
+ description = "Inline Matplotlib backend for Jupyter"
1482
+ optional = false
1483
+ python-versions = ">=3.5"
1484
+ files = [
1485
+ {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"},
1486
+ {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
1487
+ ]
1488
+
1489
+ [package.dependencies]
1490
+ traitlets = "*"
1491
+
1492
  [[package]]
1493
  name = "mdurl"
1494
  version = "0.1.2"
 
1500
  {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
1501
  ]
1502
 
1503
+ [[package]]
1504
+ name = "nest-asyncio"
1505
+ version = "1.6.0"
1506
+ description = "Patch asyncio to allow nested event loops"
1507
+ optional = false
1508
+ python-versions = ">=3.5"
1509
+ files = [
1510
+ {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"},
1511
+ {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
1512
+ ]
1513
+
1514
  [[package]]
1515
  name = "numpy"
1516
  version = "1.26.4"
 
1700
  test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
1701
  xml = ["lxml (>=4.9.2)"]
1702
 
1703
+ [[package]]
1704
+ name = "parso"
1705
+ version = "0.8.4"
1706
+ description = "A Python Parser"
1707
+ optional = false
1708
+ python-versions = ">=3.6"
1709
+ files = [
1710
+ {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"},
1711
+ {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"},
1712
+ ]
1713
+
1714
+ [package.extras]
1715
+ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
1716
+ testing = ["docopt", "pytest"]
1717
+
1718
+ [[package]]
1719
+ name = "pexpect"
1720
+ version = "4.9.0"
1721
+ description = "Pexpect allows easy control of interactive console applications."
1722
+ optional = false
1723
+ python-versions = "*"
1724
+ files = [
1725
+ {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
1726
+ {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
1727
+ ]
1728
+
1729
+ [package.dependencies]
1730
+ ptyprocess = ">=0.5"
1731
+
1732
  [[package]]
1733
  name = "pillow"
1734
  version = "10.3.0"
 
1815
  typing = ["typing-extensions"]
1816
  xmp = ["defusedxml"]
1817
 
1818
+ [[package]]
1819
+ name = "platformdirs"
1820
+ version = "4.2.0"
1821
+ description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
1822
+ optional = false
1823
+ python-versions = ">=3.8"
1824
+ files = [
1825
+ {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"},
1826
+ {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"},
1827
+ ]
1828
+
1829
+ [package.extras]
1830
+ docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
1831
+ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
1832
+
1833
+ [[package]]
1834
+ name = "prompt-toolkit"
1835
+ version = "3.0.43"
1836
+ description = "Library for building powerful interactive command lines in Python"
1837
+ optional = false
1838
+ python-versions = ">=3.7.0"
1839
+ files = [
1840
+ {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"},
1841
+ {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"},
1842
+ ]
1843
+
1844
+ [package.dependencies]
1845
+ wcwidth = "*"
1846
+
1847
  [[package]]
1848
  name = "proto-plus"
1849
  version = "1.23.0"
 
1881
  {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"},
1882
  ]
1883
 
1884
+ [[package]]
1885
+ name = "psutil"
1886
+ version = "5.9.8"
1887
+ description = "Cross-platform lib for process and system monitoring in Python."
1888
+ optional = false
1889
+ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
1890
+ files = [
1891
+ {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"},
1892
+ {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"},
1893
+ {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"},
1894
+ {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"},
1895
+ {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"},
1896
+ {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"},
1897
+ {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"},
1898
+ {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"},
1899
+ {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"},
1900
+ {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"},
1901
+ {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"},
1902
+ {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"},
1903
+ {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"},
1904
+ {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"},
1905
+ {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"},
1906
+ {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"},
1907
+ ]
1908
+
1909
+ [package.extras]
1910
+ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"]
1911
+
1912
+ [[package]]
1913
+ name = "ptyprocess"
1914
+ version = "0.7.0"
1915
+ description = "Run a subprocess in a pseudo terminal"
1916
+ optional = false
1917
+ python-versions = "*"
1918
+ files = [
1919
+ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
1920
+ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
1921
+ ]
1922
+
1923
+ [[package]]
1924
+ name = "pure-eval"
1925
+ version = "0.2.2"
1926
+ description = "Safely evaluate AST nodes without side effects"
1927
+ optional = false
1928
+ python-versions = "*"
1929
+ files = [
1930
+ {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"},
1931
+ {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"},
1932
+ ]
1933
+
1934
+ [package.extras]
1935
+ tests = ["pytest"]
1936
+
1937
  [[package]]
1938
  name = "pyasn1"
1939
  version = "0.6.0"
 
1959
  [package.dependencies]
1960
  pyasn1 = ">=0.4.6,<0.7.0"
1961
 
1962
+ [[package]]
1963
+ name = "pycparser"
1964
+ version = "2.22"
1965
+ description = "C parser in Python"
1966
+ optional = false
1967
+ python-versions = ">=3.8"
1968
+ files = [
1969
+ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
1970
+ {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
1971
+ ]
1972
+
1973
  [[package]]
1974
  name = "pydantic"
1975
  version = "2.6.4"
 
2173
  {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
2174
  ]
2175
 
2176
+ [[package]]
2177
+ name = "pywin32"
2178
+ version = "306"
2179
+ description = "Python for Window Extensions"
2180
+ optional = false
2181
+ python-versions = "*"
2182
+ files = [
2183
+ {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"},
2184
+ {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"},
2185
+ {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"},
2186
+ {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"},
2187
+ {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"},
2188
+ {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"},
2189
+ {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"},
2190
+ {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"},
2191
+ {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"},
2192
+ {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"},
2193
+ {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"},
2194
+ {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"},
2195
+ {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"},
2196
+ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"},
2197
+ ]
2198
+
2199
  [[package]]
2200
  name = "pyyaml"
2201
  version = "6.0.1"
 
2255
  {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
2256
  ]
2257
 
2258
+ [[package]]
2259
+ name = "pyzmq"
2260
+ version = "25.1.2"
2261
+ description = "Python bindings for 0MQ"
2262
+ optional = false
2263
+ python-versions = ">=3.6"
2264
+ files = [
2265
+ {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4"},
2266
+ {file = "pyzmq-25.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0"},
2267
+ {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e"},
2268
+ {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872"},
2269
+ {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d"},
2270
+ {file = "pyzmq-25.1.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75"},
2271
+ {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6"},
2272
+ {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979"},
2273
+ {file = "pyzmq-25.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08"},
2274
+ {file = "pyzmq-25.1.2-cp310-cp310-win32.whl", hash = "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886"},
2275
+ {file = "pyzmq-25.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6"},
2276
+ {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c"},
2277
+ {file = "pyzmq-25.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1"},
2278
+ {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348"},
2279
+ {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642"},
2280
+ {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840"},
2281
+ {file = "pyzmq-25.1.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d"},
2282
+ {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b"},
2283
+ {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b"},
2284
+ {file = "pyzmq-25.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3"},
2285
+ {file = "pyzmq-25.1.2-cp311-cp311-win32.whl", hash = "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097"},
2286
+ {file = "pyzmq-25.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9"},
2287
+ {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a"},
2288
+ {file = "pyzmq-25.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e"},
2289
+ {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27"},
2290
+ {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30"},
2291
+ {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee"},
2292
+ {file = "pyzmq-25.1.2-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537"},
2293
+ {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181"},
2294
+ {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe"},
2295
+ {file = "pyzmq-25.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737"},
2296
+ {file = "pyzmq-25.1.2-cp312-cp312-win32.whl", hash = "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d"},
2297
+ {file = "pyzmq-25.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7"},
2298
+ {file = "pyzmq-25.1.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7b6d09a8962a91151f0976008eb7b29b433a560fde056ec7a3db9ec8f1075438"},
2299
+ {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967668420f36878a3c9ecb5ab33c9d0ff8d054f9c0233d995a6d25b0e95e1b6b"},
2300
+ {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5edac3f57c7ddaacdb4d40f6ef2f9e299471fc38d112f4bc6d60ab9365445fb0"},
2301
+ {file = "pyzmq-25.1.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0dabfb10ef897f3b7e101cacba1437bd3a5032ee667b7ead32bbcdd1a8422fe7"},
2302
+ {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2c6441e0398c2baacfe5ba30c937d274cfc2dc5b55e82e3749e333aabffde561"},
2303
+ {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:16b726c1f6c2e7625706549f9dbe9b06004dfbec30dbed4bf50cbdfc73e5b32a"},
2304
+ {file = "pyzmq-25.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a86c2dd76ef71a773e70551a07318b8e52379f58dafa7ae1e0a4be78efd1ff16"},
2305
+ {file = "pyzmq-25.1.2-cp36-cp36m-win32.whl", hash = "sha256:359f7f74b5d3c65dae137f33eb2bcfa7ad9ebefd1cab85c935f063f1dbb245cc"},
2306
+ {file = "pyzmq-25.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:55875492f820d0eb3417b51d96fea549cde77893ae3790fd25491c5754ea2f68"},
2307
+ {file = "pyzmq-25.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8c8a419dfb02e91b453615c69568442e897aaf77561ee0064d789705ff37a92"},
2308
+ {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8807c87fa893527ae8a524c15fc505d9950d5e856f03dae5921b5e9aa3b8783b"},
2309
+ {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5e319ed7d6b8f5fad9b76daa0a68497bc6f129858ad956331a5835785761e003"},
2310
+ {file = "pyzmq-25.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3c53687dde4d9d473c587ae80cc328e5b102b517447456184b485587ebd18b62"},
2311
+ {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9add2e5b33d2cd765ad96d5eb734a5e795a0755f7fc49aa04f76d7ddda73fd70"},
2312
+ {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e690145a8c0c273c28d3b89d6fb32c45e0d9605b2293c10e650265bf5c11cfec"},
2313
+ {file = "pyzmq-25.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00a06faa7165634f0cac1abb27e54d7a0b3b44eb9994530b8ec73cf52e15353b"},
2314
+ {file = "pyzmq-25.1.2-cp37-cp37m-win32.whl", hash = "sha256:0f97bc2f1f13cb16905a5f3e1fbdf100e712d841482b2237484360f8bc4cb3d7"},
2315
+ {file = "pyzmq-25.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6cc0020b74b2e410287e5942e1e10886ff81ac77789eb20bec13f7ae681f0fdd"},
2316
+ {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:bef02cfcbded83473bdd86dd8d3729cd82b2e569b75844fb4ea08fee3c26ae41"},
2317
+ {file = "pyzmq-25.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e10a4b5a4b1192d74853cc71a5e9fd022594573926c2a3a4802020360aa719d8"},
2318
+ {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8c5f80e578427d4695adac6fdf4370c14a2feafdc8cb35549c219b90652536ae"},
2319
+ {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5dde6751e857910c1339890f3524de74007958557593b9e7e8c5f01cd919f8a7"},
2320
+ {file = "pyzmq-25.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea1608dd169da230a0ad602d5b1ebd39807ac96cae1845c3ceed39af08a5c6df"},
2321
+ {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0f513130c4c361201da9bc69df25a086487250e16b5571ead521b31ff6b02220"},
2322
+ {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:019744b99da30330798bb37df33549d59d380c78e516e3bab9c9b84f87a9592f"},
2323
+ {file = "pyzmq-25.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2e2713ef44be5d52dd8b8e2023d706bf66cb22072e97fc71b168e01d25192755"},
2324
+ {file = "pyzmq-25.1.2-cp38-cp38-win32.whl", hash = "sha256:07cd61a20a535524906595e09344505a9bd46f1da7a07e504b315d41cd42eb07"},
2325
+ {file = "pyzmq-25.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb7e49a17fb8c77d3119d41a4523e432eb0c6932187c37deb6fbb00cc3028088"},
2326
+ {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:94504ff66f278ab4b7e03e4cba7e7e400cb73bfa9d3d71f58d8972a8dc67e7a6"},
2327
+ {file = "pyzmq-25.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6dd0d50bbf9dca1d0bdea219ae6b40f713a3fb477c06ca3714f208fd69e16fd8"},
2328
+ {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:004ff469d21e86f0ef0369717351073e0e577428e514c47c8480770d5e24a565"},
2329
+ {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c0b5ca88a8928147b7b1e2dfa09f3b6c256bc1135a1338536cbc9ea13d3b7add"},
2330
+ {file = "pyzmq-25.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9a79f1d2495b167119d02be7448bfba57fad2a4207c4f68abc0bab4b92925b"},
2331
+ {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:518efd91c3d8ac9f9b4f7dd0e2b7b8bf1a4fe82a308009016b07eaa48681af82"},
2332
+ {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1ec23bd7b3a893ae676d0e54ad47d18064e6c5ae1fadc2f195143fb27373f7f6"},
2333
+ {file = "pyzmq-25.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db36c27baed588a5a8346b971477b718fdc66cf5b80cbfbd914b4d6d355e44e2"},
2334
+ {file = "pyzmq-25.1.2-cp39-cp39-win32.whl", hash = "sha256:39b1067f13aba39d794a24761e385e2eddc26295826530a8c7b6c6c341584289"},
2335
+ {file = "pyzmq-25.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:8e9f3fabc445d0ce320ea2c59a75fe3ea591fdbdeebec5db6de530dd4b09412e"},
2336
+ {file = "pyzmq-25.1.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05"},
2337
+ {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8"},
2338
+ {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e"},
2339
+ {file = "pyzmq-25.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4"},
2340
+ {file = "pyzmq-25.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d"},
2341
+ {file = "pyzmq-25.1.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:df0c7a16ebb94452d2909b9a7b3337940e9a87a824c4fc1c7c36bb4404cb0cde"},
2342
+ {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:45999e7f7ed5c390f2e87ece7f6c56bf979fb213550229e711e45ecc7d42ccb8"},
2343
+ {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ac170e9e048b40c605358667aca3d94e98f604a18c44bdb4c102e67070f3ac9b"},
2344
+ {file = "pyzmq-25.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b604734bec94f05f81b360a272fc824334267426ae9905ff32dc2be433ab96"},
2345
+ {file = "pyzmq-25.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a793ac733e3d895d96f865f1806f160696422554e46d30105807fdc9841b9f7d"},
2346
+ {file = "pyzmq-25.1.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0806175f2ae5ad4b835ecd87f5f85583316b69f17e97786f7443baaf54b9bb98"},
2347
+ {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ef12e259e7bc317c7597d4f6ef59b97b913e162d83b421dd0db3d6410f17a244"},
2348
+ {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea253b368eb41116011add00f8d5726762320b1bda892f744c91997b65754d73"},
2349
+ {file = "pyzmq-25.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b9b1f2ad6498445a941d9a4fee096d387fee436e45cc660e72e768d3d8ee611"},
2350
+ {file = "pyzmq-25.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8b14c75979ce932c53b79976a395cb2a8cd3aaf14aef75e8c2cb55a330b9b49d"},
2351
+ {file = "pyzmq-25.1.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:889370d5174a741a62566c003ee8ddba4b04c3f09a97b8000092b7ca83ec9c49"},
2352
+ {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a18fff090441a40ffda8a7f4f18f03dc56ae73f148f1832e109f9bffa85df15"},
2353
+ {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a6b36f95c98839ad98f8c553d8507644c880cf1e0a57fe5e3a3f3969040882"},
2354
+ {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4345c9a27f4310afbb9c01750e9461ff33d6fb74cd2456b107525bbeebcb5be3"},
2355
+ {file = "pyzmq-25.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3516e0b6224cf6e43e341d56da15fd33bdc37fa0c06af4f029f7d7dfceceabbc"},
2356
+ {file = "pyzmq-25.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:146b9b1f29ead41255387fb07be56dc29639262c0f7344f570eecdcd8d683314"},
2357
+ {file = "pyzmq-25.1.2.tar.gz", hash = "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226"},
2358
+ ]
2359
+
2360
+ [package.dependencies]
2361
+ cffi = {version = "*", markers = "implementation_name == \"pypy\""}
2362
+
2363
  [[package]]
2364
  name = "referencing"
2365
  version = "0.34.0"
 
2610
  {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
2611
  ]
2612
 
2613
+ [[package]]
2614
+ name = "stack-data"
2615
+ version = "0.6.3"
2616
+ description = "Extract data from python stack frames and tracebacks for informative displays"
2617
+ optional = false
2618
+ python-versions = "*"
2619
+ files = [
2620
+ {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
2621
+ {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
2622
+ ]
2623
+
2624
+ [package.dependencies]
2625
+ asttokens = ">=2.1.0"
2626
+ executing = ">=1.2.0"
2627
+ pure-eval = "*"
2628
+
2629
+ [package.extras]
2630
+ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
2631
+
2632
  [[package]]
2633
  name = "starlette"
2634
  version = "0.37.2"
 
2668
  {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"},
2669
  ]
2670
 
2671
+ [[package]]
2672
+ name = "tornado"
2673
+ version = "6.4"
2674
+ description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
2675
+ optional = false
2676
+ python-versions = ">= 3.8"
2677
+ files = [
2678
+ {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"},
2679
+ {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"},
2680
+ {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"},
2681
+ {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"},
2682
+ {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"},
2683
+ {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"},
2684
+ {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"},
2685
+ {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"},
2686
+ {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"},
2687
+ {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"},
2688
+ {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"},
2689
+ ]
2690
+
2691
  [[package]]
2692
  name = "tqdm"
2693
  version = "4.66.2"
 
2708
  slack = ["slack-sdk"]
2709
  telegram = ["requests"]
2710
 
2711
+ [[package]]
2712
+ name = "traitlets"
2713
+ version = "5.14.2"
2714
+ description = "Traitlets Python configuration system"
2715
+ optional = false
2716
+ python-versions = ">=3.8"
2717
+ files = [
2718
+ {file = "traitlets-5.14.2-py3-none-any.whl", hash = "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80"},
2719
+ {file = "traitlets-5.14.2.tar.gz", hash = "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9"},
2720
+ ]
2721
+
2722
+ [package.extras]
2723
+ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"]
2724
+ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.1)", "pytest-mock", "pytest-mypy-testing"]
2725
+
2726
  [[package]]
2727
  name = "typer"
2728
  version = "0.12.0"
 
2831
  [package.extras]
2832
  standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
2833
 
2834
+ [[package]]
2835
+ name = "wcwidth"
2836
+ version = "0.2.13"
2837
+ description = "Measures the displayed width of unicode strings in a terminal"
2838
+ optional = false
2839
+ python-versions = "*"
2840
+ files = [
2841
+ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
2842
+ {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
2843
+ ]
2844
+
2845
  [[package]]
2846
  name = "websockets"
2847
  version = "11.0.3"
 
2921
  {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"},
2922
  ]
2923
 
2924
+ [[package]]
2925
+ name = "widgetsnbextension"
2926
+ version = "4.0.10"
2927
+ description = "Jupyter interactive widgets for Jupyter Notebook"
2928
+ optional = false
2929
+ python-versions = ">=3.7"
2930
+ files = [
2931
+ {file = "widgetsnbextension-4.0.10-py3-none-any.whl", hash = "sha256:d37c3724ec32d8c48400a435ecfa7d3e259995201fbefa37163124a9fcb393cc"},
2932
+ {file = "widgetsnbextension-4.0.10.tar.gz", hash = "sha256:64196c5ff3b9a9183a8e699a4227fb0b7002f252c814098e66c4d1cd0644688f"},
2933
+ ]
2934
+
2935
  [metadata]
2936
  lock-version = "2.0"
2937
  python-versions = "^3.10"
2938
+ content-hash = "bbc41496378ec896b141e16fd2a42500c0d72f6911f3e9f1c451fc2e17570aca"
pyproject.toml CHANGED
@@ -13,6 +13,8 @@ google-generativeai = "^0.4.1"
13
 
14
  [tool.poetry.group.dev.dependencies]
15
  python-dotenv = "^1.0.1"
 
 
16
 
17
  [build-system]
18
  requires = ["poetry-core"]
 
13
 
14
  [tool.poetry.group.dev.dependencies]
15
  python-dotenv = "^1.0.1"
16
+ ipykernel = "^6.29.4"
17
+ ipywidgets = "^8.1.2"
18
 
19
  [build-system]
20
  requires = ["poetry-core"]
review.py ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import re
4
+ from functools import cache
5
+
6
+ import google.generativeai as genai
7
+
8
+ try:
9
+ from dotenv import load_dotenv
10
+
11
+ load_dotenv()
12
+ except:
13
+ pass
14
+
15
+ generation_config = {
16
+ "temperature": 0.9, # Temperature of the sampling distribution
17
+ "top_p": 1, # Probability of sampling from the top p tokens
18
+ "top_k": 1, # Number of top tokens to sample from
19
+ "max_output_tokens": 2048,
20
+ }
21
+
22
+ safety_settings = [
23
+ {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
24
+ {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
25
+ {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
26
+ {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_ONLY_HIGH"},
27
+ ]
28
+
29
+
30
+ gemini_1_0 = genai.GenerativeModel(
31
+ model_name="gemini-1.0-pro",
32
+ generation_config=generation_config,
33
+ safety_settings=safety_settings,
34
+ )
35
+ gemini_1_5 = genai.GenerativeModel(
36
+ model_name="gemini-1.5-pro-latest",
37
+ generation_config=generation_config,
38
+ safety_settings=safety_settings,
39
+ )
40
+ gemini_1_0_vision = genai.GenerativeModel(
41
+ "gemini-pro-vision",
42
+ generation_config=generation_config,
43
+ safety_settings=safety_settings,
44
+ )
45
+
46
+
47
+ genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
48
+
49
+ @cache
50
+ def get_file(relative_path: str) -> str:
51
+ current_path = os.path.dirname(os.path.abspath(__file__))
52
+ full_path = os.path.join(current_path, relative_path)
53
+ with open(full_path) as f:
54
+ return f.read()
55
+
56
+ def fix_json(json_str: str) -> str:
57
+ template = get_file("templates/prompt_json_fix.txt")
58
+ prompt = template.format(json=json_str)
59
+ response = gemini_1_0.generate_content(prompt).text
60
+ return response.split("```json")[1].split("```")[0]
61
+
62
+
63
+ def get_json_content(response: str) -> dict:
64
+ if "```json" not in response:
65
+ return []
66
+ raw_json = response.split("```json")[1].split("```")[0]
67
+ try:
68
+ return json.loads(raw_json)
69
+ except json.JSONDecodeError as e:
70
+ print(e)
71
+ new_json = fix_json(raw_json)
72
+ print(new_json)
73
+ return json.loads(new_json)
74
+
75
+
76
+ def html_title(title: str) -> str:
77
+ return f"<h1>{title}</h1>"
78
+
79
+
80
+ def apply_review(text: str, review: list[dict]) -> str:
81
+ output = ""
82
+ review = sorted(review, key=lambda x: x["start_char"])
83
+ last_end = 0
84
+ for entity in review:
85
+ starts = [
86
+ m.start() + last_end
87
+ for m in re.finditer(entity["term"].lower(), text[last_end:].lower())
88
+ ]
89
+ if len(starts) > 0:
90
+ start = starts[0]
91
+ end = start + len(entity["term"])
92
+ output += text[last_end:start]
93
+ output += get_file("templates/correction.html").format(
94
+ term=text[start:end], fix=entity["fix"], kind=entity["type"]
95
+ )
96
+ last_end = end
97
+ output += text[last_end:]
98
+ return f"<pre style='white-space: pre-wrap;'>{output}</pre>"
99
+
100
+
101
+ def review_table_summary(review: list[dict]) -> str:
102
+ table = "<table><tr><th>Term</th><th>Fix</th><th>Type</th><th>Reason</th></tr>"
103
+ for entity in review:
104
+ table += f"<tr><td>{entity['term']}</td><td>{entity['fix']}</td><td>{entity['type']}</td><td>{entity.get('reason', '-')}</td></tr>"
105
+ table += "</table>"
106
+ return table
107
+
108
+ def review_text(text: str, text_model: genai.GenerativeModel) -> list[dict]:
109
+ template = get_file("templates/prompt_v1.txt")
110
+ try:
111
+ response = text_model.generate_content(template.format(text=text)).text
112
+ except ValueError as e:
113
+ print(e)
114
+ raise ValueError(
115
+ f"Error while getting answer from the model, make sure the content isn't offensive or dangerous."
116
+ )
117
+ return get_json_content(response)
118
+
119
+ def process_text(model: str, text: str) -> str:
120
+ text_model = gemini_1_0 if model == "Gemini 1.0 Pro" else gemini_1_5
121
+ review = review_text(text, text_model)
122
+ if len(review) == 0:
123
+ return html_title("No issues found in the text 🎉🎉🎉")
124
+ return (
125
+ html_title("Reviewed text")
126
+ + apply_review(text, review)
127
+ + html_title("Explanation")
128
+ + review_table_summary(review)
129
+ )
130
+
131
+
132
+ def review_image(image, vision_model: genai.GenerativeModel) -> list[dict]:
133
+ prompt = get_file("templates/prompt_image_v1.txt")
134
+ try:
135
+ response = vision_model.generate_content([prompt, image]).text
136
+ except ValueError as e:
137
+ print(e)
138
+ message = f"Error while getting answer from the model, make sure the content isn't offensive or dangerous. Please try again or change the prompt. {str(e)}"
139
+ raise ValueError(message)
140
+ return response
141
+
142
+
143
+ def process_image(model: str, image):
144
+ vision_model = gemini_1_0_vision if model == "Gemini 1.0 Pro Vision" else gemini_1_5
145
+ return review_image(image, vision_model)
static/images/crosses.jpg ADDED

Git LFS Details

  • SHA256: 8a74265b77b787dbabc1e74141f1989d5b162d5936caf0025903f7583f85bfbb
  • Pointer size: 130 Bytes
  • Size of remote file: 59.6 kB
static/images/elephants.jpg ADDED

Git LFS Details

  • SHA256: c5745a3b824a585101d42a2f9d31eda67c63b02bcda3f041dcbc846db9c5b9ea
  • Pointer size: 131 Bytes
  • Size of remote file: 140 kB
static/intro.md CHANGED
@@ -2,4 +2,6 @@
2
 
3
  Use ✅ Write4All to review your content and make sure it is respectful and inclusive. Use the results under taking into account the context and decide if you finally need to make proposed changes.
4
 
5
- > Terms of use: You won't use this app to produce harmful content, promote hate speech, violence, or discrimination. You agree to the terms of use of Gemini API. By using this app, you agree to the terms of use of the models used in this app.
 
 
 
2
 
3
  Use ✅ Write4All to review your content and make sure it is respectful and inclusive. Use the results under taking into account the context and decide if you finally need to make proposed changes.
4
 
5
+ Using `Gemini 1.5 Pro` leads to better results but at the same time the free tier quota will be consumed faster, leading to the `429 Resource has been exhausted (e.g. check quota).` error.
6
+
7
+ > Terms of use: You won't use this app to produce harmful content, promote hate speech, violence, or discrimination. You agree to the terms of use of Gemini API. By using this app, you agree to the terms of use of the models used in this app.