devpost-api 1.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.
@@ -0,0 +1,20 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ *.so
7
+
8
+ # Packaging
9
+ build/
10
+ dist/
11
+ *.egg-info/
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+
17
+ # Tooling caches
18
+ .mypy_cache/
19
+ .ruff_cache/
20
+ .pytest_cache/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vladislav Kondratyev
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,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: devpost-api
3
+ Version: 1.0.1
4
+ Summary: Unofficial Devpost API client with resilient scraping, typed models, and CLI tooling.
5
+ Project-URL: Homepage, https://github.com/ch1kim0n1/devpost-api
6
+ Project-URL: Repository, https://github.com/ch1kim0n1/devpost-api
7
+ Project-URL: Issues, https://github.com/ch1kim0n1/devpost-api/issues
8
+ Author: Vladislav Kondratyev
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,devpost,github,hackathon,scraping
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
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
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ Provides-Extra: dev
26
+ Requires-Dist: build>=1.2.2; extra == 'dev'
27
+ Requires-Dist: coverage[toml]>=7.6.0; extra == 'dev'
28
+ Requires-Dist: mypy>=1.14.0; extra == 'dev'
29
+ Requires-Dist: ruff>=0.9.0; extra == 'dev'
30
+ Requires-Dist: twine>=6.1.0; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # devpost-api
34
+
35
+ Unofficial Devpost API and scraping client for hackathon scouting workflows.
36
+
37
+ [![CI](https://github.com/ch1kim0n1/devpost-api/actions/workflows/ci.yml/badge.svg)](https://github.com/ch1kim0n1/devpost-api/actions/workflows/ci.yml)
38
+ [![PyPI](https://img.shields.io/pypi/v/devpost-api.svg)](https://pypi.org/project/devpost-api/)
39
+ [![Python](https://img.shields.io/pypi/pyversions/devpost-api.svg)](https://pypi.org/project/devpost-api/)
40
+ [![License](https://img.shields.io/pypi/l/devpost-api.svg)](LICENSE)
41
+
42
+ ## Why use this package
43
+
44
+ - No runtime dependencies (stdlib only)
45
+ - Typed models and predictable public API
46
+ - Built-in retries, exponential backoff, and rate-limit handling
47
+ - Optional request throttling, cache, and parallel fetch
48
+ - CLI designed for scripts (`json`, `jsonl`, `csv`, `table`)
49
+
50
+ ## Naming and install model
51
+
52
+ - Install package: `pip install devpost-api`
53
+ - Python import path: `import devpost_api`
54
+ - CLI command: `devpost-api`
55
+
56
+ ## Install
57
+
58
+ ```bash
59
+ pip install devpost-api
60
+ ```
61
+
62
+ From source:
63
+
64
+ ```bash
65
+ pip install -e ".[dev]"
66
+ ```
67
+
68
+ ## Quickstart (Python)
69
+
70
+ ```python
71
+ from devpost_api import DevpostClient, RetryConfig
72
+
73
+ client = DevpostClient(
74
+ retry_config=RetryConfig(max_attempts=4, backoff_factor=0.5),
75
+ max_workers=8,
76
+ min_request_interval=0.05,
77
+ cache_ttl=30.0,
78
+ )
79
+
80
+ for project in client.iter_software(query="ai", max_pages=2):
81
+ print(project.name)
82
+
83
+ batch = client.collect_projects(
84
+ [
85
+ "https://devpost.com/software/api",
86
+ "https://devpost.com/software/does-not-exist",
87
+ ],
88
+ include_github=True,
89
+ )
90
+ print(len(batch.projects), len(batch.failures))
91
+ ```
92
+
93
+ ## Quickstart (CLI)
94
+
95
+ ```bash
96
+ # JSON (default)
97
+ devpost-api software --query ai --page 1
98
+
99
+ # CSV for shell pipelines
100
+ devpost-api --format csv --fields name,url software --query ai --page 1
101
+
102
+ # Batch project fetch from a file (one URL/slug per line)
103
+ devpost-api --format jsonl project --input-file projects.txt --with-github --best-effort
104
+
105
+ # Batch GitHub enrichment from stdin
106
+ printf "openai/openai-python\npsf/requests\n" | devpost-api github --stdin --best-effort --format table
107
+ ```
108
+
109
+ If `devpost-api` is not on your `PATH`, use `python -m devpost_api.cli ...`.
110
+
111
+ ## Public API
112
+
113
+ - `DevpostClient.list_software(page=1, query=None)`
114
+ - `DevpostClient.list_users(page=1)`
115
+ - `DevpostClient.list_hackathons(page=1, status=None)`
116
+ - `DevpostClient.iter_software(query=None, start_page=1, max_pages=None)`
117
+ - `DevpostClient.iter_users(start_page=1, max_pages=None)`
118
+ - `DevpostClient.iter_hackathons(status=None, start_page=1, max_pages=None)`
119
+ - `DevpostClient.get_project(slug_or_url, include_github=False, raise_on_error=True)`
120
+ - `DevpostClient.get_projects(slugs_or_urls, include_github=False, raise_on_error=True)`
121
+ - `DevpostClient.collect_projects(slugs_or_urls, include_github=False)`
122
+ - `DevpostClient.get_github_repo(url_or_owner_repo)`
123
+ - `DevpostClient.get_github_repos(urls_or_owner_repo, raise_on_error=True)`
124
+ - `DevpostClient.list_hackathon_project_urls(hackathon_slug_or_url, pages=1)`
125
+ - `DevpostClient.scout_hackathon_projects(hackathon_slug_or_url, pages=1, include_github=False, raise_on_error=True)`
126
+ - `DevpostClient.clear_cache()`
127
+
128
+ ## Reliability knobs
129
+
130
+ - `--retries`, `--backoff`, `--max-backoff`, `--jitter`
131
+ - `--workers` for parallel bulk operations
132
+ - `--min-interval` for global request spacing
133
+ - `--cache-ttl` for in-memory GET cache
134
+ - `--best-effort` for batch item error tolerance
135
+
136
+ ## Development workflow
137
+
138
+ Run tests:
139
+
140
+ ```bash
141
+ python -m unittest discover -s tests
142
+ ```
143
+
144
+ Run quality checks:
145
+
146
+ ```bash
147
+ ruff check .
148
+ mypy src
149
+ coverage run -m unittest discover -s tests
150
+ coverage report
151
+ ```
152
+
153
+ Build and verify artifacts:
154
+
155
+ ```bash
156
+ python -m build
157
+ python -m twine check dist/*
158
+ ```
159
+
160
+ ## Notes
161
+
162
+ - This package is unofficial and not affiliated with Devpost.
163
+ - Use responsibly and comply with Devpost and GitHub terms/policies.
@@ -0,0 +1,131 @@
1
+ # devpost-api
2
+
3
+ Unofficial Devpost API and scraping client for hackathon scouting workflows.
4
+
5
+ [![CI](https://github.com/ch1kim0n1/devpost-api/actions/workflows/ci.yml/badge.svg)](https://github.com/ch1kim0n1/devpost-api/actions/workflows/ci.yml)
6
+ [![PyPI](https://img.shields.io/pypi/v/devpost-api.svg)](https://pypi.org/project/devpost-api/)
7
+ [![Python](https://img.shields.io/pypi/pyversions/devpost-api.svg)](https://pypi.org/project/devpost-api/)
8
+ [![License](https://img.shields.io/pypi/l/devpost-api.svg)](LICENSE)
9
+
10
+ ## Why use this package
11
+
12
+ - No runtime dependencies (stdlib only)
13
+ - Typed models and predictable public API
14
+ - Built-in retries, exponential backoff, and rate-limit handling
15
+ - Optional request throttling, cache, and parallel fetch
16
+ - CLI designed for scripts (`json`, `jsonl`, `csv`, `table`)
17
+
18
+ ## Naming and install model
19
+
20
+ - Install package: `pip install devpost-api`
21
+ - Python import path: `import devpost_api`
22
+ - CLI command: `devpost-api`
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ pip install devpost-api
28
+ ```
29
+
30
+ From source:
31
+
32
+ ```bash
33
+ pip install -e ".[dev]"
34
+ ```
35
+
36
+ ## Quickstart (Python)
37
+
38
+ ```python
39
+ from devpost_api import DevpostClient, RetryConfig
40
+
41
+ client = DevpostClient(
42
+ retry_config=RetryConfig(max_attempts=4, backoff_factor=0.5),
43
+ max_workers=8,
44
+ min_request_interval=0.05,
45
+ cache_ttl=30.0,
46
+ )
47
+
48
+ for project in client.iter_software(query="ai", max_pages=2):
49
+ print(project.name)
50
+
51
+ batch = client.collect_projects(
52
+ [
53
+ "https://devpost.com/software/api",
54
+ "https://devpost.com/software/does-not-exist",
55
+ ],
56
+ include_github=True,
57
+ )
58
+ print(len(batch.projects), len(batch.failures))
59
+ ```
60
+
61
+ ## Quickstart (CLI)
62
+
63
+ ```bash
64
+ # JSON (default)
65
+ devpost-api software --query ai --page 1
66
+
67
+ # CSV for shell pipelines
68
+ devpost-api --format csv --fields name,url software --query ai --page 1
69
+
70
+ # Batch project fetch from a file (one URL/slug per line)
71
+ devpost-api --format jsonl project --input-file projects.txt --with-github --best-effort
72
+
73
+ # Batch GitHub enrichment from stdin
74
+ printf "openai/openai-python\npsf/requests\n" | devpost-api github --stdin --best-effort --format table
75
+ ```
76
+
77
+ If `devpost-api` is not on your `PATH`, use `python -m devpost_api.cli ...`.
78
+
79
+ ## Public API
80
+
81
+ - `DevpostClient.list_software(page=1, query=None)`
82
+ - `DevpostClient.list_users(page=1)`
83
+ - `DevpostClient.list_hackathons(page=1, status=None)`
84
+ - `DevpostClient.iter_software(query=None, start_page=1, max_pages=None)`
85
+ - `DevpostClient.iter_users(start_page=1, max_pages=None)`
86
+ - `DevpostClient.iter_hackathons(status=None, start_page=1, max_pages=None)`
87
+ - `DevpostClient.get_project(slug_or_url, include_github=False, raise_on_error=True)`
88
+ - `DevpostClient.get_projects(slugs_or_urls, include_github=False, raise_on_error=True)`
89
+ - `DevpostClient.collect_projects(slugs_or_urls, include_github=False)`
90
+ - `DevpostClient.get_github_repo(url_or_owner_repo)`
91
+ - `DevpostClient.get_github_repos(urls_or_owner_repo, raise_on_error=True)`
92
+ - `DevpostClient.list_hackathon_project_urls(hackathon_slug_or_url, pages=1)`
93
+ - `DevpostClient.scout_hackathon_projects(hackathon_slug_or_url, pages=1, include_github=False, raise_on_error=True)`
94
+ - `DevpostClient.clear_cache()`
95
+
96
+ ## Reliability knobs
97
+
98
+ - `--retries`, `--backoff`, `--max-backoff`, `--jitter`
99
+ - `--workers` for parallel bulk operations
100
+ - `--min-interval` for global request spacing
101
+ - `--cache-ttl` for in-memory GET cache
102
+ - `--best-effort` for batch item error tolerance
103
+
104
+ ## Development workflow
105
+
106
+ Run tests:
107
+
108
+ ```bash
109
+ python -m unittest discover -s tests
110
+ ```
111
+
112
+ Run quality checks:
113
+
114
+ ```bash
115
+ ruff check .
116
+ mypy src
117
+ coverage run -m unittest discover -s tests
118
+ coverage report
119
+ ```
120
+
121
+ Build and verify artifacts:
122
+
123
+ ```bash
124
+ python -m build
125
+ python -m twine check dist/*
126
+ ```
127
+
128
+ ## Notes
129
+
130
+ - This package is unofficial and not affiliated with Devpost.
131
+ - Use responsibly and comply with Devpost and GitHub terms/policies.
@@ -0,0 +1,81 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.24.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "devpost-api"
7
+ version = "1.0.1"
8
+ description = "Unofficial Devpost API client with resilient scraping, typed models, and CLI tooling."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Vladislav Kondratyev" }
14
+ ]
15
+ keywords = ["devpost", "api", "hackathon", "github", "scraping"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Software Development :: Libraries",
28
+ "Typing :: Typed",
29
+ ]
30
+ dependencies = []
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/ch1kim0n1/devpost-api"
34
+ Repository = "https://github.com/ch1kim0n1/devpost-api"
35
+ Issues = "https://github.com/ch1kim0n1/devpost-api/issues"
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "build>=1.2.2",
40
+ "coverage[toml]>=7.6.0",
41
+ "mypy>=1.14.0",
42
+ "ruff>=0.9.0",
43
+ "twine>=6.1.0",
44
+ ]
45
+
46
+ [project.scripts]
47
+ devpost-api = "devpost_api.cli:main"
48
+
49
+ [tool.hatch.build.targets.wheel]
50
+ packages = ["src/devpost_api"]
51
+
52
+ [tool.hatch.build.targets.sdist]
53
+ include = [
54
+ "/src",
55
+ "/tests",
56
+ "/README.md",
57
+ "/LICENSE",
58
+ "/pyproject.toml",
59
+ ]
60
+
61
+ [tool.ruff]
62
+ target-version = "py39"
63
+ line-length = 100
64
+
65
+ [tool.ruff.lint]
66
+ select = ["E", "F", "W", "I", "UP", "B"]
67
+ ignore = ["E501"]
68
+
69
+ [tool.mypy]
70
+ python_version = "3.9"
71
+ strict = true
72
+ warn_unused_configs = true
73
+ exclude = ["tests/"]
74
+
75
+ [tool.coverage.run]
76
+ source = ["src/devpost_api"]
77
+ branch = true
78
+
79
+ [tool.coverage.report]
80
+ show_missing = true
81
+ fail_under = 70
@@ -0,0 +1,56 @@
1
+ """Unofficial Devpost API client with typed models and CLI."""
2
+
3
+ from ._meta import __version__
4
+ from .client import BatchFailure, DevpostClient, ProjectBatchResult, RetryConfig
5
+ from .exceptions import (
6
+ DevpostAPIError,
7
+ GitHubResolutionError,
8
+ HTTPStatusError,
9
+ ParseError,
10
+ RateLimitError,
11
+ )
12
+ from .models import (
13
+ CreatorProfile,
14
+ ExternalLink,
15
+ GitHubRepo,
16
+ HackathonProjectsPage,
17
+ HackathonSummary,
18
+ ProjectDetails,
19
+ SoftwareSummary,
20
+ UserSummary,
21
+ )
22
+ from .parsing import (
23
+ github_owner_repo,
24
+ hackathon_gallery_url,
25
+ parse_hackathon_gallery_page,
26
+ slug_from_project_url,
27
+ to_hackathon_url,
28
+ to_project_url,
29
+ )
30
+
31
+ __all__ = [
32
+ "DevpostClient",
33
+ "BatchFailure",
34
+ "ProjectBatchResult",
35
+ "RetryConfig",
36
+ "DevpostAPIError",
37
+ "HTTPStatusError",
38
+ "ParseError",
39
+ "GitHubResolutionError",
40
+ "RateLimitError",
41
+ "SoftwareSummary",
42
+ "UserSummary",
43
+ "HackathonSummary",
44
+ "HackathonProjectsPage",
45
+ "CreatorProfile",
46
+ "ExternalLink",
47
+ "GitHubRepo",
48
+ "ProjectDetails",
49
+ "to_project_url",
50
+ "to_hackathon_url",
51
+ "slug_from_project_url",
52
+ "github_owner_repo",
53
+ "hackathon_gallery_url",
54
+ "parse_hackathon_gallery_page",
55
+ "__version__",
56
+ ]
@@ -0,0 +1,9 @@
1
+ """Package metadata used across runtime and docs."""
2
+
3
+ PACKAGE_NAME = "devpost-api"
4
+ __version__ = "1.0.1"
5
+
6
+
7
+ def default_user_agent() -> str:
8
+ """Build the default user-agent from package metadata."""
9
+ return f"{PACKAGE_NAME}/{__version__}"