pyRestarters 0.0.2__tar.gz → 0.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/.github/workflows/action.yaml +10 -10
- pyrestarters-0.0.5/Examples/map_events_this_month.py +91 -0
- pyrestarters-0.0.5/Examples/solent_repair_and_reuse_stats.py +58 -0
- {pyrestarters-0.0.2/src/pyRestarters.egg-info → pyrestarters-0.0.5}/PKG-INFO +42 -4
- pyrestarters-0.0.5/README.md +51 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/pyproject.toml +1 -1
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters/__about__.py +1 -1
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters/__init__.py +5 -5
- pyrestarters-0.0.5/src/pyRestarters/data_model.py +521 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5/src/pyRestarters.egg-info}/PKG-INFO +42 -4
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters.egg-info/SOURCES.txt +3 -3
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters.egg-info/requires.txt +3 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/tests/integration_tests/test_group.py +1 -1
- pyrestarters-0.0.2/README.md +0 -14
- pyrestarters-0.0.2/src/pyRestarters/events.py +0 -123
- pyrestarters-0.0.2/src/pyRestarters/groups.py +0 -107
- pyrestarters-0.0.2/src/pyRestarters/networks.py +0 -111
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/.gitignore +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/LICENSE +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/setup.cfg +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters/_base_client.py +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters/py.typed +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters.egg-info/dependency_links.txt +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/src/pyRestarters.egg-info/top_level.txt +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/tests/integration_tests/__init__.py +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/tests/integration_tests/test_network.py +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/tests/unit_tests/__init__.py +0 -0
- {pyrestarters-0.0.2 → pyrestarters-0.0.5}/tests/unit_tests/test_dummy_test.py +0 -0
|
@@ -24,9 +24,9 @@ jobs:
|
|
|
24
24
|
lint:
|
|
25
25
|
runs-on: ubuntu-latest
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
28
|
- name: Set up Python
|
|
29
|
-
uses: actions/setup-python@
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
30
|
with:
|
|
31
31
|
python-version: "3.12"
|
|
32
32
|
|
|
@@ -56,9 +56,9 @@ jobs:
|
|
|
56
56
|
mypy:
|
|
57
57
|
runs-on: ubuntu-latest
|
|
58
58
|
steps:
|
|
59
|
-
- uses: actions/checkout@
|
|
59
|
+
- uses: actions/checkout@v5
|
|
60
60
|
- name: Set up Python
|
|
61
|
-
uses: actions/setup-python@
|
|
61
|
+
uses: actions/setup-python@v6
|
|
62
62
|
with:
|
|
63
63
|
python-version: "3.12"
|
|
64
64
|
|
|
@@ -81,10 +81,10 @@ jobs:
|
|
|
81
81
|
python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
|
|
82
82
|
|
|
83
83
|
steps:
|
|
84
|
-
- uses: actions/checkout@
|
|
84
|
+
- uses: actions/checkout@v5
|
|
85
85
|
|
|
86
86
|
- name: Set up Python ${{ matrix.python-version }}
|
|
87
|
-
uses: actions/setup-python@
|
|
87
|
+
uses: actions/setup-python@v6
|
|
88
88
|
with:
|
|
89
89
|
python-version: ${{ matrix.python-version }}
|
|
90
90
|
|
|
@@ -107,10 +107,10 @@ jobs:
|
|
|
107
107
|
python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
|
|
108
108
|
|
|
109
109
|
steps:
|
|
110
|
-
- uses: actions/checkout@
|
|
110
|
+
- uses: actions/checkout@v5
|
|
111
111
|
|
|
112
112
|
- name: Set up Python ${{ matrix.python-version }}
|
|
113
|
-
uses: actions/setup-python@
|
|
113
|
+
uses: actions/setup-python@v6
|
|
114
114
|
with:
|
|
115
115
|
python-version: ${{ matrix.python-version }}
|
|
116
116
|
|
|
@@ -131,9 +131,9 @@ jobs:
|
|
|
131
131
|
name: Build source distribution
|
|
132
132
|
runs-on: ubuntu-latest
|
|
133
133
|
steps:
|
|
134
|
-
- uses: actions/checkout@
|
|
134
|
+
- uses: actions/checkout@v5
|
|
135
135
|
|
|
136
|
-
- uses: actions/setup-python@
|
|
136
|
+
- uses: actions/setup-python@v6
|
|
137
137
|
name: Install Python
|
|
138
138
|
with:
|
|
139
139
|
python-version: "3.12"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
An example of using pyRestarters to map all the events due in the UK this month
|
|
3
|
+
"""
|
|
4
|
+
import datetime
|
|
5
|
+
from itertools import chain
|
|
6
|
+
|
|
7
|
+
import geopandas as gpd
|
|
8
|
+
import matplotlib
|
|
9
|
+
matplotlib.use("TkAgg")
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
from shapely.geometry import Point
|
|
12
|
+
|
|
13
|
+
from pyRestarters import Groups, Group
|
|
14
|
+
|
|
15
|
+
from datetime import datetime, timedelta
|
|
16
|
+
|
|
17
|
+
now = datetime.now()
|
|
18
|
+
|
|
19
|
+
# Start of month
|
|
20
|
+
start_of_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
|
21
|
+
|
|
22
|
+
# Start of next month
|
|
23
|
+
if now.month == 12:
|
|
24
|
+
start_of_next_month = now.replace(
|
|
25
|
+
year=now.year + 1,
|
|
26
|
+
month=1,
|
|
27
|
+
day=1,
|
|
28
|
+
hour=0,
|
|
29
|
+
minute=0,
|
|
30
|
+
second=0,
|
|
31
|
+
microsecond=0,
|
|
32
|
+
)
|
|
33
|
+
else:
|
|
34
|
+
start_of_next_month = now.replace(
|
|
35
|
+
month=now.month + 1,
|
|
36
|
+
day=1,
|
|
37
|
+
hour=0,
|
|
38
|
+
minute=0,
|
|
39
|
+
second=0,
|
|
40
|
+
microsecond=0,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# End of month (last microsecond before next month)
|
|
44
|
+
end_of_month = start_of_next_month - timedelta(microseconds=1)
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
|
|
48
|
+
# plot a map of the UK
|
|
49
|
+
url = "https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json"
|
|
50
|
+
world = gpd.read_file(url)
|
|
51
|
+
uk = world[world["name"] == "United Kingdom"]
|
|
52
|
+
fig, ax = plt.subplots(figsize=(6, 8))
|
|
53
|
+
uk.plot(
|
|
54
|
+
ax=ax,
|
|
55
|
+
edgecolor="black",
|
|
56
|
+
facecolor="none",
|
|
57
|
+
linewidth=1
|
|
58
|
+
)
|
|
59
|
+
ax.set_title("Locations of Repair Cafe Events this Month")
|
|
60
|
+
ax.set_axis_off()
|
|
61
|
+
plt.show()
|
|
62
|
+
|
|
63
|
+
# go through all the groups in the restarters.net data and find:
|
|
64
|
+
# UK groups - tag == 5
|
|
65
|
+
# Events this month for those UK groups
|
|
66
|
+
restarters_groups = Groups()
|
|
67
|
+
|
|
68
|
+
# function to filter if a group has the UK tag
|
|
69
|
+
tags = restarters_groups.group_tags
|
|
70
|
+
def is_uk_group(group: Group) -> bool:
|
|
71
|
+
tags = group.tags
|
|
72
|
+
for tag in tags:
|
|
73
|
+
if tag.id == 5:
|
|
74
|
+
return True
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
# The filtering takes the full list groups, find all the UK groups and then chains together
|
|
78
|
+
# the events before filtering based on this month
|
|
79
|
+
uk_groups = filter(is_uk_group, restarters_groups)
|
|
80
|
+
events_this_month = chain.from_iterable(group.events_in_daterange(start=start_of_month, end=end_of_month).values() for group in uk_groups)
|
|
81
|
+
|
|
82
|
+
gdf_points = gpd.GeoDataFrame(
|
|
83
|
+
geometry=[Point(event.coordinates.longitude, event.coordinates.latitude) for event in events_this_month],
|
|
84
|
+
crs="EPSG:4326" # WGS84 lon/lat
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
gdf_points.plot(
|
|
88
|
+
ax=ax,
|
|
89
|
+
color="green",
|
|
90
|
+
markersize=2
|
|
91
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
An example of using pyRestarters plot the cumulative statistics for multiple repair groups
|
|
3
|
+
"""
|
|
4
|
+
from dataclasses import dataclass, asdict
|
|
5
|
+
import datetime
|
|
6
|
+
from collections.abc import Iterator
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
|
|
11
|
+
from pyRestarters import Groups
|
|
12
|
+
from pyRestarters.data_model import Statistics
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class EventSummary(Statistics):
|
|
16
|
+
group: str
|
|
17
|
+
date: datetime.date
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if __name__ == '__main__':
|
|
21
|
+
restarters_groups = Groups()
|
|
22
|
+
rcg = restarters_groups.group_by_name('Repair Café Gosport')
|
|
23
|
+
rcp = restarters_groups.group_by_name('Repair Cafe Portchester')
|
|
24
|
+
rct = restarters_groups.group_by_name('Repair Café Titchfield')
|
|
25
|
+
|
|
26
|
+
def event_summarys() -> Iterator[EventSummary]:
|
|
27
|
+
for group in [rcg,rcp,rct]:
|
|
28
|
+
for event in group.past_events.values():
|
|
29
|
+
yield EventSummary(group=group.name,
|
|
30
|
+
date=event.start.date(),
|
|
31
|
+
**asdict(event.statistics))
|
|
32
|
+
|
|
33
|
+
srr_event_summary = list(event_summarys())
|
|
34
|
+
srr_event_summary_df = pd.DataFrame(srr_event_summary)
|
|
35
|
+
|
|
36
|
+
fig, all_ax = plt.subplots(figsize=(12, 6), nrows=1, ncols=3)
|
|
37
|
+
for ax, key, y_label in zip(all_ax,
|
|
38
|
+
["fixed_devices", "co2_total", "waste_total"],
|
|
39
|
+
["Cumulative Items Fixed",
|
|
40
|
+
"Cumulative CO2 Emissions Prevented",
|
|
41
|
+
"Cumulative Waste Emissions Prevented"]):
|
|
42
|
+
# Create one column per repair cafe
|
|
43
|
+
pivot = (
|
|
44
|
+
srr_event_summary_df.pivot(index="date", columns="group", values=key)
|
|
45
|
+
.fillna(0)
|
|
46
|
+
.sort_index()
|
|
47
|
+
)
|
|
48
|
+
# Calculate cumulative totals
|
|
49
|
+
cumulative = pivot.cumsum()
|
|
50
|
+
cumulative.plot.area(ax=ax)
|
|
51
|
+
ax.set_xlabel("Date")
|
|
52
|
+
ax.set_ylabel(y_label)
|
|
53
|
+
ax.legend(title="Repair Cafe")
|
|
54
|
+
|
|
55
|
+
plt.tight_layout()
|
|
56
|
+
plt.suptitle('KPIs for Solent Repair and Reuse')
|
|
57
|
+
plt.show()
|
|
58
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyRestarters
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: Pythonic wrapper for the restarters.net API
|
|
5
5
|
Author: Keith Brady
|
|
6
6
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -190,6 +190,7 @@ Requires-Python: >=3.10
|
|
|
190
190
|
Description-Content-Type: text/markdown
|
|
191
191
|
License-File: LICENSE
|
|
192
192
|
Requires-Dist: requests
|
|
193
|
+
Requires-Dist: typing-extensions; python_version < "3.11"
|
|
193
194
|
Provides-Extra: dev
|
|
194
195
|
Requires-Dist: mypy; extra == "dev"
|
|
195
196
|
Requires-Dist: pylint; extra == "dev"
|
|
@@ -210,11 +211,48 @@ Python Wrappers for the restarters.net API
|
|
|
210
211
|
## Restarters.net
|
|
211
212
|
[restarters.net](https://restarters.net/) is a website widely used within the Repair Community.
|
|
212
213
|
|
|
213
|
-
### API
|
|
214
|
-
The [API documentation](https://restarters.net/apiv2/documentation) describes the REST API which
|
|
215
|
-
|
|
214
|
+
### Restarters API
|
|
215
|
+
The [API documentation](https://restarters.net/apiv2/documentation) describes the REST API which is wrapped by this package
|
|
216
|
+
|
|
217
|
+
## Usage
|
|
218
|
+
|
|
219
|
+
Currently this package supports reading data from the [restarters.net](https://restarters.net/) website which
|
|
220
|
+
does not require an API key. The APIs to modify or delete data are not currently supported.
|
|
221
|
+
|
|
216
222
|
|
|
217
223
|
## Getting Started
|
|
218
224
|
|
|
225
|
+
### Installation
|
|
226
|
+
|
|
227
|
+
1. Install a recent version of Python 3
|
|
228
|
+
2. Install `pyRestarters`
|
|
229
|
+
```console
|
|
230
|
+
python3 -m pip install pyRestarters
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Demo
|
|
234
|
+
|
|
235
|
+
The date for the next Repair Cafe Gosport Event
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
restarters_groups = Groups()
|
|
239
|
+
rcg = restarters_groups.group_by_name('Repair Café Gosport')
|
|
240
|
+
next_rcg_event = rcg.next_event
|
|
241
|
+
print(f'The next Repair Café Gosport is {next_rcg_event.start:%d %b %Y}')
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
This will print a string as follows, the date will change if you rerun it
|
|
245
|
+
```
|
|
246
|
+
The next Repair Café Gosport is 14 Feb 2026
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
219
257
|
|
|
220
258
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# PyRestarters
|
|
2
|
+
Python Wrappers for the restarters.net API
|
|
3
|
+
|
|
4
|
+
## Restarters.net
|
|
5
|
+
[restarters.net](https://restarters.net/) is a website widely used within the Repair Community.
|
|
6
|
+
|
|
7
|
+
### Restarters API
|
|
8
|
+
The [API documentation](https://restarters.net/apiv2/documentation) describes the REST API which is wrapped by this package
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
Currently this package supports reading data from the [restarters.net](https://restarters.net/) website which
|
|
13
|
+
does not require an API key. The APIs to modify or delete data are not currently supported.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Getting Started
|
|
17
|
+
|
|
18
|
+
### Installation
|
|
19
|
+
|
|
20
|
+
1. Install a recent version of Python 3
|
|
21
|
+
2. Install `pyRestarters`
|
|
22
|
+
```console
|
|
23
|
+
python3 -m pip install pyRestarters
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Demo
|
|
27
|
+
|
|
28
|
+
The date for the next Repair Cafe Gosport Event
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
restarters_groups = Groups()
|
|
32
|
+
rcg = restarters_groups.group_by_name('Repair Café Gosport')
|
|
33
|
+
next_rcg_event = rcg.next_event
|
|
34
|
+
print(f'The next Repair Café Gosport is {next_rcg_event.start:%d %b %Y}')
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This will print a string as follows, the date will change if you rerun it
|
|
38
|
+
```
|
|
39
|
+
The next Repair Café Gosport is 14 Feb 2026
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
@@ -5,10 +5,10 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyRestarters"
|
|
7
7
|
dynamic = ["version"]
|
|
8
|
-
# Callable is broken in python 3.9.0 and 3.9.1 so these need to be excluded
|
|
9
8
|
requires-python = ">=3.10"
|
|
10
9
|
dependencies = [
|
|
11
10
|
"requests",
|
|
11
|
+
"typing-extensions;python_version<'3.11'",
|
|
12
12
|
]
|
|
13
13
|
|
|
14
14
|
authors = [
|
|
@@ -16,8 +16,8 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
"""
|
|
18
18
|
# pylint:disable=invalid-name
|
|
19
|
-
from .
|
|
20
|
-
from .
|
|
21
|
-
from .
|
|
22
|
-
from .
|
|
23
|
-
from .
|
|
19
|
+
from .data_model import Groups
|
|
20
|
+
from .data_model import Group
|
|
21
|
+
from .data_model import Event
|
|
22
|
+
from .data_model import Networks
|
|
23
|
+
from .data_model import Network
|