dexscreen 0.0.1__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 (74) hide show
  1. dexscreen-0.0.1/.gitattributes +2 -0
  2. dexscreen-0.0.1/.github/workflows/ci.yml +39 -0
  3. dexscreen-0.0.1/.github/workflows/release.yml +36 -0
  4. dexscreen-0.0.1/.gitignore +166 -0
  5. dexscreen-0.0.1/.nvmrc +1 -0
  6. dexscreen-0.0.1/.pre-commit-config.yaml +77 -0
  7. dexscreen-0.0.1/.prettierignore +28 -0
  8. dexscreen-0.0.1/.prettierrc.json +15 -0
  9. dexscreen-0.0.1/.yamllint +32 -0
  10. dexscreen-0.0.1/LICENSE +21 -0
  11. dexscreen-0.0.1/PKG-INFO +278 -0
  12. dexscreen-0.0.1/README.md +250 -0
  13. dexscreen-0.0.1/dexscreen/__init__.py +31 -0
  14. dexscreen-0.0.1/dexscreen/api/__init__.py +3 -0
  15. dexscreen-0.0.1/dexscreen/api/client.py +672 -0
  16. dexscreen-0.0.1/dexscreen/config/__init__.py +0 -0
  17. dexscreen-0.0.1/dexscreen/core/__init__.py +27 -0
  18. dexscreen-0.0.1/dexscreen/core/http.py +460 -0
  19. dexscreen-0.0.1/dexscreen/core/models.py +106 -0
  20. dexscreen-0.0.1/dexscreen/stream/__init__.py +3 -0
  21. dexscreen-0.0.1/dexscreen/stream/polling.py +462 -0
  22. dexscreen-0.0.1/dexscreen/utils/__init__.py +4 -0
  23. dexscreen-0.0.1/dexscreen/utils/browser_selector.py +57 -0
  24. dexscreen-0.0.1/dexscreen/utils/filters.py +226 -0
  25. dexscreen-0.0.1/dexscreen/utils/ratelimit.py +65 -0
  26. dexscreen-0.0.1/docs/README.md +38 -0
  27. dexscreen-0.0.1/docs/api/data-models.md +797 -0
  28. dexscreen-0.0.1/docs/api/data-models.zh.md +312 -0
  29. dexscreen-0.0.1/docs/api/filtering.md +446 -0
  30. dexscreen-0.0.1/docs/api/filtering.zh.md +363 -0
  31. dexscreen-0.0.1/docs/api/query-api.md +375 -0
  32. dexscreen-0.0.1/docs/api/query-api.zh.md +372 -0
  33. dexscreen-0.0.1/docs/api/streaming-api.md +587 -0
  34. dexscreen-0.0.1/docs/api/streaming-api.zh.md +503 -0
  35. dexscreen-0.0.1/docs/examples.md +1024 -0
  36. dexscreen-0.0.1/docs/examples.zh.md +1024 -0
  37. dexscreen-0.0.1/docs/getting-started.md +470 -0
  38. dexscreen-0.0.1/docs/getting-started.zh.md +470 -0
  39. dexscreen-0.0.1/docs/index.md +334 -0
  40. dexscreen-0.0.1/docs/index.zh.md +331 -0
  41. dexscreen-0.0.1/examples/01_async_basic_apis.py +107 -0
  42. dexscreen-0.0.1/examples/02_dynamic_config_update.py +150 -0
  43. dexscreen-0.0.1/examples/03_token_address_polling.py +330 -0
  44. dexscreen-0.0.1/examples/04_dynamic_subscription.py +470 -0
  45. dexscreen-0.0.1/justfile +236 -0
  46. dexscreen-0.0.1/mkdocs.yml +114 -0
  47. dexscreen-0.0.1/package.json +13 -0
  48. dexscreen-0.0.1/pnpm-lock.yaml +24 -0
  49. dexscreen-0.0.1/pyproject.toml +127 -0
  50. dexscreen-0.0.1/tests/conftest.py +644 -0
  51. dexscreen-0.0.1/tests/integration/test_api_response_format.py +181 -0
  52. dexscreen-0.0.1/tests/integration/test_examples.py +26 -0
  53. dexscreen-0.0.1/tests/integration/test_pool_endpoint.py +71 -0
  54. dexscreen-0.0.1/tests/integration/test_token_endpoints.py +178 -0
  55. dexscreen-0.0.1/tests/unit/__init__.py +1 -0
  56. dexscreen-0.0.1/tests/unit/api/__init__.py +1 -0
  57. dexscreen-0.0.1/tests/unit/api/test_batch_limits.py +176 -0
  58. dexscreen-0.0.1/tests/unit/api/test_batch_limits_integration.py +112 -0
  59. dexscreen-0.0.1/tests/unit/api/test_client.py +251 -0
  60. dexscreen-0.0.1/tests/unit/core/__init__.py +1 -0
  61. dexscreen-0.0.1/tests/unit/core/test_dynamic_config.py +196 -0
  62. dexscreen-0.0.1/tests/unit/core/test_http.py +206 -0
  63. dexscreen-0.0.1/tests/unit/core/test_models.py +217 -0
  64. dexscreen-0.0.1/tests/unit/core/test_models_simple.py +74 -0
  65. dexscreen-0.0.1/tests/unit/stream/__init__.py +1 -0
  66. dexscreen-0.0.1/tests/unit/stream/test_batch_polling.py +150 -0
  67. dexscreen-0.0.1/tests/unit/stream/test_polling.py +204 -0
  68. dexscreen-0.0.1/tests/unit/utils/__init__.py +1 -0
  69. dexscreen-0.0.1/tests/unit/utils/test_filters.py +231 -0
  70. dexscreen-0.0.1/tests/unit/utils/test_ratelimit.py +136 -0
  71. dexscreen-0.0.1/tests/upstream/test_official_api.py +93 -0
  72. dexscreen-0.0.1/tests/upstream/test_official_api_multi.py +446 -0
  73. dexscreen-0.0.1/tests/upstream/test_official_api_rate.py +260 -0
  74. dexscreen-0.0.1/uv.lock +1436 -0
@@ -0,0 +1,2 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
@@ -0,0 +1,39 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - name: Checkout Repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v3
22
+ with:
23
+ enable-cache: true
24
+ cache-dependency-glob: "pyproject.toml"
25
+
26
+ - name: Set up Python ${{ matrix.python-version }}
27
+ run: uv python install ${{ matrix.python-version }}
28
+
29
+ - name: Install Dependencies
30
+ run: uv sync --all-extras --dev
31
+
32
+ - name: Run Linting
33
+ run: |
34
+ uv run ruff check .
35
+ uv run ruff format --check .
36
+ uv run pyright dexscreen/
37
+
38
+ - name: Run Tests
39
+ run: uv run pytest tests/unit --cov=dexscreen
@@ -0,0 +1,36 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build_and_publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ contents: read
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v3
20
+
21
+ - name: Set up Python
22
+ run: uv python install 3.12
23
+
24
+ - name: Build package
25
+ run: uv build
26
+
27
+ - name: Upload build artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ - name: Publish to PyPI
34
+ uses: pypa/gh-action-pypi-publish@release/v1
35
+ with:
36
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,166 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ #Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Editor directories
114
+ .zed/
115
+
116
+ # Spyder project settings
117
+ .spyderproject
118
+ .spyproject
119
+
120
+ # Rope project settings
121
+ .ropeproject
122
+
123
+ # mkdocs documentation
124
+ /site
125
+
126
+ # mypy
127
+ .mypy_cache/
128
+ .dmypy.json
129
+ dmypy.json
130
+
131
+ # Pyre type checker
132
+ .pyre/
133
+
134
+ # PyCharm
135
+ /.idea
136
+
137
+ # uv
138
+ # uv.lock
139
+
140
+ # VS Code
141
+ .vscode/
142
+
143
+ # zed
144
+ .zed
145
+
146
+ # macOS
147
+ .DS_Store
148
+
149
+ # AI
150
+ .claude
151
+ CLAUDE.md
152
+
153
+ /note
154
+
155
+ # ruff
156
+ .ruff_cache
157
+
158
+ api_test_results.json
159
+ api_multi_test_results.json
160
+
161
+ /logs
162
+
163
+ # Node.js
164
+ node_modules/
165
+ # PyPI credentials
166
+ .pypi
dexscreen-0.0.1/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 22
@@ -0,0 +1,77 @@
1
+ # 精简版 pre-commit 配置 - 使用 ruff 替代大部分功能
2
+ repos:
3
+ # Ruff - Python linter 和 formatter (替代了很多 pre-commit-hooks)
4
+ - repo: local
5
+ hooks:
6
+ - id: ruff-check
7
+ name: ruff check (linting)
8
+ entry: ruff check --fix
9
+ language: system
10
+ types:
11
+ - python
12
+ require_serial: true
13
+ - id: ruff-format
14
+ name: ruff format
15
+ entry: ruff format
16
+ language: system
17
+ types:
18
+ - python
19
+ require_serial: true
20
+
21
+ # Pyright - 类型检查
22
+ - repo: local
23
+ hooks:
24
+ - id: pyright
25
+ name: pyright type check
26
+ entry: pyright
27
+ language: system
28
+ types:
29
+ - python
30
+ pass_filenames: false
31
+ # 只在这些目录运行
32
+ files: ^(dexscreen|tests|examples)/.*\.py$
33
+
34
+ # 只保留 ruff 不能处理的必要检查
35
+ - repo: https://github.com/pre-commit/pre-commit-hooks
36
+ rev: v5.0.0
37
+ hooks:
38
+ - id: check-json
39
+ - id: check-toml
40
+ - id: check-added-large-files
41
+ - id: check-merge-conflict
42
+
43
+ # yamllint 替代 check-yaml,支持自定义标签
44
+ - repo: local
45
+ hooks:
46
+ - id: yamllint
47
+ name: yamllint
48
+ entry: yamllint
49
+ language: system
50
+ types:
51
+ - yaml
52
+ args:
53
+ - -c=.yamllint
54
+
55
+ # yamlfix - YAML formatter
56
+ - repo: local
57
+ hooks:
58
+ - id: yamlfix
59
+ name: yamlfix
60
+ entry: yamlfix
61
+ language: system
62
+ types:
63
+ - yaml
64
+ args:
65
+ - --config-file
66
+ - pyproject.toml
67
+
68
+ # prettier - Markdown formatting
69
+ - repo: local
70
+ hooks:
71
+ - id: prettier
72
+ name: prettier markdown format
73
+ entry: pnpm prettier --write
74
+ language: system
75
+ types:
76
+ - markdown
77
+ require_serial: true
@@ -0,0 +1,28 @@
1
+ # Build artifacts
2
+ htmlcov/
3
+ site/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+
8
+ # Cache directories
9
+ .pytest_cache/
10
+ .ruff_cache/
11
+ .pyright/
12
+ __pycache__/
13
+ node_modules/
14
+ .pnpm-store/
15
+
16
+ # Virtual environments
17
+ .venv/
18
+ venv/
19
+ env/
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/
24
+
25
+ # Other
26
+ *.log
27
+ .coverage
28
+ .DS_Store
@@ -0,0 +1,15 @@
1
+ {
2
+ "printWidth": 120,
3
+ "proseWrap": "always",
4
+ "singleQuote": false,
5
+ "trailingComma": "es5",
6
+ "endOfLine": "lf",
7
+ "overrides": [
8
+ {
9
+ "files": "*.md",
10
+ "options": {
11
+ "proseWrap": "always"
12
+ }
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,32 @@
1
+ extends: default
2
+
3
+ rules:
4
+ line-length:
5
+ max: 120
6
+ level: warning
7
+ truthy:
8
+ allowed-values: ['true', 'false', 'on', 'off']
9
+ document-start:
10
+ present: false # 不强制要求文档开头的 ---
11
+ comments:
12
+ min-spaces-from-content: 1 # 注释前至少1个空格
13
+
14
+ yaml-files:
15
+ - '*.yaml'
16
+ - '*.yml'
17
+
18
+ ignore: |
19
+ .venv/
20
+ site/
21
+ htmlcov/
22
+ .pytest_cache/
23
+ .ruff_cache/
24
+ .pyright/
25
+ .git/
26
+ pnpm-lock.yaml
27
+
28
+ # 允许 Python 标签
29
+ allowed-tags:
30
+ - "tag:yaml.org,2002:python/name:*"
31
+ - "!ENV"
32
+ - "!relative"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 solanab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,278 @@
1
+ Metadata-Version: 2.4
2
+ Name: dexscreen
3
+ Version: 0.0.1
4
+ Summary: Python wrapper for Dexscreener API with stable HTTP support
5
+ Project-URL: Repository, https://github.com/solanab/dexscreen
6
+ Project-URL: Documentation, https://github.com/solanab/dexscreen#readme
7
+ Project-URL: Issues, https://github.com/solanab/dexscreen/issues
8
+ Author-email: solanab <whiredj@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,crypto,cryptocurrency,dexscreener,http
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: curl-cffi>=0.12
25
+ Requires-Dist: orjson>=3.11
26
+ Requires-Dist: pydantic>=2.11
27
+ Description-Content-Type: text/markdown
28
+
29
+ # Dexscreen
30
+
31
+ A stable and reliable Python SDK for [Dexscreener.com](https://dexscreener.com/) API with HTTP support:
32
+
33
+ - **Single Query** - Traditional one-time API calls
34
+ - **Real-time Updates** - Live price updates with configurable intervals
35
+
36
+ [![Downloads](https://pepy.tech/badge/dexscreen)](https://pepy.tech/project/dexscreen)
37
+ [![PyPI version](https://badge.fury.io/py/dexscreen.svg)](https://badge.fury.io/py/dexscreen)
38
+ [![Python Version](https://img.shields.io/pypi/pyversions/dexscreen)](https://pypi.org/project/dexscreen/)
39
+
40
+ ## Features
41
+
42
+ - ✅ Complete official API coverage
43
+ - ✅ Stable HTTP-based streaming
44
+ - ✅ Automatic rate limiting
45
+ - ✅ Browser impersonation for anti-bot bypass (using curl_cffi)
46
+ - ✅ Type-safe with Pydantic models
47
+ - ✅ Async/sync support
48
+ - ✅ Simple, focused interface
49
+
50
+ ## Installation
51
+
52
+ use uv (Recommended)
53
+
54
+ ```bash
55
+ uv add dexscreen
56
+ ```
57
+
58
+ or pip
59
+
60
+ ```bash
61
+ pip install dexscreen
62
+ ```
63
+
64
+ ## Quick Start
65
+
66
+ ### Mode 1: Single Query (Traditional API calls)
67
+
68
+ ```python
69
+ from dexscreen import DexscreenerClient
70
+
71
+ client = DexscreenerClient()
72
+
73
+ # Get a specific pair by token address
74
+ pairs = client.get_pairs_by_token_address("solana", "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN")
75
+ if pairs:
76
+ pair = pairs[0] # Get the first pair
77
+ print(f"{pair.base_token.symbol}: ${pair.price_usd}")
78
+
79
+ # Search for tokens
80
+ results = client.search_pairs("PEPE")
81
+ for pair in results[:5]:
82
+ print(f"{pair.base_token.symbol} on {pair.chain_id}: ${pair.price_usd}")
83
+
84
+ # Get token information
85
+ profiles = client.get_latest_token_profiles()
86
+ boosted = client.get_latest_boosted_tokens()
87
+ ```
88
+
89
+ ### Mode 2: Real-time Updates
90
+
91
+ ```python
92
+ import asyncio
93
+ from dexscreen import DexscreenerClient
94
+
95
+ async def handle_price_update(pair):
96
+ print(f"{pair.base_token.symbol}: ${pair.price_usd} ({pair.price_change.h24:+.2f}%)")
97
+
98
+ async def main():
99
+ client = DexscreenerClient()
100
+
101
+ # Subscribe to pair updates (default interval: 0.2 seconds)
102
+ await client.subscribe_pairs(
103
+ chain_id="solana",
104
+ pair_addresses=["JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"],
105
+ callback=handle_price_update,
106
+ interval=0.2 # Poll 5 times per second (300/min)
107
+ )
108
+
109
+ # Let it run for 30 seconds
110
+ await asyncio.sleep(30)
111
+ await client.close_streams()
112
+
113
+ asyncio.run(main())
114
+ ```
115
+
116
+ ### Filtering Options
117
+
118
+ ```python
119
+ from dexscreen import DexscreenerClient, FilterPresets
120
+
121
+ # Default filtering - only receive updates when data changes
122
+ await client.subscribe_pairs(
123
+ chain_id="solana",
124
+ pair_addresses=["JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"],
125
+ callback=handle_price_update,
126
+ filter=True, # Default value
127
+ interval=0.2
128
+ )
129
+
130
+ # No filtering - receive all polling results
131
+ await client.subscribe_pairs(
132
+ chain_id="ethereum",
133
+ pair_addresses=["0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"],
134
+ callback=handle_price_update,
135
+ filter=False, # Get all updates even if data hasn't changed
136
+ interval=1.0
137
+ )
138
+
139
+ # Advanced filtering - only significant price changes (1%)
140
+ await client.subscribe_pairs(
141
+ chain_id="ethereum",
142
+ pair_addresses=["0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"],
143
+ callback=handle_price_update,
144
+ filter=FilterPresets.significant_price_changes(0.01)
145
+ )
146
+
147
+ # Rate limited updates - max 1 update per second
148
+ await client.subscribe_pairs(
149
+ chain_id="ethereum",
150
+ pair_addresses=["0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"],
151
+ callback=handle_price_update,
152
+ filter=FilterPresets.rate_limited(1.0)
153
+ )
154
+ ```
155
+
156
+ ## Advanced Usage
157
+
158
+ ### Price Monitoring for Arbitrage
159
+
160
+ ```python
161
+ from dexscreen import DexscreenerClient
162
+
163
+ async def monitor_arbitrage():
164
+ client = DexscreenerClient()
165
+
166
+ # Monitor same token on different chains
167
+ pairs = [
168
+ ("ethereum", "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"), # USDC/WETH
169
+ ("bsc", "0x7213a321F1855CF1779f42c0CD85d3D95291D34C"), # USDC/BUSD
170
+ ("polygon", "0x45dDa9cb7c25131DF268515131f647d726f50608"), # USDC/WETH
171
+ ]
172
+
173
+ prices = {}
174
+
175
+ async def track_price(pair):
176
+ key = f"{pair.chain_id}:{pair.base_token.symbol}"
177
+ prices[key] = float(pair.price_usd)
178
+
179
+ # Check for arbitrage opportunity
180
+ if len(prices) > 1:
181
+ min_price = min(prices.values())
182
+ max_price = max(prices.values())
183
+ spread = ((max_price - min_price) / min_price) * 100
184
+
185
+ if spread > 0.5: # 0.5% spread
186
+ print(f"ARBITRAGE: {spread:.2f}% spread detected!")
187
+
188
+ # Subscribe to all pairs
189
+ for chain, address in pairs:
190
+ await client.subscribe_pairs(
191
+ chain_id=chain,
192
+ pair_addresses=[address],
193
+ callback=track_price,
194
+ interval=0.5
195
+ )
196
+
197
+ await asyncio.sleep(60) # Monitor for 1 minute
198
+ ```
199
+
200
+ ### High-Volume Pairs Discovery
201
+
202
+ ```python
203
+ async def find_trending_tokens():
204
+ client = DexscreenerClient()
205
+
206
+ # Search for tokens
207
+ results = await client.search_pairs_async("SOL")
208
+
209
+ # Filter high volume pairs (>$1M daily volume)
210
+ high_volume = [
211
+ p for p in results
212
+ if p.volume.h24 and p.volume.h24 > 1_000_000
213
+ ]
214
+
215
+ # Sort by volume
216
+ high_volume.sort(key=lambda x: x.volume.h24, reverse=True)
217
+
218
+ # Monitor top 5
219
+ for pair in high_volume[:5]:
220
+ print(f"{pair.base_token.symbol}: Vol ${pair.volume.h24/1e6:.2f}M")
221
+
222
+ await client.subscribe_pairs(
223
+ chain_id=pair.chain_id,
224
+ pair_addresses=[pair.pair_address],
225
+ callback=handle_price_update,
226
+ interval=2.0
227
+ )
228
+ ```
229
+
230
+ ## Documentation
231
+
232
+ 📖 **[Full Documentation](docs/index.md)** - Complete API reference, guides, and examples.
233
+
234
+ ### Quick API Overview
235
+
236
+ #### Main Client
237
+
238
+ ```python
239
+ client = DexscreenerClient(impersonate="chrome136")
240
+ ```
241
+
242
+ #### Key Methods
243
+
244
+ - `get_pairs_by_token_address(chain_id, token_address)` - Get pairs for a token
245
+ - `search_pairs(query)` - Search pairs
246
+ - `subscribe_pairs(chain_id, pair_addresses, callback)` - Real-time pair updates
247
+ - `subscribe_tokens(chain_id, token_addresses, callback)` - Monitor all pairs of tokens
248
+
249
+ #### Data Models
250
+
251
+ - `TokenPair` - Main pair data model
252
+ - `TokenInfo` - Token profile information
253
+ - `OrderInfo` - Order information
254
+
255
+ ## Rate Limits
256
+
257
+ The SDK automatically handles rate limiting:
258
+
259
+ - 60 requests/minute for token profile endpoints
260
+ - 300 requests/minute for pair data endpoints
261
+
262
+ ## Browser Impersonation
263
+
264
+ The SDK uses curl_cffi for browser impersonation to bypass anti-bot protection:
265
+
266
+ ```python
267
+ # Use different browser versions
268
+ client = DexscreenerClient(impersonate="chrome134")
269
+ client = DexscreenerClient(impersonate="safari180")
270
+ ```
271
+
272
+ ## Contributing
273
+
274
+ Contributions are welcome! Please feel free to submit a Pull Request.
275
+
276
+ ## License
277
+
278
+ MIT License - see LICENSE file for details