water-bottle-please 0.6.4__py3-none-any.whl
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.
- water_bottle_please/__init__.py +2 -0
- water_bottle_please/helpers.py +157 -0
- water_bottle_please-0.6.4.dist-info/METADATA +213 -0
- water_bottle_please-0.6.4.dist-info/RECORD +7 -0
- water_bottle_please-0.6.4.dist-info/WHEEL +4 -0
- water_bottle_please-0.6.4.dist-info/entry_points.txt +2 -0
- water_bottle_please-0.6.4.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import polars as pl
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from datetime import date
|
|
4
|
+
|
|
5
|
+
def date_format(col: str,output_date_name = "output_date_name"):
|
|
6
|
+
""" Format Dates
|
|
7
|
+
|
|
8
|
+
Convert string dates into a yyyy-mm-dd format.
|
|
9
|
+
The function uses pl.coalesce to try to process different formats.
|
|
10
|
+
For example, it will first try to convert m/d/y, and then if that doesn't work it will try d/m/y.
|
|
11
|
+
It's not perfect, but if someone messes up the date it's their fault.
|
|
12
|
+
|
|
13
|
+
**Note: it won't attempt to convert excel dates. If someone sends us excel dates we will file a lawsuit.**
|
|
14
|
+
|
|
15
|
+
Usage
|
|
16
|
+
-----
|
|
17
|
+
To be applied to a string date column.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
col: str
|
|
22
|
+
a string column that has a date
|
|
23
|
+
|
|
24
|
+
Returns
|
|
25
|
+
-------
|
|
26
|
+
output_date: date
|
|
27
|
+
a date column
|
|
28
|
+
|
|
29
|
+
Examples
|
|
30
|
+
--------
|
|
31
|
+
```{python}
|
|
32
|
+
#| echo: false
|
|
33
|
+
{{< include "../_setup.qmd" >}}
|
|
34
|
+
```
|
|
35
|
+
```{python}
|
|
36
|
+
import polars as pl
|
|
37
|
+
from src.subtype_link.utils.helpers import date_format
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
df = pl.DataFrame({
|
|
41
|
+
"dates": [
|
|
42
|
+
"2024-10-30", # ISO format
|
|
43
|
+
"30/10/2024", # European format
|
|
44
|
+
"10/20/2024", # US format
|
|
45
|
+
"10-30-2024", # US format
|
|
46
|
+
"October 30, 2024", # Full month name format,
|
|
47
|
+
"45496", # an excel date LOL
|
|
48
|
+
"2022-12-27 08:26:49"
|
|
49
|
+
]
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
print(
|
|
53
|
+
df
|
|
54
|
+
.with_columns(
|
|
55
|
+
new_date=date_format('dates','new_date')
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
# add something new
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
"""
|
|
63
|
+
return pl.coalesce(
|
|
64
|
+
# see this for date types https://docs.rs/chrono/latest/chrono/format/strftime/index.html
|
|
65
|
+
# regular dates like sane people yyyy-mm-dd
|
|
66
|
+
pl.col(col).str.strptime(pl.Date, "%F", strict=False),
|
|
67
|
+
# datetimes - semi sane
|
|
68
|
+
pl.col(col).str.strptime(pl.Date, "%F %T", strict=False),
|
|
69
|
+
# m/d/y - gettin wild
|
|
70
|
+
pl.col(col).str.strptime(pl.Date, "%D", strict=False),
|
|
71
|
+
# dont even ask
|
|
72
|
+
pl.col(col).str.strptime(pl.Date, "%c", strict=False),
|
|
73
|
+
# mm-dd-yyyy
|
|
74
|
+
pl.col(col).str.strptime(pl.Date, "%m-%d-%Y", strict=False),
|
|
75
|
+
# dd-mm-yyyy
|
|
76
|
+
pl.col(col).str.strptime(pl.Date, "%d-%m-%Y", strict=False),
|
|
77
|
+
# mm/dd/yyyy
|
|
78
|
+
pl.col(col).str.strptime(pl.Date, "%m/%d/%Y", strict=False),
|
|
79
|
+
# dd/mm/yyyy
|
|
80
|
+
pl.col(col).str.strptime(pl.Date, "%d/%m/%Y", strict=False),
|
|
81
|
+
# if someone literally writes out the month. smh
|
|
82
|
+
pl.col(col).str.strptime(pl.Date, "%B %d, %Y", strict=False),
|
|
83
|
+
# if someone sends an excel date we'll just reject it and call the cops on them
|
|
84
|
+
|
|
85
|
+
).alias(output_date_name)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def save_raw_values(df_inp: pl.DataFrame, primary_key_col: str):
|
|
89
|
+
""" save raw values
|
|
90
|
+
|
|
91
|
+
Usage
|
|
92
|
+
-----
|
|
93
|
+
Converts a polars dataframe into a dataframe with all columns in a struct column.
|
|
94
|
+
It's good for saving raw outputs of data.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
df_inp: pl.DataFrame
|
|
99
|
+
a polars dataframe
|
|
100
|
+
primary_key_col: str
|
|
101
|
+
column name for the primary key (submission key, not person/case key)
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
df: pl.DataFrame
|
|
106
|
+
a dataframe
|
|
107
|
+
|
|
108
|
+
Examples
|
|
109
|
+
--------
|
|
110
|
+
```{python}
|
|
111
|
+
#| echo: false
|
|
112
|
+
{{< include "../_setup.qmd" >}}
|
|
113
|
+
```
|
|
114
|
+
```{python}
|
|
115
|
+
import polars as pl
|
|
116
|
+
from test_project import helpers
|
|
117
|
+
|
|
118
|
+
data = pl.DataFrame({
|
|
119
|
+
"lab_name": ["PHL", "MFT", "ELR","PHL"],
|
|
120
|
+
"first_name": ["Alice", "Bob", "Charlie", "Charlie"],
|
|
121
|
+
"last_name": ["Smith", "Johnson", "Williams", "Williams"],
|
|
122
|
+
"WA_ID": [1,2,4,4]
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
received_submissions_df = (
|
|
126
|
+
helpers.save_raw_values(df_inp=data,primary_key_col="WA_ID")
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
helpers.gt_style(df_inp=data)
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```{python}
|
|
134
|
+
helpers.gt_style(df_inp=received_submissions_df)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
df = (
|
|
140
|
+
df_inp
|
|
141
|
+
.select([
|
|
142
|
+
# save the primary key
|
|
143
|
+
pl.col(primary_key_col).alias('submission_number'),
|
|
144
|
+
|
|
145
|
+
# internal create date
|
|
146
|
+
pl.lit(date.today()).alias("internal_create_date"),
|
|
147
|
+
|
|
148
|
+
# save a copy of all the original columns and put them into a struct column
|
|
149
|
+
pl.struct(pl.all()).alias("raw_inbound_submission")
|
|
150
|
+
])
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return df
|
|
154
|
+
|
|
155
|
+
def func():
|
|
156
|
+
return print("hi")
|
|
157
|
+
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: water-bottle-please
|
|
3
|
+
Version: 0.6.4
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author: Frank Aragclear
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: polars>=1.24.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# test_project
|
|
12
|
+
testing out making a python package
|
|
13
|
+
|
|
14
|
+
# How to install the package
|
|
15
|
+
|
|
16
|
+
Open PowerShell terminal (or Ubuntu bash terminal)
|
|
17
|
+
|
|
18
|
+
1. Make a new folder
|
|
19
|
+
2. `pip install uv`
|
|
20
|
+
3. `uv venv --python 3.11`
|
|
21
|
+
4. `.\.venv\Scripts\activate`
|
|
22
|
+
5. `uv pip install polars`
|
|
23
|
+
6. `uv pip install git+https://github.com/coe-test-org/test_project.git#egg=test_project`
|
|
24
|
+
|
|
25
|
+
To install a specific version, find the git tag noted in the GitHub Release section (something like `v0.2.5`) and then put it in the install statement like `.git@v0.2.5`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv pip install git+https://github.com/coe-test-org/test_project.git@v0.2.5#egg=test_project
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
here's what it looks like when updating the install version:
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# How to test it
|
|
38
|
+
create a script called `main.py` in your folder and run this code:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
|
|
42
|
+
from test_project import helpers
|
|
43
|
+
import polars as pl
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
df = pl.DataFrame({
|
|
47
|
+
'date': [
|
|
48
|
+
'2022-01-03',
|
|
49
|
+
'01-02-2020',
|
|
50
|
+
'44115',
|
|
51
|
+
None,
|
|
52
|
+
"2022-12-27 08:26:49",
|
|
53
|
+
# "2022-12-27T08:26:49",
|
|
54
|
+
'01/02/1995',
|
|
55
|
+
'2/3/2022',
|
|
56
|
+
'2/16/2022'
|
|
57
|
+
]
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
df_output = (
|
|
61
|
+
df
|
|
62
|
+
.with_columns(
|
|
63
|
+
output_date = helpers.date_format('date')
|
|
64
|
+
)
|
|
65
|
+
.select('output_date')
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
print(df_output)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
it should give you this output
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
>>> print(df_output)
|
|
75
|
+
shape: (8, 1)
|
|
76
|
+
┌─────────────┐
|
|
77
|
+
│ output_date │
|
|
78
|
+
│ --- │
|
|
79
|
+
│ date │
|
|
80
|
+
╞═════════════╡
|
|
81
|
+
│ 2022-01-03 │
|
|
82
|
+
│ 2020-01-02 │
|
|
83
|
+
│ null │
|
|
84
|
+
│ null │
|
|
85
|
+
│ 2022-12-27 │
|
|
86
|
+
│ 1995-01-02 │
|
|
87
|
+
│ 2022-02-03 │
|
|
88
|
+
│ 2022-02-16 │
|
|
89
|
+
└─────────────┘
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# For Devs
|
|
94
|
+
|
|
95
|
+
## how to create a package with uv
|
|
96
|
+
1. In a new repo, run `uv init --package <package_name>`
|
|
97
|
+
It gives you this:
|
|
98
|
+
```bash
|
|
99
|
+
.
|
|
100
|
+
├── LICENSE
|
|
101
|
+
├── README.md
|
|
102
|
+
└── test_package
|
|
103
|
+
├── README.md
|
|
104
|
+
├── pyproject.toml
|
|
105
|
+
└── src
|
|
106
|
+
└── test_package
|
|
107
|
+
└── __init__.py
|
|
108
|
+
|
|
109
|
+
3 directories, 5 files
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
2. Create a venv with `uv venv`
|
|
113
|
+
a. This creates a venv you can activate (called your package name)
|
|
114
|
+
b. Creates a `uv.lock` file
|
|
115
|
+
c. `Uv sync` to install and update your venv
|
|
116
|
+
3. Run `uv build` and it will build your package, adding a `dist/` folder with a `.tar.gz` file of the package.
|
|
117
|
+
a. Amazing
|
|
118
|
+
b. [follow these docs](https://docs.astral.sh/uv/guides/package/#publishing-your-package) to publish it to pypi or somewhere else privately
|
|
119
|
+
4. To install from github: `uv pip install git+https://github.com/coe-test-org/test_project.git#egg=test_project`
|
|
120
|
+
If you get python version error, add python version to your .venv with `uv python install 3.11` or rebuild the venv with `uv venv --python 3.11`
|
|
121
|
+
|
|
122
|
+
5. for dev packages that you need but aren't package dependencies, like `pytest`, you can add them to the project with [development dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/#development-dependencies) like this:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
uv add --dev pytest
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
and that will add pytest to the `uv.lock` and `pyproject.toml` but as a separate dependency from the actual packages. In other words, the package won't be dependent on `pytest`, but it will be installed for devs that want to run the unit tests.
|
|
129
|
+
|
|
130
|
+
## how to build the package automatically with CI/CD
|
|
131
|
+
|
|
132
|
+
this repo has a github action that automatically runs unit tests, builds the package, and outputs a changelog for a github release.
|
|
133
|
+
|
|
134
|
+
The github action has two steps:
|
|
135
|
+
|
|
136
|
+
### 1. unit-tests
|
|
137
|
+
|
|
138
|
+
This step will install `uv`, install python, and then run the unit tests in the `tests` folder.
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
unit-tests:
|
|
142
|
+
name: Build and Test Python Package
|
|
143
|
+
runs-on: ubuntu-latest
|
|
144
|
+
|
|
145
|
+
steps:
|
|
146
|
+
- uses: actions/checkout@v4
|
|
147
|
+
|
|
148
|
+
- name: Install uv
|
|
149
|
+
uses: astral-sh/setup-uv@v5
|
|
150
|
+
with:
|
|
151
|
+
version: "0.6.5" # pin a specific version is best practice
|
|
152
|
+
enable-cache: true
|
|
153
|
+
|
|
154
|
+
# install python in
|
|
155
|
+
- name: "Set up Python"
|
|
156
|
+
uses: actions/setup-python@v5
|
|
157
|
+
with:
|
|
158
|
+
python-version-file: "pyproject.toml"
|
|
159
|
+
|
|
160
|
+
- name: Run tests
|
|
161
|
+
# For example, using `pytest`
|
|
162
|
+
run: uv run pytest tests
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 2. build-and-release
|
|
166
|
+
|
|
167
|
+
This step is dependent on the first step above. If any unit-tests fail, then this build/release will not run.
|
|
168
|
+
|
|
169
|
+
The build step works like this:
|
|
170
|
+
|
|
171
|
+
1. Scan the code for conventional commit messages (like `fix:`, `feat:`, etc) and render a changelog based on the commits
|
|
172
|
+
2. Create a GitHub Release (git tags) that bump up the version of the codebase (like `v1.0.0` to `v1.1.0`)
|
|
173
|
+
3. Build the python package and have its version match the git tag version. `uv` currently doesn't have a built in way to do this, but [they are currently working on it](https://github.com/astral-sh/uv/issues/6298). In the meantime, that link has a way to link the python package version to the git release like this:
|
|
174
|
+
|
|
175
|
+
```yaml
|
|
176
|
+
# install uv
|
|
177
|
+
- name: Set up uv
|
|
178
|
+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
179
|
+
|
|
180
|
+
- name: Build package
|
|
181
|
+
if: ${{ steps.changelog.outputs.skipped == 'false' }}
|
|
182
|
+
run: |
|
|
183
|
+
VERSION=$(uvx dunamai from any --no-metadata --style pep440) # find the version of the git tag for the python package
|
|
184
|
+
echo $VERSION
|
|
185
|
+
uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version $VERSION # update the version in the pyproject.toml
|
|
186
|
+
uv build # build the package
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
so it will update the `pyproject.toml` to have the most up to date version that matches the git tag version and then build the package with `uv build`. The [build function](https://docs.astral.sh/uv/concepts/projects/build/#using-uv-build) builds the package and outputs a `dist/` folder with a `.tar.gz` file and a `.whl` file, both of which are source files for installing the package.
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
I also wanted to take the `.tar.gz` and `.whl` files and add them to the `Assets` in the changelog for GitHub. That way we can always save copies of our package whenever we make a new release, just to be safe.
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
# Attach the build assets to the GitHub release (only if changelog creation was successful)
|
|
197
|
+
- name: Upload sdist to GitHub release
|
|
198
|
+
run: gh release upload $TAG $FILES --clobber
|
|
199
|
+
env:
|
|
200
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
201
|
+
TAG: ${{ steps.changelog.outputs.tag }} # this is pulled from the changelog step where it creates the git tag
|
|
202
|
+
FILES: dist/*.tar.gz dist/*.whl # these files are created in the build step
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
water_bottle_please/__init__.py,sha256=bFpDzlDp-dcBXUDHUeeGB0oMwcp2p0i3cb_Tw_wDAEo,58
|
|
2
|
+
water_bottle_please/helpers.py,sha256=jC_XFH4dUDaP77VQepWQGTVyXSFNP2AFJzaK9BrIXWw,4403
|
|
3
|
+
water_bottle_please-0.6.4.dist-info/METADATA,sha256=K30aQ7cwPMcQK4E-9fXqOi6RAy44FG79stgnVdHmJEo,6750
|
|
4
|
+
water_bottle_please-0.6.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
5
|
+
water_bottle_please-0.6.4.dist-info/entry_points.txt,sha256=tZ1un5vxdxvEKvtzDPQdPo_lV0l2nRujESRMuJBlEu0,65
|
|
6
|
+
water_bottle_please-0.6.4.dist-info/licenses/LICENSE,sha256=6_OJwRbyTDHUFt6errQAsS_VA6b7OlMwOBoCqf63cNU,1069
|
|
7
|
+
water_bottle_please-0.6.4.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 coe-test-org
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|