Skip to content

services

This module contains the services used to interact with different portions of the WOM API.

BaseService

Bases: ABC

The base service all API services inherit from.

Parameters:

Name Type Description Default
http_service HttpService

The http service to use for requests.

required
serializer Serializer

The serializer to use for handling incoming JSON data from the API.

required
Source code in wom/services/base.py
class BaseService(abc.ABC):
    """The base service all API services inherit from.

    Args:
        http_service: The http service to use for requests.

        serializer: The serializer to use for handling incoming
            JSON data from the API.
    """

    __slots__ = ("_http", "_serializer")

    def __init__(self, http_service: HttpService, serializer: serializer.Serializer) -> None:
        self._http = http_service
        self._serializer = serializer

    def _generate_map(self, **kwargs: t.Any) -> t.Dict[str, t.Any]:
        return {k: v for k, v in kwargs.items() if v is not None}

    def _ok(self, data: bytes, model_type: t.Type[T]) -> ResultT[T]:
        return result.Ok(self._serializer.decode(data, model_type))

    def _ok_or_err(
        self, data: t.Union[bytes, models.HttpErrorResponse], model_type: t.Type[T]
    ) -> ResultT[T]:
        if isinstance(data, models.HttpErrorResponse):
            return result.Err(data)

        return self._ok(data, model_type)

    def _success_or_err(
        self,
        data: t.Union[bytes, models.HttpErrorResponse],
        *,
        predicate: t.Optional[t.Callable[[str], bool]] = None,
    ) -> ResultT[models.HttpSuccessResponse]:
        if isinstance(data, bytes):
            err = self._serializer.decode(data, models.HttpErrorResponse)
            return result.Err(err)

        predicate = predicate or (lambda m: m.startswith("Success"))

        if not predicate(data.message):
            return result.Err(data)

        return result.Ok(models.HttpSuccessResponse(data.message, data.status))

CompetitionService

Bases: BaseService

Handles endpoints related to competitions.

Source code in wom/services/competitions.py
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
class CompetitionService(BaseService):
    """Handles endpoints related to competitions."""

    __slots__ = ()

    async def search_competitions(
        self,
        *,
        title: t.Optional[str] = None,
        type: t.Optional[models.CompetitionType] = None,
        status: t.Optional[models.CompetitionStatus] = None,
        metric: t.Optional[enums.Metric] = None,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.Competition]]:
        """Searches for competitions with the given criteria.

        Keyword Args:
            title: The optional title of the competition. Defaults to
                `None`.

            type: The optional [`CompetitionType`][wom.CompetitionType]
                filter. Defaults to `None`

            status: The optional [`CompetitionStatus`]
                [wom.CompetitionStatus] filter. Defaults to `None`.

            metric: The optional [`Metric`][wom.Metric] filter. Defaults
                to `None`.

            limit: The maximum number of paginated items to receive.
                Defaults to `None` (I think thats 20 items?).

            offset: The page offset for requesting multiple pages.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of competitions
                or an error.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.search_competitions(
                title="Sick Competition",
                type=wom.CompetitionType.Classic,
                status=wom.CompetitionStatus.Ongoing,
                limit=3,
                offset=1
            )
            ```
        """
        params = self._generate_map(
            title=title,
            limit=limit,
            offset=offset,
            type=type.value if type else None,
            status=status.value if status else None,
            metric=metric.value if metric else None,
        )

        route = routes.SEARCH_COMPETITIONS.compile().with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Competition])

    async def get_details(
        self, id: int, *, metric: t.Optional[enums.Metric] = None
    ) -> ResultT[models.CompetitionDetail]:
        """Gets details for the given competition.

        Args:
            id: The ID of the competition.

        Keyword Args:
            metric: The optional [`Metric`][wom.Metric] to view the
                competition progress in. As if this competition was
                actually for that metric. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the competition details.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.get_details(123)

            result2 = await client.competitions.get_details(
                123, wom.Metric.Attack
            )
            ```
        """
        params = self._generate_map(metric=metric.value if metric else None)
        route = routes.COMPETITION_DETAILS.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.CompetitionDetail)

    async def get_top_participant_history(
        self, id: int, *, metric: t.Optional[enums.Metric] = None
    ) -> ResultT[t.List[models.Top5ProgressResult]]:
        """Gets details for the players with the top 5 progress in the
        competition.

        Args:
            id: The ID of the competition.

        Keyword Args:
            metric: The optional [`Metric`][wom.Metric] to view the
                competition progress in. As if this competition was
                actually for that metric. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of top 5
                progress players.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            result = await client.competitions.get_competition_details(123)

            result2 = await client.competitions.get_competition_details(
                123, wom.Metric.Attack
            )
            ```
        """
        params = self._generate_map(metric=metric.value if metric else None)
        route = routes.TOP_PARTICIPANT_HISTORY.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Top5ProgressResult])

    async def create_competition(
        self,
        title: str,
        metric: enums.Metric,
        starts_at: datetime,
        ends_at: datetime,
        *,
        group_id: t.Optional[int] = None,
        group_verification_code: t.Optional[str] = None,
        teams: t.Optional[t.List[models.Team]] = None,
        participants: t.Optional[t.List[str]] = None,
    ) -> ResultT[models.CreatedCompetitionDetail]:
        """Creates a new competition.

        Args:
            title: The title of the competition.

            metric: The [`Metric`][wom.Metric] the competition should
                measure.

            starts_at: The start date for the competition.

            ends_at: The end date for the competition.

        Keyword Args:
            group_id: The optional group id to tie to this competition.
                Defaults to `None`.

            group_verification_code: The optional group verification
                code. Required if group_id is supplied. Defaults to
                `None`.

            participants: The optional list of participants to include
                in the competition. Defaults to `None`.

            teams: The optional teams to include in the competition.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the newly created
                competition detail.

        !!! info

            The `group_id`, `participants`, and `teams` parameters are
            mutually exclusive.

            - If `group_id` is provided, this method will create a
                classic competition with all members of that group as
                participants.

            - If `participants` is provided and `group_id` isn't, this
                method will create a classic competition with all those
                participants included.

            - If `teams` is provided, this endpoint will create a team
                competition with all those participants included.
                Also accepts `group_id` as a way to link this
                competition to the group.

        ??? example

            ```py
            from datetime import datetime, timedelta
            import wom

            client = wom.Client(...)

            result = await client.competitions.create_competition(
                "Slayer week",
                wom.Metric.Slayer,
                starts_at=datetime.now() + timedelta(days=7),
                ends_at=datetime.now() + timedelta(days=14),
                group_verification_code="111-111-111",
                group_id=123,
            )
            ```
        """
        payload = self._generate_map(
            title=title,
            teams=teams,
            groupId=group_id,
            participants=participants,
            endsAt=ends_at.isoformat(),
            startsAt=starts_at.isoformat(),
            metric=metric.value if metric else None,
            groupVerificationCode=group_verification_code,
        )

        route = routes.CREATE_COMPETITION.compile()
        data = await self._http.fetch(route, payload=payload)
        return self._ok_or_err(data, models.CreatedCompetitionDetail)

    async def edit_competition(
        self,
        id: int,
        verification_code: str,
        *,
        title: t.Optional[str] = None,
        metric: t.Optional[enums.Metric] = None,
        starts_at: t.Optional[datetime] = None,
        ends_at: t.Optional[datetime] = None,
        teams: t.Optional[t.List[models.Team]] = None,
        participants: t.Optional[t.List[str]] = None,
    ) -> ResultT[models.Competition]:
        """Edits an existing competition.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

        Keyword Args:
            title: The optional updated title of the competition.
                Defaults to `None`.

            metric: The optional new [`Metric`][wom.Metric] the
                competition should measure. Defaults to `None`.

            starts_at: The optional new start date for the competition.
                Defaults to `None`.

            ends_at: The optional new end date for the competition.
                Defaults to `None`.

            participants: The optional list of participants to replace
                the existing participants with. Defaults to `None`.

            teams: The optional list of teams to replace the existing
                participants with. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the edited competition
                with participations.

        !!! warning

            The teams/participants parameters will completely
            overwrite the existing participants/teams. If you're looking
            to add users, check out [`add_participants()`]
            [wom.CompetitionService.add_participants].

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.edit_competition(
                123, "111-111-111", title="New title"
            )
            ```
        """
        payload = self._generate_map(
            title=title,
            teams=teams,
            participants=participants,
            startsAt=starts_at.isoformat() if starts_at else None,
            endsAt=ends_at.isoformat() if ends_at else None,
            metric=metric.value if metric else None,
            verificationCode=verification_code,
        )

        route = routes.EDIT_COMPETITION.compile(id)
        data = await self._http.fetch(route, payload=payload)
        return self._ok_or_err(data, models.Competition)

    async def delete_competition(
        self, id: int, verification_code: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Deletes a competition.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        !!! warning

            This action can not be reversed.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.delete_competition(
                123, "111-111-111"
            )
            ```
        """
        route = routes.DELETE_COMPETITION.compile(id)
        payload = self._generate_map(verificationCode=verification_code)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def add_participants(
        self, id: int, verification_code: str, *participants: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Adds participants to a competition. Only adds valid
        participants, and ignores duplicates.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

            *participants: The participants you would like to add.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.add_participants(
                123, "111-111-111", "Jonxslays", "Zezima"
            )
            ```
        """
        route = routes.ADD_PARTICIPANTS.compile(id)
        payload = self._generate_map(verificationCode=verification_code, participants=participants)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def remove_participants(
        self, id: int, verification_code: str, *participants: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Removes participants from a competition. Ignores usernames
        that are not competing.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

            *participants: The participants you would like to remove.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.remove_participants(
                123, "111-111-111", "Jonxslays"
            )
            ```

        """
        route = routes.REMOVE_PARTICIPANTS.compile(id)
        payload = self._generate_map(verificationCode=verification_code, participants=participants)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def add_teams(
        self, id: int, verification_code: str, *teams: models.Team
    ) -> ResultT[models.HttpSuccessResponse]:
        """Adds teams to a competition. Ignores duplicates.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

            *teams: The teams you would like to add.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.add_teams(
                123,
                "111-111-111",
                wom.Team("Team 1", ["Jonxslays", "lilyuffie88"]),
                wom.Team("Team 2", ["Zezima", "the old nite"]),
            )
            ```
        """
        route = routes.ADD_TEAMS.compile(id)
        payload = self._generate_map(verificationCode=verification_code, teams=teams)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def remove_teams(
        self, id: int, verification_code: str, *teams: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Removes teams from a competition. Ignores teams that don't
        exist.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

            *teams: The team names you would like to remove.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.remove_teams(
                123, "111-111-111", "Team 1", "Team 2"
            )
            ```
        """
        route = routes.REMOVE_TEAMS.compile(id)
        payload = self._generate_map(verificationCode=verification_code, teamNames=teams)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def update_outdated_participants(
        self, id: int, verification_code: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Attempts to update all outdated competition participants.

        Args:
            id: The ID of the competition.

            verification_code: The verification code for the
                competition.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        !!! info

            Participants are outdated when either:

            - Competition is ending or started within 6h of now and
                the player hasn't been updated in over 1h.

            - Player hasn't been updated in over 24h.

        !!! warning

            This method adds every outdated participant to an
            "update queue", and the WOM servers try to update players
            in the queue one by one, with a delay in between each. For
            each player in the queue, an attempt is made to update it
            up to 3 times, with 30s in between each attempt.

            Please note that this is dependent on the OSRS hiscores
            functioning correctly, and therefore this method does NOT
            guarantee the players will be updated, it only guarantees
            that an attempt will be made to update them, up to 3 times.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.update_outdated_participants(
                123, "111-111-111"
            )
            ```
        """
        route = routes.UPDATE_OUTDATED_PARTICIPANTS.compile(id)
        payload = self._generate_map(verificationCode=verification_code)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data, predicate=lambda m: "players are being updated" in m)

    async def get_details_csv(
        self,
        id: int,
        *,
        metric: t.Optional[enums.Metric] = None,
        team_name: t.Optional[str] = None,
        table_type: t.Optional[models.CompetitionCSVTableType] = None,
    ) -> ResultT[str]:
        """Gets details about the competition in CSV format.

        Args:
            id: The ID of the competition.

        Keyword Args:
            metric: The optional [`Metric`][wom.Metric] to view the
                competition progress in. As if this competition was
                actually for that metric. Defaults to `None`.

            team_name: The optional team name you would like to get details
                for. Defaults to `None`.

            table_type: The optional table type formatting to apply.
                Defaults to `Participants`.

        Returns:
            A [`Result`][wom.Result] containing the CSV string.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.competitions.get_details_csv(
                123, team_name="Cool team"
            )
            ```
        """
        params = self._generate_map(metric=metric, teamName=team_name, table=table_type)
        route = routes.COMPETITION_DETAILS_CSV.compile(id).with_params(params)
        data = await self._http.fetch(route)

        if isinstance(data, models.HttpErrorResponse):
            return result.Err(data)

        return result.Ok(data.decode())

add_participants async

add_participants(
    id: int, verification_code: str, *participants: str
) -> ResultT[models.HttpSuccessResponse]

Adds participants to a competition. Only adds valid participants, and ignores duplicates.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required
*participants str

The participants you would like to add.

()

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.add_participants(
    123, "111-111-111", "Jonxslays", "Zezima"
)
Source code in wom/services/competitions.py
async def add_participants(
    self, id: int, verification_code: str, *participants: str
) -> ResultT[models.HttpSuccessResponse]:
    """Adds participants to a competition. Only adds valid
    participants, and ignores duplicates.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

        *participants: The participants you would like to add.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.add_participants(
            123, "111-111-111", "Jonxslays", "Zezima"
        )
        ```
    """
    route = routes.ADD_PARTICIPANTS.compile(id)
    payload = self._generate_map(verificationCode=verification_code, participants=participants)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

add_teams async

add_teams(
    id: int, verification_code: str, *teams: models.Team
) -> ResultT[models.HttpSuccessResponse]

Adds teams to a competition. Ignores duplicates.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required
*teams Team

The teams you would like to add.

()

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.add_teams(
    123,
    "111-111-111",
    wom.Team("Team 1", ["Jonxslays", "lilyuffie88"]),
    wom.Team("Team 2", ["Zezima", "the old nite"]),
)
Source code in wom/services/competitions.py
async def add_teams(
    self, id: int, verification_code: str, *teams: models.Team
) -> ResultT[models.HttpSuccessResponse]:
    """Adds teams to a competition. Ignores duplicates.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

        *teams: The teams you would like to add.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.add_teams(
            123,
            "111-111-111",
            wom.Team("Team 1", ["Jonxslays", "lilyuffie88"]),
            wom.Team("Team 2", ["Zezima", "the old nite"]),
        )
        ```
    """
    route = routes.ADD_TEAMS.compile(id)
    payload = self._generate_map(verificationCode=verification_code, teams=teams)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

create_competition async

create_competition(
    title: str,
    metric: enums.Metric,
    starts_at: datetime,
    ends_at: datetime,
    *,
    group_id: t.Optional[int] = None,
    group_verification_code: t.Optional[str] = None,
    teams: t.Optional[t.List[models.Team]] = None,
    participants: t.Optional[t.List[str]] = None
) -> ResultT[models.CreatedCompetitionDetail]

Creates a new competition.

Parameters:

Name Type Description Default
title str

The title of the competition.

required
metric Metric

The Metric the competition should measure.

required
starts_at datetime

The start date for the competition.

required
ends_at datetime

The end date for the competition.

required

Other Parameters:

Name Type Description
group_id Optional[int]

The optional group id to tie to this competition. Defaults to None.

group_verification_code Optional[str]

The optional group verification code. Required if group_id is supplied. Defaults to None.

participants Optional[List[str]]

The optional list of participants to include in the competition. Defaults to None.

teams Optional[List[Team]]

The optional teams to include in the competition. Defaults to None.

Returns:

Type Description
ResultT[CreatedCompetitionDetail]

A Result containing the newly created competition detail.

Info

The group_id, participants, and teams parameters are mutually exclusive.

  • If group_id is provided, this method will create a classic competition with all members of that group as participants.

  • If participants is provided and group_id isn't, this method will create a classic competition with all those participants included.

  • If teams is provided, this endpoint will create a team competition with all those participants included. Also accepts group_id as a way to link this competition to the group.

Example
from datetime import datetime, timedelta
import wom

client = wom.Client(...)

result = await client.competitions.create_competition(
    "Slayer week",
    wom.Metric.Slayer,
    starts_at=datetime.now() + timedelta(days=7),
    ends_at=datetime.now() + timedelta(days=14),
    group_verification_code="111-111-111",
    group_id=123,
)
Source code in wom/services/competitions.py
async def create_competition(
    self,
    title: str,
    metric: enums.Metric,
    starts_at: datetime,
    ends_at: datetime,
    *,
    group_id: t.Optional[int] = None,
    group_verification_code: t.Optional[str] = None,
    teams: t.Optional[t.List[models.Team]] = None,
    participants: t.Optional[t.List[str]] = None,
) -> ResultT[models.CreatedCompetitionDetail]:
    """Creates a new competition.

    Args:
        title: The title of the competition.

        metric: The [`Metric`][wom.Metric] the competition should
            measure.

        starts_at: The start date for the competition.

        ends_at: The end date for the competition.

    Keyword Args:
        group_id: The optional group id to tie to this competition.
            Defaults to `None`.

        group_verification_code: The optional group verification
            code. Required if group_id is supplied. Defaults to
            `None`.

        participants: The optional list of participants to include
            in the competition. Defaults to `None`.

        teams: The optional teams to include in the competition.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the newly created
            competition detail.

    !!! info

        The `group_id`, `participants`, and `teams` parameters are
        mutually exclusive.

        - If `group_id` is provided, this method will create a
            classic competition with all members of that group as
            participants.

        - If `participants` is provided and `group_id` isn't, this
            method will create a classic competition with all those
            participants included.

        - If `teams` is provided, this endpoint will create a team
            competition with all those participants included.
            Also accepts `group_id` as a way to link this
            competition to the group.

    ??? example

        ```py
        from datetime import datetime, timedelta
        import wom

        client = wom.Client(...)

        result = await client.competitions.create_competition(
            "Slayer week",
            wom.Metric.Slayer,
            starts_at=datetime.now() + timedelta(days=7),
            ends_at=datetime.now() + timedelta(days=14),
            group_verification_code="111-111-111",
            group_id=123,
        )
        ```
    """
    payload = self._generate_map(
        title=title,
        teams=teams,
        groupId=group_id,
        participants=participants,
        endsAt=ends_at.isoformat(),
        startsAt=starts_at.isoformat(),
        metric=metric.value if metric else None,
        groupVerificationCode=group_verification_code,
    )

    route = routes.CREATE_COMPETITION.compile()
    data = await self._http.fetch(route, payload=payload)
    return self._ok_or_err(data, models.CreatedCompetitionDetail)

delete_competition async

delete_competition(
    id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]

Deletes a competition.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Warning

This action can not be reversed.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.delete_competition(
    123, "111-111-111"
)
Source code in wom/services/competitions.py
async def delete_competition(
    self, id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]:
    """Deletes a competition.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    !!! warning

        This action can not be reversed.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.delete_competition(
            123, "111-111-111"
        )
        ```
    """
    route = routes.DELETE_COMPETITION.compile(id)
    payload = self._generate_map(verificationCode=verification_code)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

edit_competition async

edit_competition(
    id: int,
    verification_code: str,
    *,
    title: t.Optional[str] = None,
    metric: t.Optional[enums.Metric] = None,
    starts_at: t.Optional[datetime] = None,
    ends_at: t.Optional[datetime] = None,
    teams: t.Optional[t.List[models.Team]] = None,
    participants: t.Optional[t.List[str]] = None
) -> ResultT[models.Competition]

Edits an existing competition.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required

Other Parameters:

Name Type Description
title Optional[str]

The optional updated title of the competition. Defaults to None.

metric Optional[Metric]

The optional new Metric the competition should measure. Defaults to None.

starts_at Optional[datetime]

The optional new start date for the competition. Defaults to None.

ends_at Optional[datetime]

The optional new end date for the competition. Defaults to None.

participants Optional[List[str]]

The optional list of participants to replace the existing participants with. Defaults to None.

teams Optional[List[Team]]

The optional list of teams to replace the existing participants with. Defaults to None.

Returns:

Type Description
ResultT[Competition]

A Result containing the edited competition with participations.

Warning

The teams/participants parameters will completely overwrite the existing participants/teams. If you're looking to add users, check out add_participants().

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.edit_competition(
    123, "111-111-111", title="New title"
)
Source code in wom/services/competitions.py
async def edit_competition(
    self,
    id: int,
    verification_code: str,
    *,
    title: t.Optional[str] = None,
    metric: t.Optional[enums.Metric] = None,
    starts_at: t.Optional[datetime] = None,
    ends_at: t.Optional[datetime] = None,
    teams: t.Optional[t.List[models.Team]] = None,
    participants: t.Optional[t.List[str]] = None,
) -> ResultT[models.Competition]:
    """Edits an existing competition.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

    Keyword Args:
        title: The optional updated title of the competition.
            Defaults to `None`.

        metric: The optional new [`Metric`][wom.Metric] the
            competition should measure. Defaults to `None`.

        starts_at: The optional new start date for the competition.
            Defaults to `None`.

        ends_at: The optional new end date for the competition.
            Defaults to `None`.

        participants: The optional list of participants to replace
            the existing participants with. Defaults to `None`.

        teams: The optional list of teams to replace the existing
            participants with. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the edited competition
            with participations.

    !!! warning

        The teams/participants parameters will completely
        overwrite the existing participants/teams. If you're looking
        to add users, check out [`add_participants()`]
        [wom.CompetitionService.add_participants].

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.edit_competition(
            123, "111-111-111", title="New title"
        )
        ```
    """
    payload = self._generate_map(
        title=title,
        teams=teams,
        participants=participants,
        startsAt=starts_at.isoformat() if starts_at else None,
        endsAt=ends_at.isoformat() if ends_at else None,
        metric=metric.value if metric else None,
        verificationCode=verification_code,
    )

    route = routes.EDIT_COMPETITION.compile(id)
    data = await self._http.fetch(route, payload=payload)
    return self._ok_or_err(data, models.Competition)

get_details async

get_details(
    id: int, *, metric: t.Optional[enums.Metric] = None
) -> ResultT[models.CompetitionDetail]

Gets details for the given competition.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required

Other Parameters:

Name Type Description
metric Optional[Metric]

The optional Metric to view the competition progress in. As if this competition was actually for that metric. Defaults to None.

Returns:

Type Description
ResultT[CompetitionDetail]

A Result containing the competition details.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.get_details(123)

result2 = await client.competitions.get_details(
    123, wom.Metric.Attack
)
Source code in wom/services/competitions.py
async def get_details(
    self, id: int, *, metric: t.Optional[enums.Metric] = None
) -> ResultT[models.CompetitionDetail]:
    """Gets details for the given competition.

    Args:
        id: The ID of the competition.

    Keyword Args:
        metric: The optional [`Metric`][wom.Metric] to view the
            competition progress in. As if this competition was
            actually for that metric. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the competition details.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.get_details(123)

        result2 = await client.competitions.get_details(
            123, wom.Metric.Attack
        )
        ```
    """
    params = self._generate_map(metric=metric.value if metric else None)
    route = routes.COMPETITION_DETAILS.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.CompetitionDetail)

get_details_csv async

get_details_csv(
    id: int,
    *,
    metric: t.Optional[enums.Metric] = None,
    team_name: t.Optional[str] = None,
    table_type: t.Optional[
        models.CompetitionCSVTableType
    ] = None
) -> ResultT[str]

Gets details about the competition in CSV format.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required

Other Parameters:

Name Type Description
metric Optional[Metric]

The optional Metric to view the competition progress in. As if this competition was actually for that metric. Defaults to None.

team_name Optional[str]

The optional team name you would like to get details for. Defaults to None.

table_type Optional[CompetitionCSVTableType]

The optional table type formatting to apply. Defaults to Participants.

Returns:

Type Description
ResultT[str]

A Result containing the CSV string.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.get_details_csv(
    123, team_name="Cool team"
)
Source code in wom/services/competitions.py
async def get_details_csv(
    self,
    id: int,
    *,
    metric: t.Optional[enums.Metric] = None,
    team_name: t.Optional[str] = None,
    table_type: t.Optional[models.CompetitionCSVTableType] = None,
) -> ResultT[str]:
    """Gets details about the competition in CSV format.

    Args:
        id: The ID of the competition.

    Keyword Args:
        metric: The optional [`Metric`][wom.Metric] to view the
            competition progress in. As if this competition was
            actually for that metric. Defaults to `None`.

        team_name: The optional team name you would like to get details
            for. Defaults to `None`.

        table_type: The optional table type formatting to apply.
            Defaults to `Participants`.

    Returns:
        A [`Result`][wom.Result] containing the CSV string.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.get_details_csv(
            123, team_name="Cool team"
        )
        ```
    """
    params = self._generate_map(metric=metric, teamName=team_name, table=table_type)
    route = routes.COMPETITION_DETAILS_CSV.compile(id).with_params(params)
    data = await self._http.fetch(route)

    if isinstance(data, models.HttpErrorResponse):
        return result.Err(data)

    return result.Ok(data.decode())

get_top_participant_history async

get_top_participant_history(
    id: int, *, metric: t.Optional[enums.Metric] = None
) -> ResultT[t.List[models.Top5ProgressResult]]

Gets details for the players with the top 5 progress in the competition.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required

Other Parameters:

Name Type Description
metric Optional[Metric]

The optional Metric to view the competition progress in. As if this competition was actually for that metric. Defaults to None.

Returns:

Type Description
ResultT[List[Top5ProgressResult]]

A Result containing the list of top 5 progress players.

Example
import wom

client = wom.Client(...)

result = await client.competitions.get_competition_details(123)

result2 = await client.competitions.get_competition_details(
    123, wom.Metric.Attack
)
Source code in wom/services/competitions.py
async def get_top_participant_history(
    self, id: int, *, metric: t.Optional[enums.Metric] = None
) -> ResultT[t.List[models.Top5ProgressResult]]:
    """Gets details for the players with the top 5 progress in the
    competition.

    Args:
        id: The ID of the competition.

    Keyword Args:
        metric: The optional [`Metric`][wom.Metric] to view the
            competition progress in. As if this competition was
            actually for that metric. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of top 5
            progress players.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        result = await client.competitions.get_competition_details(123)

        result2 = await client.competitions.get_competition_details(
            123, wom.Metric.Attack
        )
        ```
    """
    params = self._generate_map(metric=metric.value if metric else None)
    route = routes.TOP_PARTICIPANT_HISTORY.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Top5ProgressResult])

remove_participants async

remove_participants(
    id: int, verification_code: str, *participants: str
) -> ResultT[models.HttpSuccessResponse]

Removes participants from a competition. Ignores usernames that are not competing.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required
*participants str

The participants you would like to remove.

()

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.remove_participants(
    123, "111-111-111", "Jonxslays"
)
Source code in wom/services/competitions.py
async def remove_participants(
    self, id: int, verification_code: str, *participants: str
) -> ResultT[models.HttpSuccessResponse]:
    """Removes participants from a competition. Ignores usernames
    that are not competing.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

        *participants: The participants you would like to remove.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.remove_participants(
            123, "111-111-111", "Jonxslays"
        )
        ```

    """
    route = routes.REMOVE_PARTICIPANTS.compile(id)
    payload = self._generate_map(verificationCode=verification_code, participants=participants)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

remove_teams async

remove_teams(
    id: int, verification_code: str, *teams: str
) -> ResultT[models.HttpSuccessResponse]

Removes teams from a competition. Ignores teams that don't exist.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required
*teams str

The team names you would like to remove.

()

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.remove_teams(
    123, "111-111-111", "Team 1", "Team 2"
)
Source code in wom/services/competitions.py
async def remove_teams(
    self, id: int, verification_code: str, *teams: str
) -> ResultT[models.HttpSuccessResponse]:
    """Removes teams from a competition. Ignores teams that don't
    exist.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

        *teams: The team names you would like to remove.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.remove_teams(
            123, "111-111-111", "Team 1", "Team 2"
        )
        ```
    """
    route = routes.REMOVE_TEAMS.compile(id)
    payload = self._generate_map(verificationCode=verification_code, teamNames=teams)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

search_competitions async

search_competitions(
    *,
    title: t.Optional[str] = None,
    type: t.Optional[models.CompetitionType] = None,
    status: t.Optional[models.CompetitionStatus] = None,
    metric: t.Optional[enums.Metric] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.Competition]]

Searches for competitions with the given criteria.

Other Parameters:

Name Type Description
title Optional[str]

The optional title of the competition. Defaults to None.

type Optional[CompetitionType]

The optional CompetitionType filter. Defaults to None

status Optional[CompetitionStatus]

The optional CompetitionStatus filter. Defaults to None.

metric Optional[Metric]

The optional Metric filter. Defaults to None.

limit Optional[int]

The maximum number of paginated items to receive. Defaults to None (I think thats 20 items?).

offset Optional[int]

The page offset for requesting multiple pages. Defaults to None.

Returns:

Type Description
ResultT[List[Competition]]

A Result containing the list of competitions or an error.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.search_competitions(
    title="Sick Competition",
    type=wom.CompetitionType.Classic,
    status=wom.CompetitionStatus.Ongoing,
    limit=3,
    offset=1
)
Source code in wom/services/competitions.py
async def search_competitions(
    self,
    *,
    title: t.Optional[str] = None,
    type: t.Optional[models.CompetitionType] = None,
    status: t.Optional[models.CompetitionStatus] = None,
    metric: t.Optional[enums.Metric] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.Competition]]:
    """Searches for competitions with the given criteria.

    Keyword Args:
        title: The optional title of the competition. Defaults to
            `None`.

        type: The optional [`CompetitionType`][wom.CompetitionType]
            filter. Defaults to `None`

        status: The optional [`CompetitionStatus`]
            [wom.CompetitionStatus] filter. Defaults to `None`.

        metric: The optional [`Metric`][wom.Metric] filter. Defaults
            to `None`.

        limit: The maximum number of paginated items to receive.
            Defaults to `None` (I think thats 20 items?).

        offset: The page offset for requesting multiple pages.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of competitions
            or an error.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.search_competitions(
            title="Sick Competition",
            type=wom.CompetitionType.Classic,
            status=wom.CompetitionStatus.Ongoing,
            limit=3,
            offset=1
        )
        ```
    """
    params = self._generate_map(
        title=title,
        limit=limit,
        offset=offset,
        type=type.value if type else None,
        status=status.value if status else None,
        metric=metric.value if metric else None,
    )

    route = routes.SEARCH_COMPETITIONS.compile().with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Competition])

update_outdated_participants async

update_outdated_participants(
    id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]

Attempts to update all outdated competition participants.

Parameters:

Name Type Description Default
id int

The ID of the competition.

required
verification_code str

The verification code for the competition.

required

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Info

Participants are outdated when either:

  • Competition is ending or started within 6h of now and the player hasn't been updated in over 1h.

  • Player hasn't been updated in over 24h.

Warning

This method adds every outdated participant to an "update queue", and the WOM servers try to update players in the queue one by one, with a delay in between each. For each player in the queue, an attempt is made to update it up to 3 times, with 30s in between each attempt.

Please note that this is dependent on the OSRS hiscores functioning correctly, and therefore this method does NOT guarantee the players will be updated, it only guarantees that an attempt will be made to update them, up to 3 times.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.competitions.update_outdated_participants(
    123, "111-111-111"
)
Source code in wom/services/competitions.py
async def update_outdated_participants(
    self, id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]:
    """Attempts to update all outdated competition participants.

    Args:
        id: The ID of the competition.

        verification_code: The verification code for the
            competition.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    !!! info

        Participants are outdated when either:

        - Competition is ending or started within 6h of now and
            the player hasn't been updated in over 1h.

        - Player hasn't been updated in over 24h.

    !!! warning

        This method adds every outdated participant to an
        "update queue", and the WOM servers try to update players
        in the queue one by one, with a delay in between each. For
        each player in the queue, an attempt is made to update it
        up to 3 times, with 30s in between each attempt.

        Please note that this is dependent on the OSRS hiscores
        functioning correctly, and therefore this method does NOT
        guarantee the players will be updated, it only guarantees
        that an attempt will be made to update them, up to 3 times.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.competitions.update_outdated_participants(
            123, "111-111-111"
        )
        ```
    """
    route = routes.UPDATE_OUTDATED_PARTICIPANTS.compile(id)
    payload = self._generate_map(verificationCode=verification_code)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data, predicate=lambda m: "players are being updated" in m)

DeltaService

Bases: BaseService

Handles endpoints related to deltas.

Source code in wom/services/deltas.py
class DeltaService(BaseService):
    """Handles endpoints related to deltas."""

    __slots__ = ()

    async def get_global_leaderboards(
        self,
        metric: enums.Metric,
        period: enums.Period,
        *,
        player_type: t.Optional[models.PlayerType] = None,
        player_build: t.Optional[models.PlayerBuild] = None,
        country: t.Optional[models.Country] = None,
    ) -> ResultT[t.List[models.DeltaLeaderboardEntry]]:
        """Gets the top global delta leaderboard for a specific
        metric and period.

        Args:
            metric: The metric to filter on.

            period: The period of time to filter on.

        Keyword Args:
            player_type: The optional player type to filter on. Defaults
                to `None`.

            player_build: The optional player build to filter on.
                Defaults to `None`.

            country: The optional country to filter on. Defaults to
                `None`.

        Returns:
            A [`Result`][wom.Result] containing a list of  delta
                leaderboard entries.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.deltas.get_global_leaderboards(
                wom.Metric.Attack,
                wom.Period.Day,
                country=wom.Country.Gb,
            )
            ```
        """
        params = self._generate_map(
            metric=metric.value,
            period=period.value,
            playerType=player_type.value if player_type else None,
            playerBuild=player_build.value if player_build else None,
            country=country.value if country else None,
        )

        route = routes.GLOBAL_DELTA_LEADERS.compile()
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.DeltaLeaderboardEntry])

get_global_leaderboards async

get_global_leaderboards(
    metric: enums.Metric,
    period: enums.Period,
    *,
    player_type: t.Optional[models.PlayerType] = None,
    player_build: t.Optional[models.PlayerBuild] = None,
    country: t.Optional[models.Country] = None
) -> ResultT[t.List[models.DeltaLeaderboardEntry]]

Gets the top global delta leaderboard for a specific metric and period.

Parameters:

Name Type Description Default
metric Metric

The metric to filter on.

required
period Period

The period of time to filter on.

required

Other Parameters:

Name Type Description
player_type Optional[PlayerType]

The optional player type to filter on. Defaults to None.

player_build Optional[PlayerBuild]

The optional player build to filter on. Defaults to None.

country Optional[Country]

The optional country to filter on. Defaults to None.

Returns:

Type Description
ResultT[List[DeltaLeaderboardEntry]]

A Result containing a list of delta leaderboard entries.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.deltas.get_global_leaderboards(
    wom.Metric.Attack,
    wom.Period.Day,
    country=wom.Country.Gb,
)
Source code in wom/services/deltas.py
async def get_global_leaderboards(
    self,
    metric: enums.Metric,
    period: enums.Period,
    *,
    player_type: t.Optional[models.PlayerType] = None,
    player_build: t.Optional[models.PlayerBuild] = None,
    country: t.Optional[models.Country] = None,
) -> ResultT[t.List[models.DeltaLeaderboardEntry]]:
    """Gets the top global delta leaderboard for a specific
    metric and period.

    Args:
        metric: The metric to filter on.

        period: The period of time to filter on.

    Keyword Args:
        player_type: The optional player type to filter on. Defaults
            to `None`.

        player_build: The optional player build to filter on.
            Defaults to `None`.

        country: The optional country to filter on. Defaults to
            `None`.

    Returns:
        A [`Result`][wom.Result] containing a list of  delta
            leaderboard entries.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.deltas.get_global_leaderboards(
            wom.Metric.Attack,
            wom.Period.Day,
            country=wom.Country.Gb,
        )
        ```
    """
    params = self._generate_map(
        metric=metric.value,
        period=period.value,
        playerType=player_type.value if player_type else None,
        playerBuild=player_build.value if player_build else None,
        country=country.value if country else None,
    )

    route = routes.GLOBAL_DELTA_LEADERS.compile()
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.DeltaLeaderboardEntry])

EfficiencyService

Bases: BaseService

Handles endpoints related to efficiency.

Source code in wom/services/efficiency.py
class EfficiencyService(BaseService):
    """Handles endpoints related to efficiency."""

    __slots__ = ()

    async def get_global_leaderboards(
        self,
        metric: enums.Metric = enums.Metric.Ehp,
        *,
        player_type: t.Optional[models.PlayerType] = None,
        player_build: t.Optional[models.PlayerBuild] = None,
        country: t.Optional[models.Country] = None,
        both: bool = False,
    ) -> ResultT[t.List[models.Player]]:
        """Gets the top global efficiency leaderboard.

        Args:
            metric: The computed metric to filter on. Defaults to `Ehp`,
                must be one of `Ehp` or `Ehb` if supplied.

        Keyword Args:
            player_type: The optional player type to filter on. Defaults
                to `None`.

            player_build: The optional player build to filter on.
                Defaults to `None`.

            country: The optional country to filter on. Defaults to
                `None`.

            both: If `True`, request both ehp and ehb computed metric
                leaderboards. This will override the `metric` if it was
                provided. Defaults to `False`.

        Returns:
            A [`Result`][wom.Result] containing a list of the top
                players.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.efficiency.get_global_leaderboards(
                player_type=wom.PlayerType.Ironman,
            )
            ```
        """
        params = self._generate_map(
            playerType=player_type.value if player_type else None,
            playerBuild=player_build.value if player_build else None,
            country=country.value if country else None,
            metric=(
                metric.value
                if not both
                else "+".join(sorted((m.value for m in enums.ComputedMetrics), reverse=True))
            ),
        )

        route = routes.GLOBAL_EFFICIENCY_LEADERS.compile()
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.Player])

get_global_leaderboards async

get_global_leaderboards(
    metric: enums.Metric = enums.Metric.Ehp,
    *,
    player_type: t.Optional[models.PlayerType] = None,
    player_build: t.Optional[models.PlayerBuild] = None,
    country: t.Optional[models.Country] = None,
    both: bool = False
) -> ResultT[t.List[models.Player]]

Gets the top global efficiency leaderboard.

Parameters:

Name Type Description Default
metric Metric

The computed metric to filter on. Defaults to Ehp, must be one of Ehp or Ehb if supplied.

Ehp

Other Parameters:

Name Type Description
player_type Optional[PlayerType]

The optional player type to filter on. Defaults to None.

player_build Optional[PlayerBuild]

The optional player build to filter on. Defaults to None.

country Optional[Country]

The optional country to filter on. Defaults to None.

both bool

If True, request both ehp and ehb computed metric leaderboards. This will override the metric if it was provided. Defaults to False.

Returns:

Type Description
ResultT[List[Player]]

A Result containing a list of the top players.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.efficiency.get_global_leaderboards(
    player_type=wom.PlayerType.Ironman,
)
Source code in wom/services/efficiency.py
async def get_global_leaderboards(
    self,
    metric: enums.Metric = enums.Metric.Ehp,
    *,
    player_type: t.Optional[models.PlayerType] = None,
    player_build: t.Optional[models.PlayerBuild] = None,
    country: t.Optional[models.Country] = None,
    both: bool = False,
) -> ResultT[t.List[models.Player]]:
    """Gets the top global efficiency leaderboard.

    Args:
        metric: The computed metric to filter on. Defaults to `Ehp`,
            must be one of `Ehp` or `Ehb` if supplied.

    Keyword Args:
        player_type: The optional player type to filter on. Defaults
            to `None`.

        player_build: The optional player build to filter on.
            Defaults to `None`.

        country: The optional country to filter on. Defaults to
            `None`.

        both: If `True`, request both ehp and ehb computed metric
            leaderboards. This will override the `metric` if it was
            provided. Defaults to `False`.

    Returns:
        A [`Result`][wom.Result] containing a list of the top
            players.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.efficiency.get_global_leaderboards(
            player_type=wom.PlayerType.Ironman,
        )
        ```
    """
    params = self._generate_map(
        playerType=player_type.value if player_type else None,
        playerBuild=player_build.value if player_build else None,
        country=country.value if country else None,
        metric=(
            metric.value
            if not both
            else "+".join(sorted((m.value for m in enums.ComputedMetrics), reverse=True))
        ),
    )

    route = routes.GLOBAL_EFFICIENCY_LEADERS.compile()
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.Player])

GroupService

Bases: BaseService

Handles endpoints related to groups.

Source code in wom/services/groups.py
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
class GroupService(BaseService):
    """Handles endpoints related to groups."""

    __slots__ = ()

    def _prepare_member_fragments(
        self, members: t.Iterable[t.Union[str, models.GroupMemberFragment]]
    ) -> tuple[t.Dict[str, t.Any], ...]:
        return tuple(
            {k: str(v) for k, v in m.to_dict().items() if v}
            for m in self._parse_member_fragments(members)
        )

    def _parse_member_fragments(
        self, members: t.Iterable[t.Union[str, models.GroupMemberFragment]]
    ) -> t.Generator[models.GroupMemberFragment, None, None]:
        return (models.GroupMemberFragment(m, None) if isinstance(m, str) else m for m in members)

    async def search_groups(
        self,
        name: t.Optional[str] = None,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.Group]]:
        """Searches for groups that at least partially match the given
        name.

        Args:
            name: The group name to search for.

            limit: The pagination limit.

            offset: The pagination offset.

        Returns:
            A [`Result`][wom.Result] containing the list of matching
                groups.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.search_groups("Some group", limit=3)
            ```
        """
        params = self._generate_map(name=name, limit=limit, offset=offset)
        route = routes.SEARCH_GROUPS.compile().with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Group])

    async def get_details(self, id: int) -> ResultT[models.GroupDetail]:
        """Gets the details for the given group id.

        Args:
            id: The group ID to get details for.

        Returns:
            A [`Result`][wom.Result] containing the group details.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_details(1234)
            ```
        """
        route = routes.GROUP_DETAILS.compile(id)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.GroupDetail)

    async def create_group(
        self,
        name: str,
        *members: t.Union[str, models.GroupMemberFragment],
        clan_chat: t.Optional[str] = None,
        description: t.Optional[str] = None,
        homeworld: t.Optional[int] = None,
    ) -> ResultT[models.CreatedGroupDetail]:
        """Creates a new group.

        Args:
            name: The name for the group.

            *members: The optional members to add to the group.

        Keyword Args:
            clan_chat: The optional clan chat for the group. Defaults to
                `None`.

            description: The optional group description. Defaults to
                `None`.

            homeworld: The optional homeworld for the group. Defaults to
                `None`.

        Returns:
            A [`Result`][wom.Result] containing the created group details.

        !!! note

            A mixture of strings and GroupMemberFragments can be passed for
            members. If a string is passed, no role will be added for that
            member.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.create_group(
                "My new group",
                wom.GroupMemberFragment("Jonxslays", wom.GroupRole.Owner),
                "Faabvk",
                "psikoi",
                "rro",
                description="The most epic group."
            )
            ```
        """
        payload = self._generate_map(
            name=name,
            clanChat=clan_chat,
            homeworld=homeworld,
            description=description,
            members=self._prepare_member_fragments(members),
        )

        route = routes.CREATE_GROUP.compile()
        data = await self._http.fetch(route, payload=payload)
        return self._ok_or_err(data, models.CreatedGroupDetail)

    async def edit_group(
        self,
        id: int,
        verification_code: str,
        *,
        name: t.Optional[str] = None,
        members: t.Optional[t.Iterable[t.Union[str, models.GroupMemberFragment]]] = None,
        clan_chat: t.Optional[str] = None,
        description: t.Optional[str] = None,
        homeworld: t.Optional[int] = None,
        social_links: t.Optional[models.SocialLinks] = None,
    ) -> ResultT[models.GroupDetail]:
        """Edits an existing group.

        Args:
            id: The ID of the group.

            verification_code: The group verification code.

        Keyword Args:
            name: The optional new name for the group. Defaults to
                `None`.

            members: The optional iterable of members to replace the
                existing group members with. Defaults to `None`.

            clan_chat: The optional new clan chat for the group.
                Defaults to `None`.

            description: The optional new group description. Defaults to
                `None`.

            homeworld: The optional new homeworld for the group.
                Defaults to `None`.

            social_links: The optional new social links for the group.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the group details.

        !!! warning

            The members list provided will completely replace the
            existing members. If you want to add members, see
            [`add_members()`][wom.GroupService.add_members]

        !!! note

             A mixture of strings and GroupMemberFragments can be passed for
             members. If a string is passed, no role will be added for that
             member.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.edit_group(
                123,
                "111-111-111",
                name="My new group name",
                members=[
                    wom.GroupMemberFragment("Jonxslays", wom.GroupRole.Owner),
                    "Faabvk",
                ],
                description="Some new description."
            )
            ```
        """
        payload = self._generate_map(
            name=name,
            clanChat=clan_chat,
            homeworld=homeworld,
            description=description,
            verificationCode=verification_code,
            members=self._prepare_member_fragments(members) if members else None,
            socialLinks=social_links.to_dict() if social_links else None,
        )

        route = routes.EDIT_GROUP.compile(id)
        data = await self._http.fetch(route, payload=payload)
        return self._ok_or_err(data, models.GroupDetail)

    async def delete_group(
        self, id: int, verification_code: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Deletes an existing group.

        Args:
            id: The ID of the group.

            verification_code: The group verification code.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        !!! warning

            This action is irreversible.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.delete_group(123, "111-111-111")
            ```
        """
        route = routes.DELETE_GROUP.compile(id)
        payload = self._generate_map(verificationCode=verification_code)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def add_members(
        self, id: int, verification_code: str, *members: t.Union[str, models.GroupMemberFragment]
    ) -> ResultT[models.HttpSuccessResponse]:
        """Adds members to an existing group.

        Args:
            id: The ID of the group.

            verification_code: The group verification code.

            *members: The members to add to the group.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        !!! note

             A mixture of strings and GroupMemberFragments can be passed for
             members. If a string is passed, no role will be added for that
             member.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.add_members(
                123,
                "111-111-111",
                wom.GroupMemberFragment(
                    "Jonxslays", wom.GroupRole.Administrator
                ),
                "Zezima",
                "Psikoi",
            )
            ```
        """
        payload = self._generate_map(
            verificationCode=verification_code,
            members=self._prepare_member_fragments(members),
        )

        route = routes.ADD_MEMBERS.compile(id)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def remove_members(
        self, id: int, verification_code: str, *members: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Removes members from an existing group.

        Args:
            id: The ID of the group.

            verification_code: The group verification code.

            *members: The usernames of members to remove from the group.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.remove_members(
                123,
                "111-111-111",
                "Jonxslays",
                "Zezima",
            )
            ```
        """
        route = routes.REMOVE_MEMBERS.compile(id)
        payload = self._generate_map(verificationCode=verification_code, members=members)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data)

    async def change_member_role(
        self, id: int, verification_code: str, username: str, role: models.GroupRole
    ) -> ResultT[models.GroupMembership]:
        """Changes the role for a member in an existing group.

        Args:
            id: The ID of the group.

            verification_code: The group verification code.

            username: The username of the player to update.

            role: The players new group role.

        Returns:
            A [`Result`][wom.Result] containing the players group
                membership.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.change_member_role(
                123,
                "111-111-111",
                "Jonxslays",
                wom.GroupRole.Admiral
            )
            ```
        """
        payload = self._generate_map(
            verificationCode=verification_code, username=username, role=role.value
        )

        route = routes.CHANGE_MEMBER_ROLE.compile(id)
        data = await self._http.fetch(route, payload=payload)
        return self._ok_or_err(data, models.GroupMembership)

    async def update_outdated_members(
        self, id: int, verification_code: str
    ) -> ResultT[models.HttpSuccessResponse]:
        """Attempts to update all outdated group members.

        Args:
            id: The ID of the group.

            verification_code: The verification code for the group.

        Returns:
            A [`Result`][wom.Result] containing the success response
                message.

        !!! info

            Group members are considered outdated when they haven't been
            updated in over 24h.

        !!! warning

            This method adds every outdated member to an "update queue",
            and the WOM servers try to update players in the queue one
            by one, with a delay in between each. For each player in the
            queue, an attempt is made to update it up to 3 times, with
            30s in between each attempt.

            Please note that this is dependent on the OSRS hiscores
            functioning correctly, and therefore this method does NOT
            guarantee the players will be updated, it only guarantees
            that an attempt will be made to update them, up to 3 times.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.groups.update_outdated_members(
                123, "111-111-111"
            )
            ```
        """
        route = routes.UPDATE_OUTDATED_MEMBERS.compile(id)
        payload = self._generate_map(verificationCode=verification_code)
        data = await self._http.fetch(route, payload=payload, allow_http_success=True)
        return self._success_or_err(data, predicate=lambda m: "players are being updated" in m)

    async def get_competitions(
        self, id: int, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
    ) -> ResultT[t.List[models.Competition]]:
        """Gets competitions for a given group.

        Args:
            id: The ID of the group.

        Keyword Args:
            limit: The optional pagination limit. Defaults to `None`.

            offset: The optional pagination offset. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of
                competitions.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_competitions(123, limit=10)
            ```
        """
        params = self._generate_map(limit=limit, offset=offset)
        route = routes.GROUP_COMPETITIONS.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Competition])

    async def get_gains(
        self,
        id: int,
        metric: enums.Metric,
        *,
        period: t.Optional[enums.Period] = None,
        start_date: t.Optional[datetime] = None,
        end_date: t.Optional[datetime] = None,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.GroupMemberGains]]:
        """Gets the gains for a group over a particular time frame.

        Args:
            id: The ID of the group.

            metric: The metric to filter on.

        Keyword Args:
            period: The optional period of time to get gains for.
                Defaults to `None`.

            start_date: The minimum date to get the gains from. Defaults
                to `None`.

            end_date: The maximum date to get the gains from. Defaults
                to `None`.

            limit: The optional pagination limit. Defaults to `None`.

            offset: The optional pagination offset. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of delta
                leaderboard entries.

        !!! info

            You must pass one of (`period`) or (`start_date` +
            `end_date`), but not both.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_gains(
                123, wom.Metric.Zulrah, limit=10
            )
            ```
        """
        params = self._generate_map(
            limit=limit,
            offset=offset,
            metric=metric.value,
            period=period.value if period else None,
            endDate=end_date.isoformat() if end_date else None,
            startDate=start_date.isoformat() if start_date else None,
        )

        route = routes.GROUP_GAINS.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.GroupMemberGains])

    async def get_achievements(
        self,
        id: int,
        *,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.Achievement]]:
        """Gets the achievements for the group.

        Args:
            id: The ID of the group.

        Keyword Args:
            limit: The optional pagination limit. Defaults to `None`.

            offset: The optional pagination offset. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of achievements.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_achievements(123, limit=10)
            ```
        """
        params = self._generate_map(limit=limit, offset=offset)
        route = routes.GROUP_ACHIEVEMENTS.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Achievement])

    async def get_records(
        self,
        id: int,
        metric: enums.Metric,
        period: enums.Period,
        *,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.RecordLeaderboardEntry]]:
        """Gets the records held by players in the group.

        Args:
            id: The ID of the group.

            metric: The metric to filter on.

            period: The period of time to get records for.

        Keyword Args:
            limit: The optional pagination limit. Defaults to `None`.

            offset: The optional pagination offset. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of record
                leaderboard entries.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_records(
                123, wom.Metric.Zulrah, wom.Period.Day, limit=3
            )
            ```
        """
        params = self._generate_map(
            limit=limit,
            offset=offset,
            metric=metric.value,
            period=period.value,
        )

        route = routes.GROUP_RECORDS.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.RecordLeaderboardEntry])

    async def get_hiscores(
        self,
        id: int,
        metric: enums.Metric,
        *,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.GroupHiscoresEntry]]:
        """Gets the hiscores for the group.

        Args:
            id: The ID of the group.

            metric: The metric to filter on.

        Keyword Args:
            limit: The optional pagination limit. Defaults to `None`.

            offset: The optional pagination offset. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of hiscores
                entries.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_hiscores(
                123, wom.Metric.Runecrafting, limit=10
            )
            ```
        """
        params = self._generate_map(limit=limit, offset=offset, metric=metric.value)
        route = routes.GROUP_HISCORES.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.GroupHiscoresEntry])

    async def get_name_changes(
        self, id: int, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
    ) -> ResultT[t.List[models.NameChange]]:
        """Gets the past name changes for the group.

        Args:
            id: The ID of the group.

        Keyword Args:
            limit: The optional pagination limit. Defaults to `None`.

            offset: The optional pagination offset. Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list name changes.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_name_changes(123, limit=10)
            ```
        """
        params = self._generate_map(limit=limit, offset=offset)
        route = routes.GROUP_NAME_CHANGES.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.NameChange])

    async def get_statistics(self, id: int) -> ResultT[models.GroupStatistics]:
        """Gets the statistics for the group.

        Args:
            id: The ID of the group.

        Returns:
            A [`Result`][wom.Result] containing the statistics.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_statistics(123)
            ```
        """
        route = routes.GROUP_STATISTICS.compile(id)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.GroupStatistics)

    async def get_activity(
        self,
        id: int,
        *,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.GroupActivity]]:
        """Gets the activity for the group. This is a paginated endpoint.

        Args:
            id: The ID of the group to fetch activity for.

        Keyword Args:
            limit: The pagination limit.

            offset: The pagination offset.

        Returns:
            A [`Result`][wom.Result] containing the list of activities.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            await client.groups.get_activity(69, limit=5)
            ```
        """
        params = self._generate_map(limit=limit, offset=offset)
        route = routes.GROUP_ACTIVITY.compile(id).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.GroupActivity])

    async def get_members_csv(self, id: int) -> ResultT[str]:
        """Gets members in this group in CSV format.

        Args:
            id: The ID of the group.

        Returns:
            A [`Result`][wom.Result] containing the CSV string.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.groups.get_members_csv(123)
            ```
        """
        route = routes.GROUP_MEMBERS_CSV.compile(id)
        data = await self._http.fetch(route)

        if isinstance(data, models.HttpErrorResponse):
            return result.Err(data)

        return result.Ok(data.decode())

add_members async

add_members(
    id: int,
    verification_code: str,
    *members: t.Union[str, models.GroupMemberFragment]
) -> ResultT[models.HttpSuccessResponse]

Adds members to an existing group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
verification_code str

The group verification code.

required
*members Union[str, GroupMemberFragment]

The members to add to the group.

()

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Note

A mixture of strings and GroupMemberFragments can be passed for members. If a string is passed, no role will be added for that member.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.add_members(
    123,
    "111-111-111",
    wom.GroupMemberFragment(
        "Jonxslays", wom.GroupRole.Administrator
    ),
    "Zezima",
    "Psikoi",
)
Source code in wom/services/groups.py
async def add_members(
    self, id: int, verification_code: str, *members: t.Union[str, models.GroupMemberFragment]
) -> ResultT[models.HttpSuccessResponse]:
    """Adds members to an existing group.

    Args:
        id: The ID of the group.

        verification_code: The group verification code.

        *members: The members to add to the group.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    !!! note

         A mixture of strings and GroupMemberFragments can be passed for
         members. If a string is passed, no role will be added for that
         member.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.add_members(
            123,
            "111-111-111",
            wom.GroupMemberFragment(
                "Jonxslays", wom.GroupRole.Administrator
            ),
            "Zezima",
            "Psikoi",
        )
        ```
    """
    payload = self._generate_map(
        verificationCode=verification_code,
        members=self._prepare_member_fragments(members),
    )

    route = routes.ADD_MEMBERS.compile(id)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

change_member_role async

change_member_role(
    id: int,
    verification_code: str,
    username: str,
    role: models.GroupRole,
) -> ResultT[models.GroupMembership]

Changes the role for a member in an existing group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
verification_code str

The group verification code.

required
username str

The username of the player to update.

required
role GroupRole

The players new group role.

required

Returns:

Type Description
ResultT[GroupMembership]

A Result containing the players group membership.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.change_member_role(
    123,
    "111-111-111",
    "Jonxslays",
    wom.GroupRole.Admiral
)
Source code in wom/services/groups.py
async def change_member_role(
    self, id: int, verification_code: str, username: str, role: models.GroupRole
) -> ResultT[models.GroupMembership]:
    """Changes the role for a member in an existing group.

    Args:
        id: The ID of the group.

        verification_code: The group verification code.

        username: The username of the player to update.

        role: The players new group role.

    Returns:
        A [`Result`][wom.Result] containing the players group
            membership.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.change_member_role(
            123,
            "111-111-111",
            "Jonxslays",
            wom.GroupRole.Admiral
        )
        ```
    """
    payload = self._generate_map(
        verificationCode=verification_code, username=username, role=role.value
    )

    route = routes.CHANGE_MEMBER_ROLE.compile(id)
    data = await self._http.fetch(route, payload=payload)
    return self._ok_or_err(data, models.GroupMembership)

create_group async

create_group(
    name: str,
    *members: t.Union[str, models.GroupMemberFragment],
    clan_chat: t.Optional[str] = None,
    description: t.Optional[str] = None,
    homeworld: t.Optional[int] = None
) -> ResultT[models.CreatedGroupDetail]

Creates a new group.

Parameters:

Name Type Description Default
name str

The name for the group.

required
*members Union[str, GroupMemberFragment]

The optional members to add to the group.

()

Other Parameters:

Name Type Description
clan_chat Optional[str]

The optional clan chat for the group. Defaults to None.

description Optional[str]

The optional group description. Defaults to None.

homeworld Optional[int]

The optional homeworld for the group. Defaults to None.

Returns:

Type Description
ResultT[CreatedGroupDetail]

A Result containing the created group details.

Note

A mixture of strings and GroupMemberFragments can be passed for members. If a string is passed, no role will be added for that member.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.create_group(
    "My new group",
    wom.GroupMemberFragment("Jonxslays", wom.GroupRole.Owner),
    "Faabvk",
    "psikoi",
    "rro",
    description="The most epic group."
)
Source code in wom/services/groups.py
async def create_group(
    self,
    name: str,
    *members: t.Union[str, models.GroupMemberFragment],
    clan_chat: t.Optional[str] = None,
    description: t.Optional[str] = None,
    homeworld: t.Optional[int] = None,
) -> ResultT[models.CreatedGroupDetail]:
    """Creates a new group.

    Args:
        name: The name for the group.

        *members: The optional members to add to the group.

    Keyword Args:
        clan_chat: The optional clan chat for the group. Defaults to
            `None`.

        description: The optional group description. Defaults to
            `None`.

        homeworld: The optional homeworld for the group. Defaults to
            `None`.

    Returns:
        A [`Result`][wom.Result] containing the created group details.

    !!! note

        A mixture of strings and GroupMemberFragments can be passed for
        members. If a string is passed, no role will be added for that
        member.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.create_group(
            "My new group",
            wom.GroupMemberFragment("Jonxslays", wom.GroupRole.Owner),
            "Faabvk",
            "psikoi",
            "rro",
            description="The most epic group."
        )
        ```
    """
    payload = self._generate_map(
        name=name,
        clanChat=clan_chat,
        homeworld=homeworld,
        description=description,
        members=self._prepare_member_fragments(members),
    )

    route = routes.CREATE_GROUP.compile()
    data = await self._http.fetch(route, payload=payload)
    return self._ok_or_err(data, models.CreatedGroupDetail)

delete_group async

delete_group(
    id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]

Deletes an existing group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
verification_code str

The group verification code.

required

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Warning

This action is irreversible.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.delete_group(123, "111-111-111")
Source code in wom/services/groups.py
async def delete_group(
    self, id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]:
    """Deletes an existing group.

    Args:
        id: The ID of the group.

        verification_code: The group verification code.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    !!! warning

        This action is irreversible.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.delete_group(123, "111-111-111")
        ```
    """
    route = routes.DELETE_GROUP.compile(id)
    payload = self._generate_map(verificationCode=verification_code)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

edit_group async

edit_group(
    id: int,
    verification_code: str,
    *,
    name: t.Optional[str] = None,
    members: t.Optional[
        t.Iterable[t.Union[str, models.GroupMemberFragment]]
    ] = None,
    clan_chat: t.Optional[str] = None,
    description: t.Optional[str] = None,
    homeworld: t.Optional[int] = None,
    social_links: t.Optional[models.SocialLinks] = None
) -> ResultT[models.GroupDetail]

Edits an existing group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
verification_code str

The group verification code.

required

Other Parameters:

Name Type Description
name Optional[str]

The optional new name for the group. Defaults to None.

members Optional[Iterable[Union[str, GroupMemberFragment]]]

The optional iterable of members to replace the existing group members with. Defaults to None.

clan_chat Optional[str]

The optional new clan chat for the group. Defaults to None.

description Optional[str]

The optional new group description. Defaults to None.

homeworld Optional[int]

The optional new homeworld for the group. Defaults to None.

social_links Optional[SocialLinks]

The optional new social links for the group. Defaults to None.

Returns:

Type Description
ResultT[GroupDetail]

A Result containing the group details.

Warning

The members list provided will completely replace the existing members. If you want to add members, see add_members()

Note

A mixture of strings and GroupMemberFragments can be passed for members. If a string is passed, no role will be added for that member.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.edit_group(
    123,
    "111-111-111",
    name="My new group name",
    members=[
        wom.GroupMemberFragment("Jonxslays", wom.GroupRole.Owner),
        "Faabvk",
    ],
    description="Some new description."
)
Source code in wom/services/groups.py
async def edit_group(
    self,
    id: int,
    verification_code: str,
    *,
    name: t.Optional[str] = None,
    members: t.Optional[t.Iterable[t.Union[str, models.GroupMemberFragment]]] = None,
    clan_chat: t.Optional[str] = None,
    description: t.Optional[str] = None,
    homeworld: t.Optional[int] = None,
    social_links: t.Optional[models.SocialLinks] = None,
) -> ResultT[models.GroupDetail]:
    """Edits an existing group.

    Args:
        id: The ID of the group.

        verification_code: The group verification code.

    Keyword Args:
        name: The optional new name for the group. Defaults to
            `None`.

        members: The optional iterable of members to replace the
            existing group members with. Defaults to `None`.

        clan_chat: The optional new clan chat for the group.
            Defaults to `None`.

        description: The optional new group description. Defaults to
            `None`.

        homeworld: The optional new homeworld for the group.
            Defaults to `None`.

        social_links: The optional new social links for the group.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the group details.

    !!! warning

        The members list provided will completely replace the
        existing members. If you want to add members, see
        [`add_members()`][wom.GroupService.add_members]

    !!! note

         A mixture of strings and GroupMemberFragments can be passed for
         members. If a string is passed, no role will be added for that
         member.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.edit_group(
            123,
            "111-111-111",
            name="My new group name",
            members=[
                wom.GroupMemberFragment("Jonxslays", wom.GroupRole.Owner),
                "Faabvk",
            ],
            description="Some new description."
        )
        ```
    """
    payload = self._generate_map(
        name=name,
        clanChat=clan_chat,
        homeworld=homeworld,
        description=description,
        verificationCode=verification_code,
        members=self._prepare_member_fragments(members) if members else None,
        socialLinks=social_links.to_dict() if social_links else None,
    )

    route = routes.EDIT_GROUP.compile(id)
    data = await self._http.fetch(route, payload=payload)
    return self._ok_or_err(data, models.GroupDetail)

get_achievements async

get_achievements(
    id: int,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.Achievement]]

Gets the achievements for the group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required

Other Parameters:

Name Type Description
limit Optional[int]

The optional pagination limit. Defaults to None.

offset Optional[int]

The optional pagination offset. Defaults to None.

Returns:

Type Description
ResultT[List[Achievement]]

A Result containing the list of achievements.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_achievements(123, limit=10)
Source code in wom/services/groups.py
async def get_achievements(
    self,
    id: int,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.Achievement]]:
    """Gets the achievements for the group.

    Args:
        id: The ID of the group.

    Keyword Args:
        limit: The optional pagination limit. Defaults to `None`.

        offset: The optional pagination offset. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of achievements.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_achievements(123, limit=10)
        ```
    """
    params = self._generate_map(limit=limit, offset=offset)
    route = routes.GROUP_ACHIEVEMENTS.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Achievement])

get_activity async

get_activity(
    id: int,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.GroupActivity]]

Gets the activity for the group. This is a paginated endpoint.

Parameters:

Name Type Description Default
id int

The ID of the group to fetch activity for.

required

Other Parameters:

Name Type Description
limit Optional[int]

The pagination limit.

offset Optional[int]

The pagination offset.

Returns:

Type Description
ResultT[List[GroupActivity]]

A Result containing the list of activities.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_activity(69, limit=5)
Source code in wom/services/groups.py
async def get_activity(
    self,
    id: int,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.GroupActivity]]:
    """Gets the activity for the group. This is a paginated endpoint.

    Args:
        id: The ID of the group to fetch activity for.

    Keyword Args:
        limit: The pagination limit.

        offset: The pagination offset.

    Returns:
        A [`Result`][wom.Result] containing the list of activities.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_activity(69, limit=5)
        ```
    """
    params = self._generate_map(limit=limit, offset=offset)
    route = routes.GROUP_ACTIVITY.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.GroupActivity])

get_competitions async

get_competitions(
    id: int,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.Competition]]

Gets competitions for a given group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required

Other Parameters:

Name Type Description
limit Optional[int]

The optional pagination limit. Defaults to None.

offset Optional[int]

The optional pagination offset. Defaults to None.

Returns:

Type Description
ResultT[List[Competition]]

A Result containing the list of competitions.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_competitions(123, limit=10)
Source code in wom/services/groups.py
async def get_competitions(
    self, id: int, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
) -> ResultT[t.List[models.Competition]]:
    """Gets competitions for a given group.

    Args:
        id: The ID of the group.

    Keyword Args:
        limit: The optional pagination limit. Defaults to `None`.

        offset: The optional pagination offset. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of
            competitions.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_competitions(123, limit=10)
        ```
    """
    params = self._generate_map(limit=limit, offset=offset)
    route = routes.GROUP_COMPETITIONS.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Competition])

get_details async

get_details(id: int) -> ResultT[models.GroupDetail]

Gets the details for the given group id.

Parameters:

Name Type Description Default
id int

The group ID to get details for.

required

Returns:

Type Description
ResultT[GroupDetail]

A Result containing the group details.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_details(1234)
Source code in wom/services/groups.py
async def get_details(self, id: int) -> ResultT[models.GroupDetail]:
    """Gets the details for the given group id.

    Args:
        id: The group ID to get details for.

    Returns:
        A [`Result`][wom.Result] containing the group details.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_details(1234)
        ```
    """
    route = routes.GROUP_DETAILS.compile(id)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.GroupDetail)

get_gains async

get_gains(
    id: int,
    metric: enums.Metric,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.GroupMemberGains]]

Gets the gains for a group over a particular time frame.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
metric Metric

The metric to filter on.

required

Other Parameters:

Name Type Description
period Optional[Period]

The optional period of time to get gains for. Defaults to None.

start_date Optional[datetime]

The minimum date to get the gains from. Defaults to None.

end_date Optional[datetime]

The maximum date to get the gains from. Defaults to None.

limit Optional[int]

The optional pagination limit. Defaults to None.

offset Optional[int]

The optional pagination offset. Defaults to None.

Returns:

Type Description
ResultT[List[GroupMemberGains]]

A Result containing the list of delta leaderboard entries.

Info

You must pass one of (period) or (start_date + end_date), but not both.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_gains(
    123, wom.Metric.Zulrah, limit=10
)
Source code in wom/services/groups.py
async def get_gains(
    self,
    id: int,
    metric: enums.Metric,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.GroupMemberGains]]:
    """Gets the gains for a group over a particular time frame.

    Args:
        id: The ID of the group.

        metric: The metric to filter on.

    Keyword Args:
        period: The optional period of time to get gains for.
            Defaults to `None`.

        start_date: The minimum date to get the gains from. Defaults
            to `None`.

        end_date: The maximum date to get the gains from. Defaults
            to `None`.

        limit: The optional pagination limit. Defaults to `None`.

        offset: The optional pagination offset. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of delta
            leaderboard entries.

    !!! info

        You must pass one of (`period`) or (`start_date` +
        `end_date`), but not both.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_gains(
            123, wom.Metric.Zulrah, limit=10
        )
        ```
    """
    params = self._generate_map(
        limit=limit,
        offset=offset,
        metric=metric.value,
        period=period.value if period else None,
        endDate=end_date.isoformat() if end_date else None,
        startDate=start_date.isoformat() if start_date else None,
    )

    route = routes.GROUP_GAINS.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.GroupMemberGains])

get_hiscores async

get_hiscores(
    id: int,
    metric: enums.Metric,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.GroupHiscoresEntry]]

Gets the hiscores for the group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
metric Metric

The metric to filter on.

required

Other Parameters:

Name Type Description
limit Optional[int]

The optional pagination limit. Defaults to None.

offset Optional[int]

The optional pagination offset. Defaults to None.

Returns:

Type Description
ResultT[List[GroupHiscoresEntry]]

A Result containing the list of hiscores entries.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_hiscores(
    123, wom.Metric.Runecrafting, limit=10
)
Source code in wom/services/groups.py
async def get_hiscores(
    self,
    id: int,
    metric: enums.Metric,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.GroupHiscoresEntry]]:
    """Gets the hiscores for the group.

    Args:
        id: The ID of the group.

        metric: The metric to filter on.

    Keyword Args:
        limit: The optional pagination limit. Defaults to `None`.

        offset: The optional pagination offset. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of hiscores
            entries.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_hiscores(
            123, wom.Metric.Runecrafting, limit=10
        )
        ```
    """
    params = self._generate_map(limit=limit, offset=offset, metric=metric.value)
    route = routes.GROUP_HISCORES.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.GroupHiscoresEntry])

get_members_csv async

get_members_csv(id: int) -> ResultT[str]

Gets members in this group in CSV format.

Parameters:

Name Type Description Default
id int

The ID of the group.

required

Returns:

Type Description
ResultT[str]

A Result containing the CSV string.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.groups.get_members_csv(123)
Source code in wom/services/groups.py
async def get_members_csv(self, id: int) -> ResultT[str]:
    """Gets members in this group in CSV format.

    Args:
        id: The ID of the group.

    Returns:
        A [`Result`][wom.Result] containing the CSV string.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.groups.get_members_csv(123)
        ```
    """
    route = routes.GROUP_MEMBERS_CSV.compile(id)
    data = await self._http.fetch(route)

    if isinstance(data, models.HttpErrorResponse):
        return result.Err(data)

    return result.Ok(data.decode())

get_name_changes async

get_name_changes(
    id: int,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.NameChange]]

Gets the past name changes for the group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required

Other Parameters:

Name Type Description
limit Optional[int]

The optional pagination limit. Defaults to None.

offset Optional[int]

The optional pagination offset. Defaults to None.

Returns:

Type Description
ResultT[List[NameChange]]

A Result containing the list name changes.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_name_changes(123, limit=10)
Source code in wom/services/groups.py
async def get_name_changes(
    self, id: int, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
) -> ResultT[t.List[models.NameChange]]:
    """Gets the past name changes for the group.

    Args:
        id: The ID of the group.

    Keyword Args:
        limit: The optional pagination limit. Defaults to `None`.

        offset: The optional pagination offset. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list name changes.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_name_changes(123, limit=10)
        ```
    """
    params = self._generate_map(limit=limit, offset=offset)
    route = routes.GROUP_NAME_CHANGES.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.NameChange])

get_records async

get_records(
    id: int,
    metric: enums.Metric,
    period: enums.Period,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.RecordLeaderboardEntry]]

Gets the records held by players in the group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
metric Metric

The metric to filter on.

required
period Period

The period of time to get records for.

required

Other Parameters:

Name Type Description
limit Optional[int]

The optional pagination limit. Defaults to None.

offset Optional[int]

The optional pagination offset. Defaults to None.

Returns:

Type Description
ResultT[List[RecordLeaderboardEntry]]

A Result containing the list of record leaderboard entries.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_records(
    123, wom.Metric.Zulrah, wom.Period.Day, limit=3
)
Source code in wom/services/groups.py
async def get_records(
    self,
    id: int,
    metric: enums.Metric,
    period: enums.Period,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.RecordLeaderboardEntry]]:
    """Gets the records held by players in the group.

    Args:
        id: The ID of the group.

        metric: The metric to filter on.

        period: The period of time to get records for.

    Keyword Args:
        limit: The optional pagination limit. Defaults to `None`.

        offset: The optional pagination offset. Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of record
            leaderboard entries.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_records(
            123, wom.Metric.Zulrah, wom.Period.Day, limit=3
        )
        ```
    """
    params = self._generate_map(
        limit=limit,
        offset=offset,
        metric=metric.value,
        period=period.value,
    )

    route = routes.GROUP_RECORDS.compile(id).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.RecordLeaderboardEntry])

get_statistics async

get_statistics(id: int) -> ResultT[models.GroupStatistics]

Gets the statistics for the group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required

Returns:

Type Description
ResultT[GroupStatistics]

A Result containing the statistics.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.get_statistics(123)
Source code in wom/services/groups.py
async def get_statistics(self, id: int) -> ResultT[models.GroupStatistics]:
    """Gets the statistics for the group.

    Args:
        id: The ID of the group.

    Returns:
        A [`Result`][wom.Result] containing the statistics.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.get_statistics(123)
        ```
    """
    route = routes.GROUP_STATISTICS.compile(id)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.GroupStatistics)

remove_members async

remove_members(
    id: int, verification_code: str, *members: str
) -> ResultT[models.HttpSuccessResponse]

Removes members from an existing group.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
verification_code str

The group verification code.

required
*members str

The usernames of members to remove from the group.

()

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.remove_members(
    123,
    "111-111-111",
    "Jonxslays",
    "Zezima",
)
Source code in wom/services/groups.py
async def remove_members(
    self, id: int, verification_code: str, *members: str
) -> ResultT[models.HttpSuccessResponse]:
    """Removes members from an existing group.

    Args:
        id: The ID of the group.

        verification_code: The group verification code.

        *members: The usernames of members to remove from the group.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.remove_members(
            123,
            "111-111-111",
            "Jonxslays",
            "Zezima",
        )
        ```
    """
    route = routes.REMOVE_MEMBERS.compile(id)
    payload = self._generate_map(verificationCode=verification_code, members=members)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data)

search_groups async

search_groups(
    name: t.Optional[str] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.Group]]

Searches for groups that at least partially match the given name.

Parameters:

Name Type Description Default
name Optional[str]

The group name to search for.

None
limit Optional[int]

The pagination limit.

None
offset Optional[int]

The pagination offset.

None

Returns:

Type Description
ResultT[List[Group]]

A Result containing the list of matching groups.

Example
import wom

client = wom.Client(...)

await client.start()

await client.groups.search_groups("Some group", limit=3)
Source code in wom/services/groups.py
async def search_groups(
    self,
    name: t.Optional[str] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.Group]]:
    """Searches for groups that at least partially match the given
    name.

    Args:
        name: The group name to search for.

        limit: The pagination limit.

        offset: The pagination offset.

    Returns:
        A [`Result`][wom.Result] containing the list of matching
            groups.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        await client.groups.search_groups("Some group", limit=3)
        ```
    """
    params = self._generate_map(name=name, limit=limit, offset=offset)
    route = routes.SEARCH_GROUPS.compile().with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Group])

update_outdated_members async

update_outdated_members(
    id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]

Attempts to update all outdated group members.

Parameters:

Name Type Description Default
id int

The ID of the group.

required
verification_code str

The verification code for the group.

required

Returns:

Type Description
ResultT[HttpSuccessResponse]

A Result containing the success response message.

Info

Group members are considered outdated when they haven't been updated in over 24h.

Warning

This method adds every outdated member to an "update queue", and the WOM servers try to update players in the queue one by one, with a delay in between each. For each player in the queue, an attempt is made to update it up to 3 times, with 30s in between each attempt.

Please note that this is dependent on the OSRS hiscores functioning correctly, and therefore this method does NOT guarantee the players will be updated, it only guarantees that an attempt will be made to update them, up to 3 times.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.groups.update_outdated_members(
    123, "111-111-111"
)
Source code in wom/services/groups.py
async def update_outdated_members(
    self, id: int, verification_code: str
) -> ResultT[models.HttpSuccessResponse]:
    """Attempts to update all outdated group members.

    Args:
        id: The ID of the group.

        verification_code: The verification code for the group.

    Returns:
        A [`Result`][wom.Result] containing the success response
            message.

    !!! info

        Group members are considered outdated when they haven't been
        updated in over 24h.

    !!! warning

        This method adds every outdated member to an "update queue",
        and the WOM servers try to update players in the queue one
        by one, with a delay in between each. For each player in the
        queue, an attempt is made to update it up to 3 times, with
        30s in between each attempt.

        Please note that this is dependent on the OSRS hiscores
        functioning correctly, and therefore this method does NOT
        guarantee the players will be updated, it only guarantees
        that an attempt will be made to update them, up to 3 times.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.groups.update_outdated_members(
            123, "111-111-111"
        )
        ```
    """
    route = routes.UPDATE_OUTDATED_MEMBERS.compile(id)
    payload = self._generate_map(verificationCode=verification_code)
    data = await self._http.fetch(route, payload=payload, allow_http_success=True)
    return self._success_or_err(data, predicate=lambda m: "players are being updated" in m)

HttpService

The HTTP service used to make requests to the WOM API.

Parameters:

Name Type Description Default
api_key Optional[str]

The optional api key to use.

required
user_agent Optional[str]

The optional user agent to use.

required
api_base_url Optional[str]

The optional api base url to use.

required
Source code in wom/services/http.py
class HttpService:
    """The HTTP service used to make requests to the WOM API.

    Args:
        api_key: The optional api key to use.

        user_agent: The optional user agent to use.

        api_base_url: The optional api base url to use.
    """

    __slots__ = ("_base_url", "_decoder", "_encoder", "_headers", "_method_mapping", "_session")

    def __init__(
        self,
        api_key: t.Optional[str],
        user_agent: t.Optional[str],
        api_base_url: t.Optional[str],
    ) -> None:
        user_agent = (
            f"{constants.USER_AGENT_BASE} {user_agent}"
            if user_agent
            else constants.DEFAULT_USER_AGENT
        )

        self._headers = {
            "x-user-agent": user_agent,
            "User-Agent": user_agent,
        }

        if api_key:
            self._headers["x-api-key"] = api_key

        self._base_url = api_base_url or constants.WOM_BASE_URL
        self._decoder = msgspec.json.Decoder()
        self._encoder = msgspec.json.Encoder()

    async def _read_content(
        self, response: aiohttp.ClientResponse
    ) -> t.Union[bytes, models.HttpErrorResponse]:
        try:
            return await response.content.read()
        except Exception:
            return models.HttpErrorResponse("Failed to read response content.", response.status)

    async def _request(
        self,
        req: t.Callable[..., t.Awaitable[t.Any]],
        url: str,
        allow_http_success: bool = False,
        **kwargs: t.Any,
    ) -> t.Union[bytes, models.HttpErrorResponse]:
        response = await req(url, **kwargs)
        content = await self._read_content(response)

        if isinstance(content, models.HttpErrorResponse):
            return content

        if not response.ok or allow_http_success:
            error = self._decoder.decode(content)

            return models.HttpErrorResponse(
                error.get("message", "An unexpected error occurred while making the request."),
                response.status,
            )

        return content

    def _get_request_func(self, method: str) -> t.Callable[..., t.Awaitable[t.Any]]:
        if not hasattr(self, "_method_mapping"):
            raise RuntimeError("HttpService.start was never called, aborting...")

        return self._method_mapping[method]  # type: ignore[return-value]

    async def _init_session(self) -> None:
        self._session = aiohttp.ClientSession(
            json_serialize=lambda o: self._encoder.encode(o).decode()
        )

        self._method_mapping = {
            "GET": self._session.get,
            "POST": self._session.post,
            "PUT": self._session.put,
            "PATCH": self._session.patch,
            "DELETE": self._session.delete,
        }

    def set_api_key(self, api_key: str) -> None:
        """Sets the api key used by the http service.

        Args:
            api_key: The new api key to use.
        """
        self._headers["x-api-key"] = api_key

    def unset_api_key(self) -> None:
        """Un-sets the current api key so it isn't sent with requests."""
        if "x-api-key" in self._headers:
            del self._headers["x-api-key"]

    def set_user_agent(self, user_agent: str) -> None:
        """Sets the user agent used by the http service.

        Args:
            user_agent: The new user agent to use.
        """
        self._headers["x-user-agent"] = user_agent
        self._headers["User-Agent"] = user_agent

    def set_base_url(self, base_url: str) -> None:
        """Sets the api base url used by the http service.

        Args:
            base_url: The new base url to use.
        """
        self._base_url = base_url

    async def start(self) -> None:
        """Starts the client session to be used by the http service."""
        if not hasattr(self, "_session"):
            await self._init_session()

    async def close(self) -> None:
        """Closes the existing client session, if it's still open."""
        if hasattr(self, "_session") and not self._session.closed:
            await self._session.close()

    async def fetch(
        self,
        route: routes.CompiledRoute,
        *,
        payload: t.Optional[t.Dict[str, t.Any]] = None,
        allow_http_success: bool = False,
    ) -> bytes | models.HttpErrorResponse:
        """Fetches the given route.

        Args:
            route: The route to make the request to.

            payload: The optional payload to send in the request
                body.

            allow_http_success: Whether or not the caller is planning
                to return http success.

        Returns:
            The requested bytes or the error response.
        """
        return await self._request(
            self._get_request_func(route.method),
            self._base_url + route.uri,
            allow_http_success,
            headers=self._headers,
            params=route.params,
            json=payload or None,
        )

close async

close() -> None

Closes the existing client session, if it's still open.

Source code in wom/services/http.py
async def close(self) -> None:
    """Closes the existing client session, if it's still open."""
    if hasattr(self, "_session") and not self._session.closed:
        await self._session.close()

fetch async

fetch(
    route: routes.CompiledRoute,
    *,
    payload: t.Optional[t.Dict[str, t.Any]] = None,
    allow_http_success: bool = False
) -> bytes | models.HttpErrorResponse

Fetches the given route.

Parameters:

Name Type Description Default
route CompiledRoute

The route to make the request to.

required
payload Optional[Dict[str, Any]]

The optional payload to send in the request body.

None
allow_http_success bool

Whether or not the caller is planning to return http success.

False

Returns:

Type Description
bytes | HttpErrorResponse

The requested bytes or the error response.

Source code in wom/services/http.py
async def fetch(
    self,
    route: routes.CompiledRoute,
    *,
    payload: t.Optional[t.Dict[str, t.Any]] = None,
    allow_http_success: bool = False,
) -> bytes | models.HttpErrorResponse:
    """Fetches the given route.

    Args:
        route: The route to make the request to.

        payload: The optional payload to send in the request
            body.

        allow_http_success: Whether or not the caller is planning
            to return http success.

    Returns:
        The requested bytes or the error response.
    """
    return await self._request(
        self._get_request_func(route.method),
        self._base_url + route.uri,
        allow_http_success,
        headers=self._headers,
        params=route.params,
        json=payload or None,
    )

set_api_key

set_api_key(api_key: str) -> None

Sets the api key used by the http service.

Parameters:

Name Type Description Default
api_key str

The new api key to use.

required
Source code in wom/services/http.py
def set_api_key(self, api_key: str) -> None:
    """Sets the api key used by the http service.

    Args:
        api_key: The new api key to use.
    """
    self._headers["x-api-key"] = api_key

set_base_url

set_base_url(base_url: str) -> None

Sets the api base url used by the http service.

Parameters:

Name Type Description Default
base_url str

The new base url to use.

required
Source code in wom/services/http.py
def set_base_url(self, base_url: str) -> None:
    """Sets the api base url used by the http service.

    Args:
        base_url: The new base url to use.
    """
    self._base_url = base_url

set_user_agent

set_user_agent(user_agent: str) -> None

Sets the user agent used by the http service.

Parameters:

Name Type Description Default
user_agent str

The new user agent to use.

required
Source code in wom/services/http.py
def set_user_agent(self, user_agent: str) -> None:
    """Sets the user agent used by the http service.

    Args:
        user_agent: The new user agent to use.
    """
    self._headers["x-user-agent"] = user_agent
    self._headers["User-Agent"] = user_agent

start async

start() -> None

Starts the client session to be used by the http service.

Source code in wom/services/http.py
async def start(self) -> None:
    """Starts the client session to be used by the http service."""
    if not hasattr(self, "_session"):
        await self._init_session()

unset_api_key

unset_api_key() -> None

Un-sets the current api key so it isn't sent with requests.

Source code in wom/services/http.py
def unset_api_key(self) -> None:
    """Un-sets the current api key so it isn't sent with requests."""
    if "x-api-key" in self._headers:
        del self._headers["x-api-key"]

NameChangeService

Bases: BaseService

Handles endpoints related to name changes.

Source code in wom/services/names.py
class NameChangeService(BaseService):
    """Handles endpoints related to name changes."""

    __slots__ = ()

    async def search_name_changes(
        self,
        username: t.Optional[str] = None,
        *,
        status: t.Optional[models.NameChangeStatus] = None,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.NameChange]]:
        """Searches for name changes.

        Args:
            username: The optional username to search for.

        Keyword Args:
            status: The optional name change status to filter on.
                Defaults to `None`.

            limit: The optional maximum items to return on this page
                from the API. Defaults to `None`.

            offset: The optional page offset. Defaults to
                `None`.

        Returns:
            A [`Result`][wom.Result] containing a list of name changes.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.names.search_name_changes(
                "Jonxslays", limit=1
            )
            ```
        """
        params = self._generate_map(username=username, status=status, limit=limit, offset=offset)
        route = routes.SEARCH_NAME_CHANGES.compile().with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.NameChange])

    async def submit_name_change(self, old_name: str, new_name: str) -> ResultT[models.NameChange]:
        """Submits a new name change.

        Args:
            old_name: The old name for the player.

            new_name: The new name for the player.

        Returns:
            A [`Result`][wom.Result] containing the name change.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.names.submit_name_change(
                "Jonxslays", "I Mahatma I"
            )
            ```
        """
        payload = self._generate_map(oldName=old_name, newName=new_name)
        route = routes.SUBMIT_NAME_CHANGE.compile()
        data = await self._http.fetch(route, payload=payload)
        return self._ok_or_err(data, models.NameChange)

search_name_changes async

search_name_changes(
    username: t.Optional[str] = None,
    *,
    status: t.Optional[models.NameChangeStatus] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.NameChange]]

Searches for name changes.

Parameters:

Name Type Description Default
username Optional[str]

The optional username to search for.

None

Other Parameters:

Name Type Description
status Optional[NameChangeStatus]

The optional name change status to filter on. Defaults to None.

limit Optional[int]

The optional maximum items to return on this page from the API. Defaults to None.

offset Optional[int]

The optional page offset. Defaults to None.

Returns:

Type Description
ResultT[List[NameChange]]

A Result containing a list of name changes.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.names.search_name_changes(
    "Jonxslays", limit=1
)
Source code in wom/services/names.py
async def search_name_changes(
    self,
    username: t.Optional[str] = None,
    *,
    status: t.Optional[models.NameChangeStatus] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.NameChange]]:
    """Searches for name changes.

    Args:
        username: The optional username to search for.

    Keyword Args:
        status: The optional name change status to filter on.
            Defaults to `None`.

        limit: The optional maximum items to return on this page
            from the API. Defaults to `None`.

        offset: The optional page offset. Defaults to
            `None`.

    Returns:
        A [`Result`][wom.Result] containing a list of name changes.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.names.search_name_changes(
            "Jonxslays", limit=1
        )
        ```
    """
    params = self._generate_map(username=username, status=status, limit=limit, offset=offset)
    route = routes.SEARCH_NAME_CHANGES.compile().with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.NameChange])

submit_name_change async

submit_name_change(
    old_name: str, new_name: str
) -> ResultT[models.NameChange]

Submits a new name change.

Parameters:

Name Type Description Default
old_name str

The old name for the player.

required
new_name str

The new name for the player.

required

Returns:

Type Description
ResultT[NameChange]

A Result containing the name change.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.names.submit_name_change(
    "Jonxslays", "I Mahatma I"
)
Source code in wom/services/names.py
async def submit_name_change(self, old_name: str, new_name: str) -> ResultT[models.NameChange]:
    """Submits a new name change.

    Args:
        old_name: The old name for the player.

        new_name: The new name for the player.

    Returns:
        A [`Result`][wom.Result] containing the name change.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.names.submit_name_change(
            "Jonxslays", "I Mahatma I"
        )
        ```
    """
    payload = self._generate_map(oldName=old_name, newName=new_name)
    route = routes.SUBMIT_NAME_CHANGE.compile()
    data = await self._http.fetch(route, payload=payload)
    return self._ok_or_err(data, models.NameChange)

PlayerService

Bases: BaseService

Handles endpoints related to players.

Source code in wom/services/players.py
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
class PlayerService(BaseService):
    """Handles endpoints related to players."""

    __slots__ = ()

    async def search_players(
        self, username: str, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
    ) -> ResultT[t.List[models.Player]]:
        """Searches for a player by partial username.

        Args:
            username: The username to search for.

        Keyword Args:
            limit: The maximum number of paginated items to receive.
                Defaults to `None`.

            offset: The page offset for requesting the next page.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of matching
                players.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.search_players("Jonxslays", limit=3)
            ```
        """
        params = self._generate_map(username=username, limit=limit, offset=offset)
        route = routes.SEARCH_PLAYERS.compile().with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Player])

    async def update_player(self, username: str) -> ResultT[models.PlayerDetail]:
        """Updates the given player.

        Args:
            username: The username to update.

        Returns:
            A [`Result`][wom.Result] containing the updated player
                details.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.update_player("Jonxslays")
            ```
        """
        route = routes.UPDATE_PLAYER.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.PlayerDetail)

    async def assert_player_type(self, username: str) -> ResultT[models.AssertPlayerType]:
        """Asserts, and fixes, a players type.

        Args:
            username: The username to assert the type for.

        Returns:
            A [`Result`][wom.Result] containing the asserted player
                type.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.assert_player_type("Jonxslays")
            ```
        """
        route = routes.ASSERT_PLAYER_TYPE.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.AssertPlayerType)

    async def get_details(self, username: str) -> ResultT[models.PlayerDetail]:
        """Gets the details for a given player.

        Args:
            username: The username to get the details for.

        Returns:
            A [`Result`][wom.Result] containing the player details.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_details("Jonxslays")
            ```
        """
        route = routes.PLAYER_DETAILS.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.PlayerDetail)

    async def get_details_by_id(self, player_id: int) -> ResultT[models.PlayerDetail]:
        """Gets the details for a given player id.

        Args:
            player_id: The is of the player to get the details for.

        Returns:
            A [`Result`][wom.Result] containing the player details.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_details_by_id(1234)
            ```
        """
        route = routes.PLAYER_DETAILS_BY_ID.compile(player_id)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.PlayerDetail)

    async def get_achievements(self, username: str) -> ResultT[t.List[models.Achievement]]:
        """Gets the achievements for a given player.

        Args:
            username: The username to get the achievements for.

        Returns:
            A [`Result`][wom.Result] containing the list of player
                achievements.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_achievements("Jonxslays")
            ```
        """
        route = routes.PLAYER_ACHIEVEMENTS.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Achievement])

    async def get_achievement_progress(
        self, username: str
    ) -> ResultT[t.List[models.PlayerAchievementProgress]]:
        """Gets the progress towards achievements for a given player.

        Args:
            username: The username to get the achievement progress for.

        Returns:
            A [`Result`][wom.Result] containing the list of player
                achievement progress.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_achievement_progress("Jonxslays")
            ```
        """
        route = routes.PLAYER_ACHIEVEMENT_PROGRESS.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.PlayerAchievementProgress])

    async def get_competition_participations(
        self,
        username: str,
        *,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
        status: t.Optional[models.CompetitionStatus] = None,
    ) -> ResultT[t.List[models.PlayerParticipation]]:
        """Gets the competition participations for a given player.

        Args:
            username: The username to get the participations for.

        Keyword Args:
            limit: The maximum number of paginated items to receive.
                Defaults to `None` (I think thats 20 items?).

            offset: The page offset for requesting multiple pages.
                Defaults to `None`.

            status: The optional [`CompetitionStatus`]
                [wom.CompetitionStatus] to filter on. Defaults to
                `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of competition
                participations.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_competition_participations(
                "Jonxslays", limit=3
            )
            ```
        """
        params = self._generate_map(
            status=status.value if status else None,
            offset=offset,
            limit=limit,
        )

        route = routes.PLAYER_COMPETITION_PARTICIPATION.compile(username)
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.PlayerParticipation])

    async def get_competition_standings(
        self,
        username: str,
        status: models.CompetitionStatus,
    ) -> ResultT[t.List[models.PlayerCompetitionStanding]]:
        """Gets the competition standings for a given player.

        Args:
            username: The username to get the standings for.

            status: The competition status to get standings for.

        Returns:
            A [`Result`][wom.Result] containing the list of competition
                standings.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_competition_standings(
                "Jonxslays", wom.CompetitionStatus.Ongoing
            )
            ```
        """
        params = self._generate_map(status=status.value)
        route = routes.PLAYER_COMPETITION_STANDINGS.compile(username)
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.PlayerCompetitionStanding])

    async def get_group_memberships(
        self, username: str, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
    ) -> ResultT[t.List[models.PlayerMembership]]:
        """Gets the group memberships for the given player.

        Args:
            username: The username to get the memberships for.

        Keyword Args:
            limit: The maximum number of paginated items to receive.
                Defaults to `None` (I think thats 20 items?).

            offset: The page offset for requesting multiple pages.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of group
                memberships.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_group_memberships(
                "Jonxslays", limit=3
            )
            ```
        """
        params = self._generate_map(limit=limit, offset=offset)
        route = routes.PLAYER_GROUP_MEMBERSHIPS.compile(username)
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.PlayerMembership])

    async def get_gains(
        self,
        username: str,
        *,
        period: t.Optional[enums.Period] = None,
        start_date: t.Optional[datetime] = None,
        end_date: t.Optional[datetime] = None,
    ) -> ResultT[models.PlayerGains]:
        """Gets the gains made by this player over the given time span.

        Args:
            username: The username to get the gains for.

        Keyword Args:
            period: The optional period of time to get gains for.
                Defaults to `None`.

            start_date: The minimum date to get the gains from. Defaults
                to `None`.

            end_date: The maximum date to get the gains from. Defaults
                to `None`.

        Returns:
            A [`Result`][wom.Result] containing the players gains.

        !!! info

            You must pass one of (`period`) or (`start_date` +
            `end_date`), but not both.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_gains(
                "Jonxslays", period=wom.Period.Day
            )
            ```
        """
        params = self._generate_map(
            period=period.value if period else None,
            startDate=start_date.isoformat() if start_date else None,
            endDate=end_date.isoformat() if end_date else None,
        )

        route = routes.PLAYER_GAINS.compile(username).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, models.PlayerGains)

    async def get_records(
        self,
        username: str,
        *,
        period: t.Optional[enums.Period] = None,
        metric: t.Optional[enums.Metric] = None,
    ) -> ResultT[t.List[models.Record]]:
        """Gets the records held by this player.

        Args:
            username: The username to get the gains for.

        Keyword Args:
            period: The optional period of time to get records for.
                Defaults to `None`.

            metric: The optional metric to filter the records on.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing a list of the players
                records.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_records(
                "Jonxslays", period=wom.Period.Day, metric=wom.Metric.Attack
            )
            ```
        """
        params = self._generate_map(
            period=period.value if period else None, metric=metric.value if metric else None
        )

        route = routes.PLAYER_RECORDS.compile(username).with_params(params)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.Record])

    async def get_snapshots(
        self,
        username: str,
        *,
        period: t.Optional[enums.Period] = None,
        start_date: t.Optional[datetime] = None,
        end_date: t.Optional[datetime] = None,
        limit: t.Optional[int] = None,
        offset: t.Optional[int] = None,
    ) -> ResultT[t.List[models.Snapshot]]:
        """Gets the snapshots for the player.

        Args:
            username: The username to get the snapshots for.

        Keyword Args:
            period: The optional period of time to get snapshots for.
                Defaults to `None`.

            start_date: The minimum date to get the snapshots from.
                Defaults to `None`.

            end_date: The maximum date to get the snapshots from.
                Defaults to `None`.

            limit: The maximum number of paginated items to receive.
                Defaults to `None`.

            offset: The page offset for requesting the next page.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of snapshots.

        !!! info

            You can pass either (`period`) or (`start_date` +
            `end_date`), but not both.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_snapshots(
                "Jonxslays", period=wom.Period.Week, limit=3
            )
            ```
        """
        params = self._generate_map(
            period=period.value if period else None,
            startDate=start_date.isoformat() if start_date else None,
            endDate=end_date.isoformat() if end_date else None,
            limit=limit if limit else None,
            offset=offset if offset else None,
        )

        route = routes.PLAYER_SNAPSHOTS.compile(username)
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.Snapshot])

    async def get_name_changes(self, username: str) -> ResultT[t.List[models.NameChange]]:
        """Gets the name changes for the player.

        Args:
            username: The username to get the name changes for.

        Returns:
            A [`Result`][wom.Result] containing the list of name changes.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_name_changes("Jonxslays")
            ```
        """
        route = routes.PLAYER_NAME_CHANGES.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.NameChange])

    async def get_snapshots_timeline(
        self,
        username: str,
        metric: enums.Metric,
        *,
        period: t.Optional[enums.Period] = None,
        start_date: t.Optional[datetime] = None,
        end_date: t.Optional[datetime] = None,
    ) -> ResultT[t.List[models.SnapshotTimelineEntry]]:
        """Gets the snapshots timeline for the given player and metric.

        Args:
            username: The username to get the timeline for.

            metric: The metric to get the timeline for.

        Keyword Args:
            period: The optional period of time to get snapshots for.
                Defaults to `None`.

            start_date: The minimum date to get the snapshots from.
                Defaults to `None`.

            end_date: The maximum date to get the snapshots from.
                Defaults to `None`.

        Returns:
            A [`Result`][wom.Result] containing the list of snapshots timeline
                entries.

        !!! info

            You can pass either (`period`) or (`start_date` +
            `end_date`), but not both.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_snapshots_timeline(
                "Jonxslays", wom.Skills.Attack, period=wom.Period.Week
            )
            ```
        """
        params = self._generate_map(
            period=period.value if period else None,
            startDate=start_date.isoformat() if start_date else None,
            endDate=end_date.isoformat() if end_date else None,
            metric=metric.value,
        )

        route = routes.PLAYER_SNAPSHOTS_TIMELINE.compile(username)
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.SnapshotTimelineEntry])

    async def get_archives(
        self,
        username: str,
    ) -> ResultT[t.List[models.PlayerArchive]]:
        """Gets the archives for the given player.

        Args:
            username: The username to get archives for.

        Returns:
            A [`Result`][wom.Result] containing the list of archives.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.players.get_archives("Jonxslays")
            ```
        """
        route = routes.PLAYER_ARCHIVES.compile(username)
        data = await self._http.fetch(route)
        return self._ok_or_err(data, t.List[models.PlayerArchive])

assert_player_type async

assert_player_type(
    username: str,
) -> ResultT[models.AssertPlayerType]

Asserts, and fixes, a players type.

Parameters:

Name Type Description Default
username str

The username to assert the type for.

required

Returns:

Type Description
ResultT[AssertPlayerType]

A Result containing the asserted player type.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.assert_player_type("Jonxslays")
Source code in wom/services/players.py
async def assert_player_type(self, username: str) -> ResultT[models.AssertPlayerType]:
    """Asserts, and fixes, a players type.

    Args:
        username: The username to assert the type for.

    Returns:
        A [`Result`][wom.Result] containing the asserted player
            type.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.assert_player_type("Jonxslays")
        ```
    """
    route = routes.ASSERT_PLAYER_TYPE.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.AssertPlayerType)

get_achievement_progress async

get_achievement_progress(
    username: str,
) -> ResultT[t.List[models.PlayerAchievementProgress]]

Gets the progress towards achievements for a given player.

Parameters:

Name Type Description Default
username str

The username to get the achievement progress for.

required

Returns:

Type Description
ResultT[List[PlayerAchievementProgress]]

A Result containing the list of player achievement progress.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_achievement_progress("Jonxslays")
Source code in wom/services/players.py
async def get_achievement_progress(
    self, username: str
) -> ResultT[t.List[models.PlayerAchievementProgress]]:
    """Gets the progress towards achievements for a given player.

    Args:
        username: The username to get the achievement progress for.

    Returns:
        A [`Result`][wom.Result] containing the list of player
            achievement progress.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_achievement_progress("Jonxslays")
        ```
    """
    route = routes.PLAYER_ACHIEVEMENT_PROGRESS.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.PlayerAchievementProgress])

get_achievements async

get_achievements(
    username: str,
) -> ResultT[t.List[models.Achievement]]

Gets the achievements for a given player.

Parameters:

Name Type Description Default
username str

The username to get the achievements for.

required

Returns:

Type Description
ResultT[List[Achievement]]

A Result containing the list of player achievements.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_achievements("Jonxslays")
Source code in wom/services/players.py
async def get_achievements(self, username: str) -> ResultT[t.List[models.Achievement]]:
    """Gets the achievements for a given player.

    Args:
        username: The username to get the achievements for.

    Returns:
        A [`Result`][wom.Result] containing the list of player
            achievements.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_achievements("Jonxslays")
        ```
    """
    route = routes.PLAYER_ACHIEVEMENTS.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Achievement])

get_archives async

get_archives(
    username: str,
) -> ResultT[t.List[models.PlayerArchive]]

Gets the archives for the given player.

Parameters:

Name Type Description Default
username str

The username to get archives for.

required

Returns:

Type Description
ResultT[List[PlayerArchive]]

A Result containing the list of archives.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_archives("Jonxslays")
Source code in wom/services/players.py
async def get_archives(
    self,
    username: str,
) -> ResultT[t.List[models.PlayerArchive]]:
    """Gets the archives for the given player.

    Args:
        username: The username to get archives for.

    Returns:
        A [`Result`][wom.Result] containing the list of archives.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_archives("Jonxslays")
        ```
    """
    route = routes.PLAYER_ARCHIVES.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.PlayerArchive])

get_competition_participations async

get_competition_participations(
    username: str,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
    status: t.Optional[models.CompetitionStatus] = None
) -> ResultT[t.List[models.PlayerParticipation]]

Gets the competition participations for a given player.

Parameters:

Name Type Description Default
username str

The username to get the participations for.

required

Other Parameters:

Name Type Description
limit Optional[int]

The maximum number of paginated items to receive. Defaults to None (I think thats 20 items?).

offset Optional[int]

The page offset for requesting multiple pages. Defaults to None.

status Optional[CompetitionStatus]

The optional CompetitionStatus to filter on. Defaults to None.

Returns:

Type Description
ResultT[List[PlayerParticipation]]

A Result containing the list of competition participations.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_competition_participations(
    "Jonxslays", limit=3
)
Source code in wom/services/players.py
async def get_competition_participations(
    self,
    username: str,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
    status: t.Optional[models.CompetitionStatus] = None,
) -> ResultT[t.List[models.PlayerParticipation]]:
    """Gets the competition participations for a given player.

    Args:
        username: The username to get the participations for.

    Keyword Args:
        limit: The maximum number of paginated items to receive.
            Defaults to `None` (I think thats 20 items?).

        offset: The page offset for requesting multiple pages.
            Defaults to `None`.

        status: The optional [`CompetitionStatus`]
            [wom.CompetitionStatus] to filter on. Defaults to
            `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of competition
            participations.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_competition_participations(
            "Jonxslays", limit=3
        )
        ```
    """
    params = self._generate_map(
        status=status.value if status else None,
        offset=offset,
        limit=limit,
    )

    route = routes.PLAYER_COMPETITION_PARTICIPATION.compile(username)
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.PlayerParticipation])

get_competition_standings async

get_competition_standings(
    username: str, status: models.CompetitionStatus
) -> ResultT[t.List[models.PlayerCompetitionStanding]]

Gets the competition standings for a given player.

Parameters:

Name Type Description Default
username str

The username to get the standings for.

required
status CompetitionStatus

The competition status to get standings for.

required

Returns:

Type Description
ResultT[List[PlayerCompetitionStanding]]

A Result containing the list of competition standings.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_competition_standings(
    "Jonxslays", wom.CompetitionStatus.Ongoing
)
Source code in wom/services/players.py
async def get_competition_standings(
    self,
    username: str,
    status: models.CompetitionStatus,
) -> ResultT[t.List[models.PlayerCompetitionStanding]]:
    """Gets the competition standings for a given player.

    Args:
        username: The username to get the standings for.

        status: The competition status to get standings for.

    Returns:
        A [`Result`][wom.Result] containing the list of competition
            standings.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_competition_standings(
            "Jonxslays", wom.CompetitionStatus.Ongoing
        )
        ```
    """
    params = self._generate_map(status=status.value)
    route = routes.PLAYER_COMPETITION_STANDINGS.compile(username)
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.PlayerCompetitionStanding])

get_details async

get_details(username: str) -> ResultT[models.PlayerDetail]

Gets the details for a given player.

Parameters:

Name Type Description Default
username str

The username to get the details for.

required

Returns:

Type Description
ResultT[PlayerDetail]

A Result containing the player details.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_details("Jonxslays")
Source code in wom/services/players.py
async def get_details(self, username: str) -> ResultT[models.PlayerDetail]:
    """Gets the details for a given player.

    Args:
        username: The username to get the details for.

    Returns:
        A [`Result`][wom.Result] containing the player details.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_details("Jonxslays")
        ```
    """
    route = routes.PLAYER_DETAILS.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.PlayerDetail)

get_details_by_id async

get_details_by_id(
    player_id: int,
) -> ResultT[models.PlayerDetail]

Gets the details for a given player id.

Parameters:

Name Type Description Default
player_id int

The is of the player to get the details for.

required

Returns:

Type Description
ResultT[PlayerDetail]

A Result containing the player details.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_details_by_id(1234)
Source code in wom/services/players.py
async def get_details_by_id(self, player_id: int) -> ResultT[models.PlayerDetail]:
    """Gets the details for a given player id.

    Args:
        player_id: The is of the player to get the details for.

    Returns:
        A [`Result`][wom.Result] containing the player details.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_details_by_id(1234)
        ```
    """
    route = routes.PLAYER_DETAILS_BY_ID.compile(player_id)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.PlayerDetail)

get_gains async

get_gains(
    username: str,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None
) -> ResultT[models.PlayerGains]

Gets the gains made by this player over the given time span.

Parameters:

Name Type Description Default
username str

The username to get the gains for.

required

Other Parameters:

Name Type Description
period Optional[Period]

The optional period of time to get gains for. Defaults to None.

start_date Optional[datetime]

The minimum date to get the gains from. Defaults to None.

end_date Optional[datetime]

The maximum date to get the gains from. Defaults to None.

Returns:

Type Description
ResultT[PlayerGains]

A Result containing the players gains.

Info

You must pass one of (period) or (start_date + end_date), but not both.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_gains(
    "Jonxslays", period=wom.Period.Day
)
Source code in wom/services/players.py
async def get_gains(
    self,
    username: str,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None,
) -> ResultT[models.PlayerGains]:
    """Gets the gains made by this player over the given time span.

    Args:
        username: The username to get the gains for.

    Keyword Args:
        period: The optional period of time to get gains for.
            Defaults to `None`.

        start_date: The minimum date to get the gains from. Defaults
            to `None`.

        end_date: The maximum date to get the gains from. Defaults
            to `None`.

    Returns:
        A [`Result`][wom.Result] containing the players gains.

    !!! info

        You must pass one of (`period`) or (`start_date` +
        `end_date`), but not both.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_gains(
            "Jonxslays", period=wom.Period.Day
        )
        ```
    """
    params = self._generate_map(
        period=period.value if period else None,
        startDate=start_date.isoformat() if start_date else None,
        endDate=end_date.isoformat() if end_date else None,
    )

    route = routes.PLAYER_GAINS.compile(username).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.PlayerGains)

get_group_memberships async

get_group_memberships(
    username: str,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.PlayerMembership]]

Gets the group memberships for the given player.

Parameters:

Name Type Description Default
username str

The username to get the memberships for.

required

Other Parameters:

Name Type Description
limit Optional[int]

The maximum number of paginated items to receive. Defaults to None (I think thats 20 items?).

offset Optional[int]

The page offset for requesting multiple pages. Defaults to None.

Returns:

Type Description
ResultT[List[PlayerMembership]]

A Result containing the list of group memberships.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_group_memberships(
    "Jonxslays", limit=3
)
Source code in wom/services/players.py
async def get_group_memberships(
    self, username: str, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
) -> ResultT[t.List[models.PlayerMembership]]:
    """Gets the group memberships for the given player.

    Args:
        username: The username to get the memberships for.

    Keyword Args:
        limit: The maximum number of paginated items to receive.
            Defaults to `None` (I think thats 20 items?).

        offset: The page offset for requesting multiple pages.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of group
            memberships.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_group_memberships(
            "Jonxslays", limit=3
        )
        ```
    """
    params = self._generate_map(limit=limit, offset=offset)
    route = routes.PLAYER_GROUP_MEMBERSHIPS.compile(username)
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.PlayerMembership])

get_name_changes async

get_name_changes(
    username: str,
) -> ResultT[t.List[models.NameChange]]

Gets the name changes for the player.

Parameters:

Name Type Description Default
username str

The username to get the name changes for.

required

Returns:

Type Description
ResultT[List[NameChange]]

A Result containing the list of name changes.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_name_changes("Jonxslays")
Source code in wom/services/players.py
async def get_name_changes(self, username: str) -> ResultT[t.List[models.NameChange]]:
    """Gets the name changes for the player.

    Args:
        username: The username to get the name changes for.

    Returns:
        A [`Result`][wom.Result] containing the list of name changes.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_name_changes("Jonxslays")
        ```
    """
    route = routes.PLAYER_NAME_CHANGES.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.NameChange])

get_records async

get_records(
    username: str,
    *,
    period: t.Optional[enums.Period] = None,
    metric: t.Optional[enums.Metric] = None
) -> ResultT[t.List[models.Record]]

Gets the records held by this player.

Parameters:

Name Type Description Default
username str

The username to get the gains for.

required

Other Parameters:

Name Type Description
period Optional[Period]

The optional period of time to get records for. Defaults to None.

metric Optional[Metric]

The optional metric to filter the records on. Defaults to None.

Returns:

Type Description
ResultT[List[Record]]

A Result containing a list of the players records.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_records(
    "Jonxslays", period=wom.Period.Day, metric=wom.Metric.Attack
)
Source code in wom/services/players.py
async def get_records(
    self,
    username: str,
    *,
    period: t.Optional[enums.Period] = None,
    metric: t.Optional[enums.Metric] = None,
) -> ResultT[t.List[models.Record]]:
    """Gets the records held by this player.

    Args:
        username: The username to get the gains for.

    Keyword Args:
        period: The optional period of time to get records for.
            Defaults to `None`.

        metric: The optional metric to filter the records on.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing a list of the players
            records.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_records(
            "Jonxslays", period=wom.Period.Day, metric=wom.Metric.Attack
        )
        ```
    """
    params = self._generate_map(
        period=period.value if period else None, metric=metric.value if metric else None
    )

    route = routes.PLAYER_RECORDS.compile(username).with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Record])

get_snapshots async

get_snapshots(
    username: str,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.Snapshot]]

Gets the snapshots for the player.

Parameters:

Name Type Description Default
username str

The username to get the snapshots for.

required

Other Parameters:

Name Type Description
period Optional[Period]

The optional period of time to get snapshots for. Defaults to None.

start_date Optional[datetime]

The minimum date to get the snapshots from. Defaults to None.

end_date Optional[datetime]

The maximum date to get the snapshots from. Defaults to None.

limit Optional[int]

The maximum number of paginated items to receive. Defaults to None.

offset Optional[int]

The page offset for requesting the next page. Defaults to None.

Returns:

Type Description
ResultT[List[Snapshot]]

A Result containing the list of snapshots.

Info

You can pass either (period) or (start_date + end_date), but not both.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_snapshots(
    "Jonxslays", period=wom.Period.Week, limit=3
)
Source code in wom/services/players.py
async def get_snapshots(
    self,
    username: str,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None,
) -> ResultT[t.List[models.Snapshot]]:
    """Gets the snapshots for the player.

    Args:
        username: The username to get the snapshots for.

    Keyword Args:
        period: The optional period of time to get snapshots for.
            Defaults to `None`.

        start_date: The minimum date to get the snapshots from.
            Defaults to `None`.

        end_date: The maximum date to get the snapshots from.
            Defaults to `None`.

        limit: The maximum number of paginated items to receive.
            Defaults to `None`.

        offset: The page offset for requesting the next page.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of snapshots.

    !!! info

        You can pass either (`period`) or (`start_date` +
        `end_date`), but not both.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_snapshots(
            "Jonxslays", period=wom.Period.Week, limit=3
        )
        ```
    """
    params = self._generate_map(
        period=period.value if period else None,
        startDate=start_date.isoformat() if start_date else None,
        endDate=end_date.isoformat() if end_date else None,
        limit=limit if limit else None,
        offset=offset if offset else None,
    )

    route = routes.PLAYER_SNAPSHOTS.compile(username)
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.Snapshot])

get_snapshots_timeline async

get_snapshots_timeline(
    username: str,
    metric: enums.Metric,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None
) -> ResultT[t.List[models.SnapshotTimelineEntry]]

Gets the snapshots timeline for the given player and metric.

Parameters:

Name Type Description Default
username str

The username to get the timeline for.

required
metric Metric

The metric to get the timeline for.

required

Other Parameters:

Name Type Description
period Optional[Period]

The optional period of time to get snapshots for. Defaults to None.

start_date Optional[datetime]

The minimum date to get the snapshots from. Defaults to None.

end_date Optional[datetime]

The maximum date to get the snapshots from. Defaults to None.

Returns:

Type Description
ResultT[List[SnapshotTimelineEntry]]

A Result containing the list of snapshots timeline entries.

Info

You can pass either (period) or (start_date + end_date), but not both.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.get_snapshots_timeline(
    "Jonxslays", wom.Skills.Attack, period=wom.Period.Week
)
Source code in wom/services/players.py
async def get_snapshots_timeline(
    self,
    username: str,
    metric: enums.Metric,
    *,
    period: t.Optional[enums.Period] = None,
    start_date: t.Optional[datetime] = None,
    end_date: t.Optional[datetime] = None,
) -> ResultT[t.List[models.SnapshotTimelineEntry]]:
    """Gets the snapshots timeline for the given player and metric.

    Args:
        username: The username to get the timeline for.

        metric: The metric to get the timeline for.

    Keyword Args:
        period: The optional period of time to get snapshots for.
            Defaults to `None`.

        start_date: The minimum date to get the snapshots from.
            Defaults to `None`.

        end_date: The maximum date to get the snapshots from.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of snapshots timeline
            entries.

    !!! info

        You can pass either (`period`) or (`start_date` +
        `end_date`), but not both.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.get_snapshots_timeline(
            "Jonxslays", wom.Skills.Attack, period=wom.Period.Week
        )
        ```
    """
    params = self._generate_map(
        period=period.value if period else None,
        startDate=start_date.isoformat() if start_date else None,
        endDate=end_date.isoformat() if end_date else None,
        metric=metric.value,
    )

    route = routes.PLAYER_SNAPSHOTS_TIMELINE.compile(username)
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.SnapshotTimelineEntry])

search_players async

search_players(
    username: str,
    *,
    limit: t.Optional[int] = None,
    offset: t.Optional[int] = None
) -> ResultT[t.List[models.Player]]

Searches for a player by partial username.

Parameters:

Name Type Description Default
username str

The username to search for.

required

Other Parameters:

Name Type Description
limit Optional[int]

The maximum number of paginated items to receive. Defaults to None.

offset Optional[int]

The page offset for requesting the next page. Defaults to None.

Returns:

Type Description
ResultT[List[Player]]

A Result containing the list of matching players.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.search_players("Jonxslays", limit=3)
Source code in wom/services/players.py
async def search_players(
    self, username: str, *, limit: t.Optional[int] = None, offset: t.Optional[int] = None
) -> ResultT[t.List[models.Player]]:
    """Searches for a player by partial username.

    Args:
        username: The username to search for.

    Keyword Args:
        limit: The maximum number of paginated items to receive.
            Defaults to `None`.

        offset: The page offset for requesting the next page.
            Defaults to `None`.

    Returns:
        A [`Result`][wom.Result] containing the list of matching
            players.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.search_players("Jonxslays", limit=3)
        ```
    """
    params = self._generate_map(username=username, limit=limit, offset=offset)
    route = routes.SEARCH_PLAYERS.compile().with_params(params)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, t.List[models.Player])

update_player async

update_player(
    username: str,
) -> ResultT[models.PlayerDetail]

Updates the given player.

Parameters:

Name Type Description Default
username str

The username to update.

required

Returns:

Type Description
ResultT[PlayerDetail]

A Result containing the updated player details.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.players.update_player("Jonxslays")
Source code in wom/services/players.py
async def update_player(self, username: str) -> ResultT[models.PlayerDetail]:
    """Updates the given player.

    Args:
        username: The username to update.

    Returns:
        A [`Result`][wom.Result] containing the updated player
            details.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.players.update_player("Jonxslays")
        ```
    """
    route = routes.UPDATE_PLAYER.compile(username)
    data = await self._http.fetch(route)
    return self._ok_or_err(data, models.PlayerDetail)

RecordService

Bases: BaseService

Handles endpoints related to records.

Source code in wom/services/records.py
class RecordService(BaseService):
    """Handles endpoints related to records."""

    __slots__ = ()

    async def get_global_leaderboards(
        self,
        metric: enums.Metric,
        period: enums.Period,
        *,
        player_type: t.Optional[models.PlayerType] = None,
        player_build: t.Optional[models.PlayerBuild] = None,
        country: t.Optional[models.Country] = None,
    ) -> ResultT[t.List[models.RecordLeaderboardEntry]]:
        """Gets the global record leaderboards.

        Args:
            metric: The metric to filter on.

            period: The period of time to filter on.

        Keyword Args:
            player_type: The optional player type to filter on. Defaults
                to `None`.

            player_build: The optional player build to filter on.
                Defaults to `None`.

            country: The optional country to filter on. Defaults to
                `None`.

        Returns:
            A [`Result`][wom.Result] containing a list of record
                leaderboard entries.

        ??? example

            ```py
            import wom

            client = wom.Client(...)

            await client.start()

            result = await client.records.get_global_leaderboards(
                wom.Metric.Attack,
                wom.Period.Day,
                country=wom.Country.Us,
            )
            ```
        """
        params = self._generate_map(
            metric=metric.value,
            period=period.value,
            playerType=player_type.value if player_type else None,
            playerBuild=player_build.value if player_build else None,
            country=country.value if country else None,
        )

        route = routes.GLOBAL_RECORD_LEADERS.compile()
        data = await self._http.fetch(route.with_params(params))
        return self._ok_or_err(data, t.List[models.RecordLeaderboardEntry])

get_global_leaderboards async

get_global_leaderboards(
    metric: enums.Metric,
    period: enums.Period,
    *,
    player_type: t.Optional[models.PlayerType] = None,
    player_build: t.Optional[models.PlayerBuild] = None,
    country: t.Optional[models.Country] = None
) -> ResultT[t.List[models.RecordLeaderboardEntry]]

Gets the global record leaderboards.

Parameters:

Name Type Description Default
metric Metric

The metric to filter on.

required
period Period

The period of time to filter on.

required

Other Parameters:

Name Type Description
player_type Optional[PlayerType]

The optional player type to filter on. Defaults to None.

player_build Optional[PlayerBuild]

The optional player build to filter on. Defaults to None.

country Optional[Country]

The optional country to filter on. Defaults to None.

Returns:

Type Description
ResultT[List[RecordLeaderboardEntry]]

A Result containing a list of record leaderboard entries.

Example
import wom

client = wom.Client(...)

await client.start()

result = await client.records.get_global_leaderboards(
    wom.Metric.Attack,
    wom.Period.Day,
    country=wom.Country.Us,
)
Source code in wom/services/records.py
async def get_global_leaderboards(
    self,
    metric: enums.Metric,
    period: enums.Period,
    *,
    player_type: t.Optional[models.PlayerType] = None,
    player_build: t.Optional[models.PlayerBuild] = None,
    country: t.Optional[models.Country] = None,
) -> ResultT[t.List[models.RecordLeaderboardEntry]]:
    """Gets the global record leaderboards.

    Args:
        metric: The metric to filter on.

        period: The period of time to filter on.

    Keyword Args:
        player_type: The optional player type to filter on. Defaults
            to `None`.

        player_build: The optional player build to filter on.
            Defaults to `None`.

        country: The optional country to filter on. Defaults to
            `None`.

    Returns:
        A [`Result`][wom.Result] containing a list of record
            leaderboard entries.

    ??? example

        ```py
        import wom

        client = wom.Client(...)

        await client.start()

        result = await client.records.get_global_leaderboards(
            wom.Metric.Attack,
            wom.Period.Day,
            country=wom.Country.Us,
        )
        ```
    """
    params = self._generate_map(
        metric=metric.value,
        period=period.value,
        playerType=player_type.value if player_type else None,
        playerBuild=player_build.value if player_build else None,
        country=country.value if country else None,
    )

    route = routes.GLOBAL_RECORD_LEADERS.compile()
    data = await self._http.fetch(route.with_params(params))
    return self._ok_or_err(data, t.List[models.RecordLeaderboardEntry])