Skip to content

Commit

Permalink
Add Eagle Eye labeling tool.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 675646759
  • Loading branch information
jzxu authored and copybara-github committed Sep 17, 2024
1 parent a0a10ba commit 700c998
Show file tree
Hide file tree
Showing 28 changed files with 1,972 additions and 0 deletions.
129 changes: 129 additions & 0 deletions src/eagle_eye/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Skai - EagleEye

EagleEye is a simple multi-user image labeling system for use with SKAI.

## Setup

### Set up Firebase
- Create a Firebase project
- Visit https://console.firebase.google.com/ and click "Create a project".
- Click "Add Firebase to Google Cloud Project".
- Select your SKAI GCP Project.
- Unselect "Enable Google Analytics for this project".
- Create Firestore database
- Visit https://console.firebase.google.com/project/\[project-name\]/overview
- In the left sidebar, click "All products".
- Click "Cloud Firestore". "Firestore Database" should now appear under the
"Project shortcuts" heading in the left sidebar.
- Click "Create database".
- Leave Database ID as "(default)". Select a location that is colocated with
your SKAI data bucket. Click "Next".
- Select "Start in production mode". Click "Create".
- Register Web App
- Visit https://console.firebase.google.com/project/\[project-name\]/overview
- Click "Add app".
- Click "Web". The icon looks like "</>".
- Enter "eagle-eye" for App nickname. Don't select the Firebase Hosting
option. Click "Register app".
- In the next screen, copy the data structure that looks like the following
somewhere for later. Then click "Continue to console".

```
const firebaseConfig = {
apiKey: "abcdefghijklmnopqrstuvwxyzABCDE12345678",
authDomain: "project-name.firebaseapp.com",
projectId: "project-name",
storageBucket: "project-name.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789012:web:1234567890abcdef123456"
};
```
- Enable Firebase Authentication
- https://console.firebase.google.com/project/\[your project\]/overview
- In the left sidebar, click "All products".
- Click "Authentication". "Authentication" should now appear under the
"Project shortcuts" heading in the left sidebar.
- In the tab bar under the "Authentication" header, click "Sign-in method".
- Under "Additional providers", click "Google", then click "Enable", then
"Save".
- Add users
- Visit https://console.firebase.google.com/project/\[project-name\]/overview
- In the left sidebar, click on the gear next to "Project Overview", then
click "Users and permissions".
- For each user you would like to access the labeling tool, click
"Add member", enter their email address, and select the "Viewer" role.
Note that the email address must work with Google OAuth, e.g. a gmail
account or a Google Workspaces account.
### Create Service Account
- Follow these
[instructions](https://cloud.google.com/iam/docs/service-account-overview)
to create a service account to run EagleEye. The service account name can be
"eagleeye" or anything you like. The service account needs these IAM roles:
- Firebase Admin
- Storage Object User
- Follow these
[instructions](https://cloud.google.com/iam/docs/keys-create-delete)
to create and download a service account JSON key file to your workstation.
### Deploy App Using Cloud Run
- On your workstation, create a text file in the `skai/src/eagle_eye` directory
named `config.json`. The contents of the file should be the `firebaseConfig`
JSON data structure you copied previously. It should look like this:
```
{
"firebaseConfig": {
"apiKey": "abcdefghijklmnopqrstuvwxyzABCDE12345678",
"authDomain": "project-name.firebaseapp.com",
"projectId": "project-name",
"storageBucket": "project-name.appspot.com",
"messagingSenderId": "123456789",
"appId": "1:123456789012:web:1234567890abcdef123456"
}
}
```
- In a terminal, run the following commands:
```
$ export GOOGLE_APPLICATION_CREDENTIALS=[path to your JSON key file]
$ cd skai/src/eagle_eye
$ gcloud run deploy
```
- The output should contain lines similar to the following:
```
Service [eagle_eye] revision [eagle_eye-00001-kpb] has been deployed and is serving 100 percent of traffic.
Service URL: https://eagle-eye-1234567890.us-central1.run.app
```
- Copy the Service URL. That is the URL of the EagleEye app.
### Add Service URL to Authorized Domains
- Visit https://console.firebase.google.com/u/0/project/\[project-name\]/authentication/settings
- Click "Authorized domains".
- Click "Add domain", then paste the EagleEye service URL into the input box and
click "Add".
### Allow Unauthenticated Domains
- Visit https://console.cloud.google.com/
- Select your project in the project dropdown.
- Open the navigation menu in the top left, then select "Cloud Run".
- You should see "eagle-eye" listed. Click on it.
- In the tab bar, click "SECURITY".
- Click "Allow unauthenticated invocations".
### Grant Admin Access
- In a terminal on your workstation, navigate to `skai/src/eagle_eye/admin`.
- Execute the following commands:
```
$ python -m venv eagle-eye-admin
$ source eagle-eye-admin/bin/activate
$ pip install -r requirements.txt
$ python grant_admin.py --email=[your email]
```
46 changes: 46 additions & 0 deletions src/eagle_eye/admin/grant_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""A script for granting / revoking admin access to EagleEye.
If --is_admin is present, grants admin access by setting the {'admin':
True} custom claim for the user; if not, unsets all custom claims.
Expects `GOOGLE_CLOUD_PROJECT` env variable to be set to the
appropriate GCP project name, and `GOOGLE_APPLICATION_CREDENTIALS` to
be set to the path to of a service account key json file with required
permission to access the GCP Admin SDK.
Example invocation:
python grant_admin.py [email protected]
"""

from absl import app
from absl import flags
import firebase_admin
from firebase_admin import auth


FLAGS = flags.FLAGS
flags.DEFINE_string(
'email', None, 'Email of the user to grant / revoke access.', required=True
)
flags.DEFINE_boolean('is_admin', True, help='If present, grants admin access.')


def main(_):
firebase_admin.initialize_app()

user = auth.get_user_by_email(FLAGS.email)
print(
f'User (email): {FLAGS.email}, user id: {user.uid}, claims:'
f' {user.custom_claims}'
)
claims = {'admin': True} if FLAGS.is_admin else {}
auth.set_custom_user_claims(user.uid, claims)
if FLAGS.is_admin:
print(f'Granted admin access for user: {FLAGS.email} (uid: {user.uid})')
else:
print(f'Revoked admin access for user: {FLAGS.email} (uid: {user.uid})')


if __name__ == '__main__':
app.run(main)
34 changes: 34 additions & 0 deletions src/eagle_eye/admin/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
absl-py==2.1.0
CacheControl==0.14.0
cachetools==5.3.3
certifi==2024.6.2
cffi==1.16.0
charset-normalizer==3.3.2
cryptography==42.0.8
firebase-admin==6.5.0
google-api-core==2.19.1
google-api-python-client==2.135.0
google-auth==2.30.0
google-auth-httplib2==0.2.0
google-cloud-core==2.4.1
google-cloud-firestore==2.16.1
google-cloud-storage==2.17.0
google-crc32c==1.5.0
google-resumable-media==2.7.1
googleapis-common-protos==1.63.2
grpcio==1.64.1
grpcio-status==1.62.2
httplib2==0.22.0
idna==3.7
msgpack==1.0.8
proto-plus==1.24.0
protobuf==4.25.3
pyasn1==0.6.0
pyasn1_modules==0.4.0
pycparser==2.22
PyJWT==2.8.0
pyparsing==3.1.2
requests==2.32.3
rsa==4.9
uritemplate==4.1.1
urllib3==2.2.2
1 change: 1 addition & 0 deletions src/eagle_eye/app/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
Loading

0 comments on commit 700c998

Please sign in to comment.