{"id":43556699,"url":"https://github.com/jasonaowen/recurse-faces","last_synced_at":"2026-02-03T20:23:37.890Z","repository":{"id":17611666,"uuid":"82347317","full_name":"jasonaowen/recurse-faces","owner":"jasonaowen","description":"A flashcard app to help you learn the faces of your fellow Recursers!","archived":false,"fork":false,"pushed_at":"2023-01-04T14:54:35.000Z","size":1257,"stargazers_count":4,"open_issues_count":27,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-14T07:39:40.346Z","etag":null,"topics":["flashcard-application","flask-api","heroku","postgresql","react","recurse-center","website"],"latest_commit_sha":null,"homepage":"https://faces.recurse.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jasonaowen.png","metadata":{"files":{"readme":"README.markdown","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-17T23:36:34.000Z","updated_at":"2021-05-30T00:20:18.000Z","dependencies_parsed_at":"2023-01-14T07:46:03.485Z","dependency_job_id":null,"html_url":"https://github.com/jasonaowen/recurse-faces","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jasonaowen/recurse-faces","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonaowen%2Frecurse-faces","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonaowen%2Frecurse-faces/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonaowen%2Frecurse-faces/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonaowen%2Frecurse-faces/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jasonaowen","download_url":"https://codeload.github.com/jasonaowen/recurse-faces/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonaowen%2Frecurse-faces/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29056034,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T20:13:53.544Z","status":"ssl_error","status_checked_at":"2026-02-03T20:13:40.507Z","response_time":96,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["flashcard-application","flask-api","heroku","postgresql","react","recurse-center","website"],"created_at":"2026-02-03T20:23:36.776Z","updated_at":"2026-02-03T20:23:37.876Z","avatar_url":"https://github.com/jasonaowen.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Recurse Faces\n\nLearn the faces of your fellow Recursers\nwith the [Recurse Faces app](https://faces.recurse.com)!\n\nThis app helps users associate names and faces of\nmembers of the [Recurse Center](https://recurse.com) community,\nincluding batch mates and staff from both current and past stints.\n\nIt uses the\n[Recurse Center API](https://github.com/recursecenter/wiki/wiki/Recurse-Center-API)\nto cycle through a set of profile photos,\nprompting users to guess the first name of the person shown in the photo.\nUsers can choose to see a set of hints if they are stuck,\nand they can filter to see profiles\nas broadly as all past and present members of the RC community\nor as narrowly as only the profiles from a specific batch they attended.\n\n## Local Set Up\n\nThe app is comprised of a Flask back-end and a React front-end.\nThe instructions below detail how to set up the\n[front end with test data](#start-the-front-end-with-test-data),\nwhich is the quickest way to get started\nand does not require setting up the backend database and server.\nTo pull live data from the Recurse Center API,\nsee the instructions for [setting up the backend](#start-the-back-end-with-the-rc-api).\n\n### Start the Front End with Test Data\n\nFirst, install dependencies by running the [npm](https://www.npmjs.com/get-npm) command:\n\n```sh\n$ npm install\n```\n\nIf you want to run the front end with test data,\nyou may set the `REACT_APP_USE_TEST_DATA` variable:\n\n```sh\n$ REACT_APP_USE_TEST_DATA=true npm run start\n```\n\nThis option is the quickest way to get started,\nand it is helpful when doing front end development or testing\nthat does not require updates to the database or calls to the RC API.\nInstead of displaying photos of Recursers,\nit will show photos and names of flowers:\n\n\u003cimg src=\"./screenshots/test_data.png?raw=true\" alt=\"Test Data Guess\" width=\"400\"/\u003e\n\nAlternatively, the `REACT_APP_USE_TEST_DATA` variable\ncan be added to a `.env` file\nto avoid re-typing it each time the React app is started.\n[Create a `.env` file](#create-a-env-file),\nenable the variable `REACT_APP_USE_TEST_DATA=true`,\nand then starting the React app is as simple as:\n```sh\n$ npm run start\n```\n\n### Start the Back End with the RC API\nThe Python server is a Flask app\nthat serves the index page and the JavaScript,\nhandles the OAuth login process,\nand looks up names and images in the database.\n\nRunning the API locally requires populating the database\nand setting up the Python environment.\n\n#### Python Virtual Environment\nYou'll first need to install the Python dependencies.\nFirst, set up a [virtual environment](https://docs.python.org/3/tutorial/venv.html):\n\n```sh\n$ python3 -m venv venv\n```\n\nor\n\n```sh\n$ python3 -m virtualenv --python=python3 venv\n```\n\nThen, activate the virtual environment\nand install the app's dependencies into it:\n\n```sh\n$ . venv/bin/activate\n(venv)$ pip install -r requirements.txt\n```\n\nTo populate the database or start the Flask app,\nthe scripts must be run in this virtual environment (venv).\nThe virtual environment can be reactivated at any time with the command:\n```sh\n$ . venv/bin/activate\n```\n\n#### Create a .env File\nThe Flask app needs some configuration,\nwhich it takes through environment variables.\nFor convenience, this project uses a `.env` file\nto store these variables.\n\nFirst, copy the `env.template` file to a new file named `.env`:\n```sh\n$ cp env.template .env\n```\n\nThe next few sections will describe\nhow to set and add to this initial set of variables.\n\n**Note**: The `.env` file should not be placed under version control\nand is included in the `.gitignore` file.\n\n#### Populate the Database\n\nWe use [PostgreSQL](https://www.postgresql.org/) as our database.\nFollow the [installation instructions](https://www.postgresql.org/download/)\nfor your platform to set up the database server.\n\nFirst, choose or [create](https://www.postgresql.org/docs/current/tutorial-createdb.html)\na database:\n\n```sh\n$ createdb --owner=$(whoami) faces\n```\n\nDepending on your platform,\nyou may need to run that command\nas the operating system user which owns the database server:\n\n```sh\n$ sudo -u postgres createdb --owner=$(whoami) faces\n```\n\nThen, create the schema:\n\n```sh\n$ psql faces \u003c schema.sql\n```\n\nAdd your database connection URL to the `.env` file:\n`DATABASE_URL=postgres:///faces/`\n\n**Note**: the `DATABASE_URL` can be any\n[libpq connection string](https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING).\nAn alternate database URL you might try is\n`postgres://localhost/faces`\nto connect over TCP/IP to the database named `faces`.\n\nThere is a script\nto get the data the application needs\nfrom the Recurse Center API\nand store it in the database.\nTo connect to the RC API,\nthe script needs a personal access token,\nwhich you can create in the\n[Apps page in your RC Settings](https://www.recurse.com/settings/apps).\nThe personal access token will only be shown once,\nso copy it to a safe place\nand add it to the `.env` file:\n`RC_API_ACCESS_TOKEN=\u003cpersonal_access_token\u003e`\n\nRun the script to populate the database\nin your [Python Virtual Environment](#python-virtual-environment):\n\n```sh\n(venv)$ ./update-data.py\n```\n\nIt should print out how many people and batches were added.\n\n#### Start the Flask App\n\nWhen running in development mode,\nthe app does not require authentication,\nbut it does need to know your Recurse Center user ID.\nYou can find your ID by going to the\n[directory](https://www.recurse.com/directory),\nlooking yourself up,\nand examining the number in the URL;\nfor example, `2092` in\n`https://www.recurse.com/directory/2092-jason-owen`.\n\nAdd your RC ID to your `.env` file:\n`DEFAULT_USER=\u003cyour_recurse_user_id\u003e`\n\nIf you are working on the RC OAuth integration,\nyou will need to\n[create an OAuth app in your RC Settings](https://www.recurse.com/settings/apps).\nThen, update the `.env`\nto include the generated client ID and the client secret:\n`CLIENT_ID=\u003cyour_client_id\u003e` and `CLIENT_SECRET=\u003cyour_client_secret\u003e`.\nOtherwise, those variables can remain set to the placeholder values `_`\n(but must still be present and non-empty).\n\nThe `CLIENT_CALLBACK` URL variable must include\nthe port number the Flask instance will be running on,\nwhich defaults to port 5000. Update this URL in your `.env` file\nif using a different port.\n\nIf the `REACT_APP_USE_TEST_DATA` variable was added to your `.env`\nin the steps above, set its value to `false` so that the app will\ndisplay data from the RC API.\n\nBuild the static resources for the Flask app to serve:\n```sh\n$ npm run build\n```\n\nNext, start the Flask API\nin your [Python Virtual Environment](#python-virtual-environment):\n```sh\n(venv)$ flask run\n```\n\nNow, your local instance of Recurse Faces\nwith live data from the RC API\nwill be available at http://127.0.0.1:5000/:\n\n\u003cimg src=\"./screenshots/live_rc_data.png?raw=true\" alt=\"Live RC Data Hint\" width=\"400\"/\u003e\n\nHowever, because this instance is running\nwith statically generated resources from `npm build`,\nlocal changes to the React front end\nwill not be reflected at this URL.\n\nThe React dev server is configured to proxy the Flask API,\nso to run your local front end code\nwith live data from the RC API,\nleave the Flask app running\nand start the React front end in another terminal window:\n```sh\n$ npm run start\n```\n\nNow, the React front end reflecting any local code changes\nwill be running at http://localhost:3000/\nwith data from the Flask back end API\nrunning at http://127.0.0.1:5000/.\n\n## Heroku Set Up\n\nThis is app is deployed on Heroku:\n\n```sh\n$ heroku apps:create\n```\n\nTo set up your Heroku app, add both the Python and Node buildpacks:\n\n```sh\n$ heroku buildpacks:add heroku/python\n$ heroku buildpacks:add heroku/nodejs\n```\n\nYou will also need to set several environment variables.\n\nThree relate to the Recurse Center OAuth API. When you create your OAuth app in\nyour RC account settings, you will need to set the callback to be\n`https://\u003cyour_url\u003e/auth/recurse/callback`. Once you create it, you will get a\n`CLIENT_ID` and `CLIENT_SECRET`. You will also need to set a randomly chosen\npassword for Flask to encrypt sessions with.\n\n```sh\n$ heroku config:set \\\n    CLIENT_CALLBACK=https://\u003cyour_url\u003e/auth/recurse/callback \\\n    CLIENT_ID=\u003cyour_client_id\u003e \\\n    CLIENT_SECRET=\u003cyour_client_secret\u003e \\\n    FLASK_SECRET_KEY=$(makepasswd --chars=64) \\\n    FLASK_ENV=production \\\n    RC_API_ACCESS_TOKEN=\u003cyour_personal_access_token\u003e\n```\n\nYou will also need to create a database:\n\n```sh\n$ heroku addons:create heroku-postgresql:hobby-dev\n```\n\nand populate it:\n\n```sh\n$ heroku pg:psql \u003c schema.sql\n```\n\nAnd you'll probably want logs of some sort. I'm using Papertrail:\n\n```sh\n$ heroku addons:create papertrail:choklad\n```\n\nWe can schedule data updates using the\n[Heroku Scheduler](https://devcenter.heroku.com/articles/scheduler):\n\n```sh\n$ heroku addons:create scheduler:standard\n$ heroku addons:open scheduler\n```\n\nCreate a new job that runs daily, and set the command to `./update-data.py`.\n\nThen, in theory, it should be a simple `git push heroku main`!\n\n\n## Troubleshooting\nIf you receive either of the following messages:\n```sh\nFile \"./update-data.py\", line 24\nheaders = {'Authorization': f'Bearer {token}'}\n                                                ^\nSyntaxError: invalid syntax\n```\n\nor\n\n```sh\n/usr/bin/python: No module named flask\n```\n\nreactivate your [Python virtual environment](#python-virtual-environment),\nand then try to run the previous command again.\n\n\u003ca href='http://www.recurse.com' title='Made with love at the Recurse Center'\u003e\u003cimg src='https://cloud.githubusercontent.com/assets/2883345/11325206/336ea5f4-9150-11e5-9e90-d86ad31993d8.png' height='20px'/\u003e\u003c/a\u003e\n![Licensed under the AGPL, version 3](https://img.shields.io/badge/license-AGPL3-blue.svg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasonaowen%2Frecurse-faces","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjasonaowen%2Frecurse-faces","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasonaowen%2Frecurse-faces/lists"}