nci-cidc-api-modules 1.0.0rc0__tar.gz → 1.0.1__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.
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/PKG-INFO +48 -3
- nci_cidc_api_modules-1.0.0rc0/nci_cidc_api_modules.egg-info/PKG-INFO → nci_cidc_api_modules-1.0.1/README.md +29 -11
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/db.py +1 -1
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/secrets.py +2 -2
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/settings.py +1 -2
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/csms/auth.py +14 -7
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/csms_api.py +101 -83
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/files/details.py +28 -38
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/files/facets.py +41 -24
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/migrations.py +16 -9
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/models.py +763 -195
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/auth.py +18 -13
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/gcloud_client.py +106 -61
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/rest_utils.py +6 -5
- nci_cidc_api_modules-1.0.0rc0/README.md → nci_cidc_api_modules-1.0.1/nci_cidc_api_modules.egg-info/PKG-INFO +56 -1
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/requires.txt +1 -1
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/requirements.modules.txt +1 -2
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/setup.py +1 -1
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/LICENSE +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/MANIFEST.in +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/__init__.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/logging.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/csms/__init__.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/__init__.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/files/__init__.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/schemas.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/__init__.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/emails.py +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/SOURCES.txt +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/dependency_links.txt +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/not-zip-safe +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/top_level.txt +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/pyproject.toml +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/setup.cfg +0 -0
- {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/tests/test_api.py +0 -0
@@ -1,12 +1,29 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: nci_cidc_api_modules
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.1
|
4
4
|
Summary: SQLAlchemy data models and configuration tools used in the NCI CIDC API
|
5
5
|
Home-page: https://github.com/NCI-CIDC/cidc-api-gae
|
6
6
|
License: MIT license
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.9
|
8
8
|
Description-Content-Type: text/markdown
|
9
9
|
License-File: LICENSE
|
10
|
+
Requires-Dist: werkzeug==2.0.3
|
11
|
+
Requires-Dist: flask~=2.0.3
|
12
|
+
Requires-Dist: flask-migrate==2.5.2
|
13
|
+
Requires-Dist: flask-sqlalchemy~=2.4.0
|
14
|
+
Requires-Dist: sqlalchemy~=1.3.0
|
15
|
+
Requires-Dist: marshmallow==3.19.0
|
16
|
+
Requires-Dist: marshmallow-sqlalchemy==0.22.3
|
17
|
+
Requires-Dist: google-cloud-storage~=1.35.0
|
18
|
+
Requires-Dist: google-cloud-secret-manager==2.16.2
|
19
|
+
Requires-Dist: google-cloud-pubsub==0.43.0
|
20
|
+
Requires-Dist: google-cloud-bigquery==3.3.5
|
21
|
+
Requires-Dist: google-api-python-client==2.64.0
|
22
|
+
Requires-Dist: pandas<2,>=1
|
23
|
+
Requires-Dist: python-dotenv==0.10.3
|
24
|
+
Requires-Dist: requests==2.22.0
|
25
|
+
Requires-Dist: jinja2~=3.0.3
|
26
|
+
Requires-Dist: nci-cidc-schemas~=0.26.28
|
10
27
|
|
11
28
|
# NCI CIDC API <!-- omit in TOC -->
|
12
29
|
|
@@ -27,10 +44,11 @@ The next generation of the CIDC API, reworked to use Google Cloud-managed servic
|
|
27
44
|
- [Deploying by hand](#deploying-by-hand)
|
28
45
|
- [Connecting to the API](#connecting-to-the-api)
|
29
46
|
- [Provisioning the system from scratch](#provisioning-the-system-from-scratch)
|
47
|
+
- [Docker Compose](#setting-up-docker-compose)
|
30
48
|
|
31
49
|
## Install Python dependencies
|
32
50
|
|
33
|
-
Python versions tested include 3.
|
51
|
+
Python versions tested include 3.9 and 3.10. The current App Engine is using version 3.9 (see [app.prod.yaml](./app.prod.yaml)). You can use https://github.com/pyenv/pyenv to manage your python versions. Homebrew will also work, but you will have to be specific when you install packages with pip outside of virtual environments. On that note, it is recommended that you install your python dependencies in an isolated environment. For example,
|
34
52
|
|
35
53
|
```bash
|
36
54
|
# make a virtual environment in the current direcory called "venv"
|
@@ -284,6 +302,33 @@ To connect to the production API locally, follow the same procedure, but instead
|
|
284
302
|
|
285
303
|
For an overview of how to set up the CIDC API service from scratch, see the step-by-step guide in `PROVISION.md`.
|
286
304
|
|
305
|
+
## Setting up Docker Compose
|
306
|
+
|
307
|
+
If you would like to run this project as a docker container. We have dockerized the cidc-api-gae and cidc-ui so that you don't have to install all the requirements above. Included in the docker-compose file are postgres:14 with data and test user login, bigquery-emulator, fake-gcs-server with buckets and data to match postgres, and gcs-oauth2-emulator to generate faked presigned urls.
|
308
|
+
|
309
|
+
**_NOTE:_** You must have docker installed and have this repository and cidc-ui in the same directory (~/git/cidc/cidc-ui and ~/git/cidc/cidc-api-gae), or you can download each and build the image with the command `docker build .`
|
310
|
+
|
311
|
+
**_NOTE:_** Having issues with the cidc-ui docker container. You'll have to start that manually using the instructions in the repo.
|
312
|
+
|
313
|
+
**_NOTE:_** You can't use Docker while simultaneously running your NIH VPN. This is due to a quirk with self-hosting a google secrets bucket. More work is required to make the docker containers work while the VPN is on.
|
314
|
+
|
315
|
+
This repo has hot code reloading. However, you will need to build the image again if there is an update to python libraries. Make sure you don't use a cached image when rebuilding.
|
316
|
+
|
317
|
+
Make sure you add this line to your /etc/hosts file: ```127.0.0.1 host.docker.internal```
|
318
|
+
|
319
|
+
To run everything simply run the following commands:
|
320
|
+
```bash
|
321
|
+
vim .env # uncomment the docker section in the .env file. Comment out any overlaping variable defintions(POSTGRES)
|
322
|
+
cp ~/.config/gcloud/application_default_credentials.json .
|
323
|
+
cd docker
|
324
|
+
docker compose up
|
325
|
+
```
|
326
|
+
**_NOTE:_** You still need to install and signin to gcloud CLI. The application_default_credentials.json should be under the cidc-api-gae directory next to the Dockerfile. We have mocked most of the connection points to GCP but at startup it still checks for a valid user account. This is very similar behavior to aws's localstack. It requires a realistic token at the start even though it doesn't make connections to aws.
|
327
|
+
|
328
|
+
**_TODO:_** The application_default_credentials.json I think could be faked and pointed to the gcs-oauth2-emulator for startup. In this case a gcloud cli wouldnt be needed at all and a faked application_default_credentials.json could be uploaded under the docker folder.
|
329
|
+
|
330
|
+
|
331
|
+
|
287
332
|
## JIRA Integration
|
288
333
|
|
289
334
|
To set-up the git hook for JIRA integration, run:
|
@@ -1,13 +1,3 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: nci-cidc-api-modules
|
3
|
-
Version: 1.0.0rc0
|
4
|
-
Summary: SQLAlchemy data models and configuration tools used in the NCI CIDC API
|
5
|
-
Home-page: https://github.com/NCI-CIDC/cidc-api-gae
|
6
|
-
License: MIT license
|
7
|
-
Requires-Python: >=3.6
|
8
|
-
Description-Content-Type: text/markdown
|
9
|
-
License-File: LICENSE
|
10
|
-
|
11
1
|
# NCI CIDC API <!-- omit in TOC -->
|
12
2
|
|
13
3
|
The next generation of the CIDC API, reworked to use Google Cloud-managed services. This API is built with the Flask REST API framework backed by Google Cloud SQL, running on Google App Engine.
|
@@ -27,10 +17,11 @@ The next generation of the CIDC API, reworked to use Google Cloud-managed servic
|
|
27
17
|
- [Deploying by hand](#deploying-by-hand)
|
28
18
|
- [Connecting to the API](#connecting-to-the-api)
|
29
19
|
- [Provisioning the system from scratch](#provisioning-the-system-from-scratch)
|
20
|
+
- [Docker Compose](#setting-up-docker-compose)
|
30
21
|
|
31
22
|
## Install Python dependencies
|
32
23
|
|
33
|
-
Python versions tested include 3.
|
24
|
+
Python versions tested include 3.9 and 3.10. The current App Engine is using version 3.9 (see [app.prod.yaml](./app.prod.yaml)). You can use https://github.com/pyenv/pyenv to manage your python versions. Homebrew will also work, but you will have to be specific when you install packages with pip outside of virtual environments. On that note, it is recommended that you install your python dependencies in an isolated environment. For example,
|
34
25
|
|
35
26
|
```bash
|
36
27
|
# make a virtual environment in the current direcory called "venv"
|
@@ -284,6 +275,33 @@ To connect to the production API locally, follow the same procedure, but instead
|
|
284
275
|
|
285
276
|
For an overview of how to set up the CIDC API service from scratch, see the step-by-step guide in `PROVISION.md`.
|
286
277
|
|
278
|
+
## Setting up Docker Compose
|
279
|
+
|
280
|
+
If you would like to run this project as a docker container. We have dockerized the cidc-api-gae and cidc-ui so that you don't have to install all the requirements above. Included in the docker-compose file are postgres:14 with data and test user login, bigquery-emulator, fake-gcs-server with buckets and data to match postgres, and gcs-oauth2-emulator to generate faked presigned urls.
|
281
|
+
|
282
|
+
**_NOTE:_** You must have docker installed and have this repository and cidc-ui in the same directory (~/git/cidc/cidc-ui and ~/git/cidc/cidc-api-gae), or you can download each and build the image with the command `docker build .`
|
283
|
+
|
284
|
+
**_NOTE:_** Having issues with the cidc-ui docker container. You'll have to start that manually using the instructions in the repo.
|
285
|
+
|
286
|
+
**_NOTE:_** You can't use Docker while simultaneously running your NIH VPN. This is due to a quirk with self-hosting a google secrets bucket. More work is required to make the docker containers work while the VPN is on.
|
287
|
+
|
288
|
+
This repo has hot code reloading. However, you will need to build the image again if there is an update to python libraries. Make sure you don't use a cached image when rebuilding.
|
289
|
+
|
290
|
+
Make sure you add this line to your /etc/hosts file: ```127.0.0.1 host.docker.internal```
|
291
|
+
|
292
|
+
To run everything simply run the following commands:
|
293
|
+
```bash
|
294
|
+
vim .env # uncomment the docker section in the .env file. Comment out any overlaping variable defintions(POSTGRES)
|
295
|
+
cp ~/.config/gcloud/application_default_credentials.json .
|
296
|
+
cd docker
|
297
|
+
docker compose up
|
298
|
+
```
|
299
|
+
**_NOTE:_** You still need to install and signin to gcloud CLI. The application_default_credentials.json should be under the cidc-api-gae directory next to the Dockerfile. We have mocked most of the connection points to GCP but at startup it still checks for a valid user account. This is very similar behavior to aws's localstack. It requires a realistic token at the start even though it doesn't make connections to aws.
|
300
|
+
|
301
|
+
**_TODO:_** The application_default_credentials.json I think could be faked and pointed to the gcs-oauth2-emulator for startup. In this case a gcloud cli wouldnt be needed at all and a faked application_default_credentials.json could be uploaded under the docker folder.
|
302
|
+
|
303
|
+
|
304
|
+
|
287
305
|
## JIRA Integration
|
288
306
|
|
289
307
|
To set-up the git hook for JIRA integration, run:
|
@@ -52,7 +52,7 @@ def get_sqlalchemy_database_uri(testing: bool = False) -> str:
|
|
52
52
|
"host": f'{socket_dir}{environ.get("CLOUD_SQL_INSTANCE_NAME")}'
|
53
53
|
}
|
54
54
|
else:
|
55
|
-
raise
|
55
|
+
raise RuntimeError(
|
56
56
|
"Either POSTGRES_URI or CLOUD_SQL_INSTANCE_NAME must be defined to connect "
|
57
57
|
+ "to a database."
|
58
58
|
)
|
@@ -11,8 +11,8 @@ def get_secrets_manager(is_testing=False):
|
|
11
11
|
|
12
12
|
# If we're testing, we shouldn't need access to secrets in Secret Manager
|
13
13
|
return MagicMock()
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
return GoogleSecretManager()
|
16
16
|
|
17
17
|
|
18
18
|
class GoogleSecretManager:
|
@@ -21,10 +21,9 @@ DEV_USE_GCS = environ.get("DEV_USE_GCS") == "True"
|
|
21
21
|
assert ENV in (
|
22
22
|
"dev",
|
23
23
|
"dev-int",
|
24
|
-
"featuredev",
|
25
24
|
"staging",
|
26
25
|
"prod",
|
27
|
-
), "ENV environment variable must be set to 'dev', 'dev-int', '
|
26
|
+
), "ENV environment variable must be set to 'dev', 'dev-int', 'staging', or 'prod'"
|
28
27
|
DEBUG = environ.get("DEBUG") == "True"
|
29
28
|
assert ENV == "dev" if DEBUG else True, "DEBUG mode is only allowed when ENV='dev'"
|
30
29
|
TESTING = environ.get("TESTING") == "True"
|
@@ -1,9 +1,9 @@
|
|
1
1
|
__all__ = ["get_token", "get_with_authorization", "get_with_paging"]
|
2
|
-
import os
|
3
2
|
|
4
|
-
os
|
3
|
+
import os
|
5
4
|
from datetime import datetime, timedelta
|
6
5
|
from typing import Any, Dict, Iterator
|
6
|
+
|
7
7
|
import requests
|
8
8
|
|
9
9
|
from ..config.settings import (
|
@@ -13,7 +13,9 @@ from ..config.settings import (
|
|
13
13
|
CSMS_TOKEN_URL,
|
14
14
|
)
|
15
15
|
|
16
|
+
os.environ["TZ"] = "UTC"
|
16
17
|
|
18
|
+
TIMEOUT_IN_SECONDS = 20
|
17
19
|
_TOKEN, _TOKEN_EXPIRY = None, datetime.now()
|
18
20
|
|
19
21
|
|
@@ -29,13 +31,14 @@ def get_token():
|
|
29
31
|
"client_id": CSMS_CLIENT_ID,
|
30
32
|
"client_secret": CSMS_CLIENT_SECRET,
|
31
33
|
},
|
34
|
+
timeout=TIMEOUT_IN_SECONDS,
|
32
35
|
).json(),
|
33
36
|
datetime.now(),
|
34
37
|
)
|
35
38
|
|
36
39
|
# res definition from https://developer.okta.com/docs/reference/api/oidc/#response-example-error-7
|
37
40
|
if "errorCode" in res:
|
38
|
-
raise
|
41
|
+
raise RuntimeError(res["errorCode"] + ": " + res.get("errorSummary"))
|
39
42
|
|
40
43
|
_TOKEN = res["access_token"]
|
41
44
|
_TOKEN_EXPIRY = time + timedelta(seconds=res["expires_in"])
|
@@ -54,7 +57,11 @@ def get_with_authorization(url: str, **kwargs) -> requests.Response:
|
|
54
57
|
kwargs["headers"] = headers
|
55
58
|
if not url.startswith(CSMS_BASE_URL):
|
56
59
|
url = CSMS_BASE_URL + url
|
57
|
-
return requests.get(
|
60
|
+
return requests.get(
|
61
|
+
url,
|
62
|
+
**kwargs,
|
63
|
+
timeout=TIMEOUT_IN_SECONDS,
|
64
|
+
)
|
58
65
|
|
59
66
|
|
60
67
|
def get_with_paging(
|
@@ -88,7 +95,7 @@ def get_with_paging(
|
|
88
95
|
else:
|
89
96
|
limit = 1
|
90
97
|
|
91
|
-
kwargs.update(
|
98
|
+
kwargs.update({"limit": limit, "offset": offset})
|
92
99
|
|
93
100
|
res = get_with_authorization(url, params=kwargs)
|
94
101
|
while res.status_code < 300 and len(res.json().get("data", [])) > 0:
|
@@ -96,5 +103,5 @@ def get_with_paging(
|
|
96
103
|
yield from res.json()["data"]
|
97
104
|
kwargs["offset"] += 1 # get the next page
|
98
105
|
res = get_with_authorization(url, params=kwargs)
|
99
|
-
|
100
|
-
|
106
|
+
|
107
|
+
res.raise_for_status()
|