Client
client
¶
Client for the Pretalx API
Documentation: https://docs.pretalx.org/api/resources/index.html
ToDo
- add additional parameters explicitly like querying according to the API
HTTP_FORBIDDEN = 403
module-attribute
¶
HTTP_NOT_FOUND = 404
module-attribute
¶
HTTP_UNAUTHORIZED = 401
module-attribute
¶
JSON: TypeAlias = JSONObj | JSONLst
module-attribute
¶
Type of the JSON response as returned by the Pretalx API
JSONLst: TypeAlias = list[JSONObj]
module-attribute
¶
Type of a JSON list of JSON objects
JSONObj: TypeAlias = dict[str, Any]
module-attribute
¶
Type of a JSON object (without recursion)
T = TypeVar('T', bound=BaseModel)
module-attribute
¶
PretalxClient(config: Config | None = None, *, blocking: bool = False)
¶
Client for the Pretalx API
Source code in src/pytanis/pretalx/client.py
def __init__(self, config: Config | None = None, *, blocking: bool = False):
if config is None:
config = get_cfg()
self._config = config
self._get_throttled = self._get
self.blocking = blocking
self.set_throttling(calls=2, seconds=1) # we are nice by default and Pretalx doesn't allow many calls at once.
# Caches for expanded objects (session-only, not persisted)
self._speaker_cache: dict[str, dict] = {}
self._submission_type_cache: dict[int, dict] = {}
self._track_cache: dict[int, dict] = {}
self._answer_cache: dict[int, dict | None] = {}
self._question_cache: dict[int, dict] = {}
self._caches_populated: dict[str, bool] = {} # Track which event caches are populated
self._use_cache_prepopulation: bool = True # Enable cache pre-population by default
blocking = blocking
instance-attribute
¶
__validate(model_type, result)
classmethod
¶
Source code in src/pytanis/pretalx/client.py
@classmethod
def __validate(cls, model_type, result):
try:
validated = model_type.model_validate(result)
return validated
except Exception as e:
# introduced to deal with API changes
_logger.error('result', resp=e)
answer(event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Answer
¶
Returns a specific answer
Source code in src/pytanis/pretalx/client.py
def answer(self, event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Answer: # noqa: A002
"""Returns a specific answer"""
return self._endpoint_id(Answer, event_slug, 'answers', id, params=params)
answers(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Answer]]
¶
Lists all answers and their details
Source code in src/pytanis/pretalx/client.py
def answers(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Answer]]:
"""Lists all answers and their details"""
return self._endpoint_lst(Answer, event_slug, 'answers', params=params)
clear_caches() -> None
¶
Clear all session caches.
This is useful if you want to force fresh data to be fetched from the API. Note that caches are session-only and are not persisted between client instances.
Source code in src/pytanis/pretalx/client.py
def clear_caches(self) -> None:
"""Clear all session caches.
This is useful if you want to force fresh data to be fetched from the API.
Note that caches are session-only and are not persisted between client instances.
"""
self._speaker_cache.clear()
self._submission_type_cache.clear()
self._track_cache.clear()
self._answer_cache.clear()
self._question_cache.clear()
self._caches_populated.clear()
_logger.info('All caches cleared')
event(event_slug: str, *, params: QueryParams | dict | None = None) -> Event
¶
Returns detailed information about a specific event
Source code in src/pytanis/pretalx/client.py
def event(self, event_slug: str, *, params: QueryParams | dict | None = None) -> Event:
"""Returns detailed information about a specific event"""
endpoint = f'/api/events/{event_slug}/'
result = self._get_one(endpoint, params)
_logger.debug('result', resp=result)
return self.__validate(Event, result)
events(*, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Event]]
¶
Lists all events and their details
Source code in src/pytanis/pretalx/client.py
def events(self, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Event]]:
"""Lists all events and their details"""
count, results = self._get_many('/api/events/', params)
events = iter(_logger.debug('result', resp=r) or Event.model_validate(r) for r in results)
return count, events
me() -> Me
¶
Returns what Pretalx knows about myself
Source code in src/pytanis/pretalx/client.py
def me(self) -> Me:
"""Returns what Pretalx knows about myself"""
result = self._get_one('/api/me/')
return self.__validate(Me, result)
question(event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Question
¶
Returns a specific question
Source code in src/pytanis/pretalx/client.py
def question(self, event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Question: # noqa: A002
"""Returns a specific question"""
return self._endpoint_id(Question, event_slug, 'questions', id, params=params)
questions(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Question]]
¶
Lists all questions and their details
Source code in src/pytanis/pretalx/client.py
def questions(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Question]]:
"""Lists all questions and their details"""
return self._endpoint_lst(Question, event_slug, 'questions', params=params)
review(event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Review
¶
Returns a specific review
Source code in src/pytanis/pretalx/client.py
def review(self, event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Review: # noqa: A002
"""Returns a specific review"""
return self._endpoint_id(Review, event_slug, 'reviews', id, params=params)
reviews(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Review]]
¶
Lists all reviews and their details
Source code in src/pytanis/pretalx/client.py
def reviews(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Review]]:
"""Lists all reviews and their details"""
return self._endpoint_lst(Review, event_slug, 'reviews', params=params)
room(event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Room
¶
Returns a specific room
Source code in src/pytanis/pretalx/client.py
def room(self, event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Room: # noqa: A002
"""Returns a specific room"""
return self._endpoint_id(Room, event_slug, 'rooms', id, params=params)
rooms(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Room]]
¶
Lists all rooms and their details
Source code in src/pytanis/pretalx/client.py
def rooms(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Room]]:
"""Lists all rooms and their details"""
return self._endpoint_lst(Room, event_slug, 'rooms', params=params)
set_cache_prepopulation(enabled: bool) -> None
¶
Enable or disable automatic cache pre-population for submissions.
When enabled (default), the client will fetch all speakers, submission types, and tracks in bulk on the first submission to minimize API calls. Disable this if you're only fetching a few submissions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
enabled | bool | Whether to enable cache pre-population | required |
Source code in src/pytanis/pretalx/client.py
def set_cache_prepopulation(self, enabled: bool) -> None: # noqa: FBT001
"""Enable or disable automatic cache pre-population for submissions.
When enabled (default), the client will fetch all speakers, submission types,
and tracks in bulk on the first submission to minimize API calls.
Disable this if you're only fetching a few submissions.
Args:
enabled: Whether to enable cache pre-population
"""
self._use_cache_prepopulation = enabled
_logger.info(f'Cache pre-population {"enabled" if enabled else "disabled"}')
set_throttling(calls: int, seconds: int)
¶
Throttle the number of calls per seconds to the Pretalx API
Source code in src/pytanis/pretalx/client.py
def set_throttling(self, calls: int, seconds: int):
"""Throttle the number of calls per seconds to the Pretalx API"""
_logger.info('throttling', calls=calls, seconds=seconds)
self._get_throttled = throttle(calls, seconds)(self._get)
speaker(event_slug: str, code: str, *, params: QueryParams | dict | None = None) -> Speaker
¶
Returns a specific speaker
Source code in src/pytanis/pretalx/client.py
def speaker(self, event_slug: str, code: str, *, params: QueryParams | dict | None = None) -> Speaker:
"""Returns a specific speaker"""
return self._endpoint_id(Speaker, event_slug, 'speakers', code, params=params)
speakers(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Speaker]]
¶
Lists all speakers and their details
Source code in src/pytanis/pretalx/client.py
def speakers(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Speaker]]:
"""Lists all speakers and their details"""
return self._endpoint_lst(Speaker, event_slug, 'speakers', params=params)
submission(event_slug: str, code: str, *, params: QueryParams | dict | None = None) -> Submission
¶
Returns a specific submission
Source code in src/pytanis/pretalx/client.py
def submission(self, event_slug: str, code: str, *, params: QueryParams | dict | None = None) -> Submission:
"""Returns a specific submission"""
return self._endpoint_id(Submission, event_slug, 'submissions', code, params=params)
submission_type(event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> SubmissionType
¶
Returns a specific submission type
Source code in src/pytanis/pretalx/client.py
def submission_type(self, event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> SubmissionType: # noqa: A002
"""Returns a specific submission type"""
return self._endpoint_id(SubmissionType, event_slug, 'submission-types', id, params=params)
submission_types(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[SubmissionType]]
¶
Lists all submission types and their details
Source code in src/pytanis/pretalx/client.py
def submission_types(
self, event_slug: str, *, params: QueryParams | dict | None = None
) -> tuple[int, Iterator[SubmissionType]]:
"""Lists all submission types and their details"""
return self._endpoint_lst(SubmissionType, event_slug, 'submission-types', params=params)
submissions(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Submission]]
¶
Lists all submissions and their details
Source code in src/pytanis/pretalx/client.py
def submissions(
self, event_slug: str, *, params: QueryParams | dict | None = None
) -> tuple[int, Iterator[Submission]]:
"""Lists all submissions and their details"""
return self._endpoint_lst(Submission, event_slug, 'submissions', params=params)
tag(event_slug: str, tag: str, *, params: QueryParams | dict | None = None) -> Tag
¶
Returns a specific tag
Source code in src/pytanis/pretalx/client.py
def tag(self, event_slug: str, tag: str, *, params: QueryParams | dict | None = None) -> Tag:
"""Returns a specific tag"""
return self._endpoint_id(Tag, event_slug, 'tags', tag, params=params)
tags(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Tag]]
¶
Lists all tags and their details
Source code in src/pytanis/pretalx/client.py
def tags(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Tag]]:
"""Lists all tags and their details"""
return self._endpoint_lst(Tag, event_slug, 'tags', params=params)
talk(event_slug: str, code: str, *, params: QueryParams | dict | None = None) -> Talk
¶
Returns a specific talk
Source code in src/pytanis/pretalx/client.py
def talk(self, event_slug: str, code: str, *, params: QueryParams | dict | None = None) -> Talk:
"""Returns a specific talk"""
try:
return self._endpoint_id(Talk, event_slug, 'talks', code, params=params)
except httpx.HTTPStatusError as e:
if e.response.status_code == HTTP_NOT_FOUND:
_logger.info('talk endpoint not available, using submission endpoint')
# Use submission endpoint but validate as Talk object
return self._endpoint_id(Talk, event_slug, 'submissions', code, params=params)
raise
talks(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Talk]]
¶
Lists all talks and their details
Source code in src/pytanis/pretalx/client.py
def talks(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Talk]]:
"""Lists all talks and their details"""
try:
return self._endpoint_lst(Talk, event_slug, 'talks', params=params)
except httpx.HTTPStatusError as e:
if e.response.status_code == HTTP_NOT_FOUND:
_logger.info('talks endpoint not available, using submissions endpoint')
# Use submissions endpoint but validate as Talk objects
return self._endpoint_lst(Talk, event_slug, 'submissions', params=params)
raise
track(event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Track
¶
Returns a specific track
Source code in src/pytanis/pretalx/client.py
def track(self, event_slug: str, id: int, *, params: QueryParams | dict | None = None) -> Track: # noqa: A002
"""Returns a specific track"""
return self._endpoint_id(Track, event_slug, 'tracks', id, params=params)
tracks(event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Track]]
¶
Lists all tracks and their details
Source code in src/pytanis/pretalx/client.py
def tracks(self, event_slug: str, *, params: QueryParams | dict | None = None) -> tuple[int, Iterator[Track]]:
"""Lists all tracks and their details"""
return self._endpoint_lst(Track, event_slug, 'tracks', params=params)