Skip to content
39 changes: 27 additions & 12 deletions squarecloud/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class AppCache:
'_logs',
'_backup',
'_app_data',
'_snapshot'
)

def __init__(self) -> None:
Expand All @@ -56,6 +57,7 @@ def __init__(self) -> None:
self._status: StatusData | None = None
self._logs: LogsData | None = None
self._backup: Snapshot | None = None
self._snapshot: Snapshot | None = None
self._app_data: AppData | None = None

@property
Expand Down Expand Up @@ -92,6 +94,17 @@ def backup(self) -> Snapshot:
"""
return self._backup

@property
def snapshot(self) -> Snapshot:
"""
The snapshot method is a property that returns the cached Snapshot of
the application.

:return: The value of the _snapshot attribute
:rtype: Snapshot
"""
return self._snapshot

@property
def app_data(self) -> AppData:
"""
Expand All @@ -115,6 +128,7 @@ def clear(self) -> None:
self._logs = None
self._backup = None
self._app_data = None
self._snapshot = None

def update(self, *args) -> None:
"""
Expand All @@ -135,6 +149,7 @@ def update(self, *args) -> None:
self._logs = arg
elif isinstance(arg, Snapshot):
self._backup = arg
self._snapshot = arg
elif isinstance(arg, AppData):
self._app_data = arg
else:
Expand Down Expand Up @@ -473,7 +488,7 @@ async def backup(self, *_args, **_kwargs) -> Snapshot:
"""
backup: Snapshot = await self.client.snapshot(self.id)
return backup

@_update_cache
@_notify_listener(Endpoint.snapshot())
async def snapshot(self, *_args, **_kwargs) -> Snapshot:
Expand Down Expand Up @@ -657,7 +672,7 @@ async def github_integration(self, access_token: str) -> str:
async def domain_analytics(self) -> DomainAnalytics:
"""
Retrieve analytics data for the application's domain.

:param self: Refer to the instance of the class.
:returns: An instance of :class:`DomainAnalytics` containing analytics data for the domain.
:rtype: DomainAnalytics
Expand Down Expand Up @@ -686,11 +701,11 @@ async def set_custom_domain(self, custom_domain: str) -> Response:
async def all_backups(self) -> list[SnapshotInfo]:
backups: list[SnapshotInfo] = await self.client.all_app_snapshots(self.id)
return backups

async def all_snapshots(self) -> list[SnapshotInfo]:
"""
Retrieve all snapshots of the application.

:return: A list of SnapshotInfo objects representing all snapshots of the application.
:rtype: list[SnapshotInfo]
"""
Expand All @@ -701,15 +716,15 @@ async def all_snapshots(self) -> list[SnapshotInfo]:
async def move_file(self, origin: str, dest: str) -> Response:
"""
Moves a file from the origin path to the destination path within the application.

:param origin: The source path of the file to be moved.
:type origin: str
:param dest: The destination path where the file should be moved.
:type dest: str
:return: A Response object containing the result of the file move operation.
:rtype: Response
"""

return await self.client.move_app_file(self.id, origin, dest)

async def current_integration(self) -> Response:
Expand All @@ -719,13 +734,13 @@ async def current_integration(self) -> Response:
async def dns_records(self) -> list[DNSRecord]:
"""
Retrieve the DNS records associated with the application.

:returns: A list of DNSRecord objects representing the DNS records.
:rtype: list[DNSRecord]
"""

return await self.client.dns_records(self.id)

async def get_envs(self) -> dict[str, str]:
"""
Get environment variables of the application.
Expand All @@ -745,7 +760,7 @@ async def set_envs(self, envs: dict[str, str]) -> dict[str,str]:
:rtype: dict[str, str]
"""
return await self.client.set_app_envs(self.id, envs)

async def delete_envs(self, keys: list[str]) -> dict[str,str]:
"""
Deletes environment variables from the application.
Expand All @@ -756,7 +771,7 @@ async def delete_envs(self, keys: list[str]) -> dict[str,str]:
:rtype: dict[str, str]
"""
return await self.client.delete_app_envs(self.id, keys)

async def overwrite_env(self, envs: dict[str, str]) -> dict[str,str]:
"""
Overwrites the environment variables for the application.
Expand All @@ -766,4 +781,4 @@ async def overwrite_env(self, envs: dict[str, str]) -> dict[str,str]:
:return: A dictionary of the environment variables.
:rtype: dict[str, str]
"""
return await self.client.overwrite_app_envs(self.id, envs)
return await self.client.overwrite_app_envs(self.id, envs)
4 changes: 4 additions & 0 deletions squarecloud/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def __init__(
"""
self.log_level = log_level
self._api_key = api_key

if not isinstance(self._api_key, str):
raise TypeError("api_key must be str")

self._http = HTTPClient(api_key=api_key)
self.logger = logger
logger.setLevel(log_level)
Expand Down
9 changes: 5 additions & 4 deletions squarecloud/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class PlanData(BaseDataClass):

name: str
memory: dict[str, Any]
duration: dict[str, Any] | None
duration: int | None


class Language(BaseDataClass):
Expand Down Expand Up @@ -139,6 +139,7 @@ class UserData(BaseDataClass):
name: str
plan: PlanData
email: str | None = None
locale: str | None = None


class LogsData(BaseDataClass):
Expand Down Expand Up @@ -306,13 +307,13 @@ def date_time(self) -> datetime:
return datetime.fromisoformat(self.date)
class ExtraBaseAnalytics(BaseAnalytics):
type: str
class Visits(BaseAnalytics):
class Visits(BaseAnalytics):
pass
class Countries(ExtraBaseAnalytics):
class Countries(ExtraBaseAnalytics):
pass
class Devices(ExtraBaseAnalytics):
pass
class Os(ExtraBaseAnalytics):
class Os(ExtraBaseAnalytics):
pass
class Browsers(ExtraBaseAnalytics):
pass
Expand Down
9 changes: 9 additions & 0 deletions squarecloud/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ def __init__(self, domain: str, *args, **kwargs) -> None:
self.message = f'"{domain}" is a invalid custom domain'


class InvalidSubdomain(RequestError):
"""
raised when an invalid subdomain is provided
"""

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.message = 'The provided subdomain is invalid or already in use.'

class InvalidStart(InvalidConfig):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
Expand Down
10 changes: 5 additions & 5 deletions squarecloud/http/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
NotFoundError,
RequestError,
TooManyRequests,
InvalidSubdomain
)
from ..logger import logger
from .endpoints import Endpoint, Router
Expand Down Expand Up @@ -82,7 +83,7 @@ def _get_error(code: str) -> type[RequestError] | None:
'FEW_MEMORY': FewMemory,
'BAD_MEMORY': BadMemory,
'MISSING_CONFIG': MissingConfigFile,
'MISSING_DEPENDENCIES_FILE': MissingDependenciesFile,
'INVALID_DEPENDENCY': MissingDependenciesFile,
'MISSING_MAIN': MissingMainFile,
'INVALID_MAIN': InvalidMain,
'INVALID_DISPLAY_NAME': InvalidDisplayName,
Expand All @@ -94,11 +95,10 @@ def _get_error(code: str) -> type[RequestError] | None:
'INVALID_ACCESS_TOKEN': InvalidAccessToken,
'REGEX_VALIDATION': InvalidDomain,
'INVALID_START': InvalidStart,
'INVALID_SUBDOMAIN': InvalidSubdomain
}
error_class = errors.get(code, None)
if error_class is None:
return None
return error_class
return errors.get(code, None)



class HTTPClient:
Expand Down
2 changes: 1 addition & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def create_zip(config: ConfigFile | str):
with zipfile.ZipFile(buffer, 'w') as zip_file:
zip_file.writestr('requirements.txt', 'discord.py')

zip_file.writestr('main.py', "print('ok')")
zip_file.writestr('main.py', "print('ok')\nwhile True:pass")

zip_file.writestr('squarecloud.app', config)

Expand Down
20 changes: 10 additions & 10 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest

import squarecloud
from squarecloud import BackupInfo
from squarecloud import SnapshotInfo
from squarecloud.app import Application
from squarecloud.http import Response
from tests import GITHUB_ACCESS_TOKEN
Expand All @@ -24,12 +24,12 @@ async def test_app_status(self, app: Application):
async def test_app_logs(self, app: Application):
assert isinstance(await app.logs(), squarecloud.LogsData)

async def test_app_backup(self, app: Application):
assert isinstance(await app.backup(), squarecloud.Backup)
async def test_app_snapshot(self, app: Application):
assert isinstance(await app.snapshot(), squarecloud.Snapshot)

async def test_download_backup(self, app: Application):
backup = await app.backup()
zip_file = await backup.download()
async def test_download_snapshot(self, app: Application):
snapshot = await app.snapshot()
zip_file = await snapshot.download()
assert isinstance(zip_file, ZipFile)

async def test_app_github_integration(self, app: Application):
Expand All @@ -49,10 +49,10 @@ async def test_domain_analytics(self, app: Application):
async def test_set_custom_domain(self, app: Application):
assert isinstance(await app.set_custom_domain('test.com.br'), str)

async def test_get_all_backups(self, app: Application):
backups = await app.all_backups()
assert isinstance(backups, list)
assert isinstance(backups[0], BackupInfo)
async def test_get_all_snapshots(self, app: Application):
snapshots = await app.all_snapshots()
assert isinstance(snapshots, list)
assert isinstance(snapshots[0], SnapshotInfo)

async def test_move_file(self, app: Application):
response = await app.move_file('main.py', 'test.py')
Expand Down
16 changes: 8 additions & 8 deletions tests/test_app_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest

from squarecloud.app import Application
from squarecloud.data import Backup, LogsData, StatusData
from squarecloud.data import Snapshot, LogsData, StatusData


@pytest.mark.asyncio(scope='session')
Expand All @@ -25,19 +25,19 @@ async def test_status(self, app: Application):
assert cache.status is None
sleep(10)

async def test_backup(self, app: Application):
async def test_snapshot(self, app: Application):
cache = app.cache

assert cache.backup is None
assert cache.snapshot is None

backup = await app.backup(update_cache=False)
assert cache.backup is None
snapshot = await app.snapshot(update_cache=False)
assert cache.snapshot is None

cache.update(backup)
assert isinstance(cache.backup, Backup)
cache.update(snapshot)
assert isinstance(cache.snapshot, Snapshot)

cache.clear()
assert cache.backup is None
assert cache.snapshot is None

async def test_logs(self, app: Application):
cache = app.cache
Expand Down
14 changes: 7 additions & 7 deletions tests/test_capture_listeners.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from squarecloud import Endpoint, errors
from squarecloud.app import Application
from squarecloud.data import Backup, LogsData, StatusData
from squarecloud.data import Snapshot, LogsData, StatusData
from squarecloud.listeners import Listener


Expand Down Expand Up @@ -36,14 +36,14 @@ async def capture_status(before, after):

await app.status()

@_clear_listener_on_rerun(Endpoint.backup())
async def test_capture_backup(self, app: Application):
@app.capture(Endpoint.backup(), force_raise=True)
async def capture_backup(before, after):
@_clear_listener_on_rerun(Endpoint.snapshot())
async def test_capture_snapshot(self, app: Application):
@app.capture(Endpoint.snapshot(), force_raise=True)
async def capture_snapshot(before, after):
assert before is None
assert isinstance(after, Backup)
assert isinstance(after, Snapshot)

await app.backup()
await app.snapshot()

@_clear_listener_on_rerun(Endpoint.logs())
async def test_capture_logs(self, app: Application):
Expand Down
Loading