toolsos 0.2.3__tar.gz → 0.2.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.
Files changed (30) hide show
  1. {toolsos-0.2.3 → toolsos-0.2.5}/PKG-INFO +9 -2
  2. {toolsos-0.2.3 → toolsos-0.2.5}/README.md +8 -1
  3. {toolsos-0.2.3 → toolsos-0.2.5}/pyproject.toml +1 -1
  4. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/cbs_tools.py +36 -17
  5. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/database/database_connection.py +52 -13
  6. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/geo.py +1 -1
  7. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/bargraph.py +11 -1
  8. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/graph_styles.py +3 -1
  9. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/linegraph.py +2 -1
  10. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/piegraph.py +2 -1
  11. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/styler.py +21 -14
  12. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/tables.py +19 -5
  13. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/PKG-INFO +9 -2
  14. {toolsos-0.2.3 → toolsos-0.2.5}/setup.cfg +0 -0
  15. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/__init__.py +0 -0
  16. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/create_tables.py +0 -0
  17. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/database/database_transfer.py +0 -0
  18. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/download.py +0 -0
  19. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/helpers.py +0 -0
  20. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/__init__.py +0 -0
  21. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/colors.py +0 -0
  22. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/graphs/__init__.py +0 -0
  23. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/__init__.py +0 -0
  24. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/table_helpers.py +0 -0
  25. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/huisstijl/tables/table_styles.py +0 -0
  26. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos/polars_helpers.py +0 -0
  27. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/SOURCES.txt +0 -0
  28. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/dependency_links.txt +0 -0
  29. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/requires.txt +0 -0
  30. {toolsos-0.2.3 → toolsos-0.2.5}/src/toolsos.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: toolsos
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: OS tools
5
5
  Author-email: OS <d.schmitz@amsterdam.nl>
6
6
  Keywords: tools,Onderzoek & Statistiek
@@ -63,5 +63,12 @@ Instructions on building a package can be found [here](https://packaging.python.
63
63
 
64
64
  - make a pypi account
65
65
  - ask to be added as collaborator to toolsos
66
- - first update twine: py -m pip install --upgrade twin
66
+ - first update twine: py -m pip install --upgrade twine
67
67
  - upload to pypi: twine upload dist/* --skip-existing
68
+
69
+ ## Install to local enviroment for testing
70
+
71
+ - python -m venv local (maak een lokale venv aan)
72
+ - local\Scripts\activate (activeer de venv)
73
+ - pip install -e . (installer toolsos)
74
+ - pip install -r local_requirements.txt (installeer de benodigde dependencies)
@@ -34,5 +34,12 @@ Instructions on building a package can be found [here](https://packaging.python.
34
34
 
35
35
  - make a pypi account
36
36
  - ask to be added as collaborator to toolsos
37
- - first update twine: py -m pip install --upgrade twin
37
+ - first update twine: py -m pip install --upgrade twine
38
38
  - upload to pypi: twine upload dist/* --skip-existing
39
+
40
+ ## Install to local enviroment for testing
41
+
42
+ - python -m venv local (maak een lokale venv aan)
43
+ - local\Scripts\activate (activeer de venv)
44
+ - pip install -e . (installer toolsos)
45
+ - pip install -r local_requirements.txt (installeer de benodigde dependencies)
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "toolsos"
9
- version = "0.2.3"
9
+ version = "0.2.5"
10
10
  description = "OS tools"
11
11
  readme = "README.md"
12
12
  authors = [{ name = "OS", email = "d.schmitz@amsterdam.nl" }]
@@ -2,8 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import pickle
5
+ from datetime import datetime
5
6
  from pathlib import Path
6
- from typing import TYPE_CHECKING, Iterator, Optional, Any
7
+ from typing import TYPE_CHECKING, Any, Iterator, Optional
7
8
 
8
9
  import pandas as pd
9
10
  import pyarrow as pa
@@ -14,18 +15,27 @@ if TYPE_CHECKING:
14
15
  import pyreadstat
15
16
 
16
17
 
18
+ def get_batch_size(path, memory_limit):
19
+ df, _ = prs.read_sav(path, row_limit=1000)
20
+
21
+ # memory in megabytes
22
+ mem_size = df.memory_usage().sum() / 1_000_000
23
+
24
+ # The amount of blocks (of a thousand rows fit in the memory_limit)
25
+ n_blocks = memory_limit / mem_size
26
+
27
+ # Calculate the number of rows that fit within the memory limit
28
+ return round(n_blocks * 1000)
29
+
30
+
17
31
  class SavToParquet:
18
32
  def __init__(
19
- self,
20
- file: str,
21
- folder_out: str,
22
- chunksize: Optional[int] = None,
23
- verbose: bool = False,
33
+ self, file: str, folder_out: str, verbose: bool = False, memory_limit=10_000
24
34
  ) -> None:
25
35
  self.file = file
26
36
  self.folder_out = folder_out
27
37
  self.verbose = verbose
28
- self.chunksize = 5_000_000 if not chunksize else chunksize
38
+ self.memory_limit = memory_limit
29
39
 
30
40
  @property
31
41
  def path_out(self) -> str:
@@ -33,20 +43,27 @@ class SavToParquet:
33
43
 
34
44
  @property
35
45
  def chunks(self) -> Iterator[tuple["pyreadstat.metadata_container", pd.DataFrame]]:
36
- return prs.read_file_in_chunks(
37
- prs.read_sav, self.file, chunksize=self.chunksize
38
- )
39
46
 
40
- def get_meta(self) -> Iterator:
41
- return prs.read_sav(self.file, row_limit=10)
47
+ chunksize = get_batch_size(self.file, self.memory_limit)
48
+
49
+ if self.verbose:
50
+ print(f"Reading file in blocks of {chunksize} rows")
51
+ print("One such block should fit within the memory limit")
52
+
53
+ return prs.read_file_in_chunks(prs.read_sav, self.file, chunksize=chunksize)
42
54
 
43
55
  def write_meta_to_json(self) -> None:
44
56
  json_path = self.path_out.replace(".parquet", "_meta.json")
45
57
 
46
58
  meta_dict = {}
47
- for attr in dir(self.meta):
48
- if not attr.startswith("__"):
49
- meta_dict[attr] = getattr(self.meta, attr)
59
+ for attr_name in dir(self.meta):
60
+ if not attr_name.startswith("__"):
61
+ attr = getattr(self.meta, attr_name)
62
+
63
+ if isinstance(attr, datetime):
64
+ attr = attr.strftime("%Y-%m-%d %H:%M:%S")
65
+
66
+ meta_dict[attr_name] = attr
50
67
 
51
68
  with open(json_path, "w") as file:
52
69
  json.dump(meta_dict, file)
@@ -58,10 +75,12 @@ class SavToParquet:
58
75
  pickle.dump(self.meta, file)
59
76
 
60
77
  def write_to_parquet(self) -> None:
61
- meta_df, self.meta = self.get_meta()
62
- schema = table = pa.Table.from_pandas(meta_df).schema
63
78
 
64
79
  print("Writing table")
80
+
81
+ line1, self.meta = prs.read_sav(self.file, row_limit=1)
82
+ schema = pa.Table.from_pandas(line1).schema
83
+
65
84
  with pq.ParquetWriter(self.path_out, schema) as writer:
66
85
  for idx, (df, _) in enumerate(self.chunks):
67
86
  if self.verbose:
@@ -2,8 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  import getpass
4
4
  import json
5
+ import os
5
6
  import subprocess
6
7
  from json import JSONDecodeError
8
+ from pathlib import Path
7
9
  from typing import Optional
8
10
 
9
11
  import keyring
@@ -99,18 +101,55 @@ def get_azure_access_token():
99
101
  subprocess.run("az login", shell=True)
100
102
 
101
103
 
102
- if __name__ == "__main__":
103
- ...
104
- # Examples
104
+ def get_token_from_pgpass() -> None:
105
+ p = Path(os.getenv("APPDATA")) / "postgresql" / "pgpass.conf"
106
+ with open(p) as f:
107
+ token = f.readline().split(":")[4]
105
108
 
106
- # Get database connection settings from yaml
107
- engine_strings = get_db_connection_strings(
108
- "src/toolsos/database/database_config.yml"
109
- )
110
- print(engine_strings.ruimte_analyse222)
109
+ return token
111
110
 
112
- # Get database connection settings from yaml and reset password
113
- engine_strings = get_db_connection_strings(
114
- "src/toolsos/database/database_config.yml", reset_pw=["ruimte_analyse222"]
115
- )
116
- print(engine_strings.ruimte_analyse222)
111
+
112
+ def write_pgpass(
113
+ host: str, port: str, database: str, user: str, path: str | None = None
114
+ ) -> None:
115
+ password = get_azure_access_token()
116
+ conn_string = f"{host}:{port}:{database}:{user}:{password}"
117
+
118
+ if not path:
119
+ if os.name == "nt":
120
+ path = Path(os.getenv("APPDATA")) / "postgresql" / "pgpass.conf"
121
+ else:
122
+ path = Path("$home/.pgpass")
123
+
124
+ if not path.parent.exists():
125
+ path.parent.mkdir()
126
+
127
+ with open(path, "w") as f:
128
+ f.write(conn_string)
129
+
130
+ if os.name != "nt":
131
+ path.chmod("0600")
132
+
133
+
134
+ def write_multiple_pgpass(conn_details, path: str | None = None):
135
+ password = get_azure_access_token()
136
+
137
+ conn_strings = []
138
+ for c in conn_details:
139
+ c_string = f'{c["host"]}:{c["port"]}:{c["database"]}:{c["user"]}:{password}'
140
+ conn_strings.append(c_string)
141
+
142
+ if not path:
143
+ if os.name == "nt":
144
+ path = Path(os.getenv("APPDATA")) / "postgresql" / "pgpass.conf"
145
+ else:
146
+ path = Path("$home/.pgpass")
147
+
148
+ if not path.parent.exists():
149
+ path.parent.mkdir()
150
+
151
+ with open(path, "w") as f:
152
+ f.writelines(line + "\n" for line in conn_strings)
153
+
154
+ if os.name != "nt":
155
+ path.chmod("0600")
@@ -17,7 +17,7 @@ def get_geo_json(
17
17
  Returns:
18
18
  dict[str, str]: geo json containg of the desired level and year
19
19
  """
20
- base_url = "https://gitlab.com/os-amsterdam/datavisualisatie-onderzoek-en-statistiek/-/raw/main/geo/"
20
+ base_url = "https://gitlab.com/os-amsterdam/datavisualisatie-onderzoek-en-statistiek/-/raw/main/public/geo/"
21
21
 
22
22
  if mra:
23
23
  level = f"{level}-mra"
@@ -1,4 +1,5 @@
1
1
  import plotly.express as px
2
+
2
3
  from .styler import BaseStyle
3
4
 
4
5
  basestyle = BaseStyle()
@@ -14,6 +15,7 @@ def bar(
14
15
  barmode=None,
15
16
  width=750,
16
17
  height=490,
18
+ font="Amsterdam Sans",
17
19
  **kwargs,
18
20
  ):
19
21
  fig = px.bar(
@@ -21,7 +23,7 @@ def bar(
21
23
  x=x,
22
24
  y=y,
23
25
  color=color,
24
- template=basestyle.get_base_template("bar", orientation=orientation),
26
+ template=basestyle.get_base_template("bar", orientation=orientation, font=font),
25
27
  width=width,
26
28
  color_discrete_sequence=color_discrete_sequence,
27
29
  height=height,
@@ -43,6 +45,7 @@ def stacked_single(
43
45
  color: str = None,
44
46
  color_discrete_sequence: list = None,
45
47
  orientation="v",
48
+ font="Amsterdam Sans",
46
49
  **kwargs,
47
50
  ):
48
51
  fig = bar(
@@ -53,6 +56,7 @@ def stacked_single(
53
56
  color_discrete_sequence=color_discrete_sequence,
54
57
  barmode="relative",
55
58
  orientation=orientation,
59
+ font=font,
56
60
  **kwargs,
57
61
  )
58
62
 
@@ -71,6 +75,7 @@ def stacked_multiple(
71
75
  color: str = None,
72
76
  color_discrete_sequence: list = None,
73
77
  orientation="v",
78
+ font="Amsterdam Sans",
74
79
  **kwargs,
75
80
  ):
76
81
  fig = bar(
@@ -81,6 +86,7 @@ def stacked_multiple(
81
86
  color_discrete_sequence=color_discrete_sequence,
82
87
  barmode="stack",
83
88
  orientation=orientation,
89
+ font=font,
84
90
  **kwargs,
85
91
  )
86
92
 
@@ -94,6 +100,7 @@ def grouped(
94
100
  color: str = None,
95
101
  color_discrete_sequence: list = None,
96
102
  orientation="v",
103
+ font="Amsterdam Sans",
97
104
  **kwargs,
98
105
  ):
99
106
  fig = bar(
@@ -104,6 +111,7 @@ def grouped(
104
111
  color_discrete_sequence=color_discrete_sequence,
105
112
  barmode="group",
106
113
  orientation=orientation,
114
+ font=font,
107
115
  **kwargs,
108
116
  )
109
117
 
@@ -116,6 +124,7 @@ def single(
116
124
  y: str,
117
125
  color_discrete_sequence: list = None,
118
126
  orientation="v",
127
+ font="Amsterdam Sans",
119
128
  **kwargs,
120
129
  ):
121
130
  fig = bar(
@@ -124,6 +133,7 @@ def single(
124
133
  y=y,
125
134
  color_discrete_sequence=color_discrete_sequence,
126
135
  orientation=orientation,
136
+ font=font,
127
137
  **kwargs,
128
138
  )
129
139
 
@@ -16,8 +16,10 @@ STYLE_OLD = {
16
16
 
17
17
  STYLE_NEW = {
18
18
  "font_bold": {"family": "Amsterdam Sans ExtraBold, Corbel", "size": 15},
19
+ "font_bold_corbel": {"family": "Corbel Bold", "size": 15},
19
20
  "font": {"family": "Amsterdam Sans, Corbel", "size": 15},
20
- "axis_font": {"family": font, "size": 15},
21
+ "font_corbel": {"family": "Corbel", "size": 15},
22
+ "axis_font": {"family": "Amsterdam Sans ExtraBold, Corbel", "size": 15},
21
23
  "plot_bgcolor": "#FFFFFF",
22
24
  "gridline_color": "#dbdbdb",
23
25
  "gridline_width": 0.75,
@@ -13,6 +13,7 @@ def line(
13
13
  width=750,
14
14
  height=490,
15
15
  color_discrete_sequence=None,
16
+ font="Amsterdam Sans",
16
17
  **kwargs,
17
18
  ):
18
19
  fig = px.line(
@@ -23,7 +24,7 @@ def line(
23
24
  width=width,
24
25
  height=height,
25
26
  color_discrete_sequence=color_discrete_sequence,
26
- template=BaseStyle().get_base_template(graph_type="line"),
27
+ template=BaseStyle().get_base_template(graph_type="line", font=font),
27
28
  **kwargs,
28
29
  )
29
30
 
@@ -14,6 +14,7 @@ def pie(
14
14
  height=490,
15
15
  text_format: str = None,
16
16
  color_discrete_sequence=None,
17
+ font="Amsterdam Sans",
17
18
  **kwargs,
18
19
  ):
19
20
  fig = px.pie(
@@ -23,7 +24,7 @@ def pie(
23
24
  width=width,
24
25
  height=height,
25
26
  hole=hole,
26
- template=BaseStyle().get_base_template(),
27
+ template=BaseStyle().get_base_template(font=font),
27
28
  color_discrete_sequence=color_discrete_sequence,
28
29
  **kwargs,
29
30
  )
@@ -109,7 +109,6 @@ class BaseStyle:
109
109
  self.style = json.load(file)
110
110
 
111
111
  def _get_axis_format(self):
112
- self.gridline_color = "#dbdbdb" # Jorren vragen om deze aan te passen
113
112
 
114
113
  return {
115
114
  "zerolinecolor": self.style["gridline_color"],
@@ -121,29 +120,37 @@ class BaseStyle:
121
120
  "showgrid": self.style["showgrid"],
122
121
  }
123
122
 
124
- def _get_base_template_layout(self):
123
+ def _get_base_template_layout(self, font):
124
+ if font == "Amsterdam Sans":
125
+ font_ = self.style["font"]
126
+ font_bold_ = self.style["font_bold"]
127
+ elif font == "Corbel":
128
+ font_ = self.style["font_corbel"]
129
+ font_bold_ = self.style["font_bold_corbel"]
130
+ else:
131
+ raise ValueError("Font should be 'Amsterdam Sans' or 'Corbel'")
132
+
125
133
  return go.layout.Template(
126
134
  layout={
127
- # "font": self.styles["font_bold"],
128
135
  "xaxis": {
129
- "tickfont": self.style["font_bold"],
136
+ "tickfont": font_bold_,
130
137
  },
131
138
  "yaxis": {
132
- "tickfont": {
133
- "family": self.style["axis_font"]["family"],
134
- "size": self.style["axis_font"]["size"],
135
- },
139
+ "tickfont": font_bold_,
136
140
  },
137
- "legend": {"font": self.style["font"]},
141
+ "legend": {"font": font_},
138
142
  "plot_bgcolor": self.style["plot_bgcolor"],
139
- # "colorway": self.colors["darkblue_lightblue_gradient_5"],
140
- "separators": ",", # Jorren vragen om deze toe te voegen
141
- "font": self.style["font_bold"],
143
+ "separators": ",",
144
+ "font": font_bold_,
142
145
  }
143
146
  )
144
147
 
145
148
  def get_base_template(
146
- self, graph_type: str = None, orientation: str = None, colors: str = None
149
+ self,
150
+ graph_type: str = None,
151
+ orientation: str = None,
152
+ colors: str = None,
153
+ font: str = "Amsterdam Sans",
147
154
  ):
148
155
  """[summary]
149
156
 
@@ -158,7 +165,7 @@ class BaseStyle:
158
165
  Returns:
159
166
  [type]: [description]
160
167
  """
161
- base_template = self._get_base_template_layout()
168
+ base_template = self._get_base_template_layout(font)
162
169
  axis_format = self._get_axis_format()
163
170
 
164
171
  if graph_type == "bar":
@@ -56,6 +56,8 @@ def cols_to_str(df: pd.DataFrame) -> pd.DataFrame:
56
56
  Returns:
57
57
  pd.DataFrame: Dataframe with column names as strings
58
58
  """
59
+
60
+ # Multiindex columns are always strings and therefore can't be casted as string
59
61
  if df.columns.nlevels == 1:
60
62
  df.columns = df.columns.astype(str)
61
63
 
@@ -379,6 +381,7 @@ def write_to_worksheet(
379
381
  source: str | None = None,
380
382
  col_filter: bool | None = None,
381
383
  col_widths: list | None = None,
384
+ min_column_width: int | None = None,
382
385
  cells_to_merge: list[list[int]] | None = None,
383
386
  ) -> None:
384
387
  """Writing data to worksheet. Used for writing values to cells and formatting the cells
@@ -423,7 +426,7 @@ def write_to_worksheet(
423
426
  _insert_source(ws, source, arr)
424
427
 
425
428
  if col_widths:
426
- _set_column_widths(ws, col_widths)
429
+ _set_column_widths(ws, col_widths, min_column_width)
427
430
 
428
431
  if title:
429
432
  _insert_title(ws, title)
@@ -432,9 +435,16 @@ def write_to_worksheet(
432
435
  _merge_cells(ws, cells_to_merge, title)
433
436
 
434
437
 
435
- def _set_column_widths(ws: Any, col_widths: list[int]) -> None:
438
+ def _set_column_widths(
439
+ ws: Any, col_widths: list[int], min_column_width: int | None
440
+ ) -> None:
436
441
  for idx, col_width in enumerate(col_widths):
437
442
  col_letter = get_column_letter(idx + 1)
443
+
444
+ if min_column_width:
445
+ if col_width < min_column_width:
446
+ col_width = min_column_width
447
+
438
448
  ws.column_dimensions[col_letter].width = col_width
439
449
 
440
450
 
@@ -493,6 +503,7 @@ def write_table(
493
503
  blue_border_row_ids: int | list[int] | None = None,
494
504
  number_format: str = "0.0",
495
505
  autofit_columns: str | None = "column_names",
506
+ min_column_width: int | None = None,
496
507
  col_filter: bool | None = False,
497
508
  style: str = "old",
498
509
  combine_multiindex: bool | int = False,
@@ -508,9 +519,6 @@ def write_table(
508
519
  data = {"Sheet1": data}
509
520
 
510
521
  for sheet_name, df in data.items():
511
- if column_names_to_string == True:
512
- df = cols_to_str(df)
513
-
514
522
  format_worksheet(
515
523
  wb=wb,
516
524
  df=df,
@@ -534,6 +542,7 @@ def write_table(
534
542
  blue_border_row_ids=blue_border_row_ids,
535
543
  number_format=number_format,
536
544
  autofit_columns=autofit_columns,
545
+ min_column_width=min_column_width,
537
546
  col_filter=col_filter,
538
547
  combine_multiindex=combine_multiindex,
539
548
  column_names_to_string=column_names_to_string,
@@ -582,6 +591,7 @@ def format_worksheet(
582
591
  blue_border_row_ids: int | list[int] | None = None,
583
592
  number_format: str = "0.0",
584
593
  autofit_columns: str | None = "column_names",
594
+ min_column_width: int | None = None,
585
595
  col_filter: bool | None = False,
586
596
  combine_multiindex: bool | int = False,
587
597
  column_names_to_string: bool = True,
@@ -607,6 +617,9 @@ def format_worksheet(
607
617
  perc_col_format (str, optional): The formatting string of percentage columns. Defaults to None.
608
618
  col_filter (bool, optional): Set filter on columns. Defaults to False.
609
619
  """
620
+ if column_names_to_string == True:
621
+ df = cols_to_str(df)
622
+
610
623
  arr = df_to_array(df)
611
624
 
612
625
  blue_rows = []
@@ -711,4 +724,5 @@ def format_worksheet(
711
724
  col_filter=col_filter,
712
725
  col_widths=col_widths,
713
726
  cells_to_merge=cells_to_merge,
727
+ min_column_width=min_column_width,
714
728
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: toolsos
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: OS tools
5
5
  Author-email: OS <d.schmitz@amsterdam.nl>
6
6
  Keywords: tools,Onderzoek & Statistiek
@@ -63,5 +63,12 @@ Instructions on building a package can be found [here](https://packaging.python.
63
63
 
64
64
  - make a pypi account
65
65
  - ask to be added as collaborator to toolsos
66
- - first update twine: py -m pip install --upgrade twin
66
+ - first update twine: py -m pip install --upgrade twine
67
67
  - upload to pypi: twine upload dist/* --skip-existing
68
+
69
+ ## Install to local enviroment for testing
70
+
71
+ - python -m venv local (maak een lokale venv aan)
72
+ - local\Scripts\activate (activeer de venv)
73
+ - pip install -e . (installer toolsos)
74
+ - pip install -r local_requirements.txt (installeer de benodigde dependencies)
File without changes
File without changes
File without changes
File without changes