intial commit of tests, documentation
This commit is contained in:
29
pyteamsnap/models/__init__.py
Normal file
29
pyteamsnap/models/__init__.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from .availability import Availability
|
||||
from .availabilitysummary import AvailabilitySummary
|
||||
from .event import Event
|
||||
from .eventlineup import EventLineup
|
||||
from .eventlineupentry import EventLineupEntry
|
||||
from .location import Location
|
||||
from .me import Me
|
||||
from .member import Member
|
||||
from .memberstatistics import MemberStatistics
|
||||
from .opponent import Opponent
|
||||
from .statistics import Statistics
|
||||
from .team import Team
|
||||
from .user import User
|
||||
|
||||
__all__ = [
|
||||
"Availability",
|
||||
"AvailabilitySummary",
|
||||
"Event",
|
||||
"EventLineup",
|
||||
"EventLineupEntry",
|
||||
"Location",
|
||||
"Me",
|
||||
"Member",
|
||||
"MemberStatistics",
|
||||
"Opponent",
|
||||
"Statistics",
|
||||
"Team",
|
||||
"User",
|
||||
]
|
||||
22
pyteamsnap/models/availability.py
Normal file
22
pyteamsnap/models/availability.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Availability(BaseApiObject):
|
||||
rel = "availabilities"
|
||||
type = "availability"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- event_id
|
||||
- member_id
|
||||
- notes
|
||||
- notes_author_member_id
|
||||
- source
|
||||
- status_code
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
15
pyteamsnap/models/availabilitysummary.py
Normal file
15
pyteamsnap/models/availabilitysummary.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class AvailabilitySummary(BaseApiObject):
|
||||
rel = "availability_summaries"
|
||||
type = "availability_summary"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
"""
|
||||
return super().data
|
||||
93
pyteamsnap/models/base.py
Normal file
93
pyteamsnap/models/base.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from __future__ import annotations
|
||||
import apiclient.exceptions
|
||||
from apiclient import (
|
||||
APIClient,
|
||||
)
|
||||
import typing as T
|
||||
|
||||
# Import "preview" of Self typing
|
||||
# https://stackoverflow.com/a/70932112
|
||||
from typing_extensions import Self
|
||||
|
||||
|
||||
class BaseApiObject:
|
||||
rel: str = None
|
||||
version: str = None
|
||||
|
||||
def __init__(
|
||||
self, client: APIClient, data: T.Dict[str, T.Union[str, list]] = {}
|
||||
) -> None:
|
||||
"""
|
||||
|
||||
:param client:
|
||||
:param data: Data to instantiate instance, defaults to empty dict.
|
||||
"""
|
||||
self.client = client
|
||||
self._data = data
|
||||
self.rel = self.__class__.rel
|
||||
"""rel: Relationship between a linked resource and the current document"""
|
||||
|
||||
def __repr__(self):
|
||||
return f'TeamSnap<{self.__class__.__name__}:{self.id}> "{self.__str__()}"'
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._data.__getitem__(key)
|
||||
|
||||
def __setitem__(self, key, newvalue):
|
||||
return self._data.__setitem__(key, newvalue)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._data.items())
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
return self._data["id"]
|
||||
|
||||
@property
|
||||
def data(self) -> T.Dict[str, T.Union[str, list]]:
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
"""
|
||||
return self._data
|
||||
|
||||
@classmethod
|
||||
def search(cls, client: APIClient, **kwargs):
|
||||
try:
|
||||
results = client.query(cls.rel, "search", **kwargs)
|
||||
except apiclient.exceptions.ServerError as e:
|
||||
raise e
|
||||
return [cls(client, data=r) for r in results]
|
||||
|
||||
@classmethod
|
||||
def get(cls, client: APIClient, id: T.Union[int, str]) -> Self:
|
||||
r = client.get(f"{client.link(cls.rel)}/{id}")
|
||||
return cls(client, cls.rel, client.parse_response(r)[0])
|
||||
|
||||
@classmethod
|
||||
def new(cls, client: Self) -> Self:
|
||||
return cls(client, cls.rel)
|
||||
|
||||
def post(self) -> Self:
|
||||
data = {
|
||||
"template": {
|
||||
"data": [{"name": k, "value": v} for k, v in self.data.items()]
|
||||
}
|
||||
}
|
||||
r = self.client.post_item(self.rel, data=data)
|
||||
self._data = r
|
||||
return self
|
||||
|
||||
def put(self) -> Self:
|
||||
data = {
|
||||
"template": {
|
||||
"data": [{"name": k, "value": str(v)} for k, v in self.data.items()]
|
||||
}
|
||||
}
|
||||
id = self.data.get("id")
|
||||
r = self.client.put_item(self.rel, id=id, data=data)
|
||||
self._data = r
|
||||
return self
|
||||
|
||||
def delete(self):
|
||||
self.client.delete_item(self.rel, id=self.data["id"])
|
||||
59
pyteamsnap/models/event.py
Normal file
59
pyteamsnap/models/event.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Event(BaseApiObject):
|
||||
"""Associated object to a team; and represents an event or game that is tracked in the TeamSnap system.
|
||||
https://www.teamsnap.com/documentation/apiv3/objects#Events
|
||||
|
||||
"""
|
||||
|
||||
rel = "events"
|
||||
type = "event"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with strings:
|
||||
- type
|
||||
- additional_location_details
|
||||
- browser_time_zone
|
||||
- division_location_id
|
||||
- doesnt_count_towards_record
|
||||
- duration_in_minutes
|
||||
- game_type_code
|
||||
- icon_color
|
||||
- is_canceled
|
||||
- is_game
|
||||
- is_overtime
|
||||
- is_shootout
|
||||
- is_tbd
|
||||
- label
|
||||
- location_id
|
||||
- minutes_to_arrive_early
|
||||
- name
|
||||
- notes
|
||||
- notify_opponent
|
||||
- notify_opponent_contacts_email
|
||||
- notify_opponent_contacts_name
|
||||
- notify_opponent_notes
|
||||
- notify_team
|
||||
- notify_team_as_member_id
|
||||
- opponent_id
|
||||
- points_for_opponent
|
||||
- points_for_team
|
||||
- repeating_include
|
||||
- repeating_type_code
|
||||
- repeating_until
|
||||
- results
|
||||
- results_url
|
||||
- shootout_points_for_opponent
|
||||
- shootout_points_for_team
|
||||
- start_date
|
||||
- team_id
|
||||
- time_zone
|
||||
- tracks_availability
|
||||
- uniform
|
||||
"""
|
||||
return super().data
|
||||
15
pyteamsnap/models/eventlineup.py
Normal file
15
pyteamsnap/models/eventlineup.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class EventLineup(BaseApiObject):
|
||||
rel = "event_lineups"
|
||||
type = "event_lineup"
|
||||
version = "3.866.0"
|
||||
template = {}
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""
|
||||
:return: dict: dict with strings:
|
||||
"""
|
||||
return super().data
|
||||
27
pyteamsnap/models/eventlineupentry.py
Normal file
27
pyteamsnap/models/eventlineupentry.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class EventLineupEntry(BaseApiObject):
|
||||
rel = "event_lineup_entries"
|
||||
type = "event_lineup_entry"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""
|
||||
:return: dict: dict with strings:
|
||||
- member_id
|
||||
- sequence
|
||||
- label
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
|
||||
@classmethod
|
||||
def search(cls, client, **kwargs):
|
||||
# For some reason the query listed for search at this endpoint is for EventLineup, not EventLineupEntry
|
||||
# this is a workaround
|
||||
r = client.get(f"{client.link(cls.rel)}/search", params=kwargs)
|
||||
results = client.parse_response(r)
|
||||
[cls(client, rel=cls.rel, data=r) for r in results]
|
||||
return [cls(client, rel=cls.rel, data=r) for r in results]
|
||||
25
pyteamsnap/models/location.py
Normal file
25
pyteamsnap/models/location.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Location(BaseApiObject):
|
||||
rel = "locations"
|
||||
type = "location"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- name
|
||||
- url
|
||||
- phone
|
||||
- notes
|
||||
- address
|
||||
- latitude
|
||||
- longitude
|
||||
- team_id
|
||||
- is_retired
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
17
pyteamsnap/models/me.py
Normal file
17
pyteamsnap/models/me.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from .user import User
|
||||
|
||||
|
||||
class Me(User):
|
||||
"""The current user's object. It is not possible to create or delete users via the API;
|
||||
however, it is possible to update data on a user's record.
|
||||
https://www.teamsnap.com/documentation/apiv3/objects#Me
|
||||
|
||||
"""
|
||||
|
||||
rel = "me"
|
||||
type = "user"
|
||||
version = "3.866.0"
|
||||
|
||||
def __new__(self, client):
|
||||
data = client.parse_response(client.get(client.link(self.rel)))[0]
|
||||
return User(client=client, data=data)
|
||||
41
pyteamsnap/models/member.py
Normal file
41
pyteamsnap/models/member.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Member(BaseApiObject):
|
||||
"""A member (also referred to as a roster in our web and mobile apps) is a member of a team.
|
||||
https://www.teamsnap.com/documentation/apiv3/objects#Members
|
||||
|
||||
"""
|
||||
|
||||
rel = "members"
|
||||
type = "member"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- first_name
|
||||
- last_name
|
||||
- address_city
|
||||
- address_state
|
||||
- address_street1
|
||||
- address_street2
|
||||
- address_zip
|
||||
- birthday
|
||||
- gender
|
||||
- hide_address
|
||||
- hide_age
|
||||
- is_address_hidden
|
||||
- is_age_hidden
|
||||
- is_manager
|
||||
- is_non_player
|
||||
- is_ownership_pending
|
||||
- jersey_number
|
||||
- position
|
||||
- source_action
|
||||
- team_id
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
5
pyteamsnap/models/memberstatistics.py
Normal file
5
pyteamsnap/models/memberstatistics.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class MemberStatistics(BaseApiObject):
|
||||
rel = "member_statistics"
|
||||
22
pyteamsnap/models/opponent.py
Normal file
22
pyteamsnap/models/opponent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Opponent(BaseApiObject):
|
||||
rel = "opponents"
|
||||
type = "opponent"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- name
|
||||
- contacts_name
|
||||
- contacts_phone
|
||||
- contacts_email
|
||||
- notes
|
||||
- team_id
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
29
pyteamsnap/models/statistics.py
Normal file
29
pyteamsnap/models/statistics.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Statistics(BaseApiObject):
|
||||
rel = "statistics"
|
||||
type = "statistic"
|
||||
version = "3.866.0"
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- acronym
|
||||
- always_display_decimals
|
||||
- formula
|
||||
- is_in_descending_order
|
||||
- display_zero_totals
|
||||
- is_percentage
|
||||
- is_private
|
||||
- is_team_statistic
|
||||
- is_top_statistic
|
||||
- name
|
||||
- precision
|
||||
- statistic_group_id
|
||||
- team_id
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
43
pyteamsnap/models/team.py
Normal file
43
pyteamsnap/models/team.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class Team(BaseApiObject):
|
||||
"""Associated teams from your origin object. Full CRUD is possible with the teams endpoint.
|
||||
https://www.teamsnap.com/documentation/apiv3/objects#Teams
|
||||
|
||||
|
||||
"""
|
||||
|
||||
rel = "teams"
|
||||
type = "team"
|
||||
version = "3.866.0"
|
||||
|
||||
# Override this class property to add docstring
|
||||
# should not change functionality. Probably a better
|
||||
# to do this...
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- ad_unit_hero_id
|
||||
- ad_unit_hero_template_id
|
||||
- ad_unit_inline_id
|
||||
- division_id
|
||||
- division_name
|
||||
- is_ownership_pending
|
||||
- league_name
|
||||
- league_url
|
||||
- location_country
|
||||
- location_postal_code
|
||||
- name
|
||||
- owner_email
|
||||
- owner_first_name
|
||||
- owner_last_name
|
||||
- season_name
|
||||
- sport_id
|
||||
- team
|
||||
- time_zone
|
||||
- type
|
||||
"""
|
||||
return super().data
|
||||
28
pyteamsnap/models/user.py
Normal file
28
pyteamsnap/models/user.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from .base import BaseApiObject
|
||||
|
||||
|
||||
class User(BaseApiObject):
|
||||
rel = "users"
|
||||
type = "user"
|
||||
version = "3.866.0"
|
||||
|
||||
def __str__(self):
|
||||
return f'{self["first_name"]} {self["last_name"]}'
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
"""Data dictionary for object
|
||||
|
||||
:return: dict: dict with keys:
|
||||
- first_name
|
||||
- last_name
|
||||
- password
|
||||
- birthday
|
||||
- email
|
||||
- facebook_id
|
||||
- facebook_access_token
|
||||
- type
|
||||
- is_lab_rat
|
||||
- receives_newsletter
|
||||
"""
|
||||
return super().data
|
||||
Reference in New Issue
Block a user