Browse Source

Merge pull request 'Use pre-commit' (#7) from pre-commit into master

Reviewed-on: https://git.sporestack.com/SporeStack/sporestack-python/pulls/7
master
spore 6 days ago
parent
commit
1bd1231a20
  1. 34
      .pre-commit-config.yaml
  2. 12
      .woodpecker.yml
  3. 7
      Makefile
  4. 3
      Pipfile
  5. 123
      Pipfile.lock
  6. 22
      README.md
  7. 24
      setup.cfg
  8. 18
      src/sporestack/api.py
  9. 6
      src/sporestack/cli.py

34
.pre-commit-config.yaml

@ -0,0 +1,34 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 8fe62d14e0b4d7d845a7022c5c2c3ae41bdd3f26 # frozen: v4.1.0
hooks:
- id: trailing-whitespace
- repo: https://github.com/psf/black
rev: f1d4e742c91dd5179d742b0db9293c4472b765f8 # frozen: 21.12b0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
rev: c5e8fa75dda5f764d20f66a215d71c21cfa198e1 # frozen: 5.10.1
hooks:
- id: isort
- repo: https://github.com/myint/autoflake
rev: 7a53fdafc82c33f446915b60fcac947c51279260 # frozen: v1.4
hooks:
- id: autoflake
- repo: https://github.com/asottile/pyupgrade
rev: e695ecd365119ab4e5463f6e49bea5f4b7ca786b # frozen: v2.31.0
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/asottile/setup-cfg-fmt
rev: 58b14248db425913ea7502c0b1af9d6653403e07 # frozen: v1.20.0
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/jackdewinter/pymarkdown
rev: cf71b3c9cb0c361c4a17eacb80ed52432b57b420 # frozen: 0.9.4
hooks:
- id: pymarkdown
args: [--disable-rules=MD013, scan]

12
.woodpecker.yml

@ -1,9 +1,9 @@
pipeline:
python-3.7:
group: test
image: python:3.7-slim # Alpine doesn't work for 3.7
image: python:3.7
commands:
- pip install pipenv==2021.11.23
- pip install pipenv==2022.1.8
- pipenv install --dev --deploy
- pipenv run almake test-pytest # We only test with pytest on 3.7
@ -20,9 +20,9 @@ pipeline:
python-3.9:
group: test
image: python:3.9-slim # Alpine image times out for some reason with 3.9
image: python:3.9
commands:
- pip install pipenv==2021.11.23
- pip install pipenv==2022.1.8 pre-commit==2.16.0
- pipenv install --dev --deploy
- pipenv run almake test
- pipenv run almake build-dist
@ -30,9 +30,9 @@ pipeline:
python-3.10:
group: test
image: python:3.10-alpine
image: python:3.10
commands:
- pip install pipenv==2021.11.23
- pip install pipenv==2022.1.8 pre-commit==2.16.0
- pipenv install --dev --deploy
- pipenv run almake test
- pipenv run almake build-dist

7
Makefile

@ -1,10 +1,5 @@
format:
python -m black .
python -m isort .
test:
python -m black --check .
python -m isort --check .
pre-commit run --all-files
python -m pflake8 .
python -m mypy --strict .
$(MAKE) test-pytest

3
Pipfile

@ -7,8 +7,6 @@ name = "pypi"
sporestack = {editable = true, path = "."}
[dev-packages]
# Have to do == because it's a pre-release.
black = "==21.12b0"
flake8 = "~=4.0"
pyproject-flake8 = "==0.0.1a2"
flake8-noqa = "~=1.2"
@ -16,7 +14,6 @@ pep8-naming = "~=0.12.1"
mypy = "==0.930"
pytest = "~=6.2"
pytest-cov = "~=3.0"
isort = "~=5.8"
types-requests = "~=2.25"

123
Pipfile.lock

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "332e87d408920da810397e416c5ae36ae0ce33237a903534140537ace099c76d"
"sha256": "5098fb1db6e80c142e7c703e2ba12ac99d5bb1af4d1c6da1e8bf53773bbbe12c"
},
"pipfile-spec": 6,
"requires": {},
@ -23,11 +23,11 @@
},
"charset-normalizer": {
"hashes": [
"sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721",
"sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"
"sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd",
"sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"
],
"markers": "python_version >= '3'",
"version": "==2.0.9"
"version": "==2.0.10"
},
"click": {
"hashes": [
@ -99,11 +99,11 @@
"socks"
],
"hashes": [
"sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24",
"sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
"sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61",
"sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==2.26.0"
"version": "==2.27.1"
},
"segno": {
"hashes": [
@ -135,11 +135,11 @@
},
"urllib3": {
"hashes": [
"sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece",
"sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"
"sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed",
"sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
"version": "==1.26.7"
"version": "==1.26.8"
}
},
"develop": {
@ -167,14 +167,6 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==21.4.0"
},
"black": {
"hashes": [
"sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3",
"sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"
],
"index": "pypi",
"version": "==21.12b0"
},
"bleach": {
"hashes": [
"sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da",
@ -200,19 +192,11 @@
},
"charset-normalizer": {
"hashes": [
"sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721",
"sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"
"sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd",
"sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"
],
"markers": "python_version >= '3'",
"version": "==2.0.9"
},
"click": {
"hashes": [
"sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3",
"sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"
],
"markers": "python_version >= '3.6'",
"version": "==8.0.3"
"version": "==2.0.10"
},
"colorama": {
"hashes": [
@ -331,14 +315,6 @@
],
"version": "==1.1.1"
},
"isort": {
"hashes": [
"sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7",
"sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"
],
"index": "pypi",
"version": "==5.10.1"
},
"jinja2": {
"hashes": [
"sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8",
@ -349,11 +325,11 @@
},
"keyring": {
"hashes": [
"sha256:3dc0f66062a4f8f6f2ce30d6a516e6e623e6c3c2e76864204ceaf64695408f07",
"sha256:88f206024295e3c6fb16bb0a60fb4bb7ec1185629dc5a729f12aa7c236d01387"
"sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9",
"sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261"
],
"markers": "python_version >= '3.6'",
"version": "==23.4.0"
"markers": "python_version >= '3.7'",
"version": "==23.5.0"
},
"markupsafe": {
"hashes": [
@ -478,19 +454,12 @@
"markers": "python_version >= '3.6'",
"version": "==21.3"
},
"pathspec": {
"hashes": [
"sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a",
"sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"
],
"version": "==0.9.0"
},
"pdoc": {
"hashes": [
"sha256:8d6cdf6f28ac57fe9a28aaab7db3a982f0c9b3f3edad6d3cd148cb3111bcda78"
"sha256:d06c3854d039e603e5b1047c91763f23c092a66873cd1b61653f62bb2506c360"
],
"index": "pypi",
"version": "==8.1.0"
"version": "==8.2.0"
},
"pep517": {
"hashes": [
@ -514,14 +483,6 @@
],
"version": "==1.8.2"
},
"platformdirs": {
"hashes": [
"sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca",
"sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"
],
"markers": "python_version >= '3.7'",
"version": "==2.4.1"
},
"pluggy": {
"hashes": [
"sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159",
@ -556,11 +517,11 @@
},
"pygments": {
"hashes": [
"sha256:59b895e326f0fb0d733fd28c6839bd18ad0687ba20efc26d4277fd1d30b971f4",
"sha256:9135c1af61eec0f650cd1ea1ed8ce298e54d56bcd8cc2ef46edd7702c171337c"
"sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65",
"sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"
],
"markers": "python_version >= '3.5'",
"version": "==2.11.1"
"version": "==2.11.2"
},
"pyparsing": {
"hashes": [
@ -607,11 +568,11 @@
"socks"
],
"hashes": [
"sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24",
"sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
"sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61",
"sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
"version": "==2.26.0"
"version": "==2.27.1"
},
"requests-toolbelt": {
"hashes": [
@ -622,10 +583,11 @@
},
"rfc3986": {
"hashes": [
"sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835",
"sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"
"sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd",
"sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"
],
"version": "==1.5.0"
"markers": "python_version >= '3.7'",
"version": "==2.0.0"
},
"six": {
"hashes": [
@ -645,11 +607,11 @@
},
"tomli": {
"hashes": [
"sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f",
"sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"
"sha256:b5bde28da1fed24b9bd1d4d2b8cba62300bfb4ec9a6187a957e8ddb9434c5224",
"sha256:c292c34f58502a1eb2bbb9f5bbc9a5ebc37bee10ffb8c2d6bbdfa8eb13cc14e1"
],
"markers": "python_version >= '3.6'",
"version": "==1.2.3"
"markers": "python_version >= '3.7'",
"version": "==2.0.0"
},
"tqdm": {
"hashes": [
@ -669,11 +631,18 @@
},
"types-requests": {
"hashes": [
"sha256:ad18284931c5ddbf050ccdd138f200d18fd56f88aa3567019d8da9b2d4fe0344",
"sha256:d63fa617846dcefff5aa2d59e47ab4ffd806e4bb0567115f7adbb5e438302fe4"
"sha256:9c9390b18b222956155af6678570f452edafa3bb94bd5a4efe67da1105aa128c",
"sha256:a67dc1a8512312b8cb89f3ba95f9a0e69ef3436ae77c9bd4f328cd88f17adda2"
],
"index": "pypi",
"version": "==2.26.3"
"version": "==2.27.5"
},
"types-urllib3": {
"hashes": [
"sha256:35c17be09e1bcef3b1e2101c5172b97cdb78330915973c741f4c1979d8405ef9",
"sha256:61a0099899b1472bfbae8ee6ad196950aac46705b99216188aa962ad1e514ed5"
],
"version": "==1.26.4"
},
"typing-extensions": {
"hashes": [
@ -685,11 +654,11 @@
},
"urllib3": {
"hashes": [
"sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece",
"sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"
"sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed",
"sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
"version": "==1.26.7"
"version": "==1.26.8"
},
"webencodings": {
"hashes": [

22
README.md

@ -2,18 +2,18 @@
## Requirements
* Python 3.7-3.10 (or maybe newer)
* Python 3.7-3.10 (or maybe newer)
## Installation
* `python3 -m pip install sporestack`
* Recommended: Create a virtual environment, first. Can use `pipenv`, as well.
* `pip install sporestack`
* Recommended: Create a virtual environment, first. Can use `pipenv`, as well.
## Running without installing (preferred)
* Make sure `pipx` is installed.
* `pipx run sporestack`
* Make sure you're on the latest version with `sporestack version`.
* Make sure `pipx` is installed.
* `pipx run sporestack`
* Make sure you're on the latest version with `sporestack version`.
## Screenshot
@ -37,13 +37,15 @@ More examples on the [website](https://sporestack.com).
## Notes
* You can use `--settlement-token` if you don't want to pay with QR codes all the time.
* If using a .onion API endpoint, will try to use a local Tor proxy if connecting to a .onion URL. (127.0.0.1:9050)
* You can use `--settlement-token` if you don't want to pay with QR codes all the time.
* If using a .onion API endpoint, will try to use a local Tor proxy if connecting to a .onion URL. (127.0.0.1:9050)
## Developing
* `pipenv install --deploy --dev`
* `pipenv run make test` (If you don't have `make`, use `almake`)
* `pip install pipenv pre-commit`
* `pipenv install --deploy --dev`
* `pipenv run make test` (If you don't have `make`, use `almake`)
* Hint: `pre-commit run` is a faster way to run some of the tests/autofixers.
## Licence

24
setup.cfg

@ -1,11 +1,21 @@
[metadata]
name = sporestack
version = 5.1.2
author = SporeStack
author_email = admin@sporestack.com
description = SporeStack.com library and client. Launch servers with Monero or Bitcoin.
long_description = file: README.md
long_description_content_type = text/markdown
url = https://sporestack.com/
author = SporeStack
author_email = admin@sporestack.com
license = Unlicense
license_file = LICENSE.txt
classifiers =
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
keywords =
bitcoin
bitcoincash
@ -15,19 +25,17 @@ keywords =
infrastructure
vps
virtual private server
license = Unlicense
url = https://sporestack.com/
[options]
python_requires = >=3.7
packages = find:
package_dir = =src
install_requires =
segno
pydantic
requests[socks]>=2.22.0
segno
typer
pydantic
importlib-metadata;python_version<"3.8"
python_requires = >=3.7
package_dir = =src
zip_safe = False
[options.packages.find]

18
src/sporestack/api.py

@ -12,7 +12,7 @@ from pydantic import BaseModel
from .models import NetworkInterface, Payment
class TokenEnable(object):
class TokenEnable:
url = "/token/{token}/enable"
method = "POST"
@ -25,7 +25,7 @@ class TokenEnable(object):
payment: Payment
class TokenAdd(object):
class TokenAdd:
url = "/token/{token}/add"
method = "POST"
@ -38,7 +38,7 @@ class TokenAdd(object):
payment: Payment
class TokenBalance(object):
class TokenBalance:
url = "/token/{token}/balance"
method = "GET"
@ -48,7 +48,7 @@ class TokenBalance(object):
usd: str
class ServerLaunch(object):
class ServerLaunch:
url = "/server/{machine_id}/launch"
method = "POST"
@ -81,7 +81,7 @@ class ServerLaunch(object):
flavor: str
class ServerTopup(object):
class ServerTopup:
url = "/server/{machine_id}/topup"
method = "POST"
@ -103,7 +103,7 @@ class ServerTopup(object):
latest_api_version: int
class ServerInfo(object):
class ServerInfo:
url = "/server/{machine_id}/info"
method = "GET"
@ -116,16 +116,16 @@ class ServerInfo(object):
region: str
class ServerStart(object):
class ServerStart:
url = "/server/{machine_id}/start"
method = "POST"
class ServerStop(object):
class ServerStop:
url = "/server/{machine_id}/stop"
method = "POST"
class ServerDelete(object):
class ServerDelete:
url = "/server/{machine_id}/delete"
method = "POST"

6
src/sporestack/cli.py

@ -344,10 +344,10 @@ def pretty_machine_info(info: Dict[str, Any]) -> str:
human_expiration = time.strftime("%Y-%m-%d %H:%M:%S %z", time.localtime(expiration))
if "running" in info:
msg += "Running: {}\n".format(info["running"])
msg += "Expiration: {} ({})\n".format(expiration, human_expiration)
msg += f"Expiration: {expiration} ({human_expiration})\n"
time_to_live = expiration - int(time.time())
hours = time_to_live // 3600
msg += "Server will be deleted in {} hours.".format(hours)
msg += f"Server will be deleted in {hours} hours."
return msg
@ -374,7 +374,7 @@ def list() -> None:
"%Y-%m-%d %H:%M:%S %z", time.localtime(expiration)
)
msg = hostname
msg += " expired ({} {}): ".format(expiration, human_expiration)
msg += f" expired ({expiration} {human_expiration}): "
msg += str(e)
typer.echo(msg)

Loading…
Cancel
Save