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.
Files changed (35) hide show
  1. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/PKG-INFO +48 -3
  2. 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
  3. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/db.py +1 -1
  4. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/secrets.py +2 -2
  5. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/settings.py +1 -2
  6. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/csms/auth.py +14 -7
  7. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/csms_api.py +101 -83
  8. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/files/details.py +28 -38
  9. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/files/facets.py +41 -24
  10. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/migrations.py +16 -9
  11. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/models.py +763 -195
  12. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/auth.py +18 -13
  13. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/gcloud_client.py +106 -61
  14. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/rest_utils.py +6 -5
  15. 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
  16. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/requires.txt +1 -1
  17. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/requirements.modules.txt +1 -2
  18. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/setup.py +1 -1
  19. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/LICENSE +0 -0
  20. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/MANIFEST.in +0 -0
  21. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/__init__.py +0 -0
  22. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/config/logging.py +0 -0
  23. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/csms/__init__.py +0 -0
  24. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/__init__.py +0 -0
  25. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/files/__init__.py +0 -0
  26. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/models/schemas.py +0 -0
  27. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/__init__.py +0 -0
  28. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/cidc_api/shared/emails.py +0 -0
  29. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/nci_cidc_api_modules.egg-info/SOURCES.txt +0 -0
  30. {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
  31. {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
  32. {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
  33. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/pyproject.toml +0 -0
  34. {nci_cidc_api_modules-1.0.0rc0 → nci_cidc_api_modules-1.0.1}/setup.cfg +0 -0
  35. {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.0rc0
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.6
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.7, 3.8, and 3.9. The current App Engine is using version 3.7 (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,
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.7, 3.8, and 3.9. The current App Engine is using version 3.7 (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,
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 Exception(
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
- else:
15
- return GoogleSecretManager()
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', 'featuredev', 'staging', or 'prod'"
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.environ["TZ"] = "UTC"
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 Exception(res["errorCode"] + ": " + res.get("errorSummary"))
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(url, **kwargs)
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(dict(limit=limit, offset=offset))
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
- else:
100
- res.raise_for_status()
106
+
107
+ res.raise_for_status()