deezer-oauth-cli 1.4.0__tar.gz → 1.5.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.
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/PKG-INFO +16 -19
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/README.md +2 -2
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/pyproject.toml +43 -35
- deezer_oauth_cli-1.5.0/setup.cfg +4 -0
- deezer_oauth_cli-1.5.0/setup.py +9 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth/__init__.py +1 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth_cli.egg-info/PKG-INFO +125 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth_cli.egg-info/SOURCES.txt +23 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth_cli.egg-info/dependency_links.txt +1 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth_cli.egg-info/entry_points.txt +2 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth_cli.egg-info/requires.txt +3 -0
- deezer_oauth_cli-1.5.0/src/deezer_oauth_cli.egg-info/top_level.txt +1 -0
- deezer_oauth_cli-1.5.0/tests/test_client.py +32 -0
- deezer_oauth_cli-1.5.0/tests/test_dunder_main.py +12 -0
- deezer_oauth_cli-1.5.0/tests/test_files.py +50 -0
- deezer_oauth_cli-1.5.0/tests/test_main.py +18 -0
- deezer_oauth_cli-1.5.0/tests/test_server.py +120 -0
- deezer_oauth_cli-1.4.0/src/deezer_oauth/__init__.py +0 -1
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/LICENSE +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/__main__.py +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/client.py +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/constants.py +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/files.py +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/main.py +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/py.typed +0 -0
- {deezer_oauth_cli-1.4.0 → deezer_oauth_cli-1.5.0}/src/deezer_oauth/server.py +0 -0
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: deezer-oauth-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
4
4
|
Summary: A small CLI to quickly obtain an API token for Deezer API.
|
|
5
|
-
|
|
5
|
+
Author-email: Bruno Alla <alla.brunoo@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/browniebroke/deezer-oauth-cli/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/browniebroke/deezer-oauth-cli/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: documentation, https://github.com/browniebroke/deezer-oauth-cli/blob/main/README.md
|
|
10
|
+
Project-URL: Mastodon, https://fosstodon.org/@browniebroke
|
|
11
|
+
Project-URL: repository, https://github.com/browniebroke/deezer-oauth-cli
|
|
12
|
+
Project-URL: Twitter, https://twitter.com/_BrunoAlla
|
|
10
13
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
11
14
|
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
13
15
|
Classifier: Natural Language :: English
|
|
14
16
|
Classifier: Operating System :: OS Independent
|
|
15
|
-
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
18
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
23
|
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
-
Requires-
|
|
23
|
-
Requires-Dist: rich (>=10)
|
|
24
|
-
Requires-Dist: typer[all] (>=0.12.0)
|
|
25
|
-
Project-URL: Bug Tracker, https://github.com/browniebroke/deezer-oauth-cli/issues
|
|
26
|
-
Project-URL: Changelog, https://github.com/browniebroke/deezer-oauth-cli/blob/main/CHANGELOG.md
|
|
27
|
-
Project-URL: Documentation, https://github.com/browniebroke/deezer-oauth-cli/blob/main/README.md
|
|
28
|
-
Project-URL: Mastodon, https://fosstodon.org/@browniebroke
|
|
29
|
-
Project-URL: Repository, https://github.com/browniebroke/deezer-oauth-cli
|
|
30
|
-
Project-URL: Twitter, https://twitter.com/_BrunoAlla
|
|
24
|
+
Requires-Python: >=3.9
|
|
31
25
|
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: httpx<0.28,>=0.27
|
|
28
|
+
Requires-Dist: rich>=10
|
|
29
|
+
Requires-Dist: typer[all]>=0.12
|
|
32
30
|
|
|
33
31
|
# Deezer OAuth CLI
|
|
34
32
|
|
|
@@ -41,8 +39,8 @@ Description-Content-Type: text/markdown
|
|
|
41
39
|
</a>
|
|
42
40
|
</p>
|
|
43
41
|
<p align="center">
|
|
44
|
-
<a href="https://
|
|
45
|
-
<img src="https://img.shields.io/endpoint?url=https://
|
|
42
|
+
<a href="https://github.com/astral-sh/uv">
|
|
43
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
|
|
46
44
|
</a>
|
|
47
45
|
<a href="https://github.com/astral-sh/ruff">
|
|
48
46
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
@@ -125,4 +123,3 @@ This package was created with
|
|
|
125
123
|
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
|
|
126
124
|
[browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage)
|
|
127
125
|
project template.
|
|
128
|
-
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
</a>
|
|
10
10
|
</p>
|
|
11
11
|
<p align="center">
|
|
12
|
-
<a href="https://
|
|
13
|
-
<img src="https://img.shields.io/endpoint?url=https://
|
|
12
|
+
<a href="https://github.com/astral-sh/uv">
|
|
13
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
|
|
14
14
|
</a>
|
|
15
15
|
<a href="https://github.com/astral-sh/ruff">
|
|
16
16
|
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
@@ -1,49 +1,52 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
build-backend = "
|
|
3
|
-
requires = [ "
|
|
2
|
+
build-backend = "setuptools.build_meta"
|
|
3
|
+
requires = [ "setuptools" ]
|
|
4
4
|
|
|
5
|
-
[
|
|
5
|
+
[project]
|
|
6
6
|
name = "deezer-oauth-cli"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.5.0"
|
|
8
8
|
description = "A small CLI to quickly obtain an API token for Deezer API."
|
|
9
|
-
authors = [ "Bruno Alla <alla.brunoo@gmail.com>" ]
|
|
10
|
-
license = "MIT"
|
|
11
9
|
readme = "README.md"
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Bruno Alla", email = "alla.brunoo@gmail.com" },
|
|
13
|
+
]
|
|
14
|
+
requires-python = ">=3.9"
|
|
14
15
|
classifiers = [
|
|
15
16
|
"Development Status :: 2 - Pre-Alpha",
|
|
16
17
|
"Intended Audience :: Developers",
|
|
17
18
|
"Natural Language :: English",
|
|
18
19
|
"Operating System :: OS Independent",
|
|
19
|
-
"
|
|
20
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
21
|
+
"Programming Language :: Python :: 3.9",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
20
24
|
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Software Development :: Libraries",
|
|
21
27
|
]
|
|
22
|
-
packages = [
|
|
23
|
-
{ include = "deezer_oauth", from = "src" },
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
[tool.poetry.urls]
|
|
27
|
-
"Bug Tracker" = "https://github.com/browniebroke/deezer-oauth-cli/issues"
|
|
28
|
-
"Changelog" = "https://github.com/browniebroke/deezer-oauth-cli/blob/main/CHANGELOG.md"
|
|
29
|
-
"Twitter" = "https://twitter.com/_BrunoAlla"
|
|
30
|
-
"Mastodon" = "https://fosstodon.org/@browniebroke"
|
|
31
28
|
|
|
32
|
-
[
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
dependencies = [
|
|
30
|
+
"httpx>=0.27,<0.28",
|
|
31
|
+
"rich>=10",
|
|
32
|
+
"typer[all]>=0.12",
|
|
33
|
+
]
|
|
34
|
+
urls."Bug Tracker" = "https://github.com/browniebroke/deezer-oauth-cli/issues"
|
|
35
|
+
urls.Changelog = "https://github.com/browniebroke/deezer-oauth-cli/blob/main/CHANGELOG.md"
|
|
36
|
+
urls.documentation = "https://github.com/browniebroke/deezer-oauth-cli/blob/main/README.md"
|
|
37
|
+
urls.Mastodon = "https://fosstodon.org/@browniebroke"
|
|
38
|
+
urls.repository = "https://github.com/browniebroke/deezer-oauth-cli"
|
|
39
|
+
urls.Twitter = "https://twitter.com/_BrunoAlla"
|
|
40
|
+
scripts.deezer-oauth = "deezer_oauth.main:app"
|
|
41
|
+
|
|
42
|
+
[dependency-groups]
|
|
43
|
+
dev = [
|
|
44
|
+
"pyfakefs>=5,<6",
|
|
45
|
+
"pytest>=8,<9",
|
|
46
|
+
"pytest-cov>=6,<7",
|
|
47
|
+
"pytest-mock>=3.6,<4",
|
|
48
|
+
"respx>=0.21.1,<1",
|
|
49
|
+
]
|
|
47
50
|
|
|
48
51
|
[tool.ruff]
|
|
49
52
|
target-version = "py39"
|
|
@@ -111,11 +114,16 @@ module = "tests.*"
|
|
|
111
114
|
allow_untyped_defs = true
|
|
112
115
|
|
|
113
116
|
[tool.semantic_release]
|
|
114
|
-
version_toml = [ "pyproject.toml:
|
|
117
|
+
version_toml = [ "pyproject.toml:project.version" ]
|
|
115
118
|
version_variables = [
|
|
116
119
|
"src/deezer_oauth/__init__.py:__version__",
|
|
117
120
|
]
|
|
118
|
-
build_command = "
|
|
121
|
+
build_command = """
|
|
122
|
+
pip install uv
|
|
123
|
+
uv lock
|
|
124
|
+
git add uv.lock
|
|
125
|
+
uv build
|
|
126
|
+
"""
|
|
119
127
|
|
|
120
128
|
[tool.semantic_release.changelog]
|
|
121
129
|
exclude_commit_patterns = [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.5.0"
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: deezer-oauth-cli
|
|
3
|
+
Version: 1.5.0
|
|
4
|
+
Summary: A small CLI to quickly obtain an API token for Deezer API.
|
|
5
|
+
Author-email: Bruno Alla <alla.brunoo@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/browniebroke/deezer-oauth-cli/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/browniebroke/deezer-oauth-cli/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: documentation, https://github.com/browniebroke/deezer-oauth-cli/blob/main/README.md
|
|
10
|
+
Project-URL: Mastodon, https://fosstodon.org/@browniebroke
|
|
11
|
+
Project-URL: repository, https://github.com/browniebroke/deezer-oauth-cli
|
|
12
|
+
Project-URL: Twitter, https://twitter.com/_BrunoAlla
|
|
13
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: httpx<0.28,>=0.27
|
|
28
|
+
Requires-Dist: rich>=10
|
|
29
|
+
Requires-Dist: typer[all]>=0.12
|
|
30
|
+
|
|
31
|
+
# Deezer OAuth CLI
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<a href="https://github.com/browniebroke/deezer-oauth-cli/actions/workflows/ci.yml?query=branch%3Amain">
|
|
35
|
+
<img src="https://img.shields.io/github/actions/workflow/status/browniebroke/deezer-oauth-cli/ci.yml?branch=main&label=CI&logo=github&style=flat-square" alt="CI Status" >
|
|
36
|
+
</a>
|
|
37
|
+
<a href="https://codecov.io/gh/browniebroke/deezer-oauth-cli">
|
|
38
|
+
<img src="https://img.shields.io/codecov/c/github/browniebroke/deezer-oauth-cli.svg?logo=codecov&logoColor=fff&style=flat-square" alt="Test coverage percentage">
|
|
39
|
+
</a>
|
|
40
|
+
</p>
|
|
41
|
+
<p align="center">
|
|
42
|
+
<a href="https://github.com/astral-sh/uv">
|
|
43
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv">
|
|
44
|
+
</a>
|
|
45
|
+
<a href="https://github.com/astral-sh/ruff">
|
|
46
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
|
|
47
|
+
</a>
|
|
48
|
+
<a href="https://github.com/pre-commit/pre-commit">
|
|
49
|
+
<img src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square" alt="pre-commit">
|
|
50
|
+
</a>
|
|
51
|
+
</p>
|
|
52
|
+
<p align="center">
|
|
53
|
+
<a href="https://pypi.org/project/deezer-oauth-cli/">
|
|
54
|
+
<img src="https://img.shields.io/pypi/v/deezer-oauth-cli.svg?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
|
|
55
|
+
</a>
|
|
56
|
+
<img src="https://img.shields.io/pypi/pyversions/deezer-oauth-cli.svg?style=flat-square&logo=python&logoColor=fff" alt="Supported Python versions">
|
|
57
|
+
<img src="https://img.shields.io/pypi/l/deezer-oauth-cli.svg?style=flat-square" alt="License">
|
|
58
|
+
</p>
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
**Source Code**: <a href="https://github.com/browniebroke/deezer-oauth-cli" target="_blank">https://github.com/browniebroke/deezer-oauth-cli</a>
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
A small CLI to quickly obtain an API token for the Deezer API.
|
|
67
|
+
|
|
68
|
+
Obtaining API token to develop API applications can be complicated and sometimes feel like a chicken and egg situation: it's hard to play with the API without a token, but it can be difficult to get a token without an application to do the OAuth flow.
|
|
69
|
+
|
|
70
|
+
Given the app ID and secret, this tool lets you quickly get an API token.
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
|
|
74
|
+
Install this via pip (or your favourite package manager):
|
|
75
|
+
|
|
76
|
+
`pip install deezer-oauth-cli`
|
|
77
|
+
|
|
78
|
+
## Usage
|
|
79
|
+
|
|
80
|
+
Before starting to use this tool, you first need to declare your Deezer app in [their developer portal](https://developers.deezer.com). Create a new app with the following Redirect URL: `http://localhost:8080/oauth/return`.
|
|
81
|
+
|
|
82
|
+
Once created, Deezer will generate an application ID and secret key for you, that's the 2 parameters that you need to run this tool:
|
|
83
|
+
|
|
84
|
+
```shell
|
|
85
|
+
$ deezer-oauth APP_ID APP_SECRET
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This will:
|
|
89
|
+
|
|
90
|
+
- Spin up a webserver in the background running at `http://localhost:8080`.
|
|
91
|
+
- Open your browser to grant authorisation access to your Deezer account.
|
|
92
|
+
- Redirect to a page showing the API token & expiry.
|
|
93
|
+
- Write the token to a `.env` file.
|
|
94
|
+
|
|
95
|
+
## Contributors ✨
|
|
96
|
+
|
|
97
|
+
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
|
98
|
+
|
|
99
|
+
<!-- prettier-ignore-start -->
|
|
100
|
+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
101
|
+
<!-- prettier-ignore-start -->
|
|
102
|
+
<!-- markdownlint-disable -->
|
|
103
|
+
<table>
|
|
104
|
+
<tbody>
|
|
105
|
+
<tr>
|
|
106
|
+
<td align="center"><a href="https://browniebroke.com/"><img src="https://avatars.githubusercontent.com/u/861044?v=4?s=80" width="80px;" alt="Bruno Alla"/><br /><sub><b>Bruno Alla</b></sub></a><br /><a href="https://github.com/browniebroke/deezer-oauth-cli/commits?author=browniebroke" title="Code">💻</a> <a href="#ideas-browniebroke" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/browniebroke/deezer-oauth-cli/commits?author=browniebroke" title="Documentation">📖</a></td>
|
|
107
|
+
<td align="center"><a href="https://github.com/prndrbr"><img src="https://avatars.githubusercontent.com/u/96344856?v=4?s=80" width="80px;" alt="Pierre"/><br /><sub><b>Pierre</b></sub></a><br /><a href="https://github.com/browniebroke/deezer-oauth-cli/commits?author=prndrbr" title="Code">💻</a></td>
|
|
108
|
+
</tr>
|
|
109
|
+
</tbody>
|
|
110
|
+
</table>
|
|
111
|
+
|
|
112
|
+
<!-- markdownlint-restore -->
|
|
113
|
+
<!-- prettier-ignore-end -->
|
|
114
|
+
|
|
115
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
116
|
+
<!-- prettier-ignore-end -->
|
|
117
|
+
|
|
118
|
+
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
119
|
+
|
|
120
|
+
## Credits
|
|
121
|
+
|
|
122
|
+
This package was created with
|
|
123
|
+
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
|
|
124
|
+
[browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage)
|
|
125
|
+
project template.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
src/deezer_oauth/__init__.py
|
|
6
|
+
src/deezer_oauth/__main__.py
|
|
7
|
+
src/deezer_oauth/client.py
|
|
8
|
+
src/deezer_oauth/constants.py
|
|
9
|
+
src/deezer_oauth/files.py
|
|
10
|
+
src/deezer_oauth/main.py
|
|
11
|
+
src/deezer_oauth/py.typed
|
|
12
|
+
src/deezer_oauth/server.py
|
|
13
|
+
src/deezer_oauth_cli.egg-info/PKG-INFO
|
|
14
|
+
src/deezer_oauth_cli.egg-info/SOURCES.txt
|
|
15
|
+
src/deezer_oauth_cli.egg-info/dependency_links.txt
|
|
16
|
+
src/deezer_oauth_cli.egg-info/entry_points.txt
|
|
17
|
+
src/deezer_oauth_cli.egg-info/requires.txt
|
|
18
|
+
src/deezer_oauth_cli.egg-info/top_level.txt
|
|
19
|
+
tests/test_client.py
|
|
20
|
+
tests/test_dunder_main.py
|
|
21
|
+
tests/test_files.py
|
|
22
|
+
tests/test_main.py
|
|
23
|
+
tests/test_server.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
deezer_oauth
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import pytest
|
|
3
|
+
import respx
|
|
4
|
+
|
|
5
|
+
from deezer_oauth.client import OAuthDancer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestOAuthDancer:
|
|
9
|
+
def test_get_auth_page(self) -> None:
|
|
10
|
+
dancer = OAuthDancer(app_id="1234", app_secret="dzr-secret") # noqa S106
|
|
11
|
+
url = dancer.get_auth_page()
|
|
12
|
+
assert url == (
|
|
13
|
+
"https://connect.deezer.com/oauth/auth.php"
|
|
14
|
+
"?app_id=1234"
|
|
15
|
+
"&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth%2Freturn"
|
|
16
|
+
"&perms=basic_access%2Cemail%2Cmanage_library%2Cmanage_community"
|
|
17
|
+
"%2Cdelete_library%2Clistening_history"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
@pytest.mark.respx(base_url="https://connect.deezer.com")
|
|
21
|
+
def test_get_token(self, respx_mock: respx.MockRouter) -> None:
|
|
22
|
+
get_token_route: respx.Route = respx_mock.get("/oauth/access_token.php")
|
|
23
|
+
get_token_route.mock(
|
|
24
|
+
return_value=httpx.Response(
|
|
25
|
+
status_code=200,
|
|
26
|
+
text="access_token=blah&expires=1234",
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
dancer = OAuthDancer(app_id="abcd", app_secret="secret") # noqa S106
|
|
30
|
+
result = dancer.get_token("my-personal-code")
|
|
31
|
+
assert result == {"access_token": "blah", "expires": "1234"}
|
|
32
|
+
assert get_token_route.call_count == 1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_can_run_as_python_module():
|
|
6
|
+
result = subprocess.run( # noqa: S603
|
|
7
|
+
[sys.executable, "-m", "deezer_oauth", "--help"],
|
|
8
|
+
check=True,
|
|
9
|
+
capture_output=True,
|
|
10
|
+
)
|
|
11
|
+
assert result.returncode == 0
|
|
12
|
+
assert b"deezer-oauth [OPTIONS]" in result.stdout
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from deezer_oauth.files import write_env_file
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestWriteEnvFile:
|
|
9
|
+
def test_create(self, fs):
|
|
10
|
+
env_file = Path(".env")
|
|
11
|
+
assert not env_file.exists()
|
|
12
|
+
write_env_file("qwerty")
|
|
13
|
+
assert env_file.exists()
|
|
14
|
+
assert env_file.read_text("utf-8") == "API_TOKEN=qwerty\n"
|
|
15
|
+
|
|
16
|
+
@pytest.mark.parametrize(
|
|
17
|
+
("before", "after"),
|
|
18
|
+
[
|
|
19
|
+
(
|
|
20
|
+
"SOMETHING=test\n",
|
|
21
|
+
"SOMETHING=test\nAPI_TOKEN=new\n",
|
|
22
|
+
),
|
|
23
|
+
(
|
|
24
|
+
"SOMETHING=test\nAPI_TOKEN=old\n",
|
|
25
|
+
"SOMETHING=test\nAPI_TOKEN=new\n",
|
|
26
|
+
),
|
|
27
|
+
(
|
|
28
|
+
"OTHER_API_TOKEN=test\nAPI_TOKEN=old\n",
|
|
29
|
+
"OTHER_API_TOKEN=test\nAPI_TOKEN=new\n",
|
|
30
|
+
),
|
|
31
|
+
(
|
|
32
|
+
"API_TOKEN=old\nTHING=test",
|
|
33
|
+
"API_TOKEN=new\nTHING=test\n",
|
|
34
|
+
),
|
|
35
|
+
(
|
|
36
|
+
"API_TOKEN=old\n",
|
|
37
|
+
"API_TOKEN=new\n",
|
|
38
|
+
),
|
|
39
|
+
(
|
|
40
|
+
"API_TOKEN=old",
|
|
41
|
+
"API_TOKEN=new\n",
|
|
42
|
+
),
|
|
43
|
+
],
|
|
44
|
+
)
|
|
45
|
+
def test_update(self, before, after):
|
|
46
|
+
env_file = Path(".env")
|
|
47
|
+
env_file.write_text(before)
|
|
48
|
+
write_env_file("new")
|
|
49
|
+
assert env_file.exists()
|
|
50
|
+
assert env_file.read_text() == after
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typer.testing import CliRunner
|
|
2
|
+
|
|
3
|
+
from deezer_oauth.main import app
|
|
4
|
+
|
|
5
|
+
runner = CliRunner()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_no_arguments():
|
|
9
|
+
result = runner.invoke(app)
|
|
10
|
+
assert result.exit_code == 2
|
|
11
|
+
assert "Error" in result.stdout
|
|
12
|
+
assert "Missing argument 'APP_ID'." in result.stdout
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_help():
|
|
16
|
+
result = runner.invoke(app, ["--help"])
|
|
17
|
+
assert result.exit_code == 0
|
|
18
|
+
assert "Obtain an API token from Deezer." in result.stdout
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import http.client
|
|
2
|
+
import sys
|
|
3
|
+
import threading
|
|
4
|
+
|
|
5
|
+
if sys.version_info < (3, 10):
|
|
6
|
+
from test.support import threading_cleanup, threading_setup
|
|
7
|
+
else:
|
|
8
|
+
from test.support.threading_helper import threading_cleanup, threading_setup
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
from deezer_oauth.client import OAuthDancer
|
|
13
|
+
from deezer_oauth.server import LocalHTTPServer, LocalRequestHandler, run_server
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestRunServer:
|
|
17
|
+
def test_run_ok(self, mocker):
|
|
18
|
+
serve_forever = mocker.patch("deezer_oauth.server.HTTPServer.serve_forever")
|
|
19
|
+
server_close = mocker.patch("deezer_oauth.server.HTTPServer.server_close")
|
|
20
|
+
run_server(OAuthDancer("a", "b"))
|
|
21
|
+
serve_forever.assert_called_once()
|
|
22
|
+
server_close.assert_called_once()
|
|
23
|
+
|
|
24
|
+
@pytest.mark.parametrize("exception_class", [KeyboardInterrupt, SystemExit])
|
|
25
|
+
def test_interrupted(self, mocker, exception_class):
|
|
26
|
+
mocker.patch("deezer_oauth.server.HTTPServer.__init__")
|
|
27
|
+
serve_forever = mocker.patch(
|
|
28
|
+
"deezer_oauth.server.HTTPServer.serve_forever",
|
|
29
|
+
side_effect=exception_class(),
|
|
30
|
+
)
|
|
31
|
+
server_close = mocker.patch("deezer_oauth.server.HTTPServer.server_close")
|
|
32
|
+
run_server(OAuthDancer("a", "b"))
|
|
33
|
+
serve_forever.assert_called_once()
|
|
34
|
+
server_close.assert_called_once()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ServerWrapperThread(threading.Thread):
|
|
38
|
+
"""
|
|
39
|
+
Run a server in a separate thread.
|
|
40
|
+
|
|
41
|
+
Forked from a similar class from the stdlib that can be found at:
|
|
42
|
+
test.test_httpservers#TestServerThread
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
server: LocalHTTPServer
|
|
46
|
+
|
|
47
|
+
def __init__(self, test_class):
|
|
48
|
+
threading.Thread.__init__(self)
|
|
49
|
+
self.test_class = test_class
|
|
50
|
+
|
|
51
|
+
def run(self):
|
|
52
|
+
self.server = LocalHTTPServer(
|
|
53
|
+
OAuthDancer("a", "b"),
|
|
54
|
+
("localhost", 0),
|
|
55
|
+
LocalRequestHandler,
|
|
56
|
+
)
|
|
57
|
+
self.test_class.host, self.test_class.port = self.server.socket.getsockname()
|
|
58
|
+
self.test_class.server_started.set()
|
|
59
|
+
self.test_class = None
|
|
60
|
+
try:
|
|
61
|
+
self.server.serve_forever(0.05)
|
|
62
|
+
finally:
|
|
63
|
+
self.server.server_close()
|
|
64
|
+
|
|
65
|
+
def stop(self):
|
|
66
|
+
self.server.shutdown()
|
|
67
|
+
self.join()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class TestLocalRequestHandler:
|
|
71
|
+
host: str
|
|
72
|
+
port: int
|
|
73
|
+
server_started: threading.Event
|
|
74
|
+
|
|
75
|
+
@pytest.fixture
|
|
76
|
+
def http_server(self):
|
|
77
|
+
_threads = threading_setup()
|
|
78
|
+
self.server_started = threading.Event()
|
|
79
|
+
thread = ServerWrapperThread(self)
|
|
80
|
+
thread.start()
|
|
81
|
+
self.server_started.wait()
|
|
82
|
+
yield
|
|
83
|
+
thread.stop()
|
|
84
|
+
# clear assignment to avoid dangling thread
|
|
85
|
+
thread = None # type: ignore[assignment]
|
|
86
|
+
threading_cleanup(*_threads)
|
|
87
|
+
|
|
88
|
+
def request(self, uri, method="GET"):
|
|
89
|
+
self.connection = http.client.HTTPConnection(self.host, self.port)
|
|
90
|
+
self.connection.request(method, uri)
|
|
91
|
+
return self.connection.getresponse()
|
|
92
|
+
|
|
93
|
+
def test_default_route(self, http_server):
|
|
94
|
+
response = self.request("/")
|
|
95
|
+
assert isinstance(response, http.client.HTTPResponse)
|
|
96
|
+
assert response.status == 200
|
|
97
|
+
body = response.read().decode()
|
|
98
|
+
assert "<title>Deezer API OAuth dancer</title>" in body
|
|
99
|
+
assert "Start Oauth Flow" in body
|
|
100
|
+
|
|
101
|
+
def test_return_route_no_query_string(self, http_server):
|
|
102
|
+
response = self.request("/oauth/return")
|
|
103
|
+
assert isinstance(response, http.client.HTTPResponse)
|
|
104
|
+
assert response.status == 400
|
|
105
|
+
body = response.read().decode()
|
|
106
|
+
assert "Invalid request: missing query parameters" in body
|
|
107
|
+
|
|
108
|
+
def test_return_route_with_query_string(self, http_server, mocker):
|
|
109
|
+
mocker.patch(
|
|
110
|
+
"deezer_oauth.client.OAuthDancer.get_token",
|
|
111
|
+
return_value={"access_token": "something", "expires": 12345},
|
|
112
|
+
)
|
|
113
|
+
write_env_file = mocker.patch("deezer_oauth.server.write_env_file")
|
|
114
|
+
response = self.request("/oauth/return?code=abcdef")
|
|
115
|
+
assert isinstance(response, http.client.HTTPResponse)
|
|
116
|
+
assert response.status == 200
|
|
117
|
+
body = response.read().decode()
|
|
118
|
+
assert "Token: something" in body
|
|
119
|
+
assert "Expires: 12345" in body
|
|
120
|
+
write_env_file.assert_called()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|