feat(models): converted to pydantic for all data models
This commit is contained in:
parent
0dda9b46fa
commit
c6b723a476
6 changed files with 329 additions and 315 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
__pycache__
|
||||
.cache
|
||||
.zipline
|
||||
dev.py
|
||||
|
|
180
poetry.lock
generated
180
poetry.lock
generated
|
@ -121,6 +121,20 @@ files = [
|
|||
{file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argcomplete"
|
||||
version = "3.2.3"
|
||||
description = "Bash tab completion for argparse"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "argcomplete-3.2.3-py3-none-any.whl", hash = "sha256:c12355e0494c76a2a7b73e3a59b09024ca0ba1e279fb9ed6c1b82d5b74b6a70c"},
|
||||
{file = "argcomplete-3.2.3.tar.gz", hash = "sha256:bf7900329262e481be5a15f56f19736b376df6f82ed27576fa893652c5de6c23"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
test = ["coverage", "mypy", "pexpect", "ruff", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "3.1.0"
|
||||
|
@ -191,6 +205,52 @@ files = [
|
|||
[package.extras]
|
||||
dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "24.3.0"
|
||||
description = "The uncompromising code formatter."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"},
|
||||
{file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"},
|
||||
{file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"},
|
||||
{file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"},
|
||||
{file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"},
|
||||
{file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"},
|
||||
{file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"},
|
||||
{file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"},
|
||||
{file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"},
|
||||
{file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"},
|
||||
{file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"},
|
||||
{file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"},
|
||||
{file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"},
|
||||
{file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"},
|
||||
{file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"},
|
||||
{file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"},
|
||||
{file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"},
|
||||
{file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"},
|
||||
{file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"},
|
||||
{file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"},
|
||||
{file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"},
|
||||
{file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
packaging = ">=22.0"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "cairocffi"
|
||||
version = "1.6.1"
|
||||
|
@ -450,6 +510,39 @@ webencodings = "*"
|
|||
doc = ["sphinx", "sphinx_rtd_theme"]
|
||||
test = ["flake8", "isort", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "datamodel-code-generator"
|
||||
version = "0.25.5"
|
||||
description = "Datamodel Code Generator"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
files = [
|
||||
{file = "datamodel_code_generator-0.25.5-py3-none-any.whl", hash = "sha256:3b62b42c8ebf2bb98cfbc24467b523c5b76780c585b72f4ac2fc1f1f576702ab"},
|
||||
{file = "datamodel_code_generator-0.25.5.tar.gz", hash = "sha256:545f897481a94781e32b3c26a452ce049320b091310729f7fc6fa780f6a87898"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
argcomplete = ">=1.10,<4.0"
|
||||
black = ">=19.10b0"
|
||||
genson = ">=1.2.1,<2.0"
|
||||
inflect = ">=4.1.0,<6.0"
|
||||
isort = ">=4.3.21,<6.0"
|
||||
jinja2 = ">=2.10.1,<4.0"
|
||||
packaging = "*"
|
||||
pydantic = [
|
||||
{version = ">=1.10.0,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.12\" and python_version < \"4.0\""},
|
||||
{version = ">=1.10.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.11\" and python_version < \"3.12\""},
|
||||
{version = ">=1.9.0,<2.4.0 || >2.4.0,<3.0", extras = ["email"], markers = "python_version >= \"3.10\" and python_version < \"3.11\""},
|
||||
]
|
||||
pyyaml = ">=6.0.1"
|
||||
toml = {version = ">=0.10.0,<1.0.0", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
debug = ["PySnooper (>=0.4.1,<2.0.0)"]
|
||||
graphql = ["graphql-core (>=3.2.3,<4.0.0)"]
|
||||
http = ["httpx"]
|
||||
validation = ["openapi-spec-validator (>=0.2.8,<0.7.0)", "prance (>=0.18.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "defusedxml"
|
||||
version = "0.7.1"
|
||||
|
@ -475,6 +568,41 @@ files = [
|
|||
[package.extras]
|
||||
graph = ["objgraph (>=1.7.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "dnspython"
|
||||
version = "2.6.1"
|
||||
description = "DNS toolkit"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"},
|
||||
{file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "sphinx (>=7.2.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"]
|
||||
dnssec = ["cryptography (>=41)"]
|
||||
doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"]
|
||||
doq = ["aioquic (>=0.9.25)"]
|
||||
idna = ["idna (>=3.6)"]
|
||||
trio = ["trio (>=0.23)"]
|
||||
wmi = ["wmi (>=1.5.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "email-validator"
|
||||
version = "2.1.1"
|
||||
description = "A robust email address syntax and deliverability validation library."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "email_validator-2.1.1-py3-none-any.whl", hash = "sha256:97d882d174e2a65732fb43bfce81a3a834cbc1bde8bf419e30ef5ea976370a05"},
|
||||
{file = "email_validator-2.1.1.tar.gz", hash = "sha256:200a70680ba08904be6d1eef729205cc0d687634399a5924d842533efb824b84"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
dnspython = ">=2.0.0"
|
||||
idna = ">=2.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "frozenlist"
|
||||
version = "1.4.1"
|
||||
|
@ -561,6 +689,16 @@ files = [
|
|||
{file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "genson"
|
||||
version = "1.2.2"
|
||||
description = "GenSON is a powerful, user-friendly JSON Schema generator."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghp-import"
|
||||
version = "2.1.0"
|
||||
|
@ -634,6 +772,21 @@ files = [
|
|||
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inflect"
|
||||
version = "5.6.2"
|
||||
description = "Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "inflect-5.6.2-py3-none-any.whl", hash = "sha256:b45d91a4a28a4e617ff1821117439b06eaa86e2a4573154af0149e9be6687238"},
|
||||
{file = "inflect-5.6.2.tar.gz", hash = "sha256:aadc7ed73928f5e014129794bbac03058cca35d0a973a5fc4eb45c7fa26005f9"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"]
|
||||
testing = ["pygments", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.13.2"
|
||||
|
@ -1032,6 +1185,17 @@ files = [
|
|||
{file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
|
@ -1182,6 +1346,7 @@ files = [
|
|||
|
||||
[package.dependencies]
|
||||
annotated-types = ">=0.4.0"
|
||||
email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""}
|
||||
pydantic-core = "2.16.3"
|
||||
typing-extensions = ">=4.6.1"
|
||||
|
||||
|
@ -1309,9 +1474,9 @@ files = [
|
|||
astroid = ">=3.1.0,<=3.2.0-dev0"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
dill = [
|
||||
{version = ">=0.2", markers = "python_version < \"3.11\""},
|
||||
{version = ">=0.3.7", markers = "python_version >= \"3.12\""},
|
||||
{version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""},
|
||||
{version = ">=0.2", markers = "python_version < \"3.11\""},
|
||||
]
|
||||
isort = ">=4.2.5,<5.13.0 || >5.13.0,<6"
|
||||
mccabe = ">=0.6,<0.8"
|
||||
|
@ -1624,6 +1789,17 @@ webencodings = ">=0.4"
|
|||
doc = ["sphinx", "sphinx_rtd_theme"]
|
||||
test = ["flake8", "isort", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.10.2"
|
||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
|
@ -1829,4 +2005,4 @@ multidict = ">=4.0"
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10 || ^3.11 || ^3.12"
|
||||
content-hash = "81bf41a2234efa4a9682bf29ea427b0e090c72c72134b7296cc135c4952199eb"
|
||||
content-hash = "3cd54cc2b740040bab9d9bae7bc04645893711c141516a9182f6c68fcf6b128b"
|
||||
|
|
|
@ -19,6 +19,7 @@ optional = true
|
|||
[tool.poetry.group.dev.dependencies]
|
||||
pylint = "^3.0.3"
|
||||
ruff = "^0.3.4"
|
||||
datamodel-code-generator = "^0.25.5"
|
||||
|
||||
[tool.poetry.group.docs]
|
||||
optional = true
|
||||
|
|
|
@ -1,64 +1,67 @@
|
|||
"""This is a list of all the models used in PyZipline. They are used to represent the data returned from the Zipline API."""
|
||||
from typing import List, Dict, Optional
|
||||
from datetime import datetime
|
||||
from pyzipline.utils import convert_str_to_datetime
|
||||
from typing import Dict, List, Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class File:
|
||||
class File(BaseModel):
|
||||
"""File object used for uploading files to Zipline
|
||||
|
||||
Attributes:
|
||||
created_at (datetime.datetime): Datetime object of when the file was created
|
||||
createdAt (datetime.datetime): Datetime object of when the file was created
|
||||
id (int): ID of the file
|
||||
mimetype (str): String of the file's mimetype
|
||||
views (int): Integer of the number of views the file has
|
||||
name (str): String of the file's name
|
||||
size (int): Integer of the file's size in bytes
|
||||
favorite (bool): Boolean of whether the file is favorited
|
||||
original_name (Optional[str]): String of the file's original name
|
||||
originalName (Optional[str]): String of the file's original name
|
||||
url (Optional[str]): String of the file's URL
|
||||
max_views (Optional[int]): Integer of the file's maximum number of views
|
||||
expired_at (Optional[datetime]): Datetime object of when the file will expire
|
||||
maxViews (Optional[int]): Integer of the file's maximum number of views
|
||||
expiredAt (Optional[datetime]): Datetime object of when the file will expire
|
||||
thumbnail (Optional[str]): String of the file's thumbnail URL
|
||||
folder_id (Optional[int]): Integer of the file's folder ID
|
||||
folderId (Optional[int]): Integer of the file's folder ID
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
createdAt: datetime,
|
||||
id: int, # pylint: disable=redefined-builtin
|
||||
mimetype: str,
|
||||
views: int,
|
||||
name: str,
|
||||
size: int,
|
||||
favorite: bool,
|
||||
originalName: str = None,
|
||||
url: str = None,
|
||||
maxViews: int = None,
|
||||
expiredAt: datetime = None,
|
||||
thumbnail: str = None,
|
||||
folderId: int = None,
|
||||
**kwargs
|
||||
):
|
||||
self.created_at = createdAt
|
||||
self.id = id
|
||||
self.mimetype = mimetype
|
||||
self.views = views
|
||||
self.name = name
|
||||
self.size = size
|
||||
self.favorite = favorite
|
||||
self.original_name = originalName
|
||||
self.url = url
|
||||
self.max_views = maxViews
|
||||
self.expired_at = expiredAt
|
||||
self.thumbnail = thumbnail
|
||||
self.folder_id = folderId
|
||||
self.__dict__.update(kwargs)
|
||||
createdAt: datetime
|
||||
id: int
|
||||
mimetype: str
|
||||
views: int
|
||||
name: str
|
||||
size: int
|
||||
favorite: bool
|
||||
originalName: Optional[str] = None
|
||||
url: Optional[str] = None
|
||||
maxViews: Optional[int] = None
|
||||
expiredAt: Optional[datetime] = None
|
||||
thumbnail: Optional[str] = None
|
||||
folderId: Optional[int] = None
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Invite(BaseModel):
|
||||
"""Invite object used for managing invites
|
||||
|
||||
class Result:
|
||||
Attributes:
|
||||
id (int): Integer ID of the invite
|
||||
code (str): String of the invite's code
|
||||
createdAt (datetime): Datetime object of when the invite was created
|
||||
expiresAt (datetime): Datetime object of when the invite will expire
|
||||
used (bool): Boolean of whether the invite has been used
|
||||
createdById (int): Integer ID of the user who created the invite
|
||||
"""
|
||||
id: int
|
||||
code: str
|
||||
createdAt: datetime
|
||||
expiresAt: datetime
|
||||
used: bool
|
||||
createdById: int
|
||||
|
||||
def __str__(self):
|
||||
return self.code
|
||||
|
||||
class Result(BaseModel):
|
||||
"""Result returned from low-level RestAdapter
|
||||
|
||||
Attributes:
|
||||
|
@ -67,50 +70,44 @@ class Result:
|
|||
message (str = ''): Human readable result
|
||||
data (Union[List[Dict], Dict]): Python List of Dictionaries (or maybe just a single Dictionary on error)
|
||||
"""
|
||||
def __init__(self, success: bool, status_code: int, message: str = '', data: List[Dict] = None):
|
||||
self.success = success
|
||||
self.status_code = status_code
|
||||
self.message = message
|
||||
self.data = data if data else {}
|
||||
success: bool
|
||||
status_code: int
|
||||
message: str = ''
|
||||
data: Union[List[Dict], Dict] = {}
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.status_code}: {self.message}\n{self.data}"
|
||||
return f"{self.status_code}: {self.message}"
|
||||
|
||||
|
||||
class Invite:
|
||||
"""Invite object used for managing invites
|
||||
class TypesCountItem(BaseModel):
|
||||
"""Model used in [StatsData](.#pyzipline.models.StatsData) for storing the number of files with a specific mimetype
|
||||
|
||||
Attributes:
|
||||
id (int): Integer ID of the invite
|
||||
code (str): String of the invite's code
|
||||
created_at (datetime): Datetime object of when the invite was created
|
||||
expires_at (datetime): Datetime object of when the invite will expire
|
||||
used (bool): Boolean of whether the invite has been used
|
||||
created_by_id (int): Integer ID of the user who created the invite
|
||||
mimetype (str): String of the mimetype
|
||||
count (int): Integer of the number of files with this mimetype
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
id: int, # pylint: disable=redefined-builtin
|
||||
code: str,
|
||||
createdAt: str,
|
||||
expiresAt: str,
|
||||
used: bool,
|
||||
createdById: int,
|
||||
**kwargs
|
||||
):
|
||||
self.id = id
|
||||
self.code = code
|
||||
self.created_at = convert_str_to_datetime(createdAt)
|
||||
self.expires_at = convert_str_to_datetime(expiresAt)
|
||||
self.used = used
|
||||
self.created_by_id = createdById
|
||||
self.__dict__.update(kwargs)
|
||||
count: int
|
||||
mimetype: str
|
||||
|
||||
def __str__(self):
|
||||
return self.code
|
||||
return f"{self.mimetype}: {self.count}"
|
||||
|
||||
class Stats:
|
||||
"""Stats object used for retrieving stats
|
||||
|
||||
class CountByUserItem(BaseModel):
|
||||
"""Model used in [StatsData](.#pyzipline.models.StatsData) for storing the number of files uploaded by a user
|
||||
|
||||
Attributes:
|
||||
username (str): String of the username
|
||||
count (int): Integer of the number of files uploaded by this user
|
||||
"""
|
||||
count: int
|
||||
username: str
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.username}: {self.count}"
|
||||
|
||||
|
||||
class StatsData(BaseModel):
|
||||
"""Stats data model
|
||||
|
||||
Attributes:
|
||||
id (int): Integer ID of the stats
|
||||
|
@ -124,225 +121,64 @@ class Stats:
|
|||
types_count (Optional[List[Mimetype]]): List of Mimetype objects
|
||||
count_by_user (Optional[List[CountByUser]]): List of CountByUser objects
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
id: int, # pylint: disable=redefined-builtin
|
||||
createdAt: datetime,
|
||||
data: dict,
|
||||
max_timestamp: Optional[datetime] = None
|
||||
):
|
||||
self.id = id
|
||||
self.createdAt = createdAt
|
||||
self._data = data
|
||||
self.max_timestamp = max_timestamp
|
||||
self.size = self._data['size']
|
||||
self.size_num = self._data['size_num']
|
||||
self.count = self._data['count']
|
||||
self.count_users = self._data['count_users']
|
||||
self.views_count = self._data['views_count']
|
||||
self.types_count: list = self._data['types_count']
|
||||
self.count_by_user: list = self._data['count_by_user']
|
||||
if self.types_count is not None:
|
||||
new_types_count = []
|
||||
for mimetype_entry in self.types_count:
|
||||
if isinstance(mimetype_entry, dict):
|
||||
m = self.Mimetype(**mimetype_entry)
|
||||
new_types_count.append(m)
|
||||
self.types_count = new_types_count
|
||||
if self.count_by_user is not None:
|
||||
new_count_by_user = []
|
||||
for count_by_user_entry in self.count_by_user:
|
||||
if isinstance(count_by_user_entry, dict):
|
||||
c = self.CountByUser(**count_by_user_entry)
|
||||
new_count_by_user.append(c)
|
||||
self.count_by_user = new_count_by_user
|
||||
size: str
|
||||
count: int
|
||||
size_num: int
|
||||
count_users: int
|
||||
types_count: List[TypesCountItem]
|
||||
views_count: int
|
||||
count_by_user: List[CountByUserItem]
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
class Mimetype:
|
||||
"""Object used in [Stats](.#pyzipline.models.Stats) for storing the number of files with a specific mimetype
|
||||
|
||||
Attributes:
|
||||
mimetype (str): String of the mimetype
|
||||
count (int): Integer of the number of files with this mimetype"""
|
||||
def __init__(
|
||||
self,
|
||||
mimetype: str,
|
||||
count: int
|
||||
):
|
||||
self.mimetype = mimetype
|
||||
self.count = count
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.mimetype}: {self.count}"
|
||||
|
||||
class CountByUser:
|
||||
"""Object used in [Stats](.#pyzipline.models.Stats) for storing the number of files uploaded by a user
|
||||
|
||||
Attributes:
|
||||
username (str): String of the username
|
||||
count (int): Integer of the number of files uploaded by this user"""
|
||||
def __init__(
|
||||
self,
|
||||
username: str,
|
||||
count: int
|
||||
):
|
||||
self.username = username
|
||||
self.count = count
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.username}: {self.count}"
|
||||
|
||||
class OAuth:
|
||||
"""OAuth object used for managing OAuth
|
||||
class Stats(BaseModel):
|
||||
"""Stats model
|
||||
|
||||
Attributes:
|
||||
id (int): Integer ID of the OAuth
|
||||
provider (str): String of the OAuth's provider, one of 'DISCORD', 'GITHUB', 'GOOGLE'
|
||||
user_id (int): Integer ID of the user who owns the OAuth
|
||||
oauth_id (str): String of the OAuth's provider ID
|
||||
username (str): String of the OAuth's connected account's username
|
||||
token (str): String of the OAuth's access token
|
||||
refresh (Optional[str]): String of the OAuth's refresh token
|
||||
id (int): Integer ID of the stats
|
||||
createdAt (datetime): Datetime object of when the stats were created
|
||||
data (StatsData): StatsData object of the stats data
|
||||
max_timestamp (Optional[datetime]): Datetime object of the maximum timestamp of the stats
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
id: int, # pylint: disable=redefined-builtin
|
||||
provider: str,
|
||||
oauthId: int,
|
||||
providerId: str,
|
||||
username: str,
|
||||
token: str,
|
||||
refresh: Optional[str],
|
||||
**kwargs
|
||||
):
|
||||
self.id = id
|
||||
self.provider = provider
|
||||
self.oauth_id = oauthId
|
||||
self.provider_id = providerId
|
||||
self.username = username
|
||||
self.token = token
|
||||
self.refresh = refresh
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.provider
|
||||
id: int
|
||||
createdAt: datetime
|
||||
data: StatsData
|
||||
max_timestamp: str = Field(default=None)
|
||||
|
||||
|
||||
class User:
|
||||
"""Object containing user information
|
||||
class Embed(BaseModel):
|
||||
color: Optional[str] = None
|
||||
title: Optional[str] = None
|
||||
siteName: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
|
||||
/// admonition | Contains Sensitive Information
|
||||
type: danger
|
||||
Please be mindful of how you use/store this object, as it contains sensitive information such as the user's token and OAuth/TOTP information.
|
||||
///
|
||||
|
||||
Attributes:
|
||||
id (int): Integer ID of the user
|
||||
uuid (str): String of the user's UUID
|
||||
username (str): String of the user's username
|
||||
avatar (Optional[str]): String of the user's avatar, base64 encoded
|
||||
token (str): String of the user's token
|
||||
administrator (bool): Boolean of whether the user is an administrator
|
||||
super_admin (bool): Boolean of whether the user is a super administrator
|
||||
system_theme (str): String of the user's system theme
|
||||
embed (Embed): Embed object of the user's embed
|
||||
totp_secret (Optional[str]): String of the user's TOTP secret
|
||||
domains (List[str]): List of Strings of the user's domains
|
||||
oauth (Optional[List[OAuth]]): List of [OAuth](.#pyzipline.models.OAuth) objects
|
||||
ratelimit (Optional[datetime]): Datetime object of when the user's ratelimit expires
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
id: int, # pylint: disable=redefined-builtin
|
||||
uuid: str,
|
||||
username: str,
|
||||
avatar: Optional[str],
|
||||
token: str,
|
||||
administrator: bool,
|
||||
superAdmin: bool,
|
||||
systemTheme: str,
|
||||
embed: 'Embed',
|
||||
totpSecret: Optional[str],
|
||||
domains: List[str],
|
||||
oauth: Optional[List['OAuth']] = None,
|
||||
ratelimit: Optional[datetime] = None,
|
||||
**kwargs
|
||||
):
|
||||
self.id = id
|
||||
self.uuid = uuid
|
||||
self.username = username
|
||||
self.avatar = avatar
|
||||
self.token = token
|
||||
self.administrator = administrator
|
||||
self.super_admin = superAdmin
|
||||
self.system_theme = systemTheme
|
||||
self.embed = self.Embed(**embed)
|
||||
self.totp_secret = totpSecret
|
||||
self.domains = domains
|
||||
self.oauth = oauth
|
||||
self.ratelimit = ratelimit
|
||||
self.__dict__.update(kwargs)
|
||||
if self.oauth is not None:
|
||||
for oauth_entry in self.oauth:
|
||||
self.oauth.remove(oauth_entry)
|
||||
o = OAuth(**oauth_entry)
|
||||
self.oauth.append(o)
|
||||
class User(BaseModel):
|
||||
id: int
|
||||
uuid: str
|
||||
username: str
|
||||
avatar: Optional[str]
|
||||
token: str
|
||||
administrator: bool
|
||||
superAdmin: bool
|
||||
systemTheme: str
|
||||
embed: Embed
|
||||
ratelimit: None
|
||||
totpSecret: Optional[str]
|
||||
domains: List[str]
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
||||
|
||||
class Embed:
|
||||
"""Object containing a user's embed settings
|
||||
class Versions(BaseModel):
|
||||
stable: str
|
||||
upstream: str
|
||||
current: str
|
||||
|
||||
Attributes:
|
||||
color (Optional[str]): String of the embed's color
|
||||
title (Optional[str]): String of the embed's title
|
||||
site_name (Optional[str]): String of the embed's site name
|
||||
description (Optional[str]): String of the embed's description
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
color: str = None,
|
||||
title: str = None,
|
||||
siteName: str = None,
|
||||
description: str = None,
|
||||
**kwargs
|
||||
):
|
||||
self.color = color
|
||||
self.title = title
|
||||
self.site_name = siteName
|
||||
self.description = description
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
def __str__(self):
|
||||
if self.title is None:
|
||||
return "None"
|
||||
return self.title
|
||||
|
||||
class Version:
|
||||
"""Object containing the current, stable, and upstream versions of Zipline
|
||||
|
||||
Attributes:
|
||||
is_upstream (bool): Boolean of whether the current version is upstream (`trunk` branch)
|
||||
update_to_type (str): String of the type of update available, one of 'stable' or 'upstream'
|
||||
stable (str): String of the stable version
|
||||
upstream (str): String of the upstream version
|
||||
current (str): String of the current version
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
isUpstream: bool,
|
||||
updateToType: str,
|
||||
versions: {dict}
|
||||
):
|
||||
self.is_upstream = isUpstream
|
||||
self.update_to_type = updateToType
|
||||
self._versions = versions
|
||||
self.stable = self._versions['stable']
|
||||
self.upstream = self._versions['upstream']
|
||||
self.current = self._versions['upstream']
|
||||
class Version(BaseModel):
|
||||
isUpstream: bool
|
||||
updateToType: str
|
||||
versions: Versions
|
||||
|
||||
def __str__(self):
|
||||
return self.current
|
||||
return self.versions.current
|
||||
|
|
|
@ -8,6 +8,7 @@ from urllib3 import disable_warnings
|
|||
from pyzipline.exceptions import HTTPFailure, PyZiplineError
|
||||
from pyzipline.models import Result
|
||||
|
||||
|
||||
class RestAdapter:
|
||||
"""Constructor for RestAdapter
|
||||
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
"""This module contains the ZiplineApi class, which is the main class used to interact with the Zipline API."""
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Union, List
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List, Union
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
from pyzipline.exceptions import (FeatureDisabledError, Forbidden, NotFound,
|
||||
PyZiplineError)
|
||||
from pyzipline.models import File, Invite, Result, Stats, User, Version
|
||||
from pyzipline.rest_adapter import RestAdapter
|
||||
from pyzipline.exceptions import PyZiplineError, FeatureDisabledError, Forbidden, NotFound
|
||||
from pyzipline.models import User, File, Result, Invite, Stats, Version
|
||||
from pyzipline.utils import convert_datetime_to_str
|
||||
|
||||
# pylint: disable=not-a-mapping
|
||||
class ZiplineApi:
|
||||
"""Represents an instance of the Zipline API.
|
||||
|
||||
All API requests should be made through this class.
|
||||
class ZiplineApiConfig(BaseModel):
|
||||
"""Represents a configuration instance for the ZiplineApi class.
|
||||
|
||||
Args:
|
||||
hostname (str): The hostname of your Zipline instance, WITHOUT https or http.
|
||||
|
@ -20,15 +22,27 @@ class ZiplineApi:
|
|||
enforced_signing (bool): Normally set to True, but if having SSL/TLS cert validation issues, can turn off with False.
|
||||
logger (logging.Logger): If your app has a logger, pass it in here.
|
||||
"""
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
hostname: str
|
||||
token: str = ''
|
||||
ssl: bool = True
|
||||
enforced_signing: bool = True
|
||||
logger: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
# pylint: disable=not-a-mapping
|
||||
class ZiplineApi:
|
||||
"""Represents an instance of the Zipline API.
|
||||
|
||||
All API requests should be made through this class.
|
||||
|
||||
Args:
|
||||
config (ZiplineApiConfig): Configuration object for the ZiplineApi class
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
hostname: str,
|
||||
token: str = '',
|
||||
ssl: bool = True,
|
||||
enforced_signing: bool = True,
|
||||
logger: logging.Logger = None
|
||||
config: ZiplineApiConfig
|
||||
):
|
||||
self._rest_adapter = RestAdapter(hostname=hostname, token=token, ssl=ssl, enforced_signing=enforced_signing, logger=logger)
|
||||
self._rest_adapter = RestAdapter(hostname=config.hostname, token=config.token, ssl=config.ssl, enforced_signing=config.enforced_signing, logger=config.logger)
|
||||
|
||||
def create_invite(self, expiry: timedelta = timedelta(days=1), count: int = 1) -> Union[Invite, List[Invite]]:
|
||||
"""Create an invite code
|
||||
|
@ -302,11 +316,7 @@ class ZiplineApi:
|
|||
"""
|
||||
result = self._rest_adapter.get(endpoint="auth/invite")
|
||||
if result.status_code == 200:
|
||||
invites = []
|
||||
for invite in result.data:
|
||||
i = Invite(**invite)
|
||||
invites.append(i)
|
||||
return invites
|
||||
return [Invite(**invite) for invite in result.data]
|
||||
if result.status_code == 401:
|
||||
raise Forbidden(result.message)
|
||||
if result.message == 'invites are disabled':
|
||||
|
@ -417,11 +427,7 @@ class ZiplineApi:
|
|||
"""
|
||||
result = self._rest_adapter.get(endpoint="users")
|
||||
if result.status_code == 200:
|
||||
users = []
|
||||
for user in result.data:
|
||||
u = User(**user)
|
||||
users.append(u)
|
||||
return users
|
||||
return [User(**user) for user in result.data]
|
||||
if result.status_code == 403:
|
||||
raise Forbidden(result.message)
|
||||
raise PyZiplineError(f"{result.status_code}: {result.message}\n{result.data}")
|
||||
|
@ -445,7 +451,7 @@ class ZiplineApi:
|
|||
///
|
||||
|
||||
Args:
|
||||
amount (int ): Number of stats to retrieve
|
||||
amount (int): Number of stats to retrieve
|
||||
force_update (bool): Force the Zipline instance to update its statistics before returning them, requires administrator
|
||||
|
||||
Raises:
|
||||
|
@ -463,14 +469,7 @@ class ZiplineApi:
|
|||
else:
|
||||
result = self._rest_adapter.get(endpoint="stats", params={'amount': amount})
|
||||
if result.status_code == 200:
|
||||
if amount > 1:
|
||||
stats_list = []
|
||||
for stats in result.data:
|
||||
s = Stats(**stats)
|
||||
stats_list.append(s)
|
||||
return stats_list
|
||||
data = result.data[0] if isinstance(result.data, list) else result.data
|
||||
return Stats(**data)
|
||||
return [Stats(**stats) for stats in result.data]
|
||||
if result.status_code in (401, 403):
|
||||
raise Forbidden(result.message)
|
||||
raise PyZiplineError(f"{result.status_code}: {result.message}\n{result.data}")
|
||||
|
|
Loading…
Reference in a new issue