papi-projects 0.2.5__tar.gz → 0.3.0__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.
- {papi_projects-0.2.5 → papi_projects-0.3.0}/PKG-INFO +45 -27
- {papi_projects-0.2.5 → papi_projects-0.3.0}/README.md +44 -26
- {papi_projects-0.2.5 → papi_projects-0.3.0}/papi/__init__.py +2 -3
- {papi_projects-0.2.5 → papi_projects-0.3.0}/papi/project.py +60 -18
- papi_projects-0.3.0/papi/task.py +66 -0
- {papi_projects-0.2.5 → papi_projects-0.3.0}/papi/wrappers.py +477 -311
- {papi_projects-0.2.5 → papi_projects-0.3.0}/pyproject.toml +2 -1
- {papi_projects-0.2.5 → papi_projects-0.3.0}/scripts/create_notion_project.py +24 -3
- papi_projects-0.3.0/scripts/create_notion_task.py +102 -0
- papi_projects-0.3.0/scripts/create_project.py +211 -0
- {papi_projects-0.2.5 → papi_projects-0.3.0}/scripts/create_toggl_project.py +3 -3
- papi_projects-0.2.5/papi/mocks.py +0 -78
- papi_projects-0.2.5/papi/tests/test_project.py +0 -123
- papi_projects-0.2.5/papi/tests/test_user.py +0 -121
- papi_projects-0.2.5/papi/tests/test_userdb.json +0 -44
- papi_projects-0.2.5/papi/tests/test_wrappers.py +0 -108
- papi_projects-0.2.5/scripts/__init__.py +0 -0
- papi_projects-0.2.5/scripts/create_project.py +0 -178
- {papi_projects-0.2.5 → papi_projects-0.3.0}/papi/user.py +0 -0
- {papi_projects-0.2.5/papi/tests → papi_projects-0.3.0/scripts}/__init__.py +0 -0
- {papi_projects-0.2.5 → papi_projects-0.3.0}/scripts/collate_toggl_hours.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: papi-projects
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: PAPI is an API for managing projects
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: sandyjmacdonald
|
|
@@ -21,7 +21,7 @@ PAPI is an API for managing projects.
|
|
|
21
21
|
|
|
22
22
|
<img src="https://imgur.com/lprJ3mP.jpg" alt="HAHA BUSINESS meme" height="250">
|
|
23
23
|
|
|
24
|
-
It has functionality for creating User and Project instances, storing users in a TinyDB database, and generating project IDs in the format we use in the Data Science group (at the Bioscience Technology Facility at the University of York). It also has wrappers for
|
|
24
|
+
It has functionality for creating User and Project instances, storing users in a TinyDB database, and generating project IDs in the format we use in the Data Science group (at the Bioscience Technology Facility at the University of York). It also has wrappers for Notion and Toggl Track, tools we use for project management and time tracking, respectively.
|
|
25
25
|
|
|
26
26
|
Much of the functionality is tailor-made to the way we manage projects in our group, but make of it what you will!
|
|
27
27
|
|
|
@@ -44,17 +44,11 @@ poetry install
|
|
|
44
44
|
|
|
45
45
|
## Environment variables
|
|
46
46
|
|
|
47
|
-
The
|
|
47
|
+
The Notion and Toggl Track wrappers expect several environment variables for API keys, etc. and the best way to do this is with a .env file that can be loaded via the Python dotenv library straight into your script. The CLI scripts provided also expect these variables to be in a .env file.
|
|
48
48
|
|
|
49
49
|
The .env file should look as follows:
|
|
50
50
|
|
|
51
51
|
```
|
|
52
|
-
# Asana config:
|
|
53
|
-
ASANA_API_KEY="YOURAPIKEY"
|
|
54
|
-
ASANA_PASSWORD=""
|
|
55
|
-
ASANA_WORKSPACE="myworkspace"
|
|
56
|
-
ASANA_TEAM="My Team Name"
|
|
57
|
-
|
|
58
52
|
# toggl track config:
|
|
59
53
|
TOGGL_TRACK_API_KEY="YOURAPIKEY"
|
|
60
54
|
TOGGL_TRACK_PASSWORD="api_token"
|
|
@@ -64,10 +58,10 @@ TOGGL_TRACK_WORKSPACE="My Workspace Name"
|
|
|
64
58
|
NOTION_API_SECRET = "YOURAPISECRET"
|
|
65
59
|
NOTION_CLIENTS_DB = "notionclientsdbid"
|
|
66
60
|
NOTION_PROJECTS_DB = "notionprojectsdbid"
|
|
61
|
+
NOTION_TASKS_DB = "notiontasksdbid"
|
|
62
|
+
NOTION_TEMPLATE_PAGE_ID = "notiontemplatepageid"
|
|
67
63
|
```
|
|
68
64
|
|
|
69
|
-
The `ASANA_PASSWORD` and `TOGGL_TRACK_PASSWORD` values can be left as above, the remaining ones should be replaced with the correct values from your Notion, Asana, and Toggl Track accounts.
|
|
70
|
-
|
|
71
65
|
This .env file can either be put in your working directory or in the top-level papi module folder wherever it is installed.
|
|
72
66
|
|
|
73
67
|
Alternatively, these values can be hard-coded in your scripts, but this is not advised and will not work with the CLI scripts provided.
|
|
@@ -81,15 +75,14 @@ Convenience CLI scripts are provided for some common tasks. They are:
|
|
|
81
75
|
This script creates a project ID if necessary, and adds the project to your Toggl Track:
|
|
82
76
|
|
|
83
77
|
```
|
|
84
|
-
usage: create-toggl-project [-h] [-u USER_ID] [-g
|
|
85
|
-
[--log-file LOG_FILE]
|
|
78
|
+
usage: create-toggl-project [-h] [-u USER_ID] [-g WORKORDER] [-n NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
86
79
|
|
|
87
80
|
options:
|
|
88
81
|
-h, --help show this help message and exit
|
|
89
82
|
-u USER_ID, --user_id USER_ID
|
|
90
83
|
three-letter user ID, e.g. JAS
|
|
91
|
-
-g
|
|
92
|
-
|
|
84
|
+
-g WORKORDER, --workorder WORKORDER
|
|
85
|
+
workorder, e.g. R12345
|
|
93
86
|
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
|
|
94
87
|
-p PROJECT_ID, --project_id PROJECT_ID
|
|
95
88
|
full project ID, e.g. P2024-JAS-ABCD, if already generated
|
|
@@ -99,7 +92,7 @@ options:
|
|
|
99
92
|
--log-file LOG_FILE path to a file where logs should be written
|
|
100
93
|
```
|
|
101
94
|
|
|
102
|
-
Ideally, a three-character user ID,
|
|
95
|
+
Ideally, a three-character user ID, workorder, and short project name will be provided, and PAPI will generate the project ID, e.g.
|
|
103
96
|
|
|
104
97
|
```
|
|
105
98
|
create-toggl-project -u JAS -g R12345 -n 'Such project. Wow.'
|
|
@@ -111,7 +104,7 @@ If a project ID has already been created, then it can be provided via the `-p` a
|
|
|
111
104
|
create-toggl-project -p P2024-JAS-ABCD -g R12345 -n 'Such project. Wow.'
|
|
112
105
|
```
|
|
113
106
|
|
|
114
|
-
The
|
|
107
|
+
The workorder (`-g`) and name (`-n`) are not required, but either a project ID (`-p`) or user ID (`-u`) _is_ necessary.
|
|
115
108
|
|
|
116
109
|
Logging can also be enabled at various levels of detail, and logs can be saved to a file.
|
|
117
110
|
|
|
@@ -148,8 +141,8 @@ collate-toggl-hours -s 2024-08-01 -e 2024-08-31 -o august-2024-hours.tsv
|
|
|
148
141
|
This script creates a project ID if necessary, and adds the project to the Notion projects database:
|
|
149
142
|
|
|
150
143
|
```
|
|
151
|
-
usage: create-notion-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--
|
|
152
|
-
[--log-file LOG_FILE]
|
|
144
|
+
usage: create-notion-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--no-default-workorder-task] [--enable-logging]
|
|
145
|
+
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
153
146
|
|
|
154
147
|
options:
|
|
155
148
|
-h, --help show this help message and exit
|
|
@@ -160,7 +153,9 @@ options:
|
|
|
160
153
|
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis', project ID will be auto-generated
|
|
161
154
|
-p PROJECT_ID, --project_id PROJECT_ID
|
|
162
155
|
full project ID, e.g. P2024-JAS-ABCD, if already generated
|
|
163
|
-
--
|
|
156
|
+
--no-default-workorder-task
|
|
157
|
+
do not add default workorder task
|
|
158
|
+
--enable-logging enable logging output for the papi library.
|
|
164
159
|
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
|
165
160
|
set the logging level (default: INFO)
|
|
166
161
|
--log-file LOG_FILE path to a file where logs should be written
|
|
@@ -180,23 +175,46 @@ create-notion-project -p P2024-JAS-ABCD -n 'Such project. Wow.'
|
|
|
180
175
|
|
|
181
176
|
Logging can also be enabled at various levels of detail, and logs can be saved to a file.
|
|
182
177
|
|
|
178
|
+
### create-notion-task
|
|
179
|
+
|
|
180
|
+
This script adds a task to a Notion project, and expects an existing (in Notion) project ID and task name to be passed in:
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
usage: create-notion-task [-h] [-t TASK_NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
184
|
+
|
|
185
|
+
options:
|
|
186
|
+
-h, --help show this help message and exit
|
|
187
|
+
-t TASK_NAME, --task_name TASK_NAME
|
|
188
|
+
task name (e.g., 'Run Seqera QC pipeline')
|
|
189
|
+
-p PROJECT_ID, --project_id PROJECT_ID
|
|
190
|
+
full project ID, e.g. P2024-JAS-DEFG
|
|
191
|
+
--enable-logging enable logging output for the papi library
|
|
192
|
+
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
|
193
|
+
set the logging level (default: INFO)
|
|
194
|
+
--log-file LOG_FILE path to a file where logs should be written
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
If no arguments are given to the script, i.e. just running `create-notion-task`, then interactive prompts are shown to enter the necessary arguments.
|
|
198
|
+
|
|
183
199
|
### create-project
|
|
184
200
|
|
|
185
201
|
This script can create a project on Toggl Track or Notion, or both:
|
|
186
202
|
|
|
187
203
|
```
|
|
188
|
-
usage: create-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--enable-toggl] [--enable-notion] [--enable-logging]
|
|
204
|
+
usage: create-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--no-default-workorder-task] [--enable-toggl] [--enable-notion] [--enable-logging]
|
|
189
205
|
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
190
206
|
|
|
191
207
|
options:
|
|
192
208
|
-h, --help show this help message and exit
|
|
193
209
|
-u USER_ID, --user_id USER_ID
|
|
194
|
-
three-letter user
|
|
210
|
+
three-letter user ID, e.g. JAS
|
|
195
211
|
-v USER_NAME, --user_name USER_NAME
|
|
196
|
-
user
|
|
197
|
-
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
|
|
212
|
+
user name, e.g. John Andrew Smith
|
|
213
|
+
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
|
|
198
214
|
-p PROJECT_ID, --project_id PROJECT_ID
|
|
199
|
-
full project ID, e.g. P2024-JAS-DEFG
|
|
215
|
+
full project ID, e.g. P2024-JAS-DEFG
|
|
216
|
+
--no-default-workorder-task
|
|
217
|
+
do not add default workorder task
|
|
200
218
|
--enable-toggl create Toggl Track project
|
|
201
219
|
--enable-notion create Notion project
|
|
202
220
|
--enable-logging enable logging output for the papi library
|
|
@@ -253,10 +271,10 @@ JAS
|
|
|
253
271
|
ABCD
|
|
254
272
|
```
|
|
255
273
|
|
|
256
|
-
If a
|
|
274
|
+
If a workorder and/or project name are available, then these can be passed in when instantiating the class.
|
|
257
275
|
|
|
258
276
|
```
|
|
259
|
-
proj = Project(user_id="JAS",
|
|
277
|
+
proj = Project(user_id="JAS", workorder="R12345", name="RNA-seq analysis")
|
|
260
278
|
```
|
|
261
279
|
|
|
262
280
|
A version 4 UUID is also generated for the project when instantiated.
|
|
@@ -2,7 +2,7 @@ PAPI is an API for managing projects.
|
|
|
2
2
|
|
|
3
3
|
<img src="https://imgur.com/lprJ3mP.jpg" alt="HAHA BUSINESS meme" height="250">
|
|
4
4
|
|
|
5
|
-
It has functionality for creating User and Project instances, storing users in a TinyDB database, and generating project IDs in the format we use in the Data Science group (at the Bioscience Technology Facility at the University of York). It also has wrappers for
|
|
5
|
+
It has functionality for creating User and Project instances, storing users in a TinyDB database, and generating project IDs in the format we use in the Data Science group (at the Bioscience Technology Facility at the University of York). It also has wrappers for Notion and Toggl Track, tools we use for project management and time tracking, respectively.
|
|
6
6
|
|
|
7
7
|
Much of the functionality is tailor-made to the way we manage projects in our group, but make of it what you will!
|
|
8
8
|
|
|
@@ -25,17 +25,11 @@ poetry install
|
|
|
25
25
|
|
|
26
26
|
## Environment variables
|
|
27
27
|
|
|
28
|
-
The
|
|
28
|
+
The Notion and Toggl Track wrappers expect several environment variables for API keys, etc. and the best way to do this is with a .env file that can be loaded via the Python dotenv library straight into your script. The CLI scripts provided also expect these variables to be in a .env file.
|
|
29
29
|
|
|
30
30
|
The .env file should look as follows:
|
|
31
31
|
|
|
32
32
|
```
|
|
33
|
-
# Asana config:
|
|
34
|
-
ASANA_API_KEY="YOURAPIKEY"
|
|
35
|
-
ASANA_PASSWORD=""
|
|
36
|
-
ASANA_WORKSPACE="myworkspace"
|
|
37
|
-
ASANA_TEAM="My Team Name"
|
|
38
|
-
|
|
39
33
|
# toggl track config:
|
|
40
34
|
TOGGL_TRACK_API_KEY="YOURAPIKEY"
|
|
41
35
|
TOGGL_TRACK_PASSWORD="api_token"
|
|
@@ -45,10 +39,10 @@ TOGGL_TRACK_WORKSPACE="My Workspace Name"
|
|
|
45
39
|
NOTION_API_SECRET = "YOURAPISECRET"
|
|
46
40
|
NOTION_CLIENTS_DB = "notionclientsdbid"
|
|
47
41
|
NOTION_PROJECTS_DB = "notionprojectsdbid"
|
|
42
|
+
NOTION_TASKS_DB = "notiontasksdbid"
|
|
43
|
+
NOTION_TEMPLATE_PAGE_ID = "notiontemplatepageid"
|
|
48
44
|
```
|
|
49
45
|
|
|
50
|
-
The `ASANA_PASSWORD` and `TOGGL_TRACK_PASSWORD` values can be left as above, the remaining ones should be replaced with the correct values from your Notion, Asana, and Toggl Track accounts.
|
|
51
|
-
|
|
52
46
|
This .env file can either be put in your working directory or in the top-level papi module folder wherever it is installed.
|
|
53
47
|
|
|
54
48
|
Alternatively, these values can be hard-coded in your scripts, but this is not advised and will not work with the CLI scripts provided.
|
|
@@ -62,15 +56,14 @@ Convenience CLI scripts are provided for some common tasks. They are:
|
|
|
62
56
|
This script creates a project ID if necessary, and adds the project to your Toggl Track:
|
|
63
57
|
|
|
64
58
|
```
|
|
65
|
-
usage: create-toggl-project [-h] [-u USER_ID] [-g
|
|
66
|
-
[--log-file LOG_FILE]
|
|
59
|
+
usage: create-toggl-project [-h] [-u USER_ID] [-g WORKORDER] [-n NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
67
60
|
|
|
68
61
|
options:
|
|
69
62
|
-h, --help show this help message and exit
|
|
70
63
|
-u USER_ID, --user_id USER_ID
|
|
71
64
|
three-letter user ID, e.g. JAS
|
|
72
|
-
-g
|
|
73
|
-
|
|
65
|
+
-g WORKORDER, --workorder WORKORDER
|
|
66
|
+
workorder, e.g. R12345
|
|
74
67
|
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
|
|
75
68
|
-p PROJECT_ID, --project_id PROJECT_ID
|
|
76
69
|
full project ID, e.g. P2024-JAS-ABCD, if already generated
|
|
@@ -80,7 +73,7 @@ options:
|
|
|
80
73
|
--log-file LOG_FILE path to a file where logs should be written
|
|
81
74
|
```
|
|
82
75
|
|
|
83
|
-
Ideally, a three-character user ID,
|
|
76
|
+
Ideally, a three-character user ID, workorder, and short project name will be provided, and PAPI will generate the project ID, e.g.
|
|
84
77
|
|
|
85
78
|
```
|
|
86
79
|
create-toggl-project -u JAS -g R12345 -n 'Such project. Wow.'
|
|
@@ -92,7 +85,7 @@ If a project ID has already been created, then it can be provided via the `-p` a
|
|
|
92
85
|
create-toggl-project -p P2024-JAS-ABCD -g R12345 -n 'Such project. Wow.'
|
|
93
86
|
```
|
|
94
87
|
|
|
95
|
-
The
|
|
88
|
+
The workorder (`-g`) and name (`-n`) are not required, but either a project ID (`-p`) or user ID (`-u`) _is_ necessary.
|
|
96
89
|
|
|
97
90
|
Logging can also be enabled at various levels of detail, and logs can be saved to a file.
|
|
98
91
|
|
|
@@ -129,8 +122,8 @@ collate-toggl-hours -s 2024-08-01 -e 2024-08-31 -o august-2024-hours.tsv
|
|
|
129
122
|
This script creates a project ID if necessary, and adds the project to the Notion projects database:
|
|
130
123
|
|
|
131
124
|
```
|
|
132
|
-
usage: create-notion-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--
|
|
133
|
-
[--log-file LOG_FILE]
|
|
125
|
+
usage: create-notion-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--no-default-workorder-task] [--enable-logging]
|
|
126
|
+
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
134
127
|
|
|
135
128
|
options:
|
|
136
129
|
-h, --help show this help message and exit
|
|
@@ -141,7 +134,9 @@ options:
|
|
|
141
134
|
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis', project ID will be auto-generated
|
|
142
135
|
-p PROJECT_ID, --project_id PROJECT_ID
|
|
143
136
|
full project ID, e.g. P2024-JAS-ABCD, if already generated
|
|
144
|
-
--
|
|
137
|
+
--no-default-workorder-task
|
|
138
|
+
do not add default workorder task
|
|
139
|
+
--enable-logging enable logging output for the papi library.
|
|
145
140
|
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
|
146
141
|
set the logging level (default: INFO)
|
|
147
142
|
--log-file LOG_FILE path to a file where logs should be written
|
|
@@ -161,23 +156,46 @@ create-notion-project -p P2024-JAS-ABCD -n 'Such project. Wow.'
|
|
|
161
156
|
|
|
162
157
|
Logging can also be enabled at various levels of detail, and logs can be saved to a file.
|
|
163
158
|
|
|
159
|
+
### create-notion-task
|
|
160
|
+
|
|
161
|
+
This script adds a task to a Notion project, and expects an existing (in Notion) project ID and task name to be passed in:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
usage: create-notion-task [-h] [-t TASK_NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
165
|
+
|
|
166
|
+
options:
|
|
167
|
+
-h, --help show this help message and exit
|
|
168
|
+
-t TASK_NAME, --task_name TASK_NAME
|
|
169
|
+
task name (e.g., 'Run Seqera QC pipeline')
|
|
170
|
+
-p PROJECT_ID, --project_id PROJECT_ID
|
|
171
|
+
full project ID, e.g. P2024-JAS-DEFG
|
|
172
|
+
--enable-logging enable logging output for the papi library
|
|
173
|
+
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
|
174
|
+
set the logging level (default: INFO)
|
|
175
|
+
--log-file LOG_FILE path to a file where logs should be written
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
If no arguments are given to the script, i.e. just running `create-notion-task`, then interactive prompts are shown to enter the necessary arguments.
|
|
179
|
+
|
|
164
180
|
### create-project
|
|
165
181
|
|
|
166
182
|
This script can create a project on Toggl Track or Notion, or both:
|
|
167
183
|
|
|
168
184
|
```
|
|
169
|
-
usage: create-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--enable-toggl] [--enable-notion] [--enable-logging]
|
|
185
|
+
usage: create-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--no-default-workorder-task] [--enable-toggl] [--enable-notion] [--enable-logging]
|
|
170
186
|
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
|
|
171
187
|
|
|
172
188
|
options:
|
|
173
189
|
-h, --help show this help message and exit
|
|
174
190
|
-u USER_ID, --user_id USER_ID
|
|
175
|
-
three-letter user
|
|
191
|
+
three-letter user ID, e.g. JAS
|
|
176
192
|
-v USER_NAME, --user_name USER_NAME
|
|
177
|
-
user
|
|
178
|
-
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
|
|
193
|
+
user name, e.g. John Andrew Smith
|
|
194
|
+
-n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
|
|
179
195
|
-p PROJECT_ID, --project_id PROJECT_ID
|
|
180
|
-
full project ID, e.g. P2024-JAS-DEFG
|
|
196
|
+
full project ID, e.g. P2024-JAS-DEFG
|
|
197
|
+
--no-default-workorder-task
|
|
198
|
+
do not add default workorder task
|
|
181
199
|
--enable-toggl create Toggl Track project
|
|
182
200
|
--enable-notion create Notion project
|
|
183
201
|
--enable-logging enable logging output for the papi library
|
|
@@ -234,10 +252,10 @@ JAS
|
|
|
234
252
|
ABCD
|
|
235
253
|
```
|
|
236
254
|
|
|
237
|
-
If a
|
|
255
|
+
If a workorder and/or project name are available, then these can be passed in when instantiating the class.
|
|
238
256
|
|
|
239
257
|
```
|
|
240
|
-
proj = Project(user_id="JAS",
|
|
258
|
+
proj = Project(user_id="JAS", workorder="R12345", name="RNA-seq analysis")
|
|
241
259
|
```
|
|
242
260
|
|
|
243
261
|
A version 4 UUID is also generated for the project when instantiated.
|
|
@@ -5,15 +5,14 @@ from dotenv import dotenv_values
|
|
|
5
5
|
dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
|
|
6
6
|
config = dotenv_values(dotenv_path)
|
|
7
7
|
|
|
8
|
-
ASANA_API_KEY = config["ASANA_API_KEY"]
|
|
9
|
-
ASANA_PASSWORD = config["ASANA_PASSWORD"]
|
|
10
|
-
|
|
11
8
|
TOGGL_TRACK_API_KEY = config["TOGGL_TRACK_API_KEY"]
|
|
12
9
|
TOGGL_TRACK_PASSWORD = config["TOGGL_TRACK_PASSWORD"]
|
|
13
10
|
|
|
14
11
|
NOTION_API_SECRET = config["NOTION_API_SECRET"]
|
|
15
12
|
NOTION_CLIENTS_DB = config["NOTION_CLIENTS_DB"]
|
|
16
13
|
NOTION_PROJECTS_DB = config["NOTION_PROJECTS_DB"]
|
|
14
|
+
NOTION_TASKS_DB = config["NOTION_TASKS_DB"]
|
|
15
|
+
NOTION_TEMPLATE_PAGE_ID = config["NOTION_TEMPLATE_PAGE_ID"]
|
|
17
16
|
|
|
18
17
|
def setup_logger(enable_logging: bool, log_level: str = 'INFO', log_file: str = None):
|
|
19
18
|
logger = logging.getLogger('papi')
|
|
@@ -40,7 +40,7 @@ def get_project_ids(project_names) -> list:
|
|
|
40
40
|
|
|
41
41
|
def decompose_project_name(project_name) -> dict:
|
|
42
42
|
"""This function takes a project name string and attempts
|
|
43
|
-
to split out a project ID, name, and
|
|
43
|
+
to split out a project ID, name, and workorder.
|
|
44
44
|
|
|
45
45
|
:param project_name: A project name string.
|
|
46
46
|
:type project_name: str
|
|
@@ -54,7 +54,7 @@ def decompose_project_name(project_name) -> dict:
|
|
|
54
54
|
(?:\s*[-–—]\s*|\s+)?
|
|
55
55
|
(?P<project_name>[^()\[\]]+?)?
|
|
56
56
|
(?:\s*[\(\[]\s*
|
|
57
|
-
(?P<
|
|
57
|
+
(?P<workorder>[^)\]]+)
|
|
58
58
|
\s*[\)\]])?
|
|
59
59
|
$
|
|
60
60
|
"""
|
|
@@ -63,17 +63,17 @@ def decompose_project_name(project_name) -> dict:
|
|
|
63
63
|
if match:
|
|
64
64
|
project_id = match.group('project_id')
|
|
65
65
|
project_name = match.group('project_name')
|
|
66
|
-
|
|
66
|
+
workorder = match.group('workorder')
|
|
67
67
|
return {
|
|
68
68
|
"project_id": project_id,
|
|
69
69
|
"project_name": project_name,
|
|
70
|
-
"
|
|
70
|
+
"workorder": workorder
|
|
71
71
|
}
|
|
72
72
|
else:
|
|
73
73
|
return {
|
|
74
74
|
"project_id": None,
|
|
75
75
|
"project_name": None,
|
|
76
|
-
"
|
|
76
|
+
"workorder": None
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
def check_project_id(id: str) -> bool:
|
|
@@ -147,27 +147,48 @@ class Project(Protocol):
|
|
|
147
147
|
"""This class represents a project and all of its associated metadata.
|
|
148
148
|
|
|
149
149
|
:param year: Year associated with the project. If no year is supplied, then the current
|
|
150
|
-
year will be used
|
|
150
|
+
year will be used.
|
|
151
151
|
:type year: int, optional
|
|
152
152
|
:param user_id: User ID associated with project. Must be a valid user ID, i.e. either
|
|
153
153
|
3 uppercase alphabetical initials, or 2 uppercase alphabetical initials followed
|
|
154
|
-
by a positive integer number
|
|
154
|
+
by a positive integer number.
|
|
155
155
|
:type user_id: str, optional
|
|
156
156
|
:param suffix: Project suffix; a 4-character, random, uppercase, alphabetical suffix.
|
|
157
|
-
If not supplied, then this will be auto-generated
|
|
157
|
+
If not supplied, then this will be auto-generated.
|
|
158
158
|
:type suffix: str, optional
|
|
159
159
|
:param id: Fully-formed project ID that can be supplied directly, assuming it is valid.
|
|
160
160
|
A valid project ID is of the form P2024-ABC-WXYZ where 2024 is the year associated
|
|
161
161
|
with the project, ABC is a valid 3-character user ID, and WXYZ is a valid 4-character
|
|
162
|
-
alphabetical suffix
|
|
162
|
+
alphabetical suffix.
|
|
163
163
|
:type id: str, optional
|
|
164
164
|
:param p_uuid: A valid version 4 UUID that can be supplied directly. If not supplied, then
|
|
165
|
-
this will be auto-generated
|
|
165
|
+
this will be auto-generated.
|
|
166
166
|
:type p_uuid: str, optional
|
|
167
167
|
:param name: A short, descriptive project name, e.g. "Mouse long-read RNA-seq analysis".
|
|
168
|
-
If not supplied,
|
|
168
|
+
If not supplied, defaults to an empty string.
|
|
169
169
|
:type name: str, optional
|
|
170
|
-
:
|
|
170
|
+
:param workorder: Internal work order number or code associated with the project.
|
|
171
|
+
If not supplied, defaults to None.
|
|
172
|
+
:type workorder: str, optional
|
|
173
|
+
:param created_at: Timestamp when the project was created.
|
|
174
|
+
If not supplied, defaults to None.
|
|
175
|
+
:type created_at: datetime or str, optional
|
|
176
|
+
:param modified_at: Timestamp when the project was last modified.
|
|
177
|
+
If not supplied, defaults to None.
|
|
178
|
+
:type modified_at: datetime or str, optional
|
|
179
|
+
:param status: Current status of the project, matching the Notion Status options
|
|
180
|
+
(e.g. "Not Started", "In Progress", "On Hold", "Completed").
|
|
181
|
+
:type status: str, optional
|
|
182
|
+
:param priority: Project priority level, matching the Notion Priority options
|
|
183
|
+
(e.g. "Low", "Medium", "High", "Critical").
|
|
184
|
+
:type priority: str, optional
|
|
185
|
+
:param owner: List of owners of the project.
|
|
186
|
+
If not supplied, defaults to None.
|
|
187
|
+
:type owner: list[str], optional
|
|
188
|
+
:param notion_page_id: The internal Notion page UUID for this project record.
|
|
189
|
+
If not supplied, defaults to None.
|
|
190
|
+
:type notion_page_id: str, optional
|
|
191
|
+
:raises TypeError: If the fully-formed project ID `id` is malformed.
|
|
171
192
|
"""
|
|
172
193
|
|
|
173
194
|
def __init__(
|
|
@@ -178,18 +199,28 @@ class Project(Protocol):
|
|
|
178
199
|
id: str = None,
|
|
179
200
|
p_uuid: str = None,
|
|
180
201
|
name: str = "",
|
|
181
|
-
|
|
202
|
+
workorder: str = None,
|
|
182
203
|
created_at = None,
|
|
183
204
|
modified_at = None,
|
|
205
|
+
status: str = None,
|
|
206
|
+
priority: str = None,
|
|
207
|
+
owner: list = None,
|
|
208
|
+
tasks: list = None,
|
|
209
|
+
notion_page_id: str = None
|
|
184
210
|
) -> None:
|
|
185
211
|
"""Constructor method"""
|
|
186
212
|
logger.debug("Creating Project instance")
|
|
187
213
|
self.year = year
|
|
188
214
|
self.user_id = user_id
|
|
189
|
-
self.
|
|
215
|
+
self.workorder = workorder
|
|
190
216
|
self.name = name
|
|
191
217
|
self.created_at = created_at
|
|
192
218
|
self.modified_at = modified_at
|
|
219
|
+
self.status = status
|
|
220
|
+
self.priority = priority
|
|
221
|
+
self.owner = owner
|
|
222
|
+
self.tasks = tasks
|
|
223
|
+
self.notion_page_id = notion_page_id
|
|
193
224
|
if suffix is not None:
|
|
194
225
|
self.suffix = suffix
|
|
195
226
|
else:
|
|
@@ -207,7 +238,7 @@ class Project(Protocol):
|
|
|
207
238
|
self.id = f"P{self.year}-{self.user_id}-{self.suffix}"
|
|
208
239
|
else:
|
|
209
240
|
raise TypeError(
|
|
210
|
-
"ID is incorrectly formed, must similar to P2024-ABC-DEFG or P2024-AB1-DEFG"
|
|
241
|
+
f"ID '{id}' is incorrectly formed, must similar to P2024-ABC-DEFG or P2024-AB1-DEFG"
|
|
211
242
|
)
|
|
212
243
|
if p_uuid is not None and check_uuid(p_uuid):
|
|
213
244
|
self.p_uuid = p_uuid
|
|
@@ -220,14 +251,25 @@ class Project(Protocol):
|
|
|
220
251
|
self.p_uuid = str(uuid.uuid4())
|
|
221
252
|
logger.info(f"Project '{self.id}' instance created")
|
|
222
253
|
|
|
223
|
-
def
|
|
254
|
+
def __str__(self) -> str:
|
|
224
255
|
"""Machine-readable representation of class..
|
|
225
256
|
|
|
226
257
|
:return: basic Project() attrs.
|
|
227
258
|
:rtype: str
|
|
228
259
|
"""
|
|
229
|
-
logger.debug("Calling Project.
|
|
230
|
-
return
|
|
260
|
+
logger.debug("Calling Project.__str__ method")
|
|
261
|
+
return (
|
|
262
|
+
f"Project(\n"
|
|
263
|
+
f" id = {self.id},\n"
|
|
264
|
+
f" name = {self.name},\n"
|
|
265
|
+
f" year = {self.year},\n"
|
|
266
|
+
f" user_id = {self.user_id},\n"
|
|
267
|
+
f" priority = {self.priority}\n"
|
|
268
|
+
f" status = {self.status}\n"
|
|
269
|
+
f" owner = {self.owner}\n"
|
|
270
|
+
f" notion_page_id = {self.notion_page_id}\n"
|
|
271
|
+
f")"
|
|
272
|
+
)
|
|
231
273
|
|
|
232
274
|
def generate_suffix(self) -> str:
|
|
233
275
|
"""Generates a 4-character, uppercase, alphabetical suffix for a project, and
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Protocol, runtime_checkable
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
@runtime_checkable
|
|
8
|
+
class Task(Protocol):
|
|
9
|
+
"""This class represents a task and all of its associated metadata.
|
|
10
|
+
|
|
11
|
+
:param name: A short, descriptive task name, e.g. "Sort gene annotations".
|
|
12
|
+
If not supplied, defaults to None.
|
|
13
|
+
:type name: str, optional
|
|
14
|
+
:param project_id: The Project ID of the Project that this task belongs to.
|
|
15
|
+
Should match an existing Project ID, defaults to None.
|
|
16
|
+
:type project_id: str, optional
|
|
17
|
+
:param status: The status of the task, matching one of your Notion Status options
|
|
18
|
+
(e.g. "Not started", "In progress", "Completed"), defaults to None.
|
|
19
|
+
:type status: str, optional
|
|
20
|
+
:param priority: The priority level of the task, matching one of your Notion Select
|
|
21
|
+
options (e.g. "Low", "Standard", "Urgent"), defaults to None.
|
|
22
|
+
:type priority: str, optional
|
|
23
|
+
:param assigned_to: The name of the person assigned to the task.
|
|
24
|
+
Should correspond to a valid Notion user name, defaults to None.
|
|
25
|
+
:type assigned_to: str, optional
|
|
26
|
+
:param notion_page_id: The internal Notion page UUID for this task record.
|
|
27
|
+
:type notion_page_id: str, optional
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
name: str = None,
|
|
33
|
+
project_id: str = None,
|
|
34
|
+
status: str = None,
|
|
35
|
+
priority: str = "Standard",
|
|
36
|
+
assigned_to: str = None,
|
|
37
|
+
notion_page_id: str = None
|
|
38
|
+
) -> None:
|
|
39
|
+
"""Constructor method"""
|
|
40
|
+
logger.debug("Creating Task instance")
|
|
41
|
+
self.name = name
|
|
42
|
+
self.project_id = project_id
|
|
43
|
+
self.status = status
|
|
44
|
+
self.priority = priority
|
|
45
|
+
self.assigned_to = assigned_to
|
|
46
|
+
self.notion_page_id = notion_page_id
|
|
47
|
+
|
|
48
|
+
logger.info(f"Task: '{self.name} ({self.project_id})' instance created")
|
|
49
|
+
|
|
50
|
+
def __str__(self) -> str:
|
|
51
|
+
"""Machine-readable representation of class..
|
|
52
|
+
|
|
53
|
+
:return: basic Task() attrs.
|
|
54
|
+
:rtype: str
|
|
55
|
+
"""
|
|
56
|
+
logger.debug("Calling Task.__str__ method")
|
|
57
|
+
return (
|
|
58
|
+
f"Task(\n"
|
|
59
|
+
f" name = {self.name},\n"
|
|
60
|
+
f" project_id = {self.project_id},\n"
|
|
61
|
+
f" status = {self.status},\n"
|
|
62
|
+
f" priority = {self.priority},\n"
|
|
63
|
+
f" assigned_to = {self.assigned_to},\n"
|
|
64
|
+
f" notion_page_id = {self.notion_page_id}\n"
|
|
65
|
+
f")"
|
|
66
|
+
)
|