codecarbon 2.7.1__tar.gz → 2.7.2__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.
Files changed (69) hide show
  1. {codecarbon-2.7.1 → codecarbon-2.7.2}/.gitignore +4 -0
  2. {codecarbon-2.7.1 → codecarbon-2.7.2}/PKG-INFO +2 -1
  3. codecarbon-2.7.2/codecarbon/_version.py +1 -0
  4. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/cli/cli_utils.py +13 -6
  5. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/cli/main.py +60 -1
  6. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/api_client.py +46 -15
  7. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/gpu.py +5 -2
  8. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/emissions_tracker.py +2 -1
  9. {codecarbon-2.7.1 → codecarbon-2.7.2}/pyproject.toml +3 -2
  10. codecarbon-2.7.1/codecarbon/_version.py +0 -1
  11. {codecarbon-2.7.1 → codecarbon-2.7.2}/LICENSE +0 -0
  12. {codecarbon-2.7.1 → codecarbon-2.7.2}/README.md +0 -0
  13. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/__init__.py +0 -0
  14. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/cli/__init__.py +0 -0
  15. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/__init__.py +0 -0
  16. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/cloud.py +0 -0
  17. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/co2_signal.py +0 -0
  18. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/config.py +0 -0
  19. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/cpu.py +0 -0
  20. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/emissions.py +0 -0
  21. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/measure.py +0 -0
  22. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/powermetrics.py +0 -0
  23. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/rapl.py +0 -0
  24. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/schemas.py +0 -0
  25. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/units.py +0 -0
  26. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/core/util.py +0 -0
  27. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/canada_provinces.geojson +0 -0
  28. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/cloud/impact.csv +0 -0
  29. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/hardware/cpu_power.csv +0 -0
  30. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2016/canada_energy_mix.json +0 -0
  31. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2016/global_energy_mix-old.json +0 -0
  32. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2016/usa_emissions.json +0 -0
  33. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2020/01_get_world_carbon_intensity.ipynb +0 -0
  34. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2020/02_convert_csv_to_json.ipynb +0 -0
  35. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2020/03_add_eu_data.ipynb +0 -0
  36. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2020/eu-carbon-intensity-electricity.csv +0 -0
  37. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/2023-07-07-22-40-48.png +0 -0
  38. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/carbon_intensity_per_source.json +0 -0
  39. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/global_energy_mix.json +0 -0
  40. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/our_world_in_data.ipynb +0 -0
  41. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/data/private_infra/world_energy_mix.csv +0 -0
  42. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/external/__init__.py +0 -0
  43. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/external/geography.py +0 -0
  44. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/external/hardware.py +0 -0
  45. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/external/logger.py +0 -0
  46. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/external/scheduler.py +0 -0
  47. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/external/task.py +0 -0
  48. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/input.py +0 -0
  49. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/lock.py +0 -0
  50. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output.py +0 -0
  51. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/__init__.py +0 -0
  52. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/base_output.py +0 -0
  53. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/emissions_data.py +0 -0
  54. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/file.py +0 -0
  55. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/http.py +0 -0
  56. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/logger.py +0 -0
  57. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/metrics/__init__.py +0 -0
  58. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/metrics/logfire.py +0 -0
  59. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/metrics/metric_docs.py +0 -0
  60. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/output_methods/metrics/prometheus.py +0 -0
  61. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/__init__.py +0 -0
  62. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/assets/__init__.py +0 -0
  63. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/assets/car_icon.png +0 -0
  64. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/assets/house_icon.png +0 -0
  65. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/assets/tv_icon.png +0 -0
  66. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/carbonboard.py +0 -0
  67. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/carbonboard_on_api.py +0 -0
  68. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/components.py +0 -0
  69. {codecarbon-2.7.1 → codecarbon-2.7.2}/codecarbon/viz/data.py +0 -0
@@ -129,3 +129,7 @@ tests/test_data/rapl/*
129
129
 
130
130
  #asciinema
131
131
  *.cast
132
+
133
+
134
+ # credentials
135
+ credentials.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: codecarbon
3
- Version: 2.7.1
3
+ Version: 2.7.2
4
4
  Project-URL: Homepage, https://codecarbon.io/
5
5
  Project-URL: Repository, https://github.com/mlco2/codecarbon
6
6
  Project-URL: Dashboard, http://dashboard.codecarbon.io/
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.12
20
20
  Requires-Python: >=3.7
21
21
  Requires-Dist: arrow
22
22
  Requires-Dist: click
23
+ Requires-Dist: fief-client[cli]
23
24
  Requires-Dist: pandas
24
25
  Requires-Dist: prometheus-client
25
26
  Requires-Dist: psutil
@@ -0,0 +1 @@
1
+ __version__ = "2.7.2"
@@ -40,12 +40,19 @@ def get_api_endpoint(path: Optional[Path] = None):
40
40
  def get_existing_local_exp_id(path: Optional[Path] = None):
41
41
  p = path or Path.cwd().resolve() / ".codecarbon.config"
42
42
  if p.exists():
43
- config = configparser.ConfigParser()
44
- config.read(str(p))
45
- if "codecarbon" in config.sections():
46
- d = dict(config["codecarbon"])
47
- if "experiment_id" in d:
48
- return d["experiment_id"]
43
+ existing_path = p
44
+ else:
45
+ existing_path = Path("~/.codecarbon.config").expanduser()
46
+ return _get_local_exp_id(existing_path)
47
+
48
+
49
+ def _get_local_exp_id(p: Optional[Path] = None):
50
+ config = configparser.ConfigParser()
51
+ config.read(str(p))
52
+ if "codecarbon" in config.sections():
53
+ d = dict(config["codecarbon"])
54
+ if "experiment_id" in d:
55
+ return d["experiment_id"]
49
56
 
50
57
 
51
58
  def write_local_exp_id(exp_id, path: Optional[Path] = None):
@@ -1,9 +1,13 @@
1
+ import os
1
2
  import time
2
3
  from pathlib import Path
3
4
  from typing import Optional
4
5
 
5
6
  import questionary
7
+ import requests
6
8
  import typer
9
+ from fief_client import Fief
10
+ from fief_client.integrations.cli import FiefAuth
7
11
  from rich import print
8
12
  from rich.prompt import Confirm
9
13
  from typing_extensions import Annotated
@@ -20,10 +24,18 @@ from codecarbon.core.api_client import ApiClient, get_datetime_with_timezone
20
24
  from codecarbon.core.schemas import ExperimentCreate, OrganizationCreate, ProjectCreate
21
25
  from codecarbon.emissions_tracker import EmissionsTracker
22
26
 
27
+ AUTH_CLIENT_ID = os.environ.get(
28
+ "AUTH_CLIENT_ID", "pkqh9CiOkp4MkPqRqM_k8Xc3mwBRpojS3RayIk1i5Pg"
29
+ )
30
+ AUTH_SERVER_URL = os.environ.get(
31
+ "AUTH_SERVER_URL", "https://auth.codecarbon.io/codecarbon-dev"
32
+ )
33
+ API_URL = os.environ.get("API_URL", "https://dash-dev.cleverapps.io/api")
34
+
23
35
  DEFAULT_PROJECT_ID = "e60afa92-17b7-4720-91a0-1ae91e409ba1"
24
36
  DEFAULT_ORGANIzATION_ID = "e60afa92-17b7-4720-91a0-1ae91e409ba1"
25
37
 
26
- codecarbon = typer.Typer()
38
+ codecarbon = typer.Typer(no_args_is_help=True)
27
39
 
28
40
 
29
41
  def _version_callback(value: bool) -> None:
@@ -85,6 +97,52 @@ def show_config(path: Path = Path("./.codecarbon.config")) -> None:
85
97
  )
86
98
 
87
99
 
100
+ fief = Fief(AUTH_SERVER_URL, AUTH_CLIENT_ID)
101
+ fief_auth = FiefAuth(fief, "./credentials.json")
102
+ print("FIEF", AUTH_SERVER_URL, AUTH_CLIENT_ID)
103
+
104
+
105
+ def _get_access_token():
106
+ access_token_info = fief_auth.access_token_info()
107
+ access_token = access_token_info["access_token"]
108
+ return access_token
109
+
110
+
111
+ @codecarbon.command(
112
+ "test-api", short_help="Make an authenticated GET request to an API endpoint"
113
+ )
114
+ def api_get():
115
+ """
116
+ ex: test-api
117
+ """
118
+ api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
119
+ api.set_access_token(_get_access_token())
120
+ organizations = api.get_list_organizations()
121
+ print(organizations)
122
+
123
+
124
+ @codecarbon.command("login", short_help="Login to CodeCarbon")
125
+ def login():
126
+ fief_auth.authorize()
127
+
128
+
129
+ @codecarbon.command("get-token", short_help="Get project token")
130
+ def get_token(project_id: str):
131
+ # api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
132
+ # api.set_access_token(_get_access_token())
133
+ req = requests.post(
134
+ f"{API_URL}/projects/{project_id}/api-tokens",
135
+ json={
136
+ "project_id": project_id,
137
+ "name": "api token",
138
+ "x_token": "???",
139
+ },
140
+ headers={"Authorization": f"Bearer {_get_access_token()}"},
141
+ )
142
+ print("Your token: " + req.json()["token"])
143
+ print("Add it to the api_key field in your configuration file")
144
+
145
+
88
146
  @codecarbon.command("config", short_help="Generate or show config")
89
147
  def config():
90
148
  """
@@ -127,6 +185,7 @@ def config():
127
185
  )
128
186
  overwrite_local_config("api_endpoint", api_endpoint, path=file_path)
129
187
  api = ApiClient(endpoint_url=api_endpoint)
188
+ api.set_access_token(_get_access_token())
130
189
  organizations = api.get_list_organizations()
131
190
  org = questionary_prompt(
132
191
  "Pick existing organization from list or Create new organization ?",
@@ -39,20 +39,22 @@ class ApiClient: # (AsyncClient)
39
39
 
40
40
  def __init__(
41
41
  self,
42
- endpoint_url="https://api.codecarbon.io",
42
+ # endpoint_url="https://api.codecarbon.io",
43
+ endpoint_url="https://dash-dev.cleverapps.io/api", # beta API
43
44
  experiment_id=None,
44
45
  api_key=None,
45
46
  conf=None,
46
47
  ):
47
48
  """
48
49
  :project_id: ID of the existing project
49
- :api_ley: Code Carbon API_KEY
50
+ :api_key: Code Carbon API_KEY
50
51
  """
51
52
  # super().__init__(base_url=endpoint_url) # (AsyncClient)
52
53
  self.url = endpoint_url
53
54
  self.experiment_id = experiment_id
54
55
  self.api_key = api_key
55
56
  self.conf = conf
57
+ self.access_token = None
56
58
  if self.experiment_id is not None:
57
59
  self._create_run(self.experiment_id)
58
60
  import warnings
@@ -64,12 +66,31 @@ class ApiClient: # (AsyncClient)
64
66
  stacklevel=2,
65
67
  )
66
68
 
69
+ def set_access_token(self, token: str):
70
+ """This method sets the access token to be used for the API. For now it is not used.
71
+
72
+ Args:
73
+ token (str): access token to be used for the API
74
+ """
75
+ self.access_token = token
76
+
77
+ def _get_headers(self):
78
+ headers = {"Content-Type": "application/json"}
79
+ if self.api_key:
80
+ print(type(self.api_key))
81
+ # set the x-api-token header
82
+ headers["x-api-token"] = self.api_key
83
+ if self.access_token:
84
+ headers["Authorization"] = f"Bearer {self.access_token}"
85
+ return headers
86
+
67
87
  def get_list_organizations(self):
68
88
  """
69
89
  List all organizations
70
90
  """
71
91
  url = self.url + "/organizations"
72
- r = requests.get(url=url, timeout=2)
92
+ headers = self._get_headers()
93
+ r = requests.get(url=url, timeout=2, headers=headers)
73
94
  if r.status_code != 200:
74
95
  self._log_error(url, {}, r)
75
96
  return None
@@ -99,7 +120,8 @@ class ApiClient: # (AsyncClient)
99
120
  )
100
121
  return organization
101
122
  else:
102
- r = requests.post(url=url, json=payload, timeout=2)
123
+ headers = self._get_headers()
124
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
103
125
  if r.status_code != 201:
104
126
  self._log_error(url, payload, r)
105
127
  return None
@@ -109,8 +131,9 @@ class ApiClient: # (AsyncClient)
109
131
  """
110
132
  Get an organization
111
133
  """
134
+ headers = self._get_headers()
112
135
  url = self.url + "/organizations/" + organization_id
113
- r = requests.get(url=url, timeout=2)
136
+ r = requests.get(url=url, timeout=2, headers=headers)
114
137
  if r.status_code != 200:
115
138
  self._log_error(url, {}, r)
116
139
  return None
@@ -121,8 +144,9 @@ class ApiClient: # (AsyncClient)
121
144
  Update an organization
122
145
  """
123
146
  payload = dataclasses.asdict(organization)
147
+ headers = self._get_headers()
124
148
  url = self.url + "/organizations/" + organization.id
125
- r = requests.patch(url=url, json=payload, timeout=2)
149
+ r = requests.patch(url=url, json=payload, timeout=2, headers=headers)
126
150
  if r.status_code != 200:
127
151
  self._log_error(url, payload, r)
128
152
  return None
@@ -133,8 +157,8 @@ class ApiClient: # (AsyncClient)
133
157
  List all projects
134
158
  """
135
159
  url = self.url + "/organizations/" + organization_id + "/projects"
136
-
137
- r = requests.get(url=url, timeout=2)
160
+ headers = self._get_headers()
161
+ r = requests.get(url=url, timeout=2, headers=headers)
138
162
  if r.status_code != 200:
139
163
  self._log_error(url, {}, r)
140
164
  return None
@@ -146,7 +170,8 @@ class ApiClient: # (AsyncClient)
146
170
  """
147
171
  payload = dataclasses.asdict(project)
148
172
  url = self.url + "/projects"
149
- r = requests.post(url=url, json=payload, timeout=2)
173
+ headers = self._get_headers()
174
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
150
175
  if r.status_code != 201:
151
176
  self._log_error(url, payload, r)
152
177
  return None
@@ -157,7 +182,8 @@ class ApiClient: # (AsyncClient)
157
182
  Get a project
158
183
  """
159
184
  url = self.url + "/projects/" + project_id
160
- r = requests.get(url=url, timeout=2)
185
+ headers = self._get_headers()
186
+ r = requests.get(url=url, timeout=2, headers=headers)
161
187
  if r.status_code != 200:
162
188
  self._log_error(url, {}, r)
163
189
  return None
@@ -199,7 +225,8 @@ class ApiClient: # (AsyncClient)
199
225
  try:
200
226
  payload = dataclasses.asdict(emission)
201
227
  url = self.url + "/emissions"
202
- r = requests.post(url=url, json=payload, timeout=2)
228
+ headers = self._get_headers()
229
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
203
230
  if r.status_code != 201:
204
231
  self._log_error(url, payload, r)
205
232
  return False
@@ -239,7 +266,8 @@ class ApiClient: # (AsyncClient)
239
266
  )
240
267
  payload = dataclasses.asdict(run)
241
268
  url = self.url + "/runs"
242
- r = requests.post(url=url, json=payload, timeout=2)
269
+ headers = self._get_headers()
270
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
243
271
  if r.status_code != 201:
244
272
  self._log_error(url, payload, r)
245
273
  return None
@@ -263,7 +291,8 @@ class ApiClient: # (AsyncClient)
263
291
  List all experiments for a project
264
292
  """
265
293
  url = self.url + "/projects/" + project_id + "/experiments"
266
- r = requests.get(url=url, timeout=2)
294
+ headers = self._get_headers()
295
+ r = requests.get(url=url, timeout=2, headers=headers)
267
296
  if r.status_code != 200:
268
297
  self._log_error(url, {}, r)
269
298
  return []
@@ -282,7 +311,8 @@ class ApiClient: # (AsyncClient)
282
311
  """
283
312
  payload = dataclasses.asdict(experiment)
284
313
  url = self.url + "/experiments"
285
- r = requests.post(url=url, json=payload, timeout=2)
314
+ headers = self._get_headers()
315
+ r = requests.post(url=url, json=payload, timeout=2, headers=headers)
286
316
  if r.status_code != 201:
287
317
  self._log_error(url, payload, r)
288
318
  return None
@@ -293,7 +323,8 @@ class ApiClient: # (AsyncClient)
293
323
  Get an experiment by id
294
324
  """
295
325
  url = self.url + "/experiments/" + experiment_id
296
- r = requests.get(url=url, timeout=2)
326
+ headers = self._get_headers()
327
+ r = requests.get(url=url, timeout=2, headers=headers)
297
328
  if r.status_code != 200:
298
329
  self._log_error(url, {}, r)
299
330
  return None
@@ -124,8 +124,11 @@ class GPUDevice:
124
124
  """Returns the name of the GPU device
125
125
  https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1ga5361803e044c6fdf3b08523fb6d1481
126
126
  """
127
- name = pynvml.nvmlDeviceGetName(self.handle)
128
- return self._to_utf8(name)
127
+ try:
128
+ name = pynvml.nvmlDeviceGetName(self.handle)
129
+ return self._to_utf8(name)
130
+ except UnicodeDecodeError:
131
+ return "Unknown GPU"
129
132
 
130
133
  def _get_uuid(self) -> Any:
131
134
  """Returns the globally unique GPU device UUID
@@ -256,6 +256,7 @@ class BaseEmissionsTracker(ABC):
256
256
 
257
257
  self._set_from_conf(api_call_interval, "api_call_interval", 8, int)
258
258
  self._set_from_conf(api_endpoint, "api_endpoint", "https://api.codecarbon.io")
259
+ self._set_from_conf(api_key, "api_key", "api_key")
259
260
  self._set_from_conf(co2_signal_api_token, "co2_signal_api_token")
260
261
  self._set_from_conf(emissions_endpoint, "emissions_endpoint")
261
262
  self._set_from_conf(experiment_name, "experiment_name", "base")
@@ -345,7 +346,7 @@ class BaseEmissionsTracker(ABC):
345
346
  self._emissions: Emissions = Emissions(
346
347
  self._data_source, self._co2_signal_api_token
347
348
  )
348
- self._init_output_methods(api_key)
349
+ self._init_output_methods(self._api_key)
349
350
 
350
351
  def set_CPU_GPU_ram_tracking(self):
351
352
  cpu_tracker = gpu_tracker = ram_tracker = "Unspecified"
@@ -27,6 +27,7 @@ classifiers = [
27
27
  dependencies = [
28
28
  "arrow",
29
29
  "click",
30
+ "fief-client[cli]",
30
31
  "pandas",
31
32
  "prometheus_client",
32
33
  "psutil",
@@ -150,7 +151,7 @@ dependencies = [
150
151
  "requests<3.0.0",
151
152
  "sqlalchemy<2.0.0",
152
153
  "uvicorn[standard]<1.0.0",
153
- "fastapi-pagination<1.0.0",
154
+ "fastapi-pagination==0.9.1",
154
155
  "pytest",
155
156
  "mock",
156
157
  "pytest",
@@ -181,7 +182,7 @@ include = [
181
182
  ]
182
183
 
183
184
  [tool.bumpver]
184
- current_version = "2.7.1"
185
+ current_version = "2.7.2"
185
186
  version_pattern = "MAJOR.MINOR.PATCH"
186
187
 
187
188
  [tool.bumpver.file_patterns]
@@ -1 +0,0 @@
1
- __version__ = "2.7.1"
File without changes
File without changes