Skip to content

Commit f0b76a4

Browse files
✨ feat: added endpoints "LAST_DEPLOYS" and "GITHUB_INTEGRATION"
1 parent c6f57a5 commit f0b76a4

File tree

9 files changed

+155
-25
lines changed

9 files changed

+155
-25
lines changed

pyproject.toml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,6 @@ pre-commit = "^3.3.3"
2828
ruff = "^0.0.289"
2929
memory-profiler = "^0.61.0"
3030

31-
[tool.poetry.group.doc.dependencies]
32-
mkdocs-material = "^9.1.21"
33-
mkdocstrings = "^0.22.0"
34-
mkdocstrings-python = "^1.2.1"
35-
termynal = "^0.11.0"
36-
mkdocs-table-reader-plugin = "^2.0.1"
37-
3831
[build-system]
3932
requires = ["poetry-core"]
4033
build-backend = "poetry.core.masonry.api"

squarecloud/app.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1+
from __future__ import annotations
2+
13
from abc import ABC
24
from io import BytesIO
35
from typing import TYPE_CHECKING, Callable
46

57
from pydantic import PositiveInt
68

7-
from .data import AppData, BackupData, FileInfo, LogsData, StatusData
9+
from .data import (
10+
AppData,
11+
BackupData,
12+
DeployData,
13+
FileInfo,
14+
LogsData,
15+
StatusData,
16+
)
817
from .errors import SquareException
918
from .file import File
1019
from .http import Endpoint, HTTPClient, Response
@@ -609,3 +618,32 @@ async def delete_file(self, path: str, **kwargs) -> Response:
609618
endpoint=endpoint, response=response
610619
)
611620
return response
621+
622+
async def last_deploys(self, **kwargs) -> list[list[DeployData]]:
623+
"""
624+
The last_deploys function returns a list of the last deploys for this
625+
application.
626+
627+
:param self: Represent the instance of the class
628+
:param: Pass in keyword arguments as a dictionary
629+
:return: A list of DeployData objects
630+
"""
631+
response: list[list[DeployData]] = await self.client.last_deploys(
632+
self.id, avoid_listener=True,
633+
)
634+
return response
635+
636+
async def github_integration(self, access_token: str, **kwargs) -> str:
637+
"""
638+
The create_github_integration function returns a webhook to integrate
639+
with a GitHub repository.
640+
641+
:param self: Access the properties of the class
642+
:param access_token: str: Authenticate the user with GitHub
643+
:param kwargs: Pass in additional arguments to the function
644+
:return: A string containing the webhook url
645+
"""
646+
webhook: str = await self.client.github_integration(
647+
self.id, access_token, avoid_listener=True,
648+
)
649+
return webhook

squarecloud/client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .data import (
1111
AppData,
1212
BackupData,
13+
DeployData,
1314
FileInfo,
1415
LogsData,
1516
StatisticsData,
@@ -583,3 +584,38 @@ async def app_data(self, app_id: str, **kwargs) -> AppData:
583584
endpoint=endpoint, response=response
584585
)
585586
return AppData(**response.response)
587+
588+
async def last_deploys(
589+
self, app_id: str, **kwargs
590+
) -> list[list[DeployData]]:
591+
"""
592+
The last_deploys function returns a list of DeployData objects.
593+
594+
:param self: Represent the instance of a class
595+
:param app_id: str: Specify the app id
596+
:param kwargs: Pass a variable number of keyword arguments to the
597+
function
598+
:return: A list of DeployData objects
599+
"""
600+
response: Response = await self._http.get_last_deploys(app_id)
601+
if not kwargs.get('avoid_listener'):
602+
endpoint: Endpoint = response.route.endpoint
603+
await self._listener.on_request(
604+
endpoint=endpoint, response=response
605+
)
606+
data = response.response
607+
return [[DeployData(**deploy) for deploy in _] for _ in data]
608+
609+
async def github_integration(
610+
self, app_id: str, access_token: str, **kwargs
611+
) -> str:
612+
response: Response = await self._http.create_github_integration(
613+
app_id=app_id, github_access_token=access_token
614+
)
615+
if not kwargs.get('avoid_listener'):
616+
endpoint: Endpoint = response.route.endpoint
617+
await self._listener.on_request(
618+
endpoint=endpoint, response=response
619+
)
620+
data = response.response
621+
return data.get('webhook')

squarecloud/data.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from datetime import datetime
34
from typing import Any, Dict, Literal
45

56
from pydantic import conint
@@ -120,7 +121,6 @@ class UserData:
120121
:ivar id: User ID;
121122
:ivar tag: Username
122123
:ivar plan: User plan
123-
:ivar blocklist: Whether to user is blocked
124124
:ivar email: User email
125125
126126
:type id: conint(ge=0)
@@ -268,16 +268,21 @@ class StatisticsData:
268268
:ivar apps: Amount of apps hosted
269269
:ivar websites: Amount of websites hosted
270270
:ivar ping: Service ping
271-
:ivar time: Time
272271
273272
:type users: conint(ge=0)
274273
:type apps: conint(ge=0)
275274
:type websites: conint(ge=0)
276275
:type ping: conint(ge=0)
277-
:type time: conint(ge=0)
278276
"""
279277

280278
users: conint(ge=0)
281279
apps: conint(ge=0)
282280
websites: conint(ge=0)
283281
ping: conint(ge=0)
282+
283+
284+
@dataclass(frozen=True)
285+
class DeployData:
286+
id: str
287+
state: str
288+
date: datetime

squarecloud/errors.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class BadRequestError(RequestError):
4545

4646
def __init__(self, *args, **kwargs):
4747
super().__init__(*args, **kwargs)
48-
self.message = 'Bad request: 400'
4948

5049

5150
class ApplicationNotFound(SquareException):
@@ -197,3 +196,8 @@ class MissingVersion(InvalidConfig):
197196
def __init__(self, *args, **kwargs):
198197
super().__init__(*args, **kwargs)
199198
self.message = 'Version value is missing in the config file'
199+
200+
201+
class InvalidAccessToken(RequestError):
202+
def __init__(self, *args, **kwargs):
203+
super().__init__(*args, **kwargs)

squarecloud/http/endpoints.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ class Endpoint:
5555
'METHOD': 'DELETE',
5656
'PATH': '/apps/{app_id}/files/delete?path={path}',
5757
},
58+
'LAST_DEPLOYS': {
59+
'METHOD': 'GET',
60+
'PATH': '/apps/{app_id}/deploy/list',
61+
},
62+
'GITHUB_INTEGRATION': {
63+
'METHOD': 'POST',
64+
'PATH': '/apps/{app_id}/deploy/git-webhook',
65+
},
5866
}
5967

6068
def __init__(self, name: str) -> None:
@@ -71,7 +79,7 @@ def __init__(self, name: str) -> None:
7179
:return: None
7280
"""
7381

74-
endpoint: Dict[str, Dict[str, Any]] = self.ENDPOINTS_V2[name]
82+
endpoint: Dict[str, Any] = self.ENDPOINTS_V2[name]
7583
self.name: str = name
7684
self.method: str = endpoint['METHOD']
7785
self.path: str = endpoint['PATH']
@@ -231,6 +239,19 @@ def statistics(cls) -> Endpoint:
231239
"""
232240
return cls('STATISTICS')
233241

242+
@classmethod
243+
def last_deploys(cls):
244+
"""
245+
The last_deploys function returns a list of the last deploys that have
246+
been made.
247+
"""
248+
249+
return cls('LAST_DEPLOYS')
250+
251+
@classmethod
252+
def github_integration(cls):
253+
return cls('GITHUB_INTEGRATION')
254+
234255

235256
# pylint: disable=too-few-public-methods
236257
class Router:

squarecloud/http/http_client.py

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
BadMemory,
1212
BadRequestError,
1313
FewMemory,
14+
InvalidAccessToken,
1415
InvalidDisplayName,
1516
InvalidMain,
1617
InvalidMemory,
@@ -64,7 +65,7 @@ def __repr__(self):
6465
return f'{Response.__name__}({self.data})'
6566

6667

67-
def _get_upload_error(code: str) -> type[RequestError]:
68+
def _get_upload_error(code: str) -> type[RequestError] | None:
6869
errors = {
6970
'FEW_MEMORY': FewMemory,
7071
'BAD_MEMORY': BadMemory,
@@ -78,10 +79,11 @@ def _get_upload_error(code: str) -> type[RequestError]:
7879
'MISSING_MEMORY': MissingMemory,
7980
'INVALID_VERSION': InvalidVersion,
8081
'MISSING_VERSION': MissingVersion,
82+
'INVALID_ACCESS_TOKEN': InvalidAccessToken,
8183
}
8284
error_class = errors.get(code, None)
8385
if error_class is None:
84-
return RequestError
86+
return
8587
else:
8688
return error_class
8789

@@ -138,13 +140,6 @@ async def request(self, route: Router, **kwargs) -> Response | bytes:
138140

139141
if status_code == 200:
140142
logger.debug(msg='request to route: ', extra=extra)
141-
if code and route.endpoint in (
142-
Endpoint.commit(),
143-
Endpoint.upload(),
144-
):
145-
error = _get_upload_error(
146-
code,
147-
)
148143
extra.pop('code')
149144
response: Response = Response(data=data, route=route)
150145
elif status_code == 404:
@@ -165,6 +160,9 @@ async def request(self, route: Router, **kwargs) -> Response | bytes:
165160
error = TooManyRequests
166161
else:
167162
error = RequestError
163+
164+
if _ := _get_upload_error(code):
165+
error = _
168166
if error:
169167
raise error(
170168
**extra_error_kwargs,
@@ -375,7 +373,7 @@ async def get_statistics(self) -> Response:
375373
The get_statistics function returns the statistics of the current
376374
market.
377375
378-
:param self: Access the attributes and methods of a class
376+
:param self: Represent the instance of a class
379377
:return: A Response object
380378
"""
381379
route: Router = Router(Endpoint.statistics())
@@ -392,6 +390,37 @@ async def get_app_data(self, app_id: str) -> Response:
392390
get data
393391
:return: A Response object
394392
"""
395-
route: Router = Router(Endpoint('APP_DATA'), app_id=app_id)
393+
route: Router = Router(Endpoint.app_data(), app_id=app_id)
394+
response: Response = await self.request(route)
395+
return response
396+
397+
async def get_last_deploys(self, app_id: str) -> Response:
398+
"""
399+
The get_last_deploys function returns the last deploys of an
400+
application.
401+
402+
:param self: Represent the instance of a class
403+
:param app_id: str: Specify the application id
404+
:return: A Response object
405+
"""
406+
route: Router = Router(Endpoint.last_deploys(), app_id=app_id)
396407
response: Response = await self.request(route)
397408
return response
409+
410+
async def create_github_integration(
411+
self, app_id: str, github_access_token: str
412+
) -> Response:
413+
"""
414+
The create_github_integration function returns a webhook to integrate
415+
with a GitHub repository.
416+
417+
:param self: Represent the instance of a class
418+
:param app_id: str: Identify the app that you want to create a GitHub
419+
integration for
420+
:param github_access_token: str: Authenticate the user
421+
:return: A response object
422+
"""
423+
route: Router = Router(Endpoint.github_integration(), app_id=app_id)
424+
body = {'access_token': github_access_token}
425+
response: Response = await self.request(route, json=body)
426+
return response

tests/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
load_dotenv()
1010
client = squarecloud.Client(os.getenv('KEY'))
1111

12+
GITHUB_ACCESS_TOKEN: str = os.getenv('GITHUB_ACCESS_TOKEN')
13+
1214

1315
def create_zip(include_squarecloud_app: bool = True):
1416
buffer = io.BytesIO()

tests/test_app.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from . import client
3+
from . import client, GITHUB_ACCESS_TOKEN
44

55

66
@pytest.mark.asyncio
@@ -13,3 +13,5 @@ async def test_basic_usage(self):
1313
await app.logs()
1414
await app.backup()
1515
await app.data()
16+
await app.github_integration(GITHUB_ACCESS_TOKEN)
17+
await app.last_deploys()

0 commit comments

Comments
 (0)