protein-quest 0.10.1__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {protein_quest-0.10.1 → protein_quest-1.0.0}/PKG-INFO +16 -1
  2. protein_quest-1.0.0/docs/faq.md +17 -0
  3. {protein_quest-0.10.1 → protein_quest-1.0.0}/mkdocs.yml +1 -0
  4. {protein_quest-0.10.1 → protein_quest-1.0.0}/pyproject.toml +24 -0
  5. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/__version__.py +1 -1
  6. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/parallel.py +22 -5
  7. protein_quest-1.0.0/tests/test_parallel.py +45 -0
  8. {protein_quest-0.10.1 → protein_quest-1.0.0}/.github/workflows/ci.yml +0 -0
  9. {protein_quest-0.10.1 → protein_quest-1.0.0}/.github/workflows/pages.yml +0 -0
  10. {protein_quest-0.10.1 → protein_quest-1.0.0}/.github/workflows/pypi-publish.yml +0 -0
  11. {protein_quest-0.10.1 → protein_quest-1.0.0}/.gitignore +0 -0
  12. {protein_quest-0.10.1 → protein_quest-1.0.0}/.howfairis.yml +0 -0
  13. {protein_quest-0.10.1 → protein_quest-1.0.0}/.python-version +0 -0
  14. {protein_quest-0.10.1 → protein_quest-1.0.0}/.vscode/extensions.json +0 -0
  15. {protein_quest-0.10.1 → protein_quest-1.0.0}/CITATION.cff +0 -0
  16. {protein_quest-0.10.1 → protein_quest-1.0.0}/CODE_OF_CONDUCT.md +0 -0
  17. {protein_quest-0.10.1 → protein_quest-1.0.0}/CONTRIBUTING.md +0 -0
  18. {protein_quest-0.10.1 → protein_quest-1.0.0}/LICENSE +0 -0
  19. {protein_quest-0.10.1 → protein_quest-1.0.0}/README.md +0 -0
  20. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/CONTRIBUTING.md +0 -0
  21. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/index.md +0 -0
  22. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/notebooks/.gitignore +0 -0
  23. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/notebooks/alphafold.ipynb +0 -0
  24. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/notebooks/index.md +0 -0
  25. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/notebooks/pdbe.ipynb +0 -0
  26. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/notebooks/uniprot.ipynb +0 -0
  27. {protein_quest-0.10.1 → protein_quest-1.0.0}/docs/protein-quest-mcp.png +0 -0
  28. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/__init__.py +0 -0
  29. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/alphafold/__init__.py +0 -0
  30. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/alphafold/confidence.py +0 -0
  31. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/alphafold/entry_summary.py +0 -0
  32. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/alphafold/fetch.py +0 -0
  33. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/cli.py +0 -0
  34. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/converter.py +0 -0
  35. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/emdb.py +0 -0
  36. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/filters.py +0 -0
  37. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/go.py +0 -0
  38. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/io.py +0 -0
  39. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/mcp_server.py +0 -0
  40. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/pdbe/__init__.py +0 -0
  41. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/pdbe/fetch.py +0 -0
  42. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/py.typed +0 -0
  43. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/ss.py +0 -0
  44. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/structure.py +0 -0
  45. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/taxonomy.py +0 -0
  46. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/uniprot.py +0 -0
  47. {protein_quest-0.10.1 → protein_quest-1.0.0}/src/protein_quest/utils.py +0 -0
  48. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/AF-A1YPR0-F1-model_v4.pdb +0 -0
  49. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/cassettes/test_fetch/test_fetch_alphafold_db_version.yaml +0 -0
  50. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/cassettes/test_fetch/test_fetch_many.yaml +0 -0
  51. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/cassettes/test_fetch/test_fetch_many_all_isoforms.yaml +0 -0
  52. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/cassettes/test_fetch/test_fetch_many_gzipped.yaml +0 -0
  53. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/cassettes/test_fetch/test_fetch_many_no_summary.yaml +0 -0
  54. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/cassettes/test_fetch/test_fetch_many_no_summary_with_version.yaml +0 -0
  55. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/test_confidence.py +0 -0
  56. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/test_entry_summary.py +0 -0
  57. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/alphafold/test_fetch.py +0 -0
  58. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_cli/test_search_alphafold.yaml +0 -0
  59. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_cli/test_search_pdbe.yaml +0 -0
  60. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_cli/test_search_uniprot.yaml +0 -0
  61. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_cli/test_search_uniprot_details.yaml +0 -0
  62. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_emdb/test_fetch.yaml +0 -0
  63. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_go/test_search_gene_ontology_term.yaml +0 -0
  64. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_taxonomy/test_search_taxon.yaml +0 -0
  65. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_taxonomy/test_search_taxon_by_id.yaml +0 -0
  66. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/TestSearch4AfExternalIsoforms.test_do_not_match_external_isoform.yaml +0 -0
  67. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/TestSearch4AfExternalIsoforms.test_match_canonical_isoform.yaml +0 -0
  68. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_map_uniprot_accessions2uniprot_details.yaml +0 -0
  69. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4af.yaml +0 -0
  70. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4af_ok_sequence_length.yaml +0 -0
  71. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4af_too_big_sequence_length.yaml +0 -0
  72. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4af_too_small_sequence_length.yaml +0 -0
  73. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4emdb.yaml +0 -0
  74. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4interaction_partners.yaml +0 -0
  75. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4macromolecular_complexes.yaml +0 -0
  76. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4pdb.yaml +0 -0
  77. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/cassettes/test_uniprot/test_search4uniprot.yaml +0 -0
  78. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/conftest.py +0 -0
  79. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/fixtures/2Y29.cif.gz +0 -0
  80. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/fixtures/3JRS_B2A.cif.gz +0 -0
  81. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/pdbe/cassettes/test_fetch/test_fetch.yaml +0 -0
  82. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/pdbe/test_fetch.py +0 -0
  83. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_cli.py +0 -0
  84. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_converter.py +0 -0
  85. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_emdb.py +0 -0
  86. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_filters.py +0 -0
  87. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_go.py +0 -0
  88. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_io.py +0 -0
  89. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_mcp.py +0 -0
  90. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_ss.py +0 -0
  91. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_structure.py +0 -0
  92. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_taxonomy.py +0 -0
  93. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_uniprot.py +0 -0
  94. {protein_quest-0.10.1 → protein_quest-1.0.0}/tests/test_utils.py +0 -0
  95. {protein_quest-0.10.1 → protein_quest-1.0.0}/uv.lock +0 -0
@@ -1,12 +1,27 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: protein_quest
3
- Version: 0.10.1
3
+ Version: 1.0.0
4
4
  Summary: Search/retrieve/filter proteins and protein structures
5
5
  Project-URL: Homepage, https://github.com/haddocking/protein-quest
6
6
  Project-URL: Issues, https://github.com/haddocking/protein-quest/issues
7
7
  Project-URL: Documentation, https://www.bonvinlab.org/protein-quest/
8
8
  Project-URL: Source, https://github.com/haddocking/protein-quest
9
9
  License-File: LICENSE
10
+ Keywords: alphafold,mmcif,pdb,protein,protein structure,uniprot
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: Framework :: AsyncIO
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Natural Language :: English
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: POSIX
19
+ Classifier: Operating System :: POSIX :: Linux
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
23
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
24
+ Classifier: Typing :: Typed
10
25
  Requires-Python: >=3.13
11
26
  Requires-Dist: aiofiles>=24.1.0
12
27
  Requires-Dist: aiohttp-retry>=2.9.1
@@ -0,0 +1,17 @@
1
+ # Frequently Asked Questions (FAQ)
2
+
3
+ ## My search is taking a long time. What can I do?
4
+
5
+ Most likely your search is returning a lot of results.
6
+ The search commands have several options to reduce the number of results returned, such as `--limit`.
7
+
8
+ ## My log is polluted with progress bar lines. How can I fix this?
9
+
10
+ To reduce the number of lines printed by the progress bar, you can increase the minimum interval between updates with the `TQDM_MININTERVAL` environment variable.
11
+ For example, setting it to `9` will update the progress bar every 9 seconds instead of every 0.1 seconds.
12
+
13
+ To not have any progress bars at all, you can set `TQDM_DISABLE` environment variable to any value.
14
+
15
+ ## My protein-quest question is not answered here. Where can I get help?
16
+
17
+ Please see the [Contributing](CONTRIBUTING.md#you-have-a-question) document for instructions on how to ask questions and report issues.
@@ -76,6 +76,7 @@ markdown_extensions:
76
76
  nav:
77
77
  - Home: index.md
78
78
  - CLI Reference: cli.md
79
+ - FAQ: faq.md
79
80
  - Notebooks:
80
81
  - notebooks/index.md
81
82
  - Search uniprot: notebooks/uniprot.ipynb
@@ -4,6 +4,30 @@ dynamic = ["version"]
4
4
  description = "Search/retrieve/filter proteins and protein structures"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
7
+ keywords = [
8
+ "alphafold",
9
+ "mmcif",
10
+ "pdb",
11
+ "protein structure",
12
+ "protein",
13
+ "uniprot",
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 5 - Production/Stable",
17
+ "Environment :: Console",
18
+ "Framework :: AsyncIO",
19
+ "Intended Audience :: Science/Research",
20
+ "License :: OSI Approved :: Apache Software License",
21
+ "Natural Language :: English",
22
+ "Operating System :: MacOS",
23
+ "Operating System :: POSIX :: Linux",
24
+ "Operating System :: POSIX",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Programming Language :: Python :: 3.14",
27
+ "Topic :: Scientific/Engineering :: Bio-Informatics",
28
+ "Topic :: Scientific/Engineering :: Chemistry",
29
+ "Typing :: Typed",
30
+ ]
7
31
  dependencies = [
8
32
  "aiofiles>=24.1.0",
9
33
  "aiohttp[speedups]>=3.11.18",
@@ -1,2 +1,2 @@
1
- __version__ = "0.10.1"
1
+ __version__ = "1.0.0"
2
2
  """The version of the package."""
@@ -86,12 +86,15 @@ def _configure_cpu_dask_scheduler(nproc: int, name: str) -> LocalCluster:
86
86
  return LocalCluster(name=name, threads_per_worker=1, n_workers=n_workers)
87
87
 
88
88
 
89
- # Generic type parameters used across helpers
90
- P = ParamSpec("P")
89
+ class MyProgressBar(ProgressBar):
90
+ """Show progress of Dask computations.
91
91
 
92
+ Copy of distributed.diagnostics.progressbar.TextProgressBar that:
92
93
 
93
- class _StderrTextProgressBar(ProgressBar):
94
- """Copy of distributed.diagnostics.progressbar.TextProgressBar that prints to stderr instead of stdout."""
94
+ - prints to stderr instead of stdout
95
+ - Can have its interval (in seconds) set with `TQDM_MININTERVAL` environment variable
96
+
97
+ """
95
98
 
96
99
  __loop: IOLoop | None = None
97
100
 
@@ -107,6 +110,11 @@ class _StderrTextProgressBar(ProgressBar):
107
110
  **kwargs, # noqa: ARG002
108
111
  ):
109
112
  self._loop_runner = loop_runner = LoopRunner(loop=loop)
113
+ if interval == "100ms":
114
+ interval_env = os.getenv("TQDM_MININTERVAL")
115
+ if interval_env is not None:
116
+ interval = interval_env + "s"
117
+
110
118
  super().__init__(keys, scheduler, interval, complete)
111
119
  self.width = width
112
120
 
@@ -144,6 +152,10 @@ class _StderrTextProgressBar(ProgressBar):
144
152
  sys.stderr.flush()
145
153
 
146
154
 
155
+ # Generic type parameters used across helpers
156
+ P = ParamSpec("P")
157
+
158
+
147
159
  def dask_map_with_progress[T, R, **P](
148
160
  client: Client,
149
161
  func: Callable[Concatenate[T, P], R],
@@ -154,6 +166,10 @@ def dask_map_with_progress[T, R, **P](
154
166
  """
155
167
  Wrapper for map, progress, and gather of Dask that returns a correctly typed list.
156
168
 
169
+ Environment variables:
170
+ - Set interval (in seconds) of progress updates with `TQDM_MININTERVAL`
171
+ - Disabled by setting `TQDM_DISABLE` to any value
172
+
157
173
  Args:
158
174
  client: Dask client.
159
175
  func: Function to map; first parameter comes from ``iterable`` and any
@@ -169,6 +185,7 @@ def dask_map_with_progress[T, R, **P](
169
185
  if client.dashboard_link:
170
186
  logger.info(f"Follow progress on dask dashboard at: {client.dashboard_link}")
171
187
  futures = client.map(func, iterable, *args, **kwargs)
172
- _StderrTextProgressBar(futures)
188
+ if not os.getenv("TQDM_DISABLE"):
189
+ MyProgressBar(futures)
173
190
  results = client.gather(futures)
174
191
  return cast("list[R]", results)
@@ -0,0 +1,45 @@
1
+ import pytest
2
+ from distributed import Client
3
+
4
+ from protein_quest.parallel import MyProgressBar, dask_map_with_progress
5
+
6
+
7
+ def test_MyProgressBar_interval_env(monkeypatch):
8
+ monkeypatch.setenv("TQDM_MININTERVAL", "1234")
9
+
10
+ with Client():
11
+ progress_bar = MyProgressBar([])
12
+ assert progress_bar.interval == 1234
13
+
14
+
15
+ def run_dask_map_with_progress():
16
+ def square(x: int) -> int:
17
+ return x**2
18
+
19
+ with Client() as client:
20
+ result = dask_map_with_progress(
21
+ client,
22
+ square,
23
+ range(5),
24
+ )
25
+ assert result == [0, 1, 4, 9, 16]
26
+
27
+
28
+ def test_dask_map_with_progress(capsys: pytest.CaptureFixture, caplog: pytest.LogCaptureFixture):
29
+ caplog.set_level("INFO")
30
+
31
+ run_dask_map_with_progress()
32
+
33
+ captured = capsys.readouterr()
34
+ assert "Completed" in captured.err
35
+
36
+ assert "Follow progress on dask dashboard at" in caplog.text
37
+
38
+
39
+ def test_dask_map_with_progress_disabled(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture):
40
+ monkeypatch.setenv("TQDM_DISABLE", "1")
41
+
42
+ run_dask_map_with_progress()
43
+
44
+ captured = capsys.readouterr()
45
+ assert "Completed" not in captured.err
File without changes
File without changes
File without changes
File without changes