1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchPypi,
6 pythonOlder,
7 writeShellScriptBin,
8 gradio,
9
10 # pyproject
11 hatchling,
12 hatch-requirements-txt,
13 hatch-fancy-pypi-readme,
14
15 # runtime
16 setuptools,
17 aiofiles,
18 altair,
19 diffusers,
20 fastapi,
21 ffmpy,
22 gradio-client,
23 httpx,
24 huggingface-hub,
25 importlib-resources,
26 jinja2,
27 markupsafe,
28 matplotlib,
29 numpy,
30 orjson,
31 packaging,
32 pandas,
33 pillow,
34 pydantic,
35 python-multipart,
36 pydub,
37 pyyaml,
38 semantic-version,
39 typing-extensions,
40 uvicorn,
41 typer,
42 tomlkit,
43
44 # oauth
45 authlib,
46 itsdangerous,
47
48 # check
49 pytestCheckHook,
50 boto3,
51 gradio-pdf,
52 ffmpeg,
53 ipython,
54 pytest-asyncio,
55 respx,
56 scikit-image,
57 torch,
58 tqdm,
59 transformers,
60 vega-datasets,
61}:
62
63buildPythonPackage rec {
64 pname = "gradio";
65 version = "4.36.1";
66 format = "pyproject";
67
68 disabled = pythonOlder "3.7";
69
70 # We use the Pypi release, since it provides prebuilt webui assets
71 src = fetchPypi {
72 inherit pname version;
73 hash = "sha256-crLSEVbTRnEjuubzD0Y/AC7wbicnZidDCPXtPKw3Vjs=";
74 };
75
76 # fix packaging.ParserSyntaxError, which can't handle comments
77 postPatch = ''
78 sed -ie "s/ #.*$//g" requirements*.txt
79
80 # they bundle deps?
81 rm -rf venv/
82 '';
83
84 pythonRelaxDeps = [ "tomlkit" ];
85
86 pythonRemoveDeps = [
87 # our package is presented as a binary, not a python lib - and
88 # this isn't a real runtime dependency
89 "ruff"
90 ];
91
92 nativeBuildInputs = [
93 hatchling
94 hatch-requirements-txt
95 hatch-fancy-pypi-readme
96 ];
97
98 dependencies = [
99 setuptools # needed for 'pkg_resources'
100 aiofiles
101 altair
102 diffusers
103 fastapi
104 ffmpy
105 gradio-client
106 httpx
107 huggingface-hub
108 importlib-resources
109 jinja2
110 markupsafe
111 matplotlib
112 numpy
113 orjson
114 packaging
115 pandas
116 pillow
117 pydantic
118 python-multipart
119 pydub
120 pyyaml
121 semantic-version
122 typing-extensions
123 uvicorn
124 typer
125 tomlkit
126 ];
127
128 passthru.optional-dependencies.oauth = [
129 authlib
130 itsdangerous
131 ];
132
133 nativeCheckInputs = [
134 pytestCheckHook
135 boto3
136 gradio-pdf
137 ffmpeg
138 ipython
139 pytest-asyncio
140 respx
141 scikit-image
142 # shap is needed as well, but breaks too often
143 torch
144 tqdm
145 transformers
146 vega-datasets
147
148 # mock calls to `shutil.which(...)`
149 (writeShellScriptBin "npm" "false")
150 ] ++ passthru.optional-dependencies.oauth ++ pydantic.passthru.optional-dependencies.email;
151
152 # Add a pytest hook skipping tests that access network, marking them as "Expected fail" (xfail).
153 # We additionally xfail FileNotFoundError, since the gradio devs often fail to upload test assets to pypi.
154 preCheck =
155 ''
156 export HOME=$TMPDIR
157 cat ${./conftest-skip-network-errors.py} >> test/conftest.py
158 ''
159 + lib.optionalString stdenv.isDarwin ''
160 # OSError: [Errno 24] Too many open files
161 ulimit -n 4096
162 '';
163
164 disabledTests = [
165 # Actually broken
166 "test_mount_gradio_app"
167
168 # requires network, it caught our xfail exception
169 "test_error_analytics_successful"
170
171 # Flaky, tries to pin dependency behaviour. Sensitive to dep versions
172 # These error only affect downstream use of the check dependencies.
173 "test_no_color"
174 "test_in_interface_as_output"
175 "test_should_warn_url_not_having_version"
176
177 # Flaky, unknown reason
178 "test_in_interface"
179
180 # shap is too often broken in nixpkgs
181 "test_shapley_text"
182
183 # fails without network
184 "test_download_if_url_correct_parse"
185
186 # tests if pip and other tools are installed
187 "test_get_executable_path"
188 ] ++ lib.optionals stdenv.isDarwin [
189 # flaky on darwin (depend on port availability)
190 "test_all_status_messages"
191 "test_async_generators"
192 "test_async_generators_interface"
193 "test_async_iterator_update_with_new_component"
194 "test_concurrency_limits"
195 "test_default_concurrency_limits"
196 "test_default_flagging_callback"
197 "test_end_to_end"
198 "test_end_to_end_cache_examples"
199 "test_event_data"
200 "test_every_does_not_block_queue"
201 "test_example_caching_relaunch"
202 "test_example_caching_relaunch"
203 "test_exit_called_at_launch"
204 "test_file_component_uploads"
205 "test_files_saved_as_file_paths"
206 "test_flagging_does_not_create_unnecessary_directories"
207 "test_flagging_no_permission_error_with_flagging_disabled"
208 "test_info_and_warning_alerts"
209 "test_info_isolation"
210 "test_launch_analytics_does_not_error_with_invalid_blocks"
211 "test_no_empty_audio_files"
212 "test_no_empty_image_files"
213 "test_no_empty_video_files"
214 "test_non_streaming_api"
215 "test_non_streaming_api_async"
216 "test_pil_images_hashed"
217 "test_progress_bar"
218 "test_progress_bar_track_tqdm"
219 "test_queue_when_using_auth"
220 "test_restart_after_close"
221 "test_set_share_in_colab"
222 "test_show_error"
223 "test_simple_csv_flagging_callback"
224 "test_single_request"
225 "test_socket_reuse"
226 "test_start_server"
227 "test_state_holder_is_used_in_postprocess"
228 "test_state_stored_up_to_capacity"
229 "test_static_files_single_app"
230 "test_streaming_api"
231 "test_streaming_api_async"
232 "test_streaming_api_with_additional_inputs"
233 "test_sync_generators"
234 "test_time_to_live_and_delete_callback_for_state"
235 "test_updates_stored_up_to_capacity"
236 "test_varying_output_forms_with_generators"
237 ];
238 disabledTestPaths = [
239 # 100% touches network
240 "test/test_networking.py"
241 # makes pytest freeze 50% of the time
242 "test/test_interfaces.py"
243 ] ++ lib.optionals stdenv.isDarwin [
244 # Network-related tests that are flaky on darwin (depend on port availability)
245 "test/test_routes.py"
246 ];
247 pytestFlagsArray = [
248 "-x" # abort on first failure
249 "-m 'not flaky'"
250 #"-W" "ignore" # uncomment for debugging help
251 ];
252
253 # check the binary works outside the build env
254 doInstallCheck = true;
255 postInstallCheck = ''
256 env --ignore-environment $out/bin/gradio environment >/dev/null
257 '';
258
259 pythonImportsCheck = [ "gradio" ];
260
261 # Cyclic dependencies are fun!
262 # This is gradio without gradio-client and gradio-pdf
263 passthru.sans-reverse-dependencies =
264 (gradio.override (old: {
265 gradio-client = null;
266 gradio-pdf = null;
267 })).overridePythonAttrs
268 (old: {
269 pname = old.pname + "-sans-reverse-dependencies";
270 pythonRemoveDeps = (old.pythonRemoveDeps or [ ]) ++ [ "gradio-client" ];
271 doInstallCheck = false;
272 doCheck = false;
273 pythonImportsCheck = null;
274 dontCheckRuntimeDeps = true;
275 });
276
277 meta = with lib; {
278 homepage = "https://www.gradio.app/";
279 description = "Python library for easily interacting with trained machine learning models";
280 license = licenses.asl20;
281 maintainers = with maintainers; [ pbsds ];
282 };
283}