{"id":28395220,"url":"https://github.com/databiosphere/bond","last_synced_at":"2025-09-02T10:43:59.938Z","repository":{"id":37905237,"uuid":"135297095","full_name":"DataBiosphere/bond","owner":"DataBiosphere","description":"Account linking service","archived":true,"fork":false,"pushed_at":"2024-02-07T20:53:47.000Z","size":446,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":20,"default_branch":"develop","last_synced_at":"2025-06-27T01:38:26.051Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DataBiosphere.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-05-29T13:04:06.000Z","updated_at":"2024-09-03T16:23:33.000Z","dependencies_parsed_at":"2025-06-27T01:31:42.919Z","dependency_job_id":"05867f41-5313-492d-96b7-b1cdba4f6f65","html_url":"https://github.com/DataBiosphere/bond","commit_stats":null,"previous_names":[],"tags_count":184,"template":false,"template_full_name":null,"purl":"pkg:github/DataBiosphere/bond","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataBiosphere%2Fbond","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataBiosphere%2Fbond/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataBiosphere%2Fbond/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataBiosphere%2Fbond/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DataBiosphere","download_url":"https://codeload.github.com/DataBiosphere/bond/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataBiosphere%2Fbond/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273272554,"owners_count":25075982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-31T19:39:33.053Z","updated_at":"2025-09-02T10:43:59.901Z","avatar_url":"https://github.com/DataBiosphere.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bond\n\nService for linking [Sam](https://github.com/broadinstitute/sam) User accounts with registered 3rd party services via\nOauth2. Bond is a Flask application written in Python 3.9 deployed on Google App Engine.\n\n# Swagger/OpenAPI Interface\n\nThe only user interface that Bond makes available is a Swagger UI for directly interacting with its endpoints.  The UI \ncan be reached at the path:\n\n`http://{your_host}/api/docs/`\n\nFor example: https://broad-bond-dev.appspot.com/api/docs/\n\n## Authorization \nFor endpoints that require authorization, you will need a Google Access Token that you can generate using the \n[gcloud](https://cloud.google.com/sdk/gcloud) command:\n\n`gcloud auth print-access-token`\n\nWhen you \"authorize\" in the Bond Swagger UI:\n\n1. Click the `Authorize` button at the top right of the Swagger UI\n1. Copy/paste the generated Access Token from the gcloud CLI into `Value` field\n1. Click the `Authorize` button\n\nYour token will authorize you to make requests for about 30 minutes, at which point you will need to repeat the \nauthorization process.\n\n# Setup\n\nIn order to run tests or run the local development app server, you need to install Python 3.9, Pip, and [Google Cloud SDK](https://cloud.google.com/sdk/install).\n\nIf you need to have multiple Python versions installed, we recommend using [pyenv](https://github.com/pyenv/pyenv).\n\n### A note to M1 Mac users\nAt the time of this writing, it is recommended that M1 Mac users perform all of the setup steps in a terminal running Rosetta 2 x86 emulation. See the following Apple support article: [If you need to install Rosetta on your Mac](https://support.apple.com/en-us/HT211861)\n\n## Virtualenv\n\n[Virtualenv](https://virtualenv.pypa.io/en/stable/) is a tool that helps you manage multiple Python versions and your \nproject dependencies.  We recommend you setup Virtualenv for development and testing of Bond.  If you are using \n[pyenv](https://github.com/pyenv/pyenv), be sure to specify to set that up prior to configuring virtualenv for Bond.  \n\n1. Verify that you have Python 3.9 installed: `python --version`\n(**Note**: The name of your Python 3.9 command may be something different like `python3` if you have multiple versions \nof Python installed)\n1. Install virtualenv: `pip install virtualenv`\n1. `cd` to the Bond root directory\n1. Set up virtualenv for Bond: `virtualenv -p python env` \n(**Note**: Ensure that you pass the correct Python 3.9 executable to the [`-p` parameter](https://virtualenv.pypa.io/en/stable/reference/#cmdoption-p)) \n1. Activate virtualenv: `source env/bin/activate`\n1. Install project dependencies: `pip install -r requirements.txt --ignore-installed`\n\nYou may now run tests or run the application server normally.\n\nWhen you are ready to exit or deactivate your Bond virtualenv, just type the command `deactivate` on your command line.\n\n### In IntelliJ\n\nFollow the [instructions](https://www.jetbrains.com/help/idea/creating-virtual-environment.html) on the JetBrains site.\n\n# Running Tests\n\nBond has unit tests, integration tests, and automation tests. \n\nBond supports test runners: [unittest](https://docs.python.org/3/library/unittest.html).\n\n## Unit tests\n\n`python -m unittest discover -s tests/unit -p \"*_test.py\"`\n\nWhen writing new tests, do not put any tests in the root `tests/` directory.  Instead, write new unit tests in the \n`tests/unit` directory.\n\n## Integration tests\n\nTo run integration tests, provide the `test-path` parameter to with the path to the integration tests:\n\n`python -m unittest discover -s tests/integration -p \"*_test.py\"` \n\nWhen writing new tests, do not put any tests in the root `tests/` directory.  Instead, write new integration tests in \nthe `tests/integration` directory.\n\n### Integration testing with real providers\nIntegration tests are written to be run against the [mock provider service](https://github.com/broadinstitute/mock-provider).\nThe mock provider service skips the authentication step of the oauth dance in order to make testing easier.  \n\nIf you want to test against _real_ providers, do the following:\n\n1. Update `config.ini` to have all the requisite data for the real providers\n1. At the top of `tests/integration/oauth_adapter_test.py`, set the variable `using_mock_providers =\nFalse`. \n1. Run the Integration Tests the same way as described above.  The tests will stop and print instructions and a link to \nauthenticate with each provider.  Follow the instructions and copy/paste the `auth_code` into the command line for each \nprovider to complete the oauth dance.\n\nBecause the test execution will become an interactive experience, you **_must_** run these tests in an environment\nwhere you can provide the required command line inputs.  In other words, you won't be able to run tests this way on a \nbuild server, but you will be able to run them in your local environment.\n\n## Datastore Emulator tests\nTo run the integration tests that require the Datastore emulator locally, follow [the instructions in the readme](tests/datastore_emulator/README.md). \n\n# Running locally\n\n## Render configs\n\nBefore you run locally, you will need to render configs:\n\nFor Broad devs:\n\n```\ndocker run -v $PWD:/app \\\n  -e GOOGLE_PROJ=broad-bond-dev \\\n  -e SERVICE_VERSION=2016-08-01r0 \\\n  -e INPUT_PATH=/app \\\n  -e OUT_PATH=/app \\\n  -e VAULT_TOKEN=$(cat ~/.vault-token) \\\n  -e ENVIRONMENT=dev \\\n  -e RUN_CONTEXT=local \\\n  -e DNS_DOMAIN=local \\\n  broadinstitute/dsde-toolbox:master render-templates.sh\n```\n  \nFor non-Broad, manually edit the config.ini and app.yaml files in the root of the project to use your desired values.\n\n## Run on your local environment\n\n### Run locally\nAfter installing project dependencies, rendering configs, and setting up paths, start up a Datastore Emulator. We need\nthe emulator so that our local runs have a Datastore backend to talk to, and we do not want them to talk to real Google\nDatastores.\n\nNote that the following script must be run from a python2 virtualenv environment. See\n[tests/datastore_emulator/README.md](tests/datastore_emulator/README.md)\n\n```tests/datastore_emulator/run_emulator.sh```\n\nThen back in the Python 3 environment, start a local flask server:\n\n```./run_local.sh```\n\nYou can check [http://127.0.0.1:8080/api/status/v1/status](http://127.0.0.1:8080/api/status/v1/status) to make sure you're up and running.\n\nYou can also check [http://0.0.0.0:8432](http://0.0.0.0:8432) which should show 'Ok' if the datastore emulator is working properly.\n\n### Run locally from IntelliJ\n\nThese instructions are for running the app in IntelliJ specifically, not PyCharm.\n\n- Go to `Run` -\u003e `Edit Configurations` -\u003e `Add New Configuration` -\u003e `Flask Server`\n- For `Target Type` choose: `Module Name`\n- In the `Target` field enter: `main.py`\n- Leave the `Application`, `Additional Options`, and `FLASK_ENV` fields blank\n- If you want to debug the application, check the `FLASK_DEBUG` checkbox\n- In the `Environment variables` field enter: `DATASTORE_EMULATOR_HOST=0.0.0.0:8432;FLASK_HOST=127.0.0.1`\n- Click `OK`\n- Try running the app by clicking `Run` -\u003e `Run 'Flask (main.py)'` (or by clicking the `Run` button in the Toolbar)\n\n*NOTE* - If you see an error like: `module 'enum' has no attribute 'IntFlag'` when trying to run the Flask Server,  try \nthe following:\n\n- Go to `File` -\u003e `Project Structure` -\u003e `Libraries`\n- Remove the `Google App Engine` library\n\n## Run in a Docker container\n\nFirst, render configs (see above). If you try to run the docker compose before rendering, subsequent rendering may not\nwork. `docker-compose` may create directories when it tries to access configuration files that do not exist. Try\nremoving created directories (e.g. remove `config.ini` which should be created from `config.ini.ctmpl`) and\nre-rendering.\n\nChoose one of the options below:\n\nA) To run an existing image:\n\n1) Render configs.\n2) Browse the available tags [here](https://quay.io/repository/databiosphere/bond?tag=latest\u0026tab=tags)\n3) With your tag of choice (such as `develop`), run `IMAGE_ID=us-central1-docker.pkg.dev/dsp-artifact-registry/bond/bond:{TAG} docker-compose -f docker/local-docker-compose.yml up`\n4) Check http://127.0.0.1:8080/api/status/v1/status to make sure you're up and running\n5) Navigate to http://127.0.0.1:8080/api/docs/ to interact with endpoints via Swagger\n\nB) Run your local code:\n\n1) Render configs.\n2) Build your image: `docker build -f docker/Dockerfile .`\n3) Grab the Image ID and run: `IMAGE_ID={your image id} docker-compose -f docker/local-docker-compose.yml up`\n4) Check http://127.0.0.1:8080/api/status/v1/status to make sure you're up and running\n5) Navigate to http://127.0.0.1:8080/api/docs/ to interact with endpoints via Swagger\n\n# Development\n\nThis app is written in Python 3 as a Flask application intended to be run in Google App Engine.  It has runtime\ndependencies on Google Datastore.\n\n## Logging\n\nFollow standard Python [logging instructions](https://docs.python.org/3/howto/logging.html#logging-advanced-tutorial). \nLogging is configured for our application in `main.py` in the `setup_logging` method.  This method loads a logging\nconfig defined in `log_config.yaml` and among other settings, allows us to specify the log level for specific modules \nand for the application in general.  \n\nIn order to use the logging config, you will need to load the right logger for your Python module (or class).  Calling\nthe logging methods on the `logging` module directly will log messages using the default logger, which is not bad, but \nit is not preferred either.  Instead, you should get the specific logger for your module so that the right configuration\nfrom `log_config.yaml` will be applied to your module.  For example:\n\n```python\nimport logging\n\nlogger = logging.getLogger(__name__)\n\nclass MyCoolClass:\n    def __init__(self, base_url):\n        logger.debug(\"Constructed an instance of MyCoolClass\")\n\n    def do_something(self):\n        logger.info(\"Stuff is happening\")\n\nlogger.warning(\"I like turtles\")\n```\n\n# Deployment (for Broad only)\n\nDeployments to non-production and production environments are performed in Beehive.\n\n## Deploy to the \"dev\" environment\n\nA deployment to `dev` environment will be automatically triggered every time there is a commit or push to the \n[develop](https://github.com/DataBiosphere/bond/tree/develop) branch on Github.  If you would like to deploy a different \nbranch or tag to the `dev` environment, you can do so by following the instructions below, but be aware that a new\ndeployment of the `develop` branch will be triggered if anyone commits or pushes to that branch.\n\n## Deploy to other non-production environments\n\nNote: if you are deploying to non-prod envs as part of a prod release, then skip this section since these instructions are already included in the [Production Deployment Checklist](#production-deployment-checklist).\n\n1. Deploy to dev first, as staging follows dev, and prod follow staging.\n2. Log in to [Beehive](https://beehive.dsp-devops.broadinstitute.org/).\n3. Navigate to the [Environments](https://beehive.dsp-devops.broadinstitute.org/environments) section.\n4. In the left menu, click on the environment you want to deploy to.\n5. Click on the Bond instance in the list.\n6. Click on \"Change Versions\" and then \"Click to Refresh and Preview Changes\". If the version of Bond you want to deploy is in dev already, you should see a diff, if not, go back to step 1.\n7. Apply the changes.\n\n## Production Deployment Checklist\n\n### Create a ticket and load the Bond Release Checklist template\nTo perform a release, you are _required_ to create a Release Issue in [Jira](https://broadworkbench.atlassian.net/browse/CA).\nYou should title the issue something like `Bond Release version x.x.x` (`x.x.x` is a placeholder that will get replaced).  After creating the issue, search for a way to add a \"Checklist\" (which may be a ☑ icon near the top of the ticket) and click on the ellipsis `...` icon for \nthat field and choose `Load templates`, select `Independent Services Release Checklist`, and click the `Load templates` button.  \n\nWhen doing a production deployment, each step of the checklist **must** be performed.\n\n### Deploy and Test\nYou must deploy to each tier one-by-one and [manually test](https://docs.google.com/document/d/1-SXw-tgt1tb3FEuNCGHWIZJ304POmfz5ragpphlq2Ng/edit?ts=5e964fbe#)\nin each tier after you deploy to it.  Your deployment to a tier should not be considered complete until you have \nsuccessfully executed each step of the [manual test](https://docs.google.com/document/d/1-SXw-tgt1tb3FEuNCGHWIZJ304POmfz5ragpphlq2Ng/edit?ts=5e964fbe#)\non that tier. To deploy the application code, navigate to [Beehive](https://beehive.dsp-devops.broadinstitute.org/) \nand follow the non-prod deployment instructions above. Then do the same but for the prod environment.\n \n**NOTE:** \n* It is important that you deploy to all tiers.  Because Bond is an \"indie service\", we should strive to make sure\nthat all tiers other than `dev` are kept in sync and are running the same versions of code.  This is essential so that\nas other DSP services are tested during their release process, they can ensure that their code will work properly with \nthe latest version of Bond running in `prod`. \n  \n### Maintenance of the Deployment Checklist\n\nThe checklist is implemented using the [Issue Checklist](https://herocoders.atlassian.net/wiki/spaces/IC/overview) \nplugin for Jira. The checklist source markup can be found in the [release-checklist.md](release-checklist.md) file.  If \nyou need to modify the release checklist, do so in that file, and then copy the contents of that file into the \n\"checklist template\" in Jira after the changes have been reviewed and merged in git.\n\n# Git Secrets\n\nTo run Bond you will need to modify `config.ini` to contain a few secrets that should never be committed into git.  To \nhelp protect you from accidentally committing secrets, we recommend that you download and install \n[git-secrets](https://github.com/awslabs/git-secrets).\n\nOnce installed, you can add the following patterns:\n\n```\ngit secrets --add 'CLIENT_ID\\s*=\\s*.+'\ngit secrets --add 'CLIENT_SECRET\\s*=\\s*.+'\ngit secrets --add --allowed 'REPLACE_ME'\ngit secrets --add --allowed 'ignored'\ngit secrets --add --allowed '\\{\\{ \\$secrets\\.Data\\.client_id \\}\\}'\ngit secrets --add --allowed '\\{\\{ \\$secrets\\.Data\\.client_secret \\}\\}'\ngit secrets --add --allowed '\\{\\{ \\$secrets\\.Data\\.dcf_fence_client_id \\}\\}'\ngit secrets --add --allowed '\\{\\{ \\$secrets\\.Data\\.dcf_fence_client_secret \\}\\}'\ngit secrets --add --allowed '\\{\\{ \\$secrets\\.Data\\.anvil_client_id \\}\\}'\ngit secrets --add --allowed '\\{\\{ \\$secrets\\.Data\\.anvil_secret \\}\\}'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatabiosphere%2Fbond","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatabiosphere%2Fbond","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatabiosphere%2Fbond/lists"}