blob: 0456f98e83ce0172fa8f91c5a066bfa20cd9fd13 [file] [log] [blame]
Simon Glass2c266d82025-04-29 07:22:13 -06001# SPDX-License-Identifier: GPL-2.0+
2#
3# Copyright 2025 Simon Glass <sjg@chromium.org>
4#
5"""Provides a basic API for the patchwork server
6"""
7
8import asyncio
9
10import aiohttp
11
12# Number of retries
13RETRIES = 3
14
15# Max concurrent request
16MAX_CONCURRENT = 50
17
18class Patchwork:
19 """Class to handle communication with patchwork
20 """
21 def __init__(self, url, show_progress=True):
22 """Set up a new patchwork handler
23
24 Args:
25 url (str): URL of patchwork server, e.g.
26 'https://patchwork.ozlabs.org'
27 """
28 self.url = url
29 self.proj_id = None
30 self.link_name = None
31 self._show_progress = show_progress
32 self.semaphore = asyncio.Semaphore(MAX_CONCURRENT)
33 self.request_count = 0
34
35 async def _request(self, client, subpath):
36 """Call the patchwork API and return the result as JSON
37
38 Args:
39 client (aiohttp.ClientSession): Session to use
40 subpath (str): URL subpath to use
41
42 Returns:
43 dict: Json result
44
45 Raises:
46 ValueError: the URL could not be read
47 """
48 # print('subpath', subpath)
49 self.request_count += 1
50
51 full_url = f'{self.url}/api/1.2/{subpath}'
52 async with self.semaphore:
53 # print('full_url', full_url)
54 for i in range(RETRIES + 1):
55 try:
56 async with client.get(full_url) as response:
57 if response.status != 200:
58 raise ValueError(
59 f"Could not read URL '{full_url}'")
60 result = await response.json()
61 # print('- done', full_url)
62 return result
63 break
64 except aiohttp.client_exceptions.ServerDisconnectedError:
65 if i == RETRIES:
66 raise