papi-projects 0.1.4__tar.gz → 0.1.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: papi-projects
3
- Version: 0.1.4
3
+ Version: 0.1.7
4
4
  Summary: PAPI is an API for managing projects
5
5
  License: MIT
6
6
  Author: sandyjmacdonald
@@ -20,7 +20,7 @@ PAPI is an API for managing projects.
20
20
 
21
21
  <img src="https://imgur.com/lprJ3mP.jpg" alt="HAHA BUSINESS meme" height="250">
22
22
 
23
- 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 Asana and Toggl Track, two tools we use for project management and time tracking, respectively.
23
+ 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 Asana and Notion, and Toggl Track, tools we use for project management and time tracking, respectively.
24
24
 
25
25
  Much of the functionality is tailor-made to the way we manage projects in our group, but make of it what you will!
26
26
 
@@ -58,9 +58,14 @@ ASANA_TEAM="My Team Name"
58
58
  TOGGL_TRACK_API_KEY="YOURAPIKEY"
59
59
  TOGGL_TRACK_PASSWORD="api_token"
60
60
  TOGGL_TRACK_WORKSPACE="My Workspace Name"
61
+
62
+ # Notion config
63
+ NOTION_API_SECRET = "YOURAPISECRET"
64
+ NOTION_CLIENTS_DB = "notionclientsdbid"
65
+ NOTION_PROJECTS_DB = "notionprojectsdbid"
61
66
  ```
62
67
 
63
- 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 Asana and Toggl Track accounts.
68
+ 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.
64
69
 
65
70
  This .env file can either be put in your working directory or in the top-level papi module folder wherever it is installed.
66
71
 
@@ -68,41 +73,48 @@ Alternatively, these values can be hard-coded in your scripts, but this is not a
68
73
 
69
74
  ## CLI scripts
70
75
 
71
- Two convenience CLI scripts are provided for common Toggl Track tasks. They are:
76
+ Convenience CLI scripts are provided for some common tasks. They are:
72
77
 
73
- ## create-toggl-project
78
+ ### create-toggl-project
74
79
 
75
80
  This script creates a project ID if necessary, and adds the project to your Toggl Track:
76
81
 
77
82
  ```
78
- usage: create-toggl-project [-h] [-u USER_ID] [-g GRANT_CODE] [-n NAME] [-p PROJECT_ID]
83
+ usage: create-toggl-project [-h] [-u USER_ID] [-g GRANT_CODE] [-n NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
84
+ [--log-file LOG_FILE]
79
85
 
80
86
  options:
81
87
  -h, --help show this help message and exit
82
88
  -u USER_ID, --user_id USER_ID
83
- three-letter user ID, e.g. CRD
89
+ three-letter user ID, e.g. JAS
84
90
  -g GRANT_CODE, --grant_code GRANT_CODE
85
91
  grant code, e.g. R12345
86
92
  -n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
87
93
  -p PROJECT_ID, --project_id PROJECT_ID
88
- full project ID, e.g. P2024-ABC-DEFG, if already generated
94
+ full project ID, e.g. P2024-JAS-ABCD, if already generated
95
+ --enable-logging enable logging output for the papi library
96
+ --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
97
+ set the logging level (default: INFO)
98
+ --log-file LOG_FILE path to a file where logs should be written
89
99
  ```
90
100
 
91
101
  Ideally, a three-character user ID, grant code, and short project name will be provided, and PAPI will generate the project ID, e.g.
92
102
 
93
103
  ```
94
- create-toggl-project -u CRD -g R12345 -n 'Such project. Wow.'
104
+ create-toggl-project -u JAS -g R12345 -n 'Such project. Wow.'
95
105
  ```
96
106
 
97
107
  If a project ID has already been created, then it can be provided via the `-p` argument and the user ID is not necessary, e.g.
98
108
 
99
109
  ```
100
- create-toggl-project -p P2024-CRD-ABCD -g R12345 -n 'Such project. Wow.'
110
+ create-toggl-project -p P2024-JAS-ABCD -g R12345 -n 'Such project. Wow.'
101
111
  ```
102
112
 
103
113
  The grant code (`-g`) and name (`-n`) are not required, but either a project ID (`-p`) or user ID (`-u`) _is_ necessary.
104
114
 
105
- ## collate-toggl-hours
115
+ Logging can also be enabled at various levels of detail, and logs can be saved to a file.
116
+
117
+ ### collate-toggl-hours
106
118
 
107
119
  This script collates and returns your Toggl Track hours tracked over a specified time period:
108
120
 
@@ -130,11 +142,75 @@ To collate your hours worked in August 2024:
130
142
  collate-toggl-hours -s 2024-08-01 -e 2024-08-31 -o august-2024-hours.tsv
131
143
  ```
132
144
 
145
+ ### create-notion-project
146
+
147
+ This script creates a project ID if necessary, and adds the project to the Notion projects database:
148
+
149
+ ```
150
+ usage: create-notion-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
151
+ [--log-file LOG_FILE]
152
+
153
+ options:
154
+ -h, --help show this help message and exit
155
+ -u USER_ID, --user_id USER_ID
156
+ three-letter user (client) ID, e.g. JAS
157
+ -v USER_NAME, --user_name USER_NAME
158
+ user (client) name, e.g. John Andrew Smith
159
+ -n NAME, --name NAME short project name, e.g. 'RNA-seq analysis', project ID will be auto-generated
160
+ -p PROJECT_ID, --project_id PROJECT_ID
161
+ full project ID, e.g. P2024-JAS-ABCD, if already generated
162
+ --enable-logging enable logging output for the papi library
163
+ --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
164
+ set the logging level (default: INFO)
165
+ --log-file LOG_FILE path to a file where logs should be written
166
+ ```
167
+
168
+ Similar to the `create-toggl-project` script, you can simply provide a three-character user ID and a short project name, and PAPI will generate the project ID, e.g.
169
+
170
+ ```
171
+ create-notion-project -u JAS -n 'Such project. Wow.'
172
+ ```
173
+
174
+ If a project ID has already been created, then it can be provided via the `-p` argument and the user ID is not necessary, e.g.
175
+
176
+ ```
177
+ create-notion-project -p P2024-JAS-ABCD -n 'Such project. Wow.'
178
+ ```
179
+
180
+ Logging can also be enabled at various levels of detail, and logs can be saved to a file.
181
+
182
+ ### create-project
183
+
184
+ This script can create a project on Toggl Track or Notion, or both:
185
+
186
+ ```
187
+ usage: create-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--enable-toggl] [--enable-notion] [--enable-logging]
188
+ [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
189
+
190
+ options:
191
+ -h, --help show this help message and exit
192
+ -u USER_ID, --user_id USER_ID
193
+ three-letter user (client) ID, e.g. JAS
194
+ -v USER_NAME, --user_name USER_NAME
195
+ user (client) name, e.g. John Andrew Smith
196
+ -n NAME, --name NAME short project name, e.g. 'RNA-seq analysis', project ID will be auto-generated
197
+ -p PROJECT_ID, --project_id PROJECT_ID
198
+ full project ID, e.g. P2024-JAS-DEFG, if already generated
199
+ --enable-toggl create Toggl Track project
200
+ --enable-notion create Notion project
201
+ --enable-logging enable logging output for the papi library
202
+ --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
203
+ set the logging level (default: INFO)
204
+ --log-file LOG_FILE path to a file where logs should be written
205
+ ```
206
+
207
+ If no arguments are given to the script, i.e. just running `create-project`, then interactive prompts are shown to enter the necessary arguments.
208
+
133
209
  ## API reference
134
210
 
135
- ## project module
211
+ ### project module
136
212
 
137
- ## Project class
213
+ ### Project class
138
214
 
139
215
  The `Project` class is central to the whole library. A `Project` instance can be created in a few different ways.
140
216
 
@@ -143,7 +219,7 @@ At the most basic level, a valid `user_id` (either three letter initials or two
143
219
  ```
144
220
  from papi.project import Project
145
221
 
146
- proj = Project(user_id="CRD")
222
+ proj = Project(user_id="JAS")
147
223
  ```
148
224
 
149
225
  This will generate the project ID, `id` attribute using the current year, and a random four-letter suffix.
@@ -155,15 +231,15 @@ print(proj.suffix)
155
231
  ```
156
232
 
157
233
  ```
158
- P2024-CRD-FZLL
234
+ P2024-JAS-ABCD
159
235
  2024
160
- FZLL
236
+ ABCD
161
237
  ```
162
238
 
163
239
  If a valid project ID has already been created, then a `Project` instance can be instantiated with the `id` attribute, and the `year`, `user_id`, and `suffix` attributes will be pulled out and set on the instance.
164
240
 
165
241
  ```
166
- proj = Project(id="P2024-CRD-FZLL")
242
+ proj = Project(id="P2024-JAS-ABCD")
167
243
 
168
244
  print(proj.year)
169
245
  print(proj.user_id)
@@ -172,20 +248,20 @@ print(proj.suffix)
172
248
 
173
249
  ```
174
250
  2024
175
- CRD
176
- FZLL
251
+ JAS
252
+ ABCD
177
253
  ```
178
254
 
179
255
  If a grant code and/or project name are available, then these can be passed in when instantiating the class.
180
256
 
181
257
  ```
182
- proj = Project(user_id="CRD", grant_code="R12345", name="RNA-seq analysis")
258
+ proj = Project(user_id="JAS", grant_code="R12345", name="RNA-seq analysis")
183
259
  ```
184
260
 
185
261
  A version 4 UUID is also generated for the project when instantiated.
186
262
 
187
263
  ```
188
- proj = Project(user_id="CRD")
264
+ proj = Project(user_id="JAS")
189
265
 
190
266
  print(proj.p_uuid)
191
267
  ```
@@ -197,10 +273,10 @@ print(proj.p_uuid)
197
273
  Or if a version 4 UUID has been generated separately then it can be provided when instantiating.
198
274
 
199
275
  ```
200
- proj = Project(user_id="CRD", p_uuid="6697e457-9785-4668-b78b-72616b27aede")
276
+ proj = Project(user_id="JAS", p_uuid="6697e457-9785-4668-b78b-72616b27aede")
201
277
  ```
202
278
 
203
- ## project functions
279
+ ### project functions
204
280
 
205
281
  A couple of functions are provided to check the validity of a project ID, to check the validity of a suffix, and to check for a valid version 4 UUID.
206
282
 
@@ -209,8 +285,8 @@ You can check the validity of a project ID as follows:
209
285
  ```
210
286
  from papi.project import check_project_id
211
287
 
212
- print(check_project_id("P2024-CRD-FZLL"))
213
- print(check_project_id("P2024-CRD-1234"))
288
+ print(check_project_id("P2024-JAS-ABCD"))
289
+ print(check_project_id("P2024-JAS-1234"))
214
290
  ```
215
291
 
216
292
  ```
@@ -223,7 +299,59 @@ You can check the validity of a project suffix as follows:
223
299
  ```
224
300
  from papi.project import check_suffix
225
301
 
226
- print(check_suffix("FZLL"))
302
+ print(check_suffix("ABCD"))
227
303
  print(check_suffix("1234"))
228
304
  ```
229
305
 
306
+ ```
307
+ True
308
+ False
309
+ ```
310
+
311
+ ### user module
312
+
313
+ ### User class
314
+
315
+ The `User` class stores attributes of a user: their name, a three-letter initial (or two-letter initial and integer number from 1 to 9), and an optional email address.
316
+
317
+ The most basic way of instantiating a `User` instance is as follows:
318
+
319
+ ```
320
+ from papi.user import User
321
+
322
+ usr = User("John Andrew Smith")
323
+
324
+ print(usr.user_id)
325
+ print(usr.user_name)
326
+ ```
327
+
328
+ ```
329
+ JAS
330
+ John Andrew Smith
331
+ ```
332
+
333
+ The first initials are converted into the `user_id` attribute.
334
+
335
+ If an email address is available, then this can be provided when instantiating:
336
+
337
+ ```
338
+ from papi.user import User
339
+
340
+ usr = User("John Andrew Smith", email="jasmith@email.com")
341
+
342
+ print(usr.email)
343
+ ```
344
+
345
+ ```
346
+ jasmith@email.com
347
+ ```
348
+
349
+ Because our user ID naming scheme enforces that a user ID must be unique, the `user_id` attribute should not really be set directly, although it can in theory:
350
+
351
+ ```
352
+ usr = User("John Smith")
353
+ usr.user_id = "JS1"
354
+ ```
355
+
356
+ Setting the `user_id` attribute creates the possibility of a clash in user IDs, therefore the `user` module provides a means to create a basic user database with the TinyDB library. This avoids the possibility of a clash and appends and increments integer numbers to the end of the user ID if a matching one is already in the database.
357
+
@@ -0,0 +1,338 @@
1
+ PAPI is an API for managing projects.
2
+
3
+ <img src="https://imgur.com/lprJ3mP.jpg" alt="HAHA BUSINESS meme" height="250">
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 Asana and Notion, and Toggl Track, tools we use for project management and time tracking, respectively.
6
+
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
+
9
+ ## Installation
10
+
11
+ The simplest way to install this is to do as follows:
12
+
13
+ ```
14
+ pip install papi-projects
15
+ ```
16
+
17
+ You can also install the Poetry packaging and dependency tool and then clone this repository and install with poetry, as follows:
18
+
19
+ ```
20
+ pipx install poetry
21
+ git clone https://github.com/sandyjmacdonald/papi
22
+ cd papi
23
+ poetry install
24
+ ```
25
+
26
+ ## Environment variables
27
+
28
+ The Asana 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
+
30
+ The .env file should look as follows:
31
+
32
+ ```
33
+ # Asana config:
34
+ ASANA_API_KEY="YOURAPIKEY"
35
+ ASANA_PASSWORD=""
36
+ ASANA_WORKSPACE="myworkspace"
37
+ ASANA_TEAM="My Team Name"
38
+
39
+ # toggl track config:
40
+ TOGGL_TRACK_API_KEY="YOURAPIKEY"
41
+ TOGGL_TRACK_PASSWORD="api_token"
42
+ TOGGL_TRACK_WORKSPACE="My Workspace Name"
43
+
44
+ # Notion config
45
+ NOTION_API_SECRET = "YOURAPISECRET"
46
+ NOTION_CLIENTS_DB = "notionclientsdbid"
47
+ NOTION_PROJECTS_DB = "notionprojectsdbid"
48
+ ```
49
+
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
+ This .env file can either be put in your working directory or in the top-level papi module folder wherever it is installed.
53
+
54
+ Alternatively, these values can be hard-coded in your scripts, but this is not advised and will not work with the CLI scripts provided.
55
+
56
+ ## CLI scripts
57
+
58
+ Convenience CLI scripts are provided for some common tasks. They are:
59
+
60
+ ### create-toggl-project
61
+
62
+ This script creates a project ID if necessary, and adds the project to your Toggl Track:
63
+
64
+ ```
65
+ usage: create-toggl-project [-h] [-u USER_ID] [-g GRANT_CODE] [-n NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
66
+ [--log-file LOG_FILE]
67
+
68
+ options:
69
+ -h, --help show this help message and exit
70
+ -u USER_ID, --user_id USER_ID
71
+ three-letter user ID, e.g. JAS
72
+ -g GRANT_CODE, --grant_code GRANT_CODE
73
+ grant code, e.g. R12345
74
+ -n NAME, --name NAME short project name, e.g. 'RNA-seq analysis'
75
+ -p PROJECT_ID, --project_id PROJECT_ID
76
+ full project ID, e.g. P2024-JAS-ABCD, if already generated
77
+ --enable-logging enable logging output for the papi library
78
+ --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
79
+ set the logging level (default: INFO)
80
+ --log-file LOG_FILE path to a file where logs should be written
81
+ ```
82
+
83
+ Ideally, a three-character user ID, grant code, and short project name will be provided, and PAPI will generate the project ID, e.g.
84
+
85
+ ```
86
+ create-toggl-project -u JAS -g R12345 -n 'Such project. Wow.'
87
+ ```
88
+
89
+ If a project ID has already been created, then it can be provided via the `-p` argument and the user ID is not necessary, e.g.
90
+
91
+ ```
92
+ create-toggl-project -p P2024-JAS-ABCD -g R12345 -n 'Such project. Wow.'
93
+ ```
94
+
95
+ The grant code (`-g`) and name (`-n`) are not required, but either a project ID (`-p`) or user ID (`-u`) _is_ necessary.
96
+
97
+ Logging can also be enabled at various levels of detail, and logs can be saved to a file.
98
+
99
+ ### collate-toggl-hours
100
+
101
+ This script collates and returns your Toggl Track hours tracked over a specified time period:
102
+
103
+ ```
104
+ usage: collate-toggl-hours [-h] -s START [-e END] [-o OUTPUT]
105
+
106
+ options:
107
+ -h, --help show this help message and exit
108
+ -s START, --start START
109
+ start date in YYYY-MM-DD format
110
+ -e END, --end END end date in YYYY-MM-DD format, if none supplied then end date is now
111
+ -o OUTPUT, --output OUTPUT
112
+ output TSV filename, omit to write to stdout
113
+ ```
114
+
115
+ This script collates your tracked hours for any projects worked during a given time period and return the project name and decimal number of hours in tab-separated format.
116
+
117
+ If an output filename is provided, then the resulting hours are saved to that file, otherwise they are printed to stdout.
118
+
119
+ If no end date (`-e`) is provided, then the end date is the current time/date.
120
+
121
+ To collate your hours worked in August 2024:
122
+
123
+ ```
124
+ collate-toggl-hours -s 2024-08-01 -e 2024-08-31 -o august-2024-hours.tsv
125
+ ```
126
+
127
+ ### create-notion-project
128
+
129
+ This script creates a project ID if necessary, and adds the project to the Notion projects database:
130
+
131
+ ```
132
+ usage: create-notion-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--enable-logging] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
133
+ [--log-file LOG_FILE]
134
+
135
+ options:
136
+ -h, --help show this help message and exit
137
+ -u USER_ID, --user_id USER_ID
138
+ three-letter user (client) ID, e.g. JAS
139
+ -v USER_NAME, --user_name USER_NAME
140
+ user (client) name, e.g. John Andrew Smith
141
+ -n NAME, --name NAME short project name, e.g. 'RNA-seq analysis', project ID will be auto-generated
142
+ -p PROJECT_ID, --project_id PROJECT_ID
143
+ full project ID, e.g. P2024-JAS-ABCD, if already generated
144
+ --enable-logging enable logging output for the papi library
145
+ --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
146
+ set the logging level (default: INFO)
147
+ --log-file LOG_FILE path to a file where logs should be written
148
+ ```
149
+
150
+ Similar to the `create-toggl-project` script, you can simply provide a three-character user ID and a short project name, and PAPI will generate the project ID, e.g.
151
+
152
+ ```
153
+ create-notion-project -u JAS -n 'Such project. Wow.'
154
+ ```
155
+
156
+ If a project ID has already been created, then it can be provided via the `-p` argument and the user ID is not necessary, e.g.
157
+
158
+ ```
159
+ create-notion-project -p P2024-JAS-ABCD -n 'Such project. Wow.'
160
+ ```
161
+
162
+ Logging can also be enabled at various levels of detail, and logs can be saved to a file.
163
+
164
+ ### create-project
165
+
166
+ This script can create a project on Toggl Track or Notion, or both:
167
+
168
+ ```
169
+ usage: create-project [-h] [-u USER_ID] [-v USER_NAME] [-n NAME] [-p PROJECT_ID] [--enable-toggl] [--enable-notion] [--enable-logging]
170
+ [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--log-file LOG_FILE]
171
+
172
+ options:
173
+ -h, --help show this help message and exit
174
+ -u USER_ID, --user_id USER_ID
175
+ three-letter user (client) ID, e.g. JAS
176
+ -v USER_NAME, --user_name USER_NAME
177
+ user (client) name, e.g. John Andrew Smith
178
+ -n NAME, --name NAME short project name, e.g. 'RNA-seq analysis', project ID will be auto-generated
179
+ -p PROJECT_ID, --project_id PROJECT_ID
180
+ full project ID, e.g. P2024-JAS-DEFG, if already generated
181
+ --enable-toggl create Toggl Track project
182
+ --enable-notion create Notion project
183
+ --enable-logging enable logging output for the papi library
184
+ --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
185
+ set the logging level (default: INFO)
186
+ --log-file LOG_FILE path to a file where logs should be written
187
+ ```
188
+
189
+ If no arguments are given to the script, i.e. just running `create-project`, then interactive prompts are shown to enter the necessary arguments.
190
+
191
+ ## API reference
192
+
193
+ ### project module
194
+
195
+ ### Project class
196
+
197
+ The `Project` class is central to the whole library. A `Project` instance can be created in a few different ways.
198
+
199
+ At the most basic level, a valid `user_id` (either three letter initials or two letter initials and an integer number from 1 to 9) can be provided when instantiating the class, and the prefix and suffix will be generated.
200
+
201
+ ```
202
+ from papi.project import Project
203
+
204
+ proj = Project(user_id="JAS")
205
+ ```
206
+
207
+ This will generate the project ID, `id` attribute using the current year, and a random four-letter suffix.
208
+
209
+ ```
210
+ print(proj.id)
211
+ print(proj.year)
212
+ print(proj.suffix)
213
+ ```
214
+
215
+ ```
216
+ P2024-JAS-ABCD
217
+ 2024
218
+ ABCD
219
+ ```
220
+
221
+ If a valid project ID has already been created, then a `Project` instance can be instantiated with the `id` attribute, and the `year`, `user_id`, and `suffix` attributes will be pulled out and set on the instance.
222
+
223
+ ```
224
+ proj = Project(id="P2024-JAS-ABCD")
225
+
226
+ print(proj.year)
227
+ print(proj.user_id)
228
+ print(proj.suffix)
229
+ ```
230
+
231
+ ```
232
+ 2024
233
+ JAS
234
+ ABCD
235
+ ```
236
+
237
+ If a grant code and/or project name are available, then these can be passed in when instantiating the class.
238
+
239
+ ```
240
+ proj = Project(user_id="JAS", grant_code="R12345", name="RNA-seq analysis")
241
+ ```
242
+
243
+ A version 4 UUID is also generated for the project when instantiated.
244
+
245
+ ```
246
+ proj = Project(user_id="JAS")
247
+
248
+ print(proj.p_uuid)
249
+ ```
250
+
251
+ ```
252
+ 6697e457-9785-4668-b78b-72616b27aede
253
+ ```
254
+
255
+ Or if a version 4 UUID has been generated separately then it can be provided when instantiating.
256
+
257
+ ```
258
+ proj = Project(user_id="JAS", p_uuid="6697e457-9785-4668-b78b-72616b27aede")
259
+ ```
260
+
261
+ ### project functions
262
+
263
+ A couple of functions are provided to check the validity of a project ID, to check the validity of a suffix, and to check for a valid version 4 UUID.
264
+
265
+ You can check the validity of a project ID as follows:
266
+
267
+ ```
268
+ from papi.project import check_project_id
269
+
270
+ print(check_project_id("P2024-JAS-ABCD"))
271
+ print(check_project_id("P2024-JAS-1234"))
272
+ ```
273
+
274
+ ```
275
+ True
276
+ False
277
+ ```
278
+
279
+ You can check the validity of a project suffix as follows:
280
+
281
+ ```
282
+ from papi.project import check_suffix
283
+
284
+ print(check_suffix("ABCD"))
285
+ print(check_suffix("1234"))
286
+ ```
287
+
288
+ ```
289
+ True
290
+ False
291
+ ```
292
+
293
+ ### user module
294
+
295
+ ### User class
296
+
297
+ The `User` class stores attributes of a user: their name, a three-letter initial (or two-letter initial and integer number from 1 to 9), and an optional email address.
298
+
299
+ The most basic way of instantiating a `User` instance is as follows:
300
+
301
+ ```
302
+ from papi.user import User
303
+
304
+ usr = User("John Andrew Smith")
305
+
306
+ print(usr.user_id)
307
+ print(usr.user_name)
308
+ ```
309
+
310
+ ```
311
+ JAS
312
+ John Andrew Smith
313
+ ```
314
+
315
+ The first initials are converted into the `user_id` attribute.
316
+
317
+ If an email address is available, then this can be provided when instantiating:
318
+
319
+ ```
320
+ from papi.user import User
321
+
322
+ usr = User("John Andrew Smith", email="jasmith@email.com")
323
+
324
+ print(usr.email)
325
+ ```
326
+
327
+ ```
328
+ jasmith@email.com
329
+ ```
330
+
331
+ Because our user ID naming scheme enforces that a user ID must be unique, the `user_id` attribute should not really be set directly, although it can in theory:
332
+
333
+ ```
334
+ usr = User("John Smith")
335
+ usr.user_id = "JS1"
336
+ ```
337
+
338
+ Setting the `user_id` attribute creates the possibility of a clash in user IDs, therefore the `user` module provides a means to create a basic user database with the TinyDB library. This avoids the possibility of a clash and appends and increments integer numbers to the end of the user ID if a matching one is already in the database.
@@ -0,0 +1,48 @@
1
+ import os
2
+ import logging
3
+ from dotenv import dotenv_values
4
+
5
+ dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
6
+ config = dotenv_values(dotenv_path)
7
+
8
+ ASANA_API_KEY = config["ASANA_API_KEY"]
9
+ ASANA_PASSWORD = config["ASANA_PASSWORD"]
10
+
11
+ TOGGL_TRACK_API_KEY = config["TOGGL_TRACK_API_KEY"]
12
+ TOGGL_TRACK_PASSWORD = config["TOGGL_TRACK_PASSWORD"]
13
+
14
+ NOTION_API_SECRET = config["NOTION_API_SECRET"]
15
+ NOTION_CLIENTS_DB = config["NOTION_CLIENTS_DB"]
16
+ NOTION_PROJECTS_DB = config["NOTION_PROJECTS_DB"]
17
+
18
+ def setup_logger(enable_logging: bool, log_level: str = 'INFO', log_file: str = None):
19
+ logger = logging.getLogger('papi')
20
+
21
+ if enable_logging:
22
+ # Convert log_level string to logging level
23
+ numeric_level = getattr(logging, log_level.upper(), logging.INFO)
24
+ logger.setLevel(numeric_level)
25
+
26
+ # Create handler
27
+ if log_file:
28
+ handler = logging.FileHandler(log_file)
29
+ else:
30
+ handler = logging.StreamHandler()
31
+
32
+ handler.setLevel(numeric_level)
33
+
34
+ # Create formatter
35
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
36
+ handler.setFormatter(formatter)
37
+
38
+ # Add handler to logger if not already added
39
+ if not logger.handlers:
40
+ logger.addHandler(handler)
41
+
42
+ # Prevent propagation to root logger
43
+ logger.propagate = False
44
+ else:
45
+ # Set a higher log level to suppress lower-level logs
46
+ logger.setLevel(logging.WARNING)
47
+
48
+ return logger
@@ -1,5 +1,7 @@
1
1
  import random
2
+ import logging
2
3
 
4
+ logger = logging.getLogger(__name__)
3
5
 
4
6
  def random_number(length):
5
7
  return "".join([str(random.randint(1, 9)) for i in range(length)])