├── lambda ├── tests │ ├── handler.py │ ├── __init__.py │ └── test_base.py ├── download_and_predict │ ├── __init__.py │ ├── custom_types.py │ └── __main__.py ├── mypy.ini ├── requirements.txt ├── Makefile ├── upload-lambda.sh └── Dockerfile ├── tasks ├── task-pop │ ├── pop │ │ └── __init__.py │ ├── .gitignore │ ├── requirements.txt │ └── Dockerfile ├── task-vectorize │ ├── .gitignore │ ├── test │ │ ├── fixtures │ │ │ └── feature.json │ │ ├── feature.test.js │ │ └── image.test.js │ ├── Dockerfile │ ├── task │ ├── lib │ │ └── api.js │ └── package.json ├── task-build │ ├── .gitignore │ ├── test │ │ └── fixtures │ │ │ └── pytorch-seg.mar │ ├── Dockerfile │ ├── package.json │ └── lib │ │ ├── tfserving.js │ │ └── ptserving.js └── task-tfrecords │ ├── requirements.txt │ ├── Dockerfile │ └── imagery.py ├── api ├── web │ ├── .gitignore │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── src │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ ├── util │ │ │ │ ├── InputError.vue │ │ │ │ ├── Loading.vue │ │ │ │ ├── InfVersion.vue │ │ │ │ ├── InfModel.vue │ │ │ │ ├── InfType.vue │ │ │ │ └── InfGitSha.vue │ │ │ ├── iteration │ │ │ │ └── stack │ │ │ │ │ ├── QueueList.vue │ │ │ │ │ └── QueueXYZ.vue │ │ │ ├── Lost.vue │ │ │ ├── Err.vue │ │ │ ├── Profile.vue │ │ │ └── Admin.vue │ │ └── std.js │ ├── babel.config.js │ ├── vue.config.js │ └── README.md ├── schema │ ├── geography_columns │ │ ├── f_table_name.json │ │ ├── f_table_catalog.json │ │ ├── f_table_schema.json │ │ ├── f_geography_column.json │ │ ├── srid.json │ │ ├── type.json │ │ └── coord_dimension.json │ ├── geometry_columns │ │ ├── f_table_name.json │ │ ├── f_geometry_column.json │ │ ├── f_table_schema.json │ │ ├── srid.json │ │ ├── coord_dimension.json │ │ ├── type.json │ │ └── f_table_catalog.json │ ├── res.Inference.json │ ├── aois │ │ ├── id.json │ │ ├── name.json │ │ ├── pid.json │ │ ├── bounds.json │ │ ├── created.json │ │ ├── updated.json │ │ └── iter_id.json │ ├── imagery │ │ ├── id.json │ │ ├── fmt.json │ │ ├── name.json │ │ ├── pid.json │ │ ├── url.json │ │ ├── created.json │ │ └── updated.json │ ├── meta │ │ ├── key.json │ │ ├── value.json │ │ ├── created.json │ │ └── updated.json │ ├── tasks │ │ ├── id.json │ │ ├── type.json │ │ ├── iter_id.json │ │ ├── created.json │ │ ├── updated.json │ │ ├── batch_id.json │ │ └── log_link.json │ ├── users │ │ ├── id.json │ │ ├── access.json │ │ ├── email.json │ │ ├── password.json │ │ ├── username.json │ │ ├── validated.json │ │ └── created.json │ ├── integrations │ │ ├── id.json │ │ ├── name.json │ │ ├── pid.json │ │ ├── url.json │ │ ├── integration.json │ │ ├── created.json │ │ ├── updated.json │ │ └── auth.json │ ├── iterations │ │ ├── id.json │ │ ├── pid.json │ │ ├── tile_zoom.json │ │ ├── model_type.json │ │ ├── created.json │ │ ├── updated.json │ │ ├── hint.json │ │ ├── gitsha.json │ │ ├── imagery_id.json │ │ ├── inf_list.json │ │ ├── inf_type.json │ │ ├── model_link.json │ │ ├── save_link.json │ │ ├── version.json │ │ ├── checkpoint_link.json │ │ ├── docker_link.json │ │ ├── inf_binary.json │ │ ├── inf_supertile.json │ │ └── tfrecord_link.json │ ├── projects │ │ ├── access.json │ │ ├── id.json │ │ ├── name.json │ │ ├── notes.json │ │ ├── source.json │ │ ├── tags.json │ │ ├── archived.json │ │ ├── project_url.json │ │ ├── created.json │ │ ├── updated.json │ │ └── repo.json │ ├── users_tokens │ │ ├── id.json │ │ ├── name.json │ │ ├── token.json │ │ ├── uid.json │ │ └── created.json │ ├── aoi_submission │ │ ├── id.json │ │ ├── iter_id.json │ │ ├── created.json │ │ └── aoi_id.json │ ├── knex_migrations │ │ ├── id.json │ │ ├── batch.json │ │ ├── name.json │ │ └── migration_time.json │ ├── projects_access │ │ ├── id.json │ │ ├── pid.json │ │ ├── uid.json │ │ ├── access.json │ │ ├── created.json │ │ └── updated.json │ ├── projects_invite │ │ ├── id.json │ │ ├── pid.json │ │ ├── email.json │ │ ├── token.json │ │ └── created.json │ ├── spatial_ref_sys │ │ ├── srid.json │ │ ├── auth_srid.json │ │ ├── auth_name.json │ │ ├── proj4text.json │ │ └── srtext.json │ ├── util │ │ ├── any.json │ │ ├── validated.json │ │ ├── created.json │ │ ├── updated.json │ │ ├── page.json │ │ ├── limit.json │ │ ├── project-access.json │ │ ├── order.json │ │ ├── version.json │ │ ├── access.json │ │ ├── bounds.json │ │ ├── polygon.json │ │ ├── project-tags.json │ │ ├── inf-list.json │ │ └── project-users.json │ ├── knex_migrations_lock │ │ ├── index.json │ │ └── is_locked.json │ ├── users_reset │ │ ├── uid.json │ │ ├── action.json │ │ ├── token.json │ │ └── expires.json │ ├── res.ListSchema.json │ ├── req.body.PatchAOI.json │ ├── req.body.PatchTask.json │ ├── req.body.PatchProjectAccess.json │ ├── req.body.PatchToken.json │ ├── req.body.PatchMeta.json │ ├── res.TilejsonPredictions.json │ ├── res.Mapbox.json │ ├── req.body.PatchUser.json │ ├── req.query.ListStacks.json │ ├── req.body.ForgotLogin.json │ ├── req.body.VerifyLogin.json │ ├── req.body.PatchImagery.json │ ├── req.body.CreateInference.json │ ├── req.body.CreateProjectAccess.json │ ├── req.body.CreateToken.json │ ├── knex_migrations_lock.json │ ├── req.body.CreateMeta.json │ ├── req.body.PatchIntegration.json │ ├── res.UserReset.json │ ├── res.StackQueue.json │ ├── req.query.UploadIterationAsset.json │ ├── req.body.ResetLogin.json │ ├── req.query.ListMeta.json │ ├── req.query.ListTokens.json │ ├── res.Health.json │ ├── res.Standard.json │ ├── req.body.CreateStack.json │ ├── req.body.CreateImagery.json │ ├── req.body.PatchIteration.json │ ├── req.body.CreateLogin.json │ ├── res.Meta.json │ ├── meta.json │ ├── users_reset.json │ ├── res.Stack.json │ ├── req.body.CreateAOI.json │ ├── req.body.CreateIntegration.json │ ├── aoi_submission.json │ ├── knex_migrations.json │ ├── req.query.DownloadIterationAsset.json │ ├── res.ProjectAccess.json │ ├── req.query.ListSubmissions.json │ ├── req.body.CreateTask.json │ ├── req.query.ListSchema.json │ ├── res.Token.json │ ├── users_tokens.json │ ├── projects_invite.json │ ├── res.CreateToken.json │ ├── req.body.CreateUser.json │ ├── spatial_ref_sys.json │ ├── res.Integration.json │ ├── res.Login.json │ ├── res.User.json │ ├── req.body.PatchProject.json │ ├── req.body.PopulateStackQueue.json │ ├── projects_access.json │ ├── aois.json │ ├── imagery.json │ ├── res.Submission.json │ ├── tasks.json │ ├── users.json │ ├── req.query.ListAOI.json │ ├── req.query.ListProjectAccess.json │ ├── req.query.ListImagery.json │ ├── req.query.ListIntegrations.json │ ├── req.query.ListUsers.json │ ├── res.AOI.json │ ├── integrations.json │ ├── res.Imagery.json │ ├── req.query.GetExport.json │ ├── res.Task.json │ ├── geometry_columns.json │ ├── res.ListTokens.json │ ├── geography_columns.json │ ├── req.query.ListProjects.json │ ├── req.body.CreateProject.json │ ├── res.ListMeta.json │ ├── res.Project.json │ ├── req.query.ListIterations.json │ ├── res.ListProjectAccess.json │ ├── req.query.ListTasks.json │ ├── projects.json │ ├── res.TileJSON.json │ ├── res.ListImagery.json │ ├── res.ListSubmission.json │ ├── res.ListIntegrations.json │ ├── res.ListUsers.json │ ├── req.body.CreateIteration.json │ ├── res.ListTasks.json │ ├── res.ListStacks.json │ └── res.ListAOI.json ├── doc │ ├── img │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ └── android-chrome-512x512.png │ ├── assets │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── api_project.json │ ├── api_project.js │ ├── locales │ │ ├── zh.js │ │ ├── zh_cn.js │ │ ├── tr.js │ │ ├── pl.js │ │ ├── ca.js │ │ ├── vi.js │ │ ├── cs.js │ │ ├── ro.js │ │ ├── de.js │ │ ├── pt_br.js │ │ ├── ru.js │ │ ├── es.js │ │ ├── nl.js │ │ ├── fr.js │ │ ├── it.js │ │ └── locale.js │ └── vendor │ │ └── path-to-regexp │ │ └── LICENSE ├── migrations │ ├── migration.stub │ ├── 20211221145633_remove-inf.js │ ├── 20220310194805_gh_repo-repo.js │ ├── 20220310194437_iteration-git.js │ ├── 20220211173513_meta.js │ ├── 20220310194626_project-github.js │ ├── 20210913183520_aoi-iter-id-null.js │ ├── 20211202194845_model-format.js │ ├── 20220211212740_meta-created-updated.js │ ├── 20210911030015_task-log-link.js │ ├── 20211206173656_aoi-submission.js │ └── 20220215151013_inf_list-json.js ├── test │ ├── fixtures │ │ ├── imagery.json │ │ └── project.json │ ├── drop.js │ ├── health.srv.test.js │ ├── 404.srv.test.js │ ├── server.srv.test.js │ └── schema.test.js ├── knexfile.js ├── docker-compose.yml ├── Dockerfile ├── lib │ └── auth.js ├── routes │ ├── mapbox.js │ └── stacks.js └── nginx.conf ├── .gitignore ├── cloudformation └── lib │ └── s3.js ├── package.json ├── .deploy ├── clone ├── .github └── workflows │ ├── lambda.yml │ ├── ecr_task_pop.yml │ ├── ecr_task_build.yml │ ├── ecr_task_tfrecords.yml │ ├── task_vectorize.yml │ └── api.yml └── LICENSE /lambda/tests/handler.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lambda/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tasks/task-pop/pop/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tasks/task-pop/.gitignore: -------------------------------------------------------------------------------- 1 | local.py 2 | -------------------------------------------------------------------------------- /api/web/.gitignore: -------------------------------------------------------------------------------- 1 | public/assembly.* 2 | -------------------------------------------------------------------------------- /lambda/download_and_predict/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tasks/task-vectorize/.gitignore: -------------------------------------------------------------------------------- 1 | data/ 2 | -------------------------------------------------------------------------------- /api/schema/geography_columns/f_table_name.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /api/schema/geometry_columns/f_table_name.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /tasks/task-build/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /api/schema/geography_columns/f_table_catalog.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /api/schema/geography_columns/f_table_schema.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /api/schema/geometry_columns/f_geometry_column.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /api/schema/geometry_columns/f_table_schema.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /api/schema/geography_columns/f_geography_column.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /api/schema/res.Inference.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object" 3 | } 4 | -------------------------------------------------------------------------------- /api/doc/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/img/favicon.ico -------------------------------------------------------------------------------- /api/schema/aois/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/aois/name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/aois/pid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/imagery/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/meta/key.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/tasks/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/tasks/type.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/doc/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/favicon.ico -------------------------------------------------------------------------------- /api/schema/aois/bounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "description": "", 4 | "$comment": "geometry" 5 | } -------------------------------------------------------------------------------- /api/schema/imagery/fmt.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/imagery/name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/imagery/pid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/imagery/url.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/integrations/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/iterations/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/iterations/pid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/meta/value.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "description": "", 4 | "$comment": "jsonb" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/access.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/notes.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "description": "", 4 | "$comment": "jsonb" 5 | } -------------------------------------------------------------------------------- /api/schema/tasks/iter_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/users/access.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users/email.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users/password.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users/username.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users_tokens/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/web/public/favicon.ico -------------------------------------------------------------------------------- /api/web/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/web/src/assets/logo.png -------------------------------------------------------------------------------- /api/doc/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/img/favicon-16x16.png -------------------------------------------------------------------------------- /api/doc/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/img/favicon-32x32.png -------------------------------------------------------------------------------- /api/schema/aoi_submission/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/integrations/name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/integrations/pid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/integrations/url.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/iterations/tile_zoom.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int4" 5 | } -------------------------------------------------------------------------------- /api/schema/knex_migrations/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int4" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/archived.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "boolean", 3 | "description": "", 4 | "$comment": "bool" 5 | } -------------------------------------------------------------------------------- /api/schema/projects/project_url.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_access/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_access/pid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_access/uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_invite/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_invite/pid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/spatial_ref_sys/srid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int4" 5 | } -------------------------------------------------------------------------------- /api/schema/users/validated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "boolean", 3 | "description": "", 4 | "$comment": "bool" 5 | } -------------------------------------------------------------------------------- /api/schema/users_tokens/name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users_tokens/token.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/users_tokens/uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/doc/assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/favicon-16x16.png -------------------------------------------------------------------------------- /api/doc/assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/favicon-32x32.png -------------------------------------------------------------------------------- /api/doc/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/img/apple-touch-icon.png -------------------------------------------------------------------------------- /api/schema/aoi_submission/iter_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int8" 5 | } -------------------------------------------------------------------------------- /api/schema/integrations/integration.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/iterations/model_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_access/access.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_invite/email.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/projects_invite/token.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "", 4 | "$comment": "text" 5 | } -------------------------------------------------------------------------------- /api/schema/util/any.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ "array", "boolean", "integer", "null", "number", "object", "string" ] 3 | } 4 | -------------------------------------------------------------------------------- /api/web/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /api/doc/assets/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/apple-touch-icon.png -------------------------------------------------------------------------------- /api/schema/knex_migrations_lock/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "number", 3 | "description": "", 4 | "$comment": "int4" 5 | } -------------------------------------------------------------------------------- /api/doc/img/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/img/android-chrome-192x192.png -------------------------------------------------------------------------------- /api/doc/img/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/img/android-chrome-512x512.png -------------------------------------------------------------------------------- /api/schema/util/validated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "boolean", 3 | "description": "Has the user's email address been validated" 4 | } 5 | -------------------------------------------------------------------------------- /lambda/download_and_predict/custom_types.py: -------------------------------------------------------------------------------- 1 | from typing import List, Dict, Any 2 | 3 | SQSEvent = Dict[str, List[Dict[str, Any]]] 4 | -------------------------------------------------------------------------------- /api/schema/util/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "integer", 3 | "description": "The timestamp at which the resource was created" 4 | } 5 | -------------------------------------------------------------------------------- /api/doc/assets/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/android-chrome-192x192.png -------------------------------------------------------------------------------- /api/doc/assets/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/android-chrome-512x512.png -------------------------------------------------------------------------------- /api/schema/util/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "integer", 3 | "description": "The timestamp at which the resource was last updated" 4 | } 5 | -------------------------------------------------------------------------------- /api/schema/aois/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/aois/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/meta/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/meta/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/tasks/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/tasks/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/users/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/doc/assets/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /api/doc/assets/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /api/doc/assets/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /api/doc/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /api/doc/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /api/doc/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /api/doc/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /api/schema/imagery/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/iterations/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/iterations/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/projects/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/projects/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /tasks/task-build/test/fixtures/pytorch-seg.mar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/tasks/task-build/test/fixtures/pytorch-seg.mar -------------------------------------------------------------------------------- /api/doc/assets/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/developmentseed/ml-enabler/HEAD/api/doc/assets/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /api/schema/aoi_submission/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/aois/iter_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int8" 8 | } -------------------------------------------------------------------------------- /api/schema/integrations/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/integrations/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/iterations/hint.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/projects/repo.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/projects_access/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/projects_access/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/projects_invite/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/tasks/batch_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/tasks/log_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/users_reset/uid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int8" 8 | } -------------------------------------------------------------------------------- /api/schema/users_tokens/created.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "format": "date-time", 4 | "description": "", 5 | "$comment": "timestamp" 6 | } -------------------------------------------------------------------------------- /api/schema/aoi_submission/aoi_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int8" 8 | } -------------------------------------------------------------------------------- /api/schema/geometry_columns/srid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/integrations/auth.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/gitsha.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/imagery_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int8" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/inf_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "object", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "jsonb" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/inf_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/model_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/save_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/knex_migrations/batch.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/users_reset/action.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/users_reset/token.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/geography_columns/srid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/geography_columns/type.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/checkpoint_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/docker_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/inf_binary.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "boolean", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "bool" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/inf_supertile.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "boolean", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "bool" 8 | } -------------------------------------------------------------------------------- /api/schema/iterations/tfrecord_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "text" 8 | } -------------------------------------------------------------------------------- /api/schema/spatial_ref_sys/auth_srid.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/util/page.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "integer", 3 | "default": 0, 4 | "minimum": 0, 5 | "description": "The page, based on the limit, to return" 6 | } 7 | -------------------------------------------------------------------------------- /tasks/task-pop/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.26.0 2 | boto3==1.20.24 3 | mercantile==1.2.1 4 | tiletanic==1.1.0 5 | pyproj==2.6.0 6 | Shapely==1.7.1 7 | geojson==2.5.0 8 | -------------------------------------------------------------------------------- /api/schema/knex_migrations_lock/is_locked.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/geography_columns/coord_dimension.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/geometry_columns/coord_dimension.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "number", 4 | "null" 5 | ], 6 | "description": "", 7 | "$comment": "int4" 8 | } -------------------------------------------------------------------------------- /api/schema/res.ListSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "schemas": { 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /api/schema/util/limit.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "integer", 3 | "default": 100, 4 | "maximum": 100, 5 | "minimum": 1, 6 | "description": "Limit number of returned items" 7 | } 8 | -------------------------------------------------------------------------------- /api/schema/geometry_columns/type.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "maxLength": 30, 7 | "description": "", 8 | "$comment": "varchar" 9 | } -------------------------------------------------------------------------------- /api/schema/imagery/updated.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "format": "date-time", 7 | "description": "", 8 | "$comment": "timestamp" 9 | } -------------------------------------------------------------------------------- /api/schema/knex_migrations/name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "maxLength": 255, 7 | "description": "", 8 | "$comment": "varchar" 9 | } -------------------------------------------------------------------------------- /lambda/mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | 3 | scripts_are_modules = True 4 | show_traceback = True 5 | ignore_missing_imports = True 6 | mypy_path = lambdas/download_and_predict 7 | namespace_packages = True 8 | -------------------------------------------------------------------------------- /api/schema/spatial_ref_sys/auth_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "maxLength": 256, 7 | "description": "", 8 | "$comment": "varchar" 9 | } -------------------------------------------------------------------------------- /api/schema/spatial_ref_sys/proj4text.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "maxLength": 2048, 7 | "description": "", 8 | "$comment": "varchar" 9 | } -------------------------------------------------------------------------------- /api/schema/spatial_ref_sys/srtext.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "maxLength": 2048, 7 | "description": "", 8 | "$comment": "varchar" 9 | } -------------------------------------------------------------------------------- /api/schema/users_reset/expires.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "format": "date-time", 7 | "description": "", 8 | "$comment": "timestamp" 9 | } -------------------------------------------------------------------------------- /api/schema/geometry_columns/f_table_catalog.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "maxLength": 256, 7 | "description": "", 8 | "$comment": "varchar" 9 | } -------------------------------------------------------------------------------- /api/schema/util/project-access.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "description": "Is the project public or private", 4 | "enum": [ 5 | "private", 6 | "public" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /lambda/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3==1.21.19 2 | numpy==1.22.3 3 | rasterio==1.2.10 4 | mercantile==1.2.1 5 | requests==2.27.1 6 | geojson==2.5.0 7 | pillow==8.0.1 8 | shapely==1.8.0 9 | affine==2.3.0 10 | -------------------------------------------------------------------------------- /api/schema/knex_migrations/migration_time.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": [ 3 | "string", 4 | "null" 5 | ], 6 | "format": "date-time", 7 | "description": "", 8 | "$comment": "timestamptz" 9 | } -------------------------------------------------------------------------------- /api/schema/req.body.PatchAOI.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/schema/util/order.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "default": "asc", 4 | "enum": [ 5 | "desc", 6 | "asc" 7 | ], 8 | "description": "Sort order to apply to results" 9 | } 10 | -------------------------------------------------------------------------------- /api/web/vue.config.js: -------------------------------------------------------------------------------- 1 | const Assembly = require('@mapbox/assembly'); 2 | 3 | module.exports = { 4 | publicPath: './', 5 | chainWebpack: () => { 6 | Assembly.buildUserAssets('public/') 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchTask.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "log_link": { 6 | "type": "string" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/migrations/migration.stub: -------------------------------------------------------------------------------- 1 | function up(knex) { 2 | return knex.schema.raw(``); 3 | } 4 | 5 | function down(knex) { 6 | return knex.schema.raw(``); 7 | } 8 | 9 | export { 10 | up, 11 | down 12 | } 13 | -------------------------------------------------------------------------------- /api/schema/util/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "minLength": 5, 4 | "maxLength": 14, 5 | "pattern": "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$", 6 | "description": "Semver of iteration" 7 | } 8 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchProjectAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "access": { 6 | "$ref": "./util/access.json" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /api/schema/util/access.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "string", 3 | "enum": [ 4 | "user", 5 | "read", 6 | "disabled", 7 | "admin" 8 | ], 9 | "description": "The access level of a given user" 10 | } 11 | -------------------------------------------------------------------------------- /lambda/Makefile: -------------------------------------------------------------------------------- 1 | 2 | SHELL = /bin/bash 3 | 4 | build: 5 | docker build --tag lambda:latest . 6 | docker run --name lambda -itd lambda:latest /bin/bash 7 | docker cp lambda:/tmp/package.zip package.zip 8 | docker stop lambda 9 | docker rm lambda -------------------------------------------------------------------------------- /api/migrations/20211221145633_remove-inf.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | DROP TABLE iteration_tiles; 4 | `); 5 | } 6 | 7 | export function down(knex) { 8 | return knex.schema.raw(``); 9 | } 10 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "name": { 6 | "type": "string", 7 | "description": "Name of the Token" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | venv/ 2 | venv-*/ 3 | node_modules/ 4 | web/dist/ 5 | 6 | *.pyc 7 | __pycache__/ 8 | 9 | instance/ 10 | 11 | .pytest_cache/ 12 | .coverage 13 | htmlcov/ 14 | 15 | dist/ 16 | build/ 17 | *.egg-info/ 18 | 19 | ml_enabler.env 20 | .DS_Store 21 | .vscode/ 22 | -------------------------------------------------------------------------------- /api/schema/util/bounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "array", 3 | "description": "GeoJSON bounds Array", 4 | "minItems": 4, 5 | "maxItems": 4, 6 | "items": { 7 | "type": "number", 8 | "description": "GeoJSON bounds Coordinate" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchMeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "value" 5 | ], 6 | "additionalProperties": false, 7 | "properties": { 8 | "value": { 9 | "$ref": "./util/any.json" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/schema/res.TilejsonPredictions.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "uploaded" 6 | ], 7 | "properties": { 8 | "uploaded": { 9 | "type": "boolean" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/test/fixtures/imagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "json": true, 3 | "url": "/api/project/1/imagery", 4 | "method": "POST", 5 | "body": { 6 | "name": "Test Imagery", 7 | "fmt": "wms", 8 | "url": "https://example.com/{z}/{x}/{y}.png" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /api/migrations/20220310194805_gh_repo-repo.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE projects 4 | RENAME github_repo TO repo; 5 | `); 6 | } 7 | 8 | export function down(knex) { 9 | return knex.schema.raw(``); 10 | } 11 | -------------------------------------------------------------------------------- /tasks/task-pop/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.3-jessie 2 | 3 | ENV HOME=/home/hot 4 | 5 | WORKDIR $HOME 6 | 7 | COPY ./ $HOME/task-pop 8 | WORKDIR $HOME/task-pop 9 | 10 | RUN \ 11 | pip install --upgrade pip \ 12 | pip install -r requirements.txt 13 | 14 | CMD python -m pop.handler 15 | -------------------------------------------------------------------------------- /api/schema/res.Mapbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "token" 5 | ], 6 | "additionalProperties": false, 7 | "properties": { 8 | "token": { 9 | "type": "string", 10 | "description": "Mapbox access token" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchUser.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "access": { 6 | "$ref": "./util/access.json" 7 | }, 8 | "validated": { 9 | "$ref": "./util/validated.json" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /api/schema/req.query.ListStacks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "filter": { 6 | "type": "string", 7 | "default": "", 8 | "description": "Filter a complete or partial stack name" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tasks/task-tfrecords/requirements.txt: -------------------------------------------------------------------------------- 1 | pyproj==2.6.0 2 | Shapely==1.7.1 3 | requests==2.24.0 4 | numpy==1.19.1 5 | boto3==1.14.41 6 | pandas==1.1.0 7 | scikit-learn==0.23.2 8 | tqdm==4.48.2 9 | mercantile==1.1.5 10 | pillow==7.2.0 11 | rasterio==1.1.5 12 | requests-toolbelt==0.9.1 13 | semver==2.10.2 14 | tiletanic==1.1.0 15 | -------------------------------------------------------------------------------- /api/web/src/components/util/InputError.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 15 | 16 | -------------------------------------------------------------------------------- /api/schema/req.body.ForgotLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "username" 5 | ], 6 | "additionalProperties": false, 7 | "properties": { 8 | "username": { 9 | "type": "string", 10 | "description": "username or email to reset password of" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /cloudformation/lib/s3.js: -------------------------------------------------------------------------------- 1 | import cf from '@mapbox/cloudfriend'; 2 | 3 | export default { 4 | Resources: { 5 | MLEnablerBucket: { 6 | Type: 'AWS::S3::Bucket', 7 | Properties: { 8 | BucketName: cf.join('-', [cf.stackName, cf.accountId, cf.region]) 9 | } 10 | } 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /api/schema/req.body.VerifyLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "token" 6 | ], 7 | "properties": { 8 | "token": { 9 | "type": "string", 10 | "description": "The validation token which was emailed to you" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchImagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | }, 8 | "url": { 9 | "type": "string" 10 | }, 11 | "fmt": { 12 | "type": "string" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lambda/upload-lambda.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # based on github.com/mapbox/lambda-cfn 3 | 4 | # ./util/upload-lambda lambda-directory bucket/prefix 5 | 6 | GITSHA=$(git rev-parse HEAD) 7 | echo "ok - ${GITSHA}" 8 | 9 | make -B build 10 | 11 | aws s3 cp ./package.zip s3://devseed-artifacts/ml-enabler/lambda-${GITSHA}.zip 12 | 13 | rm ./package.zip 14 | -------------------------------------------------------------------------------- /tasks/task-tfrecords/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM tensorflow/tensorflow:2.1.0-py3 2 | 3 | ENV SHELL /bin/bash 4 | ENV HOME=/home/task 5 | WORKDIR $HOME 6 | 7 | COPY ./ $HOME/retrain 8 | WORKDIR $HOME/retrain 9 | 10 | RUN mkdir /tmp/tfrecords 11 | 12 | RUN apt-get update \ 13 | && apt-get install -y git curl 14 | 15 | RUN pip install -r requirements.txt 16 | 17 | -------------------------------------------------------------------------------- /tasks/task-vectorize/test/fixtures/feature.json: -------------------------------------------------------------------------------- 1 | { "type": "Feature", "properties": {}, "geometry": { "type": "Polygon", "coordinates": [ [ [ -79.37772274017334, 38.833966309680264 ], [ -79.37630116939545, 38.833966309680264 ], [ -79.37630116939545, 38.8349900841108 ], [ -79.37772274017334, 38.8349900841108 ], [ -79.37772274017334, 38.833966309680264 ] ] ] } } 2 | 3 | -------------------------------------------------------------------------------- /api/migrations/20220310194437_iteration-git.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE iterations 4 | ADD COLUMN gitsha TEXT; 5 | `); 6 | } 7 | 8 | export function down(knex) { 9 | return knex.schema.raw(` 10 | ALTER TABLE iterations 11 | DROP COLUMN gitsha; 12 | `); 13 | } 14 | -------------------------------------------------------------------------------- /api/migrations/20220211173513_meta.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | CREATE TABLE meta ( 4 | key TEXT NOT NULL PRIMARY KEY, 5 | value JSONB NOT NULL 6 | ) 7 | `); 8 | } 9 | 10 | export function down(knex) { 11 | return knex.schema.raw(` 12 | DROP TABLE meta; 13 | `); 14 | } 15 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateInference.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "inferences" 5 | ], 6 | "additionalProperties": false, 7 | "properties": { 8 | "inferences": { 9 | "type": "array", 10 | "items": { 11 | "type": "object" 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateProjectAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "uid": { 6 | "type": "integer", 7 | "description": "User ID to add to project" 8 | }, 9 | "access": { 10 | "$ref": "./util/access.json" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/migrations/20220310194626_project-github.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE projects 4 | ADD COLUMN github_repo TEXT; 5 | `); 6 | } 7 | 8 | export function down(knex) { 9 | return knex.schema.raw(` 10 | ALTER TABLE projects 11 | DROP COLUMN github_repo; 12 | `); 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.0.0", 3 | "type": "module", 4 | "scripts": { 5 | "lint": "eslint cloudformation/*.js cloudformation/lib/*.js" 6 | }, 7 | "dependencies": { 8 | "@mapbox/cloudfriend": "^6.0.0", 9 | "batch-alarms": "^2.0.0", 10 | "eslint": "^8.25.0", 11 | "eslint-plugin-node": "^11.1.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /api/migrations/20210913183520_aoi-iter-id-null.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE aois 4 | ALTER COLUMN iter_id DROP NOT NULL; 5 | `); 6 | } 7 | 8 | export function down(knex) { 9 | return knex.schema.raw(` 10 | ALTER TABLE aois 11 | ALTER COLUMN iter_id SET NOT NULL; 12 | `); 13 | } 14 | -------------------------------------------------------------------------------- /api/doc/api_project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ML Enabler", 3 | "title": "ML Enabler", 4 | "version": "3.0.0", 5 | "description": "", 6 | "sampleUrl": false, 7 | "defaultVersion": "0.0.0", 8 | "apidoc": "0.3.0", 9 | "generator": { 10 | "name": "apidoc", 11 | "time": "2021-09-13T17:34:03.236Z", 12 | "url": "https://apidocjs.com", 13 | "version": "0.29.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /api/doc/api_project.js: -------------------------------------------------------------------------------- 1 | define({ 2 | "name": "ML Enabler", 3 | "title": "ML Enabler", 4 | "version": "3.0.0", 5 | "description": "", 6 | "sampleUrl": false, 7 | "defaultVersion": "0.0.0", 8 | "apidoc": "0.3.0", 9 | "generator": { 10 | "name": "apidoc", 11 | "time": "2021-09-13T17:34:03.236Z", 12 | "url": "https://apidocjs.com", 13 | "version": "0.29.0" 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /api/migrations/20211202194845_model-format.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE iterations 4 | ADD COLUMN model_type TEXT NOT NULL DEFAULT 'tensorflow'; 5 | `); 6 | } 7 | 8 | export function down(knex) { 9 | return knex.schema.raw(` 10 | ALTER TABLE iterations 11 | DROP COLUMN model_type; 12 | `); 13 | } 14 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "name" 5 | ], 6 | "additionalProperties": false, 7 | "properties": { 8 | "name": { 9 | "type": "string", 10 | "minLength": 2, 11 | "maxLength": 40, 12 | "description": "Human Readable name of the API Token" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /api/migrations/20220211212740_meta-created-updated.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE meta 4 | ADD COLUMN created TIMESTAMP NOT NULL DEFAULT NOW(); 5 | 6 | ALTER TABLE meta 7 | ADD COLUMN updated TIMESTAMP NOT NULL DEFAULT NOW(); 8 | `); 9 | } 10 | 11 | export function down(knex) { 12 | return knex.schema.raw(``); 13 | } 14 | -------------------------------------------------------------------------------- /api/schema/util/polygon.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "description": "GeoJSON Polygon", 4 | "required": [ 5 | "type", 6 | "coordinates" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "type": { 11 | "type": "string", 12 | "enum": [ "Polygon" ] 13 | }, 14 | "coordinates": { 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /api/schema/knex_migrations_lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "index": { 6 | "$ref": "./knex_migrations_lock/index.json" 7 | }, 8 | "is_locked": { 9 | "$ref": "./knex_migrations_lock/is_locked.json" 10 | } 11 | }, 12 | "required": [ 13 | "index", 14 | "is_locked" 15 | ] 16 | } -------------------------------------------------------------------------------- /api/schema/req.body.CreateMeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "key", 5 | "value" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "key": { 10 | "type": "string", 11 | "minLength": 2, 12 | "maxLength": 40 13 | }, 14 | "value": { 15 | "$ref": "./util/any.json" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/web/README.md: -------------------------------------------------------------------------------- 1 | # ml-enabler 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | yarn lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchIntegration.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "integration": { 6 | "type": "string" 7 | }, 8 | "name": { 9 | "type": "string" 10 | }, 11 | "url": { 12 | "type": "string" 13 | }, 14 | "auth": { 15 | "type": "string" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/knexfile.js: -------------------------------------------------------------------------------- 1 | export default { 2 | client: 'postgresql', 3 | connection: process.env.POSTGRES || 'postgres://postgres@localhost:5432/mlenabler', 4 | pool: { 5 | min: 2, 6 | max: 10 7 | }, 8 | migrations: { 9 | tableName: 'knex_migrations', 10 | stub: 'migrations/migration.stub', 11 | directory: String(new URL('./migrations', import.meta.url)).replace('file://', '') 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /api/schema/res.UserReset.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "uid", 5 | "expires", 6 | "action" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "uid": { 11 | "type": "integer" 12 | }, 13 | "expires": { 14 | "type": "string" 15 | }, 16 | "action": { 17 | "type": "string" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api/schema/res.StackQueue.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "queued", 5 | "inflight", 6 | "dead" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "queued": { 11 | "type": "integer" 12 | }, 13 | "inflight": { 14 | "type": "integer" 15 | }, 16 | "dead": { 17 | "type": "integer" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api/schema/req.query.UploadIterationAsset.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "type" 6 | ], 7 | "properties": { 8 | "type": { 9 | "type": "string", 10 | "enum": [ 11 | "model", 12 | "tfrecord", 13 | "checkpoint" 14 | ], 15 | "description": "Asset Type to upload" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/schema/req.body.ResetLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "token", 5 | "password" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "token": { 10 | "type": "string", 11 | "description": "Email provided reset token" 12 | }, 13 | "password": { 14 | "type": "string", 15 | "description": "The new user password" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/schema/req.query.ListMeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial meta key" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /api/schema/req.query.ListTokens.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial token name" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /api/schema/res.Health.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "healthy", 5 | "message" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "healthy": { 10 | "type": "boolean", 11 | "description": "Is the service healthy?" 12 | }, 13 | "message": { 14 | "type": "string", 15 | "description": "The service on how it is doing" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/schema/res.Standard.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "status", 5 | "message" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "status": { 10 | "type": "integer", 11 | "description": "The HTTP Status Code of the response" 12 | }, 13 | "message": { 14 | "type": "string", 15 | "description": "A human readable status message" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateStack.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "tags", 6 | "max_size", 7 | "max_concurrency" 8 | ], 9 | "properties": { 10 | "tags": { 11 | "$ref": "./util/project-tags.json" 12 | }, 13 | "max_size": { 14 | "type": "integer" 15 | }, 16 | "max_concurrency": { 17 | "type": "integer" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api/migrations/20210911030015_task-log-link.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | ALTER TABLE tasks 4 | ADD COLUMN log_link TEXT; 5 | 6 | ALTER TABLE iterations 7 | DROP COLUMN log_link; 8 | `); 9 | } 10 | 11 | export function down(knex) { 12 | return knex.schema.raw(` 13 | ALTER TABLE tasks 14 | DROP COLUMN log_link; 15 | 16 | ALTER TABLE iterations 17 | ADD COLUMN log_link TEXT; 18 | `); 19 | } 20 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateImagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "name", 5 | "url", 6 | "fmt" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "name": { 11 | "type": "string", 12 | "minLength": 2, 13 | "maxLength": 40 14 | }, 15 | "url": { 16 | "type": "string" 17 | }, 18 | "fmt": { 19 | "type": "string" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /api/migrations/20211206173656_aoi-submission.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | CREATE TABLE aoi_submission ( 4 | id BIGSERIAL, 5 | aoi_id BIGINT REFERENCES aois(id), 6 | created TIMESTAMP NOT NULL DEFAULT NOW(), 7 | iter_id BIGINT NOT NULL REFERENCES iterations(id) 8 | ); 9 | `); 10 | } 11 | 12 | export function down(knex) { 13 | return knex.schema.raw(` 14 | DROP TABLE aoi_submission; 15 | `); 16 | } 17 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchIteration.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "docker_link": { 6 | "type": "string" 7 | }, 8 | "model_link": { 9 | "type": "string" 10 | }, 11 | "checkpoint_link": { 12 | "type": "string" 13 | }, 14 | "tfrecord_link": { 15 | "type": "string" 16 | }, 17 | "save_link": { 18 | "type": "string" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /api/schema/util/project-tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "array", 3 | "description": "Billing tags that should be attached to project resources", 4 | "items": { 5 | "type": "object", 6 | "additionalProperties": false, 7 | "required": [ 8 | "Key", 9 | "Value" 10 | ], 11 | "properties": { 12 | "Key": { 13 | "type": "string" 14 | }, 15 | "Value": { 16 | "type": "string" 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api/test/fixtures/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "json": true, 3 | "url": "/api/project", 4 | "method": "POST", 5 | "body": { 6 | "name": "Test Project", 7 | "source": "Development Seed", 8 | "project_url": "example.com/test", 9 | "access": "private", 10 | "notes": "I am a note", 11 | "tags": [{ 12 | "Key": "Billing", 13 | "Value": "Tags" 14 | }], 15 | "users": [{ 16 | "uid": 1, 17 | "access": "admin" 18 | }] 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "username", 5 | "password" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "username": { 10 | "type": "string", 11 | "minLength": 2, 12 | "maxLength": 40, 13 | "description": "username" 14 | }, 15 | "password": { 16 | "type": "string", 17 | "minLength": 8, 18 | "description": "password" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lambda/download_and_predict/__main__.py: -------------------------------------------------------------------------------- 1 | import json 2 | from download_and_predict.handler import handler 3 | 4 | handler(event={ 5 | 'Records': [{ 6 | 'body': json.dumps({ 7 | 'name': '18-52269-100179', 8 | 'x': 52269, 9 | 'y': 100179, 10 | 'z': 18, 11 | 'url': 'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/256/18/52269/100179?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXFhYTA2bTMyeW44ZG0ybXBkMHkifQ.gUGbDOPUN1v1fTs5SeOR4A' 12 | }) 13 | }] 14 | }, context={}) 15 | -------------------------------------------------------------------------------- /api/web/src/components/util/Loading.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | -------------------------------------------------------------------------------- /api/schema/res.Meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "key", 5 | "value", 6 | "created", 7 | "updated" 8 | ], 9 | "additionalProperties": false, 10 | "properties": { 11 | "key": { 12 | "type": "string" 13 | }, 14 | "value": { 15 | "$ref": "./util/any.json" 16 | }, 17 | "created": { 18 | "$ref": "./util/created.json" 19 | }, 20 | "updated": { 21 | "$ref": "./util/updated.json" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tasks/task-build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker:19.03.0-dind 2 | 3 | ENV SHELL /bin/bash 4 | ENV DEBIAN_FRONTEND=noninteractive 5 | ENV DOCKER_DRIVER=overlay2 6 | ENV DOCKER_TLS_CERTDIR='' 7 | 8 | RUN apk add nodejs npm 9 | RUN apk -v --update add \ 10 | python3 \ 11 | groff \ 12 | less \ 13 | mailcap \ 14 | && python3 -m ensurepip \ 15 | && pip3 install --upgrade pip \ 16 | && pip3 install --upgrade awscli==1.14.5 s3cmd==2.0.1 python-magic 17 | 18 | WORKDIR /usr/local/src/batch 19 | ADD . /usr/local/src/batch 20 | 21 | RUN npm install 22 | -------------------------------------------------------------------------------- /api/schema/meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "key": { 6 | "$ref": "./meta/key.json" 7 | }, 8 | "value": { 9 | "$ref": "./meta/value.json" 10 | }, 11 | "created": { 12 | "$ref": "./meta/created.json" 13 | }, 14 | "updated": { 15 | "$ref": "./meta/updated.json" 16 | } 17 | }, 18 | "required": [ 19 | "key", 20 | "value", 21 | "created", 22 | "updated" 23 | ] 24 | } -------------------------------------------------------------------------------- /api/web/src/components/iteration/stack/QueueList.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | Submit "" For Inferencing 4 | 5 | Submit 6 | 7 | 8 | 9 | 10 | 19 | -------------------------------------------------------------------------------- /.deploy: -------------------------------------------------------------------------------- 1 | { 2 | "profile": "devseed", 3 | "artifacts": { 4 | "docker": [ 5 | "{{project}}:{{gitsha}}", 6 | "{{project}}:task-build-{{gitsha}}", 7 | "{{project}}:task-pop-{{gitsha}}", 8 | "{{project}}:task-vectorize-{{gitsha}}" 9 | ], 10 | "lambda": [ 11 | "devseed-artifacts/ml-enabler/lambda-{{gitsha}}.zip" 12 | ] 13 | }, 14 | "tags": [{ 15 | "Key": "Project", 16 | "Value": "ml-enabler" 17 | },{ 18 | "Key": "Client", 19 | "Value": "labs" 20 | }] 21 | } 22 | -------------------------------------------------------------------------------- /tasks/task-vectorize/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.15 2 | 3 | RUN apk add nodejs npm git make bash sqlite-dev zlib-dev gcc g++ python3 py3-pip 4 | 5 | RUN pip3 install --upgrade pip \ 6 | && pip3 install --no-cache-dir awscli 7 | 8 | 9 | # Download and install Tippecanoe 10 | RUN git clone -b 1.36.0 https://github.com/mapbox/tippecanoe.git /tmp/tippecanoe && \ 11 | cd /tmp/tippecanoe && \ 12 | make && \ 13 | PREFIX=/usr/local make install && \ 14 | rm -rf /tmp/tippecanoe 15 | 16 | WORKDIR /usr/local/src/task 17 | ADD . /usr/local/src/task 18 | 19 | RUN npm install 20 | 21 | CMD ./task 22 | -------------------------------------------------------------------------------- /api/schema/users_reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "uid": { 6 | "$ref": "./users_reset/uid.json" 7 | }, 8 | "expires": { 9 | "$ref": "./users_reset/expires.json" 10 | }, 11 | "token": { 12 | "$ref": "./users_reset/token.json" 13 | }, 14 | "action": { 15 | "$ref": "./users_reset/action.json" 16 | } 17 | }, 18 | "required": [ 19 | "uid", 20 | "expires", 21 | "token", 22 | "action" 23 | ] 24 | } -------------------------------------------------------------------------------- /api/schema/util/inf-list.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "array", 3 | "items": { 4 | "type": "object", 5 | "required": [ 6 | "name" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "name": { 11 | "type": "string", 12 | "description": "Class Name" 13 | }, 14 | "color": { 15 | "type": "string", 16 | "description": "Color to use for class", 17 | "pattern": "^#(?:[0-9a-fA-F]{3}){1,2}$" 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /api/schema/util/project-users.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "array", 3 | "description": "Access list of users for a particular project", 4 | "items": { 5 | "type": "object", 6 | "additionalProperties": false, 7 | "required": [ 8 | "uid", 9 | "access" 10 | ], 11 | "properties": { 12 | "uid": { 13 | "type": "integer", 14 | "description": "User ID to set access for" 15 | }, 16 | "access": { 17 | "$ref": "./access.json" 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /api/schema/res.Stack.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "id", 5 | "name", 6 | "status" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "id": { 11 | "type": "string", 12 | "description": "AWS ARN ID" 13 | }, 14 | "name": { 15 | "type": "string", 16 | "description": "Human Readable CloudFormation Stack Name" 17 | }, 18 | "status": { 19 | "type": "string", 20 | "description": "CloudFormation Status Enum" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateAOI.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "bounds", 6 | "name" 7 | ], 8 | "properties": { 9 | "iter_id": { 10 | "type": "integer", 11 | "description": "Iteration ID" 12 | }, 13 | "name": { 14 | "type": "string", 15 | "minLength": 2, 16 | "maxLength": 40, 17 | "description": "Human readable name of the AOI" 18 | }, 19 | "bounds": { 20 | "$ref": "./util/bounds.json" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateIntegration.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "integration", 6 | "name", 7 | "url", 8 | "auth" 9 | ], 10 | "properties": { 11 | "integration": { 12 | "type": "string" 13 | }, 14 | "name": { 15 | "type": "string", 16 | "minLength": 1, 17 | "maxLength": 40 18 | }, 19 | "url": { 20 | "type": "string" 21 | }, 22 | "auth": { 23 | "type": "string" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /api/schema/aoi_submission.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./aoi_submission/id.json" 7 | }, 8 | "aoi_id": { 9 | "$ref": "./aoi_submission/aoi_id.json" 10 | }, 11 | "created": { 12 | "$ref": "./aoi_submission/created.json" 13 | }, 14 | "iter_id": { 15 | "$ref": "./aoi_submission/iter_id.json" 16 | } 17 | }, 18 | "required": [ 19 | "id", 20 | "aoi_id", 21 | "created", 22 | "iter_id" 23 | ] 24 | } -------------------------------------------------------------------------------- /api/schema/knex_migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./knex_migrations/id.json" 7 | }, 8 | "name": { 9 | "$ref": "./knex_migrations/name.json" 10 | }, 11 | "batch": { 12 | "$ref": "./knex_migrations/batch.json" 13 | }, 14 | "migration_time": { 15 | "$ref": "./knex_migrations/migration_time.json" 16 | } 17 | }, 18 | "required": [ 19 | "id", 20 | "name", 21 | "batch", 22 | "migration_time" 23 | ] 24 | } -------------------------------------------------------------------------------- /api/schema/req.query.DownloadIterationAsset.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "type", 6 | "token" 7 | ], 8 | "properties": { 9 | "type": { 10 | "type": "string", 11 | "enum": [ 12 | "model", 13 | "tfrecord", 14 | "checkpoint", 15 | "save" 16 | ], 17 | "description": "Asset Type to upload" 18 | }, 19 | "token": { 20 | "type": "string", 21 | "description": "Authentication Token" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /api/web/src/components/Lost.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Not all who wander are lost 5 | 6 | 7 | But you are! 8 | 9 | 10 | Take Me Home 11 | 12 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /api/test/drop.js: -------------------------------------------------------------------------------- 1 | import PG from 'pg'; 2 | const Pool = PG.Pool; 3 | 4 | import config from '../knexfile.js'; 5 | 6 | export default async function drop() { 7 | const pool = new Pool({ 8 | connectionString: config.connection 9 | }); 10 | 11 | const pgres = await pool.query(` 12 | SELECT 13 | 'drop table "' || tablename || '" cascade;' AS drop 14 | FROM 15 | pg_tables 16 | WHERE 17 | schemaname = 'public' 18 | AND tablename != 'spatial_ref_sys' 19 | `); 20 | 21 | for (const r of pgres.rows) { 22 | await pool.query(r.drop); 23 | } 24 | 25 | await pool.end(); 26 | } 27 | -------------------------------------------------------------------------------- /api/schema/res.ProjectAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "id", 6 | "uid", 7 | "pid", 8 | "access" 9 | ], 10 | "properties": { 11 | "id": { 12 | "type": "integer", 13 | "description": "Project Access ID" 14 | }, 15 | "uid": { 16 | "type": "integer", 17 | "description": "User ID" 18 | }, 19 | "pid": { 20 | "type": "integer", 21 | "description": "Project ID" 22 | }, 23 | "access": { 24 | "$ref": "./util/access.json" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api/schema/req.query.ListSubmissions.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "order": { 12 | "$ref": "./util/order.json" 13 | }, 14 | "sort": { 15 | "type": "string", 16 | "default": "created", 17 | "enum": [ 18 | "id", 19 | "created", 20 | "aoi_id" 21 | ], 22 | "description": "Field to sort order by" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateTask.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "type" 5 | ], 6 | "additionalProperties": false, 7 | "properties": { 8 | "type": { 9 | "type": "string", 10 | "enum": [ 11 | "vectorize" 12 | ], 13 | "description": "The class of type to start" 14 | }, 15 | "data": { 16 | "oneOf": [{ 17 | "type": "object", 18 | "properties": { 19 | "submission": { 20 | "type": "integer" 21 | } 22 | } 23 | }] 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /clone: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Clone a stacks database into a local database for development 4 | # 5 | 6 | if [[ -z $1 ]]; then 7 | echo "Error: Must provide stack name" 8 | echo 9 | echo "./clone " 10 | echo 11 | exit 1 12 | fi 13 | 14 | set -xeuo pipefail 15 | 16 | DB=$(deploy info $1 | jq -rc .Outputs.DB) 17 | pg_dump --verbose --schema public -Fc "$DB" > /tmp/$1-out.sql 18 | 19 | echo " 20 | DROP DATABASE mlenabler; 21 | CREATE DATABASE mlenabler; 22 | " | psql -U postgres 23 | 24 | echo " 25 | CREATE EXTENSION POSTGIS; 26 | CREATE EXTENSION PGCrypto; 27 | " | psql -U postgres mlenabler 28 | 29 | pg_restore -U postgres -d mlenabler < /tmp/$1-out.sql 30 | -------------------------------------------------------------------------------- /api/schema/req.query.ListSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "method": { 6 | "type": "string", 7 | "description": "HTTP Verb", 8 | "enum": [ 9 | "GET", 10 | "HEAD", 11 | "POST", 12 | "PUT", 13 | "DELETE", 14 | "CONNECT", 15 | "OPTIONS", 16 | "TRACE", 17 | "PATCH" 18 | ] 19 | }, 20 | "url": { 21 | "type": "string", 22 | "description": "URLEncoded URL that you want to fetch" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api/schema/res.Token.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "id", 5 | "name", 6 | "created" 7 | ], 8 | "additionalProperties": false, 9 | "properties": { 10 | "id": { 11 | "type": "integer", 12 | "description": "Token ID" 13 | }, 14 | "name": { 15 | "type": "string", 16 | "description": "Human Readable name of the API Token" 17 | }, 18 | "created": { 19 | "$ref": "./util/created.json" 20 | }, 21 | "token": { 22 | "type": "string", 23 | "description": "Token returned when initially created" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /api/schema/users_tokens.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./users_tokens/id.json" 7 | }, 8 | "uid": { 9 | "$ref": "./users_tokens/uid.json" 10 | }, 11 | "name": { 12 | "$ref": "./users_tokens/name.json" 13 | }, 14 | "token": { 15 | "$ref": "./users_tokens/token.json" 16 | }, 17 | "created": { 18 | "$ref": "./users_tokens/created.json" 19 | } 20 | }, 21 | "required": [ 22 | "id", 23 | "uid", 24 | "name", 25 | "token", 26 | "created" 27 | ] 28 | } -------------------------------------------------------------------------------- /api/test/health.srv.test.js: -------------------------------------------------------------------------------- 1 | import test from 'tape'; 2 | import Flight from './flight.js'; 3 | 4 | const flight = new Flight(); 5 | 6 | flight.init(test); 7 | flight.takeoff(test); 8 | 9 | test('GET: health', async (t) => { 10 | try { 11 | const res = await flight.request({ 12 | url: '/health', 13 | method: 'GET', 14 | json: true 15 | }); 16 | 17 | t.equals(res.statusCode, 200, 'http: 200'); 18 | t.deepEquals(res.body, { 19 | healthy: true, 20 | message: ':wave:' 21 | }); 22 | } catch (err) { 23 | t.error(err, 'no error'); 24 | } 25 | 26 | t.end(); 27 | }); 28 | 29 | flight.landing(test); 30 | -------------------------------------------------------------------------------- /api/schema/projects_invite.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./projects_invite/id.json" 7 | }, 8 | "pid": { 9 | "$ref": "./projects_invite/pid.json" 10 | }, 11 | "created": { 12 | "$ref": "./projects_invite/created.json" 13 | }, 14 | "email": { 15 | "$ref": "./projects_invite/email.json" 16 | }, 17 | "token": { 18 | "$ref": "./projects_invite/token.json" 19 | } 20 | }, 21 | "required": [ 22 | "id", 23 | "pid", 24 | "created", 25 | "email", 26 | "token" 27 | ] 28 | } -------------------------------------------------------------------------------- /api/web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ML-Enabler 9 | 10 | 11 | 12 | 13 | 14 | 15 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue. 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /lambda/tests/test_base.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from mercantile import Tile 3 | 4 | from download_and_predict.base import DownloadAndPredict 5 | 6 | def test_get_tiles(): 7 | # create a class with fake environment variables 8 | dap = DownloadAndPredict( 9 | imagery='https://example.com/{z}/{x}/{y}.png', 10 | db='postgres://usr:pw@host:port/database', 11 | prediction_endpoint='https://myloadbalancer.com/v1/models/ml:predict' 12 | ) 13 | 14 | # create an example SQS event which invokes a lambda 15 | event = { 'Records': [ { "body": '{ "x": 4, "y": 5, "z":3 }' }] } 16 | 17 | tiles = dap.get_tiles(event) 18 | fixture_tiles = [Tile(x=4, y=5, z=3)] 19 | 20 | assert(tiles == fixture_tiles) 21 | -------------------------------------------------------------------------------- /api/schema/res.CreateToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "id", 5 | "name", 6 | "token", 7 | "created" 8 | ], 9 | "additionalProperties": false, 10 | "properties": { 11 | "id": { 12 | "type": "integer", 13 | "description": "Token ID" 14 | }, 15 | "name": { 16 | "type": "string", 17 | "description": "Human Readable name of the API Token" 18 | }, 19 | "token": { 20 | "type": "string", 21 | "description": "API Token (Only returned once at creation time)" 22 | }, 23 | "created": { 24 | "$ref": "./util/created.json" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateUser.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "username", 5 | "email" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "username": { 10 | "type": "string", 11 | "minLength": 2, 12 | "maxLength": 40, 13 | "description": "username" 14 | }, 15 | "password": { 16 | "type": "string", 17 | "minLength": 2, 18 | "maxLength": 40, 19 | "description": "password" 20 | }, 21 | "email": { 22 | "type": "string", 23 | "minLength": 2, 24 | "maxLength": 320, 25 | "description": "email" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /api/test/404.srv.test.js: -------------------------------------------------------------------------------- 1 | import test from 'tape'; 2 | import Flight from './flight.js'; 3 | 4 | const flight = new Flight(); 5 | 6 | flight.init(test); 7 | flight.takeoff(test); 8 | 9 | test('GET: api/fake', async (t) => { 10 | try { 11 | const res = await flight.request({ 12 | url: '/api/fake', 13 | method: 'GET', 14 | json: true 15 | }); 16 | 17 | t.equals(res.statusCode, 404, 'http: 404'); 18 | t.deepEquals(res.body, { 19 | status: 404, 20 | message: 'API endpoint does not exist!', 21 | messages: [] 22 | }); 23 | } catch (err) { 24 | t.error(err, 'no error'); 25 | } 26 | 27 | t.end(); 28 | }); 29 | 30 | flight.landing(test); 31 | -------------------------------------------------------------------------------- /api/schema/spatial_ref_sys.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "srid": { 6 | "$ref": "./spatial_ref_sys/srid.json" 7 | }, 8 | "auth_name": { 9 | "$ref": "./spatial_ref_sys/auth_name.json" 10 | }, 11 | "auth_srid": { 12 | "$ref": "./spatial_ref_sys/auth_srid.json" 13 | }, 14 | "srtext": { 15 | "$ref": "./spatial_ref_sys/srtext.json" 16 | }, 17 | "proj4text": { 18 | "$ref": "./spatial_ref_sys/proj4text.json" 19 | } 20 | }, 21 | "required": [ 22 | "srid", 23 | "auth_name", 24 | "auth_srid", 25 | "srtext", 26 | "proj4text" 27 | ] 28 | } -------------------------------------------------------------------------------- /api/schema/res.Integration.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "id", 6 | "pid", 7 | "created", 8 | "updated", 9 | "integration", 10 | "name", 11 | "url" 12 | ], 13 | "properties": { 14 | "id": { 15 | "type": "integer" 16 | }, 17 | "created": { 18 | "$ref": "./util/created.json" 19 | }, 20 | "updated": { 21 | "$ref": "./util/updated.json" 22 | }, 23 | "integration": { 24 | "type": "string" 25 | }, 26 | "name": { 27 | "type": "string" 28 | }, 29 | "url": { 30 | "type": "string" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /api/test/server.srv.test.js: -------------------------------------------------------------------------------- 1 | import test from 'tape'; 2 | import Flight from './flight.js'; 3 | 4 | const flight = new Flight(); 5 | 6 | flight.init(test); 7 | flight.takeoff(test); 8 | 9 | test('GET: api', async (t) => { 10 | try { 11 | const res = await flight.request({ 12 | url: '/api', 13 | method: 'GET', 14 | json: true 15 | }); 16 | 17 | t.equals(res.statusCode, 200, 'http: 200'); 18 | t.deepEquals(res.body, { 19 | version: '3.0.0', 20 | stack: 'test', 21 | environment: 'docker', 22 | security: 'authenticated' 23 | }); 24 | } catch (err) { 25 | t.error(err, 'no error'); 26 | } 27 | 28 | t.end(); 29 | }); 30 | 31 | flight.landing(test); 32 | -------------------------------------------------------------------------------- /api/schema/res.Login.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "id", 5 | "username", 6 | "email", 7 | "access" 8 | ], 9 | "additionalProperties": false, 10 | "properties": { 11 | "id": { 12 | "type": "integer" 13 | }, 14 | "username": { 15 | "type": "string" 16 | }, 17 | "email": { 18 | "type": "string" 19 | }, 20 | "access": { 21 | "$ref": "./util/access.json" 22 | }, 23 | "validated": { 24 | "$ref": "./util/validated.json" 25 | }, 26 | "token": { 27 | "type": "string", 28 | "description": "JSON Web Token to use for subsequent auth" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/schema/res.User.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "id", 5 | "username", 6 | "email", 7 | "access", 8 | "validated" 9 | ], 10 | "additionalProperties": false, 11 | "properties": { 12 | "id": { 13 | "type": "integer", 14 | "description": "User ID" 15 | }, 16 | "validated": { 17 | "$ref": "./util/validated.json" 18 | }, 19 | "username": { 20 | "type": "string", 21 | "description": "Unique Username" 22 | }, 23 | "email": { 24 | "type": "string", 25 | "description": "Unique Email" 26 | }, 27 | "access": { 28 | "$ref": "./util/access.json" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/schema/req.body.PatchProject.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | }, 8 | "source": { 9 | "type": "string" 10 | }, 11 | "project_url": { 12 | "type": "string" 13 | }, 14 | "archived": { 15 | "type": "boolean" 16 | }, 17 | "tags": { 18 | "$ref": "./util/project-tags.json" 19 | }, 20 | "access": { 21 | "$ref": "./util/project-access.json" 22 | }, 23 | "notes": { 24 | "type": "string" 25 | }, 26 | "repo": { 27 | "type": "string", 28 | "minLength": 2, 29 | "maxLength": 128 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/lambda.yml: -------------------------------------------------------------------------------- 1 | name: AWS Lambda 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Configure AWS Credentials 12 | uses: aws-actions/configure-aws-credentials@v1 13 | with: 14 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 15 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 16 | aws-region: us-east-1 17 | 18 | - name: Docker Layer Caching 19 | uses: satackey/action-docker-layer-caching@v0.0.11 20 | continue-on-error: true 21 | 22 | - name: Build Lambda 23 | run: | 24 | cd ./lambda 25 | ./upload-lambda.sh 26 | -------------------------------------------------------------------------------- /api/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | api: 3 | platform: linux/amd64 4 | build: . 5 | command: sh -c "./node_modules/.bin/knex migrate:latest && npm run lint && npm run doc && npm test" 6 | restart: always 7 | links: 8 | - postgis 9 | ports: 10 | - "2000:2000" 11 | environment: 12 | - GitSha=testing 13 | - POSTGRES=postgres://docker:docker@postgis:5432/gis 14 | - MAPBOX_TOKEN 15 | 16 | postgis: 17 | platform: linux/amd64 18 | image: kartoza/postgis:13.0 19 | restart: 'always' 20 | ports: 21 | - 5433:5432 22 | environment: 23 | - ALLOW_IP_RANGE=0.0.0.0/0 24 | - POSTGRES_DB=gis 25 | - POSTGRES_USER=docker 26 | - POSTGRES_PASS=docker 27 | - POSTGRES_MULTIPLE_EXTENSIONS="postgis","uuid-ossp" 28 | - DATADIR=/opt/postgres/data 29 | -------------------------------------------------------------------------------- /api/schema/req.body.PopulateStackQueue.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [], 4 | "additionalProperties": false, 5 | "properties": { 6 | "aoi_id": { 7 | "type": "integer" 8 | }, 9 | "geometry": { 10 | "$ref": "./util/polygon.json" 11 | }, 12 | "autoTerminate": { 13 | "type": "boolean", 14 | "default": true, 15 | "description": "If true, delete the stack after the SQS queue has emptied and inferencing is finished" 16 | }, 17 | "autoVectorize": { 18 | "type": "boolean", 19 | "default": true, 20 | "description": "If true, automatically start a vectorize task to compile inferences after sqs queue has emptied and inferencing is finished" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api/schema/projects_access.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./projects_access/id.json" 7 | }, 8 | "pid": { 9 | "$ref": "./projects_access/pid.json" 10 | }, 11 | "uid": { 12 | "$ref": "./projects_access/uid.json" 13 | }, 14 | "access": { 15 | "$ref": "./projects_access/access.json" 16 | }, 17 | "created": { 18 | "$ref": "./projects_access/created.json" 19 | }, 20 | "updated": { 21 | "$ref": "./projects_access/updated.json" 22 | } 23 | }, 24 | "required": [ 25 | "id", 26 | "pid", 27 | "uid", 28 | "access", 29 | "created", 30 | "updated" 31 | ] 32 | } -------------------------------------------------------------------------------- /api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | EXPOSE 2000 4 | 5 | ENV HOME=/home/mle 6 | WORKDIR $HOME 7 | COPY ./ $HOME/api 8 | WORKDIR $HOME/api 9 | 10 | RUN apt-get update > /dev/null \ 11 | && DEBIAN_FRONTEND=noninteractive apt-get install -y nginx curl git python3 > /dev/null 12 | 13 | RUN export NODEV='18.7.0' \ 14 | && curl "https://nodejs.org/dist/v${NODEV}/node-v${NODEV}-linux-x64.tar.gz" | tar -xzv > /dev/null \ 15 | && cp ./node-v${NODEV}-linux-x64/bin/node /usr/bin/ \ 16 | && ./node-v${NODEV}-linux-x64/bin/npm install -g npm 17 | 18 | RUN npm install \ 19 | && npm run doc \ 20 | && cd web \ 21 | && npm install \ 22 | && npm run prod 23 | 24 | RUN cp ./nginx.conf /etc/nginx/sites-enabled/default 25 | 26 | CMD service nginx restart \ 27 | && ./node_modules/.bin/knex migrate:latest \ 28 | && npm start 29 | 30 | -------------------------------------------------------------------------------- /api/web/src/components/util/InfVersion.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | Model Version 4 | 5 | 6 | 7 | 8 | 35 | -------------------------------------------------------------------------------- /api/schema/aois.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./aois/id.json" 7 | }, 8 | "created": { 9 | "$ref": "./aois/created.json" 10 | }, 11 | "updated": { 12 | "$ref": "./aois/updated.json" 13 | }, 14 | "pid": { 15 | "$ref": "./aois/pid.json" 16 | }, 17 | "iter_id": { 18 | "$ref": "./aois/iter_id.json" 19 | }, 20 | "bounds": { 21 | "$ref": "./aois/bounds.json" 22 | }, 23 | "name": { 24 | "$ref": "./aois/name.json" 25 | } 26 | }, 27 | "required": [ 28 | "id", 29 | "created", 30 | "updated", 31 | "pid", 32 | "iter_id", 33 | "bounds", 34 | "name" 35 | ] 36 | } -------------------------------------------------------------------------------- /api/lib/auth.js: -------------------------------------------------------------------------------- 1 | import Err from '@openaddresses/batch-error'; 2 | 3 | /** 4 | * @class 5 | */ 6 | export default class Auth { 7 | static async is_auth(req) { 8 | if (req.user === 'internal') return true; 9 | 10 | if (!req.user || !req.user.access || !req.user.id) { 11 | throw new Err(401, null, 'Authentication Required'); 12 | } 13 | 14 | if (req.user.access === 'disabled') { 15 | throw new Err(403, null, 'Account Disabled - Please Contact Us'); 16 | } 17 | 18 | return true; 19 | } 20 | 21 | static async is_admin(req) { 22 | if (req.user === 'internal') return true; 23 | 24 | await this.is_auth(req); 25 | 26 | if (req.user.access !== 'admin') { 27 | throw new Err(401, null, 'Admin token required'); 28 | } 29 | 30 | return true; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /api/schema/imagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./imagery/id.json" 7 | }, 8 | "pid": { 9 | "$ref": "./imagery/pid.json" 10 | }, 11 | "name": { 12 | "$ref": "./imagery/name.json" 13 | }, 14 | "url": { 15 | "$ref": "./imagery/url.json" 16 | }, 17 | "fmt": { 18 | "$ref": "./imagery/fmt.json" 19 | }, 20 | "created": { 21 | "$ref": "./imagery/created.json" 22 | }, 23 | "updated": { 24 | "$ref": "./imagery/updated.json" 25 | } 26 | }, 27 | "required": [ 28 | "id", 29 | "pid", 30 | "name", 31 | "url", 32 | "fmt", 33 | "created", 34 | "updated" 35 | ] 36 | } -------------------------------------------------------------------------------- /api/schema/res.Submission.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "id", 6 | "aoi_id", 7 | "created", 8 | "iter_id", 9 | "storage", 10 | "tiles" 11 | ], 12 | "properties": { 13 | "id": { 14 | "type": "integer", 15 | "description": "Submission ID" 16 | }, 17 | "created": { 18 | "$ref": "./util/created.json" 19 | }, 20 | "iter_id": { 21 | "type": "integer", 22 | "description": "Iteration ID" 23 | }, 24 | "aoi_id": { 25 | "type": "integer", 26 | "description": "AOI ID" 27 | }, 28 | "storage": { 29 | "type": "boolean" 30 | }, 31 | "tiles": { 32 | "type": "boolean" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /api/schema/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./tasks/id.json" 7 | }, 8 | "iter_id": { 9 | "$ref": "./tasks/iter_id.json" 10 | }, 11 | "type": { 12 | "$ref": "./tasks/type.json" 13 | }, 14 | "created": { 15 | "$ref": "./tasks/created.json" 16 | }, 17 | "updated": { 18 | "$ref": "./tasks/updated.json" 19 | }, 20 | "batch_id": { 21 | "$ref": "./tasks/batch_id.json" 22 | }, 23 | "log_link": { 24 | "$ref": "./tasks/log_link.json" 25 | } 26 | }, 27 | "required": [ 28 | "id", 29 | "iter_id", 30 | "type", 31 | "created", 32 | "updated", 33 | "batch_id", 34 | "log_link" 35 | ] 36 | } -------------------------------------------------------------------------------- /api/routes/mapbox.js: -------------------------------------------------------------------------------- 1 | import Err from '@openaddresses/batch-error'; 2 | import Auth from '../lib/auth.js'; 3 | 4 | export default async function router(schema, config) { 5 | 6 | /** 7 | * @api {get} /api/mapbox Mapbox Settings 8 | * @apiVersion 1.0.0 9 | * @apiName GetMapbox 10 | * @apiGroup Mapbox 11 | * @apiPermission user 12 | * 13 | * @apiDescription 14 | * Return necessary information to show Mapbox maps 15 | * 16 | * @apiSchema {jsonschema=../schema/res.Mapbox.json} apiSuccess 17 | */ 18 | await schema.get('/mapbox', { 19 | res: 'res.Mapbox.json' 20 | }, async (req, res) => { 21 | try { 22 | await Auth.is_auth(req); 23 | 24 | res.json({ 25 | token: config.Mapbox 26 | }); 27 | } catch (err) { 28 | return Err.respond(err, res); 29 | } 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /api/schema/users.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./users/id.json" 7 | }, 8 | "created": { 9 | "$ref": "./users/created.json" 10 | }, 11 | "email": { 12 | "$ref": "./users/email.json" 13 | }, 14 | "username": { 15 | "$ref": "./users/username.json" 16 | }, 17 | "password": { 18 | "$ref": "./users/password.json" 19 | }, 20 | "access": { 21 | "$ref": "./users/access.json" 22 | }, 23 | "validated": { 24 | "$ref": "./users/validated.json" 25 | } 26 | }, 27 | "required": [ 28 | "id", 29 | "created", 30 | "email", 31 | "username", 32 | "password", 33 | "access", 34 | "validated" 35 | ] 36 | } -------------------------------------------------------------------------------- /api/schema/req.query.ListAOI.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial project name" 15 | }, 16 | "order": { 17 | "$ref": "./util/order.json" 18 | }, 19 | "sort": { 20 | "type": "string", 21 | "default": "created", 22 | "enum": [ 23 | "id", 24 | "iter_id", 25 | "created", 26 | "updated", 27 | "name" 28 | ], 29 | "description": "Field to sort order by" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /api/schema/req.query.ListProjectAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial name" 15 | }, 16 | "order": { 17 | "$ref": "./util/order.json" 18 | }, 19 | "sort": { 20 | "type": "string", 21 | "default": "created", 22 | "enum": [ 23 | "id", 24 | "uid", 25 | "created", 26 | "updated", 27 | "access" 28 | ], 29 | "description": "Field to sort order by" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tasks/task-build/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "task-build", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "author": "Nick Ingalls ", 6 | "license": "ISC", 7 | "private": true, 8 | "engines": { 9 | "node": ">= 14.0.0" 10 | }, 11 | "scripts": { 12 | "lint": "eslint *.js", 13 | "test": "tape test/**.test.js" 14 | }, 15 | "dependencies": { 16 | "aws-sdk": "^2.631.0", 17 | "d3-queue": "^3.0.7", 18 | "find": "^0.3.0", 19 | "fs-extra": "^10.0.0", 20 | "minimist": "^1.2.5", 21 | "mkdirp": "^1.0.3", 22 | "nock": "^13.2.4", 23 | "request": "^2.88.2", 24 | "unzipper": "^0.10.10" 25 | }, 26 | "devDependencies": { 27 | "@mapbox/mock-aws-sdk-js": "^1.0.0", 28 | "eslint": "^8.3.0", 29 | "eslint-plugin-node": "^11.1.0", 30 | "tape": "^5.5.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /api/schema/req.query.ListImagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial project name" 15 | }, 16 | "order": { 17 | "$ref": "./util/order.json" 18 | }, 19 | "sort": { 20 | "type": "string", 21 | "default": "created", 22 | "enum": [ 23 | "id", 24 | "name", 25 | "url", 26 | "fmt", 27 | "created", 28 | "updated" 29 | ], 30 | "description": "Field to sort order by" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /api/schema/req.query.ListIntegrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial name" 15 | }, 16 | "order": { 17 | "$ref": "./util/order.json" 18 | }, 19 | "sort": { 20 | "type": "string", 21 | "default": "created", 22 | "enum": [ 23 | "id", 24 | "created", 25 | "updated", 26 | "integration", 27 | "name", 28 | "url" 29 | ], 30 | "description": "Field to sort order by" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tasks/task-vectorize/task: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -xeuo pipefail 4 | 5 | if [[ -z ${ASSET_BUCKET} ]]; then 6 | echo "ASSET_BUCKET env must be set" 7 | exit 1 8 | elif [[ -z ${PROJECT_ID} ]]; then 9 | echo "PROJECT_ID env must be set" 10 | exit 1 11 | elif [[ -z ${ITERATION_ID} ]]; then 12 | echo "ITERATION_ID env must be set" 13 | exit 1 14 | elif [[ -z ${SUBMISSION_ID} ]]; then 15 | echo "SUBMISSION_ID env must be set" 16 | exit 1 17 | fi 18 | 19 | mkdir ./data || true 20 | rm -rf ./data/* 21 | mkdir ./data/raw/ 22 | 23 | aws s3 cp --recursive s3://${ASSET_BUCKET}/project/${PROJECT_ID}/iteration/${ITERATION_ID}/prediction/submission-${SUBMISSION_ID} data/raw/ 24 | find ./data/raw/ -type f -exec gunzip {} + 25 | cat $(find ./data/raw/ -type f) > ./data/input.geojson 26 | rm -rf ./data/raw 27 | 28 | aws s3 cp ./data/input.geojson s3://${ASSET_BUCKET}/project/${PROJECT_ID}/iteration/${ITERATION_ID}/submission-${SUBMISSION_ID}.geojson 29 | 30 | node index.js 31 | -------------------------------------------------------------------------------- /api/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 2000; 3 | listen [::]:2000; 4 | 5 | client_max_body_size 512M; 6 | 7 | location / { 8 | if ($request_uri ~ ^/(.*)\.html) { 9 | return 302 /$1; 10 | } 11 | 12 | alias /home/mle/api/web/dist/; 13 | try_files $uri $uri.html $uri/ /index.html; 14 | autoindex on; 15 | } 16 | 17 | location /docs/ { 18 | alias /home/mle/api/doc/; 19 | autoindex on; 20 | } 21 | 22 | location /health { 23 | proxy_pass http://127.0.0.1:2001; 24 | proxy_set_header X-Real-IP $remote_addr; 25 | proxy_set_header Host $host; 26 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 27 | } 28 | 29 | location ~ ^/api(?:/(.*))?$ { 30 | proxy_pass http://127.0.0.1:2001; 31 | proxy_set_header X-Real-IP $remote_addr; 32 | proxy_set_header Host $host; 33 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /api/test/schema.test.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import test from 'node:test'; 4 | import assert from 'assert'; 5 | 6 | import glob from 'glob'; 7 | import $RefParser from 'json-schema-ref-parser'; 8 | import Ajv from 'ajv'; 9 | import addFormats from 'ajv-formats'; 10 | 11 | const ajv = new Ajv({ 12 | allErrors: true 13 | }); 14 | 15 | addFormats(ajv); 16 | 17 | for (const source of glob.sync('../schema/**/*.json')) { 18 | test(`schema/${path.parse(source).base}`, async () => { 19 | try { 20 | const file = fs.readFileSync(source); 21 | assert.ok(file.length, 'file loaded'); 22 | 23 | JSON.parse(file); 24 | } catch (err) { 25 | assert.ifError(err, 'no JSON errors'); 26 | } 27 | 28 | try { 29 | const schema = await $RefParser.dereference(source); 30 | 31 | ajv.compile(schema); 32 | } catch (err) { 33 | assert.ifError(err, 'no errors'); 34 | } 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /api/schema/req.query.ListUsers.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial username/email" 15 | }, 16 | "access": { 17 | "$ref": "./util/access.json" 18 | }, 19 | "order": { 20 | "$ref": "./util/order.json" 21 | }, 22 | "sort": { 23 | "type": "string", 24 | "default": "created", 25 | "enum": [ 26 | "id", 27 | "created", 28 | "username", 29 | "access", 30 | "validated", 31 | "email" 32 | ], 33 | "description": "Field to sort order by" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /api/schema/res.AOI.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "id", 6 | "pid", 7 | "created", 8 | "updated", 9 | "iter_id", 10 | "bounds", 11 | "name" 12 | ], 13 | "properties": { 14 | "id": { 15 | "type": "integer", 16 | "description": "AOI ID" 17 | }, 18 | "pid": { 19 | "type": "integer", 20 | "description": "Project ID" 21 | }, 22 | "created": { 23 | "$ref": "./util/created.json" 24 | }, 25 | "updated": { 26 | "$ref": "./util/updated.json" 27 | }, 28 | "name": { 29 | "type": "string", 30 | "description": "Human readable name of the AOI" 31 | }, 32 | "iter_id": { 33 | "type": "integer", 34 | "description": "Iteration ID" 35 | }, 36 | "bounds": { 37 | "$ref": "./util/bounds.json" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /api/schema/integrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./integrations/id.json" 7 | }, 8 | "pid": { 9 | "$ref": "./integrations/pid.json" 10 | }, 11 | "created": { 12 | "$ref": "./integrations/created.json" 13 | }, 14 | "updated": { 15 | "$ref": "./integrations/updated.json" 16 | }, 17 | "integration": { 18 | "$ref": "./integrations/integration.json" 19 | }, 20 | "name": { 21 | "$ref": "./integrations/name.json" 22 | }, 23 | "url": { 24 | "$ref": "./integrations/url.json" 25 | }, 26 | "auth": { 27 | "$ref": "./integrations/auth.json" 28 | } 29 | }, 30 | "required": [ 31 | "id", 32 | "pid", 33 | "created", 34 | "updated", 35 | "integration", 36 | "name", 37 | "url", 38 | "auth" 39 | ] 40 | } -------------------------------------------------------------------------------- /api/schema/res.Imagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "id", 5 | "pid", 6 | "name", 7 | "url", 8 | "created", 9 | "updated", 10 | "fmt" 11 | ], 12 | "additionalProperties": false, 13 | "properties": { 14 | "id": { 15 | "type": "integer", 16 | "description": "Imagery ID" 17 | }, 18 | "pid": { 19 | "type": "integer", 20 | "description": "Project ID" 21 | }, 22 | "created": { 23 | "$ref": "./util/created.json" 24 | }, 25 | "updated": { 26 | "$ref": "./util/updated.json" 27 | }, 28 | "name": { 29 | "type": "string", 30 | "description": "Human readable name of the Imagery source" 31 | }, 32 | "url": { 33 | "type": "string", 34 | "description": "URL to the imagery source" 35 | }, 36 | "fmt": { 37 | "type": "string" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /api/migrations/20220215151013_inf_list-json.js: -------------------------------------------------------------------------------- 1 | export function up(knex) { 2 | return knex.schema.raw(` 3 | CREATE TABLE tmp AS 4 | SELECT 5 | id, 6 | JSON_AGG(jsonb) AS list 7 | FROM ( 8 | SELECT 9 | id, 10 | ('{ "name": ' || json_array_elements(ARRAY_TO_JSON(STRING_TO_ARRAY(inf_list, ','))) || ' }')::JSONB 11 | FROM 12 | iterations 13 | ) AS a 14 | GROUP BY 15 | id; 16 | 17 | ALTER TABLE iterations 18 | ALTER COLUMN 19 | inf_list TYPE JSONB 20 | USING 21 | '[]'::JSONB; 22 | 23 | UPDATE iterations 24 | SET 25 | inf_list = list 26 | FROM 27 | tmp 28 | WHERE 29 | iterations.id = tmp.id; 30 | 31 | DROP TABLE tmp; 32 | `); 33 | } 34 | 35 | export function down(knex) { 36 | return knex.schema.raw(``); 37 | } 38 | -------------------------------------------------------------------------------- /api/schema/req.query.GetExport.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "token" 6 | ], 7 | "properties": { 8 | "token": { 9 | "type": "string", 10 | "description": "Auth Token" 11 | }, 12 | "format": { 13 | "type": "string", 14 | "default": "geojsonld", 15 | "enum": [ 16 | "csv", 17 | "geojson", 18 | "geojsonld" 19 | ] 20 | }, 21 | "validity": { 22 | "type": "string", 23 | "default": "both", 24 | "enum": [ 25 | "both", 26 | "validated", 27 | "unvalidated" 28 | ] 29 | }, 30 | "inferences": { 31 | "type": "string", 32 | "default": "all" 33 | }, 34 | "threshold": { 35 | "type": "number" 36 | }, 37 | "submission": { 38 | "type": "number" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /api/schema/res.Task.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "id", 6 | "iter_id", 7 | "created", 8 | "updated", 9 | "type", 10 | "batch_id", 11 | "log_link", 12 | "status", 13 | "statusReason" 14 | ], 15 | "properties": { 16 | "id": { 17 | "type": "integer" 18 | }, 19 | "iter_id": { 20 | "type": "integer" 21 | }, 22 | "created": { 23 | "$ref": "./util/created.json" 24 | }, 25 | "updated": { 26 | "$ref": "./util/updated.json" 27 | }, 28 | "type": { 29 | "type": "string" 30 | }, 31 | "batch_id": { 32 | "type": "integer" 33 | }, 34 | "log_link": { 35 | "type": ["string", "null"] 36 | }, 37 | "status": { 38 | "type": "string" 39 | }, 40 | "statusReason": { 41 | "type": "string" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /api/web/src/components/util/InfModel.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | Model Type: 4 | 5 | 6 | Tensorflow 7 | PyTorch 8 | 9 | 10 | 11 | 12 | 13 | 14 | 41 | -------------------------------------------------------------------------------- /tasks/task-tfrecords/imagery.py: -------------------------------------------------------------------------------- 1 | import requests, shapely, mercantile, pyproj, csv 2 | from requests.auth import HTTPBasicAuth 3 | from tiletanic import tilecover, tileschemes 4 | from functools import partial 5 | from shapely.ops import transform 6 | from io import StringIO 7 | 8 | def chiplist(api, auth, imagery, pred): 9 | 10 | if imagery['fmt'] != 'wms': 11 | imagery['imglist'] = {} 12 | 13 | f = StringIO(get_list(imagery['url'])) 14 | for row in csv.reader(f, delimiter=','): 15 | imagery['imglist'][row[0]] = { 16 | 'name': row[0], 17 | 'url': row[1], 18 | 'bounds': row[2] 19 | } 20 | 21 | def get_pred_tilejson(api, auth, model_id, prediction_id): 22 | r = requests.get(api + '/v1/model/' + str(model_id) + '/prediction/' + str(prediction_id) + '/tiles', auth=HTTPBasicAuth('machine', auth)) 23 | r.raise_for_status() 24 | 25 | return r.json() 26 | 27 | def get_list(imagery_url): 28 | r = requests.get(imagery_url) 29 | r.raise_for_status() 30 | 31 | return r.text 32 | 33 | -------------------------------------------------------------------------------- /api/schema/geometry_columns.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "f_table_catalog": { 6 | "$ref": "./geometry_columns/f_table_catalog.json" 7 | }, 8 | "f_table_schema": { 9 | "$ref": "./geometry_columns/f_table_schema.json" 10 | }, 11 | "f_table_name": { 12 | "$ref": "./geometry_columns/f_table_name.json" 13 | }, 14 | "f_geometry_column": { 15 | "$ref": "./geometry_columns/f_geometry_column.json" 16 | }, 17 | "coord_dimension": { 18 | "$ref": "./geometry_columns/coord_dimension.json" 19 | }, 20 | "srid": { 21 | "$ref": "./geometry_columns/srid.json" 22 | }, 23 | "type": { 24 | "$ref": "./geometry_columns/type.json" 25 | } 26 | }, 27 | "required": [ 28 | "f_table_catalog", 29 | "f_table_schema", 30 | "f_table_name", 31 | "f_geometry_column", 32 | "coord_dimension", 33 | "srid", 34 | "type" 35 | ] 36 | } -------------------------------------------------------------------------------- /api/schema/res.ListTokens.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "tokens" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of users with the service" 12 | }, 13 | "tokens": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | "id", 19 | "created", 20 | "name" 21 | ], 22 | "additionalProperties": false, 23 | "properties": { 24 | "id": { 25 | "type": "integer" 26 | }, 27 | "created": { 28 | "$ref": "./util/created.json" 29 | }, 30 | "name": { 31 | "type": "string" 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /api/schema/geography_columns.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "f_table_catalog": { 6 | "$ref": "./geography_columns/f_table_catalog.json" 7 | }, 8 | "f_table_schema": { 9 | "$ref": "./geography_columns/f_table_schema.json" 10 | }, 11 | "f_table_name": { 12 | "$ref": "./geography_columns/f_table_name.json" 13 | }, 14 | "f_geography_column": { 15 | "$ref": "./geography_columns/f_geography_column.json" 16 | }, 17 | "coord_dimension": { 18 | "$ref": "./geography_columns/coord_dimension.json" 19 | }, 20 | "srid": { 21 | "$ref": "./geography_columns/srid.json" 22 | }, 23 | "type": { 24 | "$ref": "./geography_columns/type.json" 25 | } 26 | }, 27 | "required": [ 28 | "f_table_catalog", 29 | "f_table_schema", 30 | "f_table_name", 31 | "f_geography_column", 32 | "coord_dimension", 33 | "srid", 34 | "type" 35 | ] 36 | } -------------------------------------------------------------------------------- /api/doc/locales/zh.js: -------------------------------------------------------------------------------- 1 | define({ 2 | zh: { 3 | 'Allowed values:' : '允許值:', 4 | 'Compare all with predecessor': '預先比較所有', 5 | 'compare changes to:' : '比較變更:', 6 | 'compared to' : '對比', 7 | 'Default value:' : '預設值:', 8 | 'Description' : '描述', 9 | 'Field' : '欄位', 10 | 'General' : '概括', 11 | 'Generated with' : '生成工具', 12 | 'Name' : '名稱', 13 | 'No response values.' : '無對應資料.', 14 | 'optional' : '選填', 15 | 'Parameter' : '參數', 16 | 'Permission:' : '權限:', 17 | 'Response' : '回應', 18 | 'Send' : '發送', 19 | 'Send a Sample Request' : '發送試用需求', 20 | 'show up to version:' : '顯示到版本:', 21 | 'Size range:' : '區間:', 22 | 'Type' : '類型', 23 | 'url' : '網址' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /.github/workflows/ecr_task_pop.yml: -------------------------------------------------------------------------------- 1 | name: AWS ECR Task Pop 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Docker Build Task 12 | run: docker build -t task-pop tasks/task-pop/ 13 | 14 | - name: Configure AWS Credentials 15 | uses: aws-actions/configure-aws-credentials@v1 16 | with: 17 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 18 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 19 | aws-region: us-east-1 20 | 21 | - name: Login to Amazon ECR 22 | id: login-ecr 23 | uses: aws-actions/amazon-ecr-login@v1 24 | 25 | - name: Docker Tag Task 26 | run: docker tag task-pop ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-pop-${GITHUB_SHA} 27 | 28 | - name: Docker Push Task 29 | run: docker push ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-pop-${GITHUB_SHA} 30 | 31 | -------------------------------------------------------------------------------- /.github/workflows/ecr_task_build.yml: -------------------------------------------------------------------------------- 1 | name: AWS ECR Task 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Docker Build Task 12 | run: docker build -t task-build tasks/task-build/ 13 | 14 | - name: Configure AWS Credentials 15 | uses: aws-actions/configure-aws-credentials@v1 16 | with: 17 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 18 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 19 | aws-region: us-east-1 20 | 21 | - name: Login to Amazon ECR 22 | id: login-ecr 23 | uses: aws-actions/amazon-ecr-login@v1 24 | 25 | - name: Docker Tag Task 26 | run: docker tag task-build ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-build-${GITHUB_SHA} 27 | 28 | - name: Docker Push Task 29 | run: docker push ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-build-${GITHUB_SHA} 30 | 31 | -------------------------------------------------------------------------------- /api/web/src/components/util/InfType.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inference Type: 4 | 5 | 6 | Classification 7 | Object Detection 8 | Segmentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 42 | -------------------------------------------------------------------------------- /.github/workflows/ecr_task_tfrecords.yml: -------------------------------------------------------------------------------- 1 | name: AWS ECR Task TFRecords 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Docker Build Task 12 | run: docker build -t task-tfrecords tasks/task-tfrecords/ 13 | 14 | - name: Configure AWS Credentials 15 | uses: aws-actions/configure-aws-credentials@v1 16 | with: 17 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 18 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 19 | aws-region: us-east-1 20 | 21 | - name: Login to Amazon ECR 22 | id: login-ecr 23 | uses: aws-actions/amazon-ecr-login@v1 24 | 25 | - name: Docker Tag Task 26 | run: docker tag task-tfrecords ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-tfrecords-${GITHUB_SHA} 27 | 28 | - name: Docker Push Task 29 | run: docker push ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-tfrecords-${GITHUB_SHA} 30 | 31 | -------------------------------------------------------------------------------- /api/web/src/components/Err.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Uh Oh! 16 | 17 | 18 | Ok 19 | 20 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /tasks/task-vectorize/lib/api.js: -------------------------------------------------------------------------------- 1 | import fetch from 'node-fetch'; 2 | 3 | /** 4 | * @class 5 | */ 6 | class Iteration { 7 | constructor(url, token) { 8 | if (!url) throw new Error('MLEnabler Url not provided'); 9 | if (!token) throw new Error('MLEnabler Token not provided'); 10 | 11 | this.url = new URL(url); 12 | this.token = token; 13 | } 14 | 15 | async from(pid, id) { 16 | const res = await fetch(new URL(`/api/project/${pid}/iteration/${id}`, this.url), { 17 | method: 'GET', 18 | headers: { 19 | Authorization: 'Bearer ' + this.token 20 | } 21 | }); 22 | 23 | return await res.json(); 24 | } 25 | } 26 | 27 | /** 28 | * @class 29 | */ 30 | class MLEnabler { 31 | constructor(url, token) { 32 | if (!url) throw new Error('MLEnabler Url not provided'); 33 | if (!token) throw new Error('MLEnabler Token not provided'); 34 | 35 | this.url = new URL(url); 36 | this.token = token; 37 | 38 | this.iteration = new Iteration(url, token); 39 | } 40 | 41 | 42 | } 43 | 44 | export { 45 | MLEnabler as default, 46 | Iteration 47 | }; 48 | -------------------------------------------------------------------------------- /api/doc/vendor/path-to-regexp/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /api/schema/req.query.ListProjects.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial project name" 15 | }, 16 | "order": { 17 | "$ref": "./util/order.json" 18 | }, 19 | "archived": { 20 | "type": "boolean", 21 | "default": false, 22 | "description": "Show archived projects" 23 | }, 24 | "sort": { 25 | "type": "string", 26 | "default": "created", 27 | "enum": [ 28 | "id", 29 | "repo", 30 | "created", 31 | "updated", 32 | "name", 33 | "source", 34 | "archived", 35 | "access", 36 | "project_url" 37 | ], 38 | "description": "Field to sort order by" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tasks/task-vectorize/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "task-vectorize", 3 | "type": "module", 4 | "private": true, 5 | "version": "1.0.0", 6 | "description": "", 7 | "main": "index.js", 8 | "scripts": { 9 | "lint": "eslint index.js 'test/**/*.js' 'lib/**/*.js'", 10 | "test": "tape test/**.test.js" 11 | }, 12 | "author": "Nick Ingalls ", 13 | "license": "ISC", 14 | "engines": { 15 | "node": ">= 16.0.0" 16 | }, 17 | "dependencies": { 18 | "@mapbox/mbtiles": "^0.12.1", 19 | "@mapbox/sphericalmercator": "^1.2.0", 20 | "@mapbox/tilebelt": "^1.0.2", 21 | "@turf/bbox-polygon": "^6.5.0", 22 | "@turf/centroid": "^6.5.0", 23 | "aws-sdk": "^2.1039.0", 24 | "fast-png": "^6.1.0", 25 | "image-js": "^0.33.1", 26 | "minimist": "^1.2.5", 27 | "node-fetch": "^3.2.0", 28 | "randomcolor": "^0.6.2", 29 | "tilebase": "^3.0.0" 30 | }, 31 | "devDependencies": { 32 | "@mapbox/mock-aws-sdk-js": "^1.0.0", 33 | "sinon": "^13.0.1", 34 | "eslint": "^8.7.0", 35 | "eslint-plugin-node": "^11.1.0", 36 | "tape": "^5.5.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /api/web/src/components/iteration/stack/QueueXYZ.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | Submit 14 | 15 | 16 | 17 | 46 | -------------------------------------------------------------------------------- /api/doc/locales/zh_cn.js: -------------------------------------------------------------------------------- 1 | define({ 2 | 'zh_cn': { 3 | 'Allowed values:' : '允许值:', 4 | 'Compare all with predecessor': '与所有较早的比较', 5 | 'compare changes to:' : '将当前版本与指定版本比较:', 6 | 'compared to' : '相比于', 7 | 'Default value:' : '默认值:', 8 | 'Description' : '描述', 9 | 'Field' : '字段', 10 | 'General' : '概要', 11 | 'Generated with' : '基于', 12 | 'Name' : '名称', 13 | 'No response values.' : '无返回值.', 14 | 'optional' : '可选', 15 | 'Parameter' : '参数', 16 | 'Parameters' : '参数', 17 | 'Headers' : '头部参数', 18 | 'Permission:' : '权限:', 19 | 'Response' : '返回', 20 | 'Send' : '发送', 21 | 'Send a Sample Request' : '发送示例请求', 22 | 'show up to version:' : '显示到指定版本:', 23 | 'Size range:' : '取值范围:', 24 | 'Type' : '类型', 25 | 'url' : '网址' 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /lambda/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM lambgeo/lambda-gdal:3.3-python3.8 2 | 3 | ARG PACKAGE_PREFIX=/var/task 4 | WORKDIR $PACKAGE_PREFIX 5 | 6 | ADD requirements.txt requirements.txt 7 | 8 | RUN pip install -r requirements.txt --no-binary :all: -t ${PACKAGE_PREFIX}/ 9 | 10 | # Reduce size of the C libs 11 | RUN cd $PREFIX && find lib -name \*.so\* -exec strip {} \; 12 | 13 | RUN cd ${PACKAGE_PREFIX} && find . -type f -name '*.pyc' | while read f; do n=$(echo $f | sed 's/__pycache__\///' | sed 's/.cpython-[2-3][0-9]//'); cp $f $n; done; 14 | RUN cd ${PACKAGE_PREFIX} && find . -type d -a -name '__pycache__' -print0 | xargs -0 rm -rf 15 | RUN cd ${PACKAGE_PREFIX} && find . -type f -a -name '*.py' -print0 | xargs -0 rm -f 16 | RUN find ${PACKAGE_PREFIX} -type d -a -name 'tests' -print0 | xargs -0 rm -rf 17 | 18 | RUN rm -rdf \ 19 | ${PACKAGE_PREFIX}/numpy/doc/ \ 20 | ${PACKAGE_PREFIX}/boto3* \ 21 | ${PACKAGE_PREFIX}/botocore* \ 22 | ${PACKAGE_PREFIX}/bin \ 23 | ${PACKAGE_PREFIX}/geos_license \ 24 | ${PACKAGE_PREFIX}/Misc 25 | 26 | COPY download_and_predict ${PACKAGE_PREFIX}/download_and_predict 27 | 28 | # Create package.zip 29 | RUN cd $PACKAGE_PREFIX && zip -r9q /tmp/package.zip * 30 | RUN cd $PREFIX && zip -r9q --symlinks /tmp/package.zip lib/*.so* share 31 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateProject.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "name", 6 | "source", 7 | "project_url", 8 | "tags", 9 | "access", 10 | "users" 11 | ], 12 | "properties": { 13 | "name": { 14 | "type": "string", 15 | "minLength": 2, 16 | "maxLength": 40, 17 | "description": "Human readable Project name" 18 | }, 19 | "source": { 20 | "type": "string", 21 | "minLength": 2, 22 | "maxLength": 40 23 | }, 24 | "project_url": { 25 | "type": "string", 26 | "default": "" 27 | }, 28 | "tags": { 29 | "$ref": "./util/project-tags.json" 30 | }, 31 | "access": { 32 | "$ref": "./util/project-access.json" 33 | }, 34 | "notes": { 35 | "type": "string", 36 | "default": "" 37 | }, 38 | "users": { 39 | "$ref": "./util/project-users.json" 40 | }, 41 | "repo": { 42 | "type": "string", 43 | "minLength": 2, 44 | "maxLength": 128 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /api/schema/res.ListMeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "meta" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items with the service" 12 | }, 13 | "meta": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | "key", 19 | "value", 20 | "created", 21 | "updated" 22 | ], 23 | "additionalProperties": false, 24 | "properties": { 25 | "key": { 26 | "type": "string" 27 | }, 28 | "value": { 29 | "$ref": "./util/any.json" 30 | }, 31 | "created": { 32 | "$ref": "./util/created.json" 33 | }, 34 | "updated": { 35 | "$ref": "./util/updated.json" 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /api/schema/res.Project.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "id", 6 | "created", 7 | "updated", 8 | "name", 9 | "source", 10 | "project_url", 11 | "archived", 12 | "tags", 13 | "access", 14 | "notes", 15 | "repo" 16 | ], 17 | "properties": { 18 | "id": { 19 | "type": "integer" 20 | }, 21 | "created": { 22 | "$ref": "./util/created.json" 23 | }, 24 | "updated": { 25 | "$ref": "./util/updated.json" 26 | }, 27 | "name": { 28 | "type": "string" 29 | }, 30 | "source": { 31 | "type": "string" 32 | }, 33 | "project_url": { 34 | "type": "string" 35 | }, 36 | "archived": { 37 | "type": "boolean" 38 | }, 39 | "tags": { 40 | "$ref": "./util/project-tags.json" 41 | }, 42 | "access": { 43 | "$ref": "./util/project-access.json" 44 | }, 45 | "notes": { 46 | "type": "string" 47 | }, 48 | "repo": { 49 | "type": ["string", "null"] 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /api/schema/req.query.ListIterations.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "filter": { 12 | "type": "string", 13 | "default": "", 14 | "description": "Filter a complete or partial version" 15 | }, 16 | "order": { 17 | "$ref": "./util/order.json" 18 | }, 19 | "sort": { 20 | "type": "string", 21 | "default": "created", 22 | "enum": [ 23 | "id", 24 | "gitsha", 25 | "created", 26 | "updated", 27 | "tile_zoom", 28 | "docker_link", 29 | "model_link", 30 | "checkpoint_link", 31 | "tfrecord_link", 32 | "save_link", 33 | "inf_list", 34 | "inf_type", 35 | "inf_binary", 36 | "inf_supertile", 37 | "version", 38 | "hint" 39 | ], 40 | "description": "Field to sort order by" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /api/doc/locales/tr.js: -------------------------------------------------------------------------------- 1 | define({ 2 | tr: { 3 | 'Allowed values:' : 'İzin verilen değerler:', 4 | 'Compare all with predecessor': 'Tümünü öncekiler ile karşılaştır', 5 | 'compare changes to:' : 'değişiklikleri karşılaştır:', 6 | 'compared to' : 'karşılaştır', 7 | 'Default value:' : 'Varsayılan değer:', 8 | 'Description' : 'Açıklama', 9 | 'Field' : 'Alan', 10 | 'General' : 'Genel', 11 | 'Generated with' : 'Oluşturan', 12 | 'Name' : 'İsim', 13 | 'No response values.' : 'Dönüş verisi yok.', 14 | 'optional' : 'opsiyonel', 15 | 'Parameter' : 'Parametre', 16 | 'Permission:' : 'İzin:', 17 | 'Response' : 'Dönüş', 18 | 'Send' : 'Gönder', 19 | 'Send a Sample Request' : 'Örnek istek gönder', 20 | 'show up to version:' : 'bu versiyona kadar göster:', 21 | 'Size range:' : 'Boyut aralığı:', 22 | 'Type' : 'Tip', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/pl.js: -------------------------------------------------------------------------------- 1 | define({ 2 | pl: { 3 | 'Allowed values:' : 'Dozwolone wartości:', 4 | 'Compare all with predecessor': 'Porównaj z poprzednimi wersjami', 5 | 'compare changes to:' : 'porównaj zmiany do:', 6 | 'compared to' : 'porównaj do:', 7 | 'Default value:' : 'Wartość domyślna:', 8 | 'Description' : 'Opis', 9 | 'Field' : 'Pole', 10 | 'General' : 'Generalnie', 11 | 'Generated with' : 'Wygenerowano z', 12 | 'Name' : 'Nazwa', 13 | 'No response values.' : 'Brak odpowiedzi.', 14 | 'optional' : 'opcjonalny', 15 | 'Parameter' : 'Parametr', 16 | 'Permission:' : 'Uprawnienia:', 17 | 'Response' : 'Odpowiedź', 18 | 'Send' : 'Wyślij', 19 | 'Send a Sample Request' : 'Wyślij przykładowe żądanie', 20 | 'show up to version:' : 'pokaż do wersji:', 21 | 'Size range:' : 'Zakres rozmiaru:', 22 | 'Type' : 'Typ', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/ca.js: -------------------------------------------------------------------------------- 1 | define({ 2 | ca: { 3 | 'Allowed values:' : 'Valors permesos:', 4 | 'Compare all with predecessor': 'Comparar tot amb versió anterior', 5 | 'compare changes to:' : 'comparar canvis amb:', 6 | 'compared to' : 'comparat amb', 7 | 'Default value:' : 'Valor per defecte:', 8 | 'Description' : 'Descripció', 9 | 'Field' : 'Camp', 10 | 'General' : 'General', 11 | 'Generated with' : 'Generat amb', 12 | 'Name' : 'Nom', 13 | 'No response values.' : 'Sense valors en la resposta.', 14 | 'optional' : 'opcional', 15 | 'Parameter' : 'Paràmetre', 16 | 'Permission:' : 'Permisos:', 17 | 'Response' : 'Resposta', 18 | 'Send' : 'Enviar', 19 | 'Send a Sample Request' : 'Enviar una petició d\'exemple', 20 | 'show up to version:' : 'mostrar versió:', 21 | 'Size range:' : 'Tamany de rang:', 22 | 'Type' : 'Tipus', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/vi.js: -------------------------------------------------------------------------------- 1 | define({ 2 | vi: { 3 | 'Allowed values:' : 'Giá trị chấp nhận:', 4 | 'Compare all with predecessor': 'So sánh với tất cả phiên bản trước', 5 | 'compare changes to:' : 'so sánh sự thay đổi với:', 6 | 'compared to' : 'so sánh với', 7 | 'Default value:' : 'Giá trị mặc định:', 8 | 'Description' : 'Chú thích', 9 | 'Field' : 'Trường dữ liệu', 10 | 'General' : 'Tổng quan', 11 | 'Generated with' : 'Được tạo bởi', 12 | 'Name' : 'Tên', 13 | 'No response values.' : 'Không có kết quả trả về.', 14 | 'optional' : 'Tùy chọn', 15 | 'Parameter' : 'Tham số', 16 | 'Permission:' : 'Quyền hạn:', 17 | 'Response' : 'Kết quả', 18 | 'Send' : 'Gửi', 19 | 'Send a Sample Request' : 'Gửi một yêu cầu mẫu', 20 | 'show up to version:' : 'hiển thị phiên bản:', 21 | 'Size range:' : 'Kích cỡ:', 22 | 'Type' : 'Kiểu', 23 | 'url' : 'liên kết' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/web/src/components/Profile.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Profile: 7 | 8 | 9 | 10 | 11 | 12 | Username: 13 | 14 | 15 | 16 | Email: 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 45 | -------------------------------------------------------------------------------- /api/doc/locales/cs.js: -------------------------------------------------------------------------------- 1 | define({ 2 | cs: { 3 | 'Allowed values:' : 'Povolené hodnoty:', 4 | 'Compare all with predecessor': 'Porovnat vše s předchozími verzemi', 5 | 'compare changes to:' : 'porovnat změny s:', 6 | 'compared to' : 'porovnat s', 7 | 'Default value:' : 'Výchozí hodnota:', 8 | 'Description' : 'Popis', 9 | 'Field' : 'Pole', 10 | 'General' : 'Obecné', 11 | 'Generated with' : 'Vygenerováno pomocí', 12 | 'Name' : 'Název', 13 | 'No response values.' : 'Nebyly vráceny žádné hodnoty.', 14 | 'optional' : 'volitelné', 15 | 'Parameter' : 'Parametr', 16 | 'Permission:' : 'Oprávnění:', 17 | 'Response' : 'Odpověď', 18 | 'Send' : 'Odeslat', 19 | 'Send a Sample Request' : 'Odeslat ukázkový požadavek', 20 | 'show up to version:' : 'zobrazit po verzi:', 21 | 'Size range:' : 'Rozsah velikosti:', 22 | 'Type' : 'Typ', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/ro.js: -------------------------------------------------------------------------------- 1 | define({ 2 | ro: { 3 | 'Allowed values:' : 'Valori permise:', 4 | 'Compare all with predecessor': 'Compară toate cu versiunea precedentă', 5 | 'compare changes to:' : 'compară cu versiunea:', 6 | 'compared to' : 'comparat cu', 7 | 'Default value:' : 'Valoare implicită:', 8 | 'Description' : 'Descriere', 9 | 'Field' : 'Câmp', 10 | 'General' : 'General', 11 | 'Generated with' : 'Generat cu', 12 | 'Name' : 'Nume', 13 | 'No response values.' : 'Nici o valoare returnată.', 14 | 'optional' : 'opțional', 15 | 'Parameter' : 'Parametru', 16 | 'Permission:' : 'Permisiune:', 17 | 'Response' : 'Răspuns', 18 | 'Send' : 'Trimite', 19 | 'Send a Sample Request' : 'Trimite o cerere de probă', 20 | 'show up to version:' : 'arată până la versiunea:', 21 | 'Size range:' : 'Interval permis:', 22 | 'Type' : 'Tip', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/de.js: -------------------------------------------------------------------------------- 1 | define({ 2 | de: { 3 | 'Allowed values:' : 'Erlaubte Werte:', 4 | 'Compare all with predecessor': 'Vergleiche alle mit ihren Vorgängern', 5 | 'compare changes to:' : 'vergleiche Änderungen mit:', 6 | 'compared to' : 'verglichen mit', 7 | 'Default value:' : 'Standardwert:', 8 | 'Description' : 'Beschreibung', 9 | 'Field' : 'Feld', 10 | 'General' : 'Allgemein', 11 | 'Generated with' : 'Erstellt mit', 12 | 'Name' : 'Name', 13 | 'No response values.' : 'Keine Rückgabewerte.', 14 | 'optional' : 'optional', 15 | 'Parameter' : 'Parameter', 16 | 'Permission:' : 'Berechtigung:', 17 | 'Response' : 'Antwort', 18 | 'Send' : 'Senden', 19 | 'Send a Sample Request' : 'Eine Beispielanfrage senden', 20 | 'show up to version:' : 'zeige bis zur Version:', 21 | 'Size range:' : 'Größenbereich:', 22 | 'Type' : 'Typ', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/pt_br.js: -------------------------------------------------------------------------------- 1 | define({ 2 | 'pt_br': { 3 | 'Allowed values:' : 'Valores permitidos:', 4 | 'Compare all with predecessor': 'Compare todos com antecessores', 5 | 'compare changes to:' : 'comparar alterações com:', 6 | 'compared to' : 'comparado com', 7 | 'Default value:' : 'Valor padrão:', 8 | 'Description' : 'Descrição', 9 | 'Field' : 'Campo', 10 | 'General' : 'Geral', 11 | 'Generated with' : 'Gerado com', 12 | 'Name' : 'Nome', 13 | 'No response values.' : 'Sem valores de resposta.', 14 | 'optional' : 'opcional', 15 | 'Parameter' : 'Parâmetro', 16 | 'Permission:' : 'Permissão:', 17 | 'Response' : 'Resposta', 18 | 'Send' : 'Enviar', 19 | 'Send a Sample Request' : 'Enviar um Exemplo de Pedido', 20 | 'show up to version:' : 'aparecer para a versão:', 21 | 'Size range:' : 'Faixa de tamanho:', 22 | 'Type' : 'Tipo', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/ru.js: -------------------------------------------------------------------------------- 1 | define({ 2 | ru: { 3 | 'Allowed values:' : 'Допустимые значения:', 4 | 'Compare all with predecessor': 'Сравнить с предыдущей версией', 5 | 'compare changes to:' : 'сравнить с:', 6 | 'compared to' : 'в сравнении с', 7 | 'Default value:' : 'По умолчанию:', 8 | 'Description' : 'Описание', 9 | 'Field' : 'Название', 10 | 'General' : 'Общая информация', 11 | 'Generated with' : 'Сгенерировано с помощью', 12 | 'Name' : 'Название', 13 | 'No response values.' : 'Нет значений для ответа.', 14 | 'optional' : 'необязательный', 15 | 'Parameter' : 'Параметр', 16 | 'Permission:' : 'Разрешено:', 17 | 'Response' : 'Ответ', 18 | 'Send' : 'Отправить', 19 | 'Send a Sample Request' : 'Отправить тестовый запрос', 20 | 'show up to version:' : 'показать версию:', 21 | 'Size range:' : 'Ограничения:', 22 | 'Type' : 'Тип', 23 | 'url' : 'URL' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/es.js: -------------------------------------------------------------------------------- 1 | define({ 2 | es: { 3 | 'Allowed values:' : 'Valores permitidos:', 4 | 'Compare all with predecessor': 'Comparar todo con versión anterior', 5 | 'compare changes to:' : 'comparar cambios con:', 6 | 'compared to' : 'comparado con', 7 | 'Default value:' : 'Valor por defecto:', 8 | 'Description' : 'Descripción', 9 | 'Field' : 'Campo', 10 | 'General' : 'General', 11 | 'Generated with' : 'Generado con', 12 | 'Name' : 'Nombre', 13 | 'No response values.' : 'Sin valores en la respuesta.', 14 | 'optional' : 'opcional', 15 | 'Parameter' : 'Parámetro', 16 | 'Permission:' : 'Permisos:', 17 | 'Response' : 'Respuesta', 18 | 'Send' : 'Enviar', 19 | 'Send a Sample Request' : 'Enviar una petición de ejemplo', 20 | 'show up to version:' : 'mostrar a versión:', 21 | 'Size range:' : 'Tamaño de rango:', 22 | 'Type' : 'Tipo', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/nl.js: -------------------------------------------------------------------------------- 1 | define({ 2 | nl: { 3 | 'Allowed values:' : 'Toegestane waarden:', 4 | 'Compare all with predecessor': 'Vergelijk alle met voorgaande versie', 5 | 'compare changes to:' : 'vergelijk veranderingen met:', 6 | 'compared to' : 'vergelijk met', 7 | 'Default value:' : 'Standaard waarde:', 8 | 'Description' : 'Omschrijving', 9 | 'Field' : 'Veld', 10 | 'General' : 'Algemeen', 11 | 'Generated with' : 'Gegenereerd met', 12 | 'Name' : 'Naam', 13 | 'No response values.' : 'Geen response waardes.', 14 | 'optional' : 'optioneel', 15 | 'Parameter' : 'Parameter', 16 | 'Permission:' : 'Permissie:', 17 | 'Response' : 'Antwoorden', 18 | 'Send' : 'Sturen', 19 | 'Send a Sample Request' : 'Stuur een sample aanvragen', 20 | 'show up to version:' : 'toon tot en met versie:', 21 | 'Size range:' : 'Maatbereik:', 22 | 'Type' : 'Type', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/schema/res.ListProjectAccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "total", 6 | "users" 7 | ], 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "users": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | 19 | ], 20 | "additionalProperties": false, 21 | "properties": { 22 | "id": { 23 | "type": "integer" 24 | }, 25 | "username": { 26 | "type": "string" 27 | }, 28 | "created": { 29 | "$ref": "./util/created.json" 30 | }, 31 | "updated": { 32 | "$ref": "./util/updated.json" 33 | }, 34 | "uid": { 35 | "type": "integer" 36 | }, 37 | "access": { 38 | "type": "string" 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /api/doc/locales/fr.js: -------------------------------------------------------------------------------- 1 | define({ 2 | fr: { 3 | 'Allowed values:' : 'Valeurs autorisées :', 4 | 'Compare all with predecessor': 'Tout comparer avec ...', 5 | 'compare changes to:' : 'comparer les changements à :', 6 | 'compared to' : 'comparer à', 7 | 'Default value:' : 'Valeur par défaut :', 8 | 'Description' : 'Description', 9 | 'Field' : 'Champ', 10 | 'General' : 'Général', 11 | 'Generated with' : 'Généré avec', 12 | 'Name' : 'Nom', 13 | 'No response values.' : 'Aucune valeur de réponse.', 14 | 'optional' : 'optionnel', 15 | 'Parameter' : 'Paramètre', 16 | 'Permission:' : 'Permission :', 17 | 'Response' : 'Réponse', 18 | 'Send' : 'Envoyer', 19 | 'Send a Sample Request' : 'Envoyer une requête représentative', 20 | 'show up to version:' : 'Montrer à partir de la version :', 21 | 'Size range:' : 'Ordre de grandeur :', 22 | 'Type' : 'Type', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/doc/locales/it.js: -------------------------------------------------------------------------------- 1 | define({ 2 | it: { 3 | 'Allowed values:' : 'Valori permessi:', 4 | 'Compare all with predecessor': 'Confronta tutto con versioni precedenti', 5 | 'compare changes to:' : 'confronta modifiche con:', 6 | 'compared to' : 'confrontato con', 7 | 'Default value:' : 'Valore predefinito:', 8 | 'Description' : 'Descrizione', 9 | 'Field' : 'Campo', 10 | 'General' : 'Generale', 11 | 'Generated with' : 'Creato con', 12 | 'Name' : 'Nome', 13 | 'No response values.' : 'Nessun valore di risposta.', 14 | 'optional' : 'opzionale', 15 | 'Parameter' : 'Parametro', 16 | 'Permission:' : 'Permessi:', 17 | 'Response' : 'Risposta', 18 | 'Send' : 'Invia', 19 | 'Send a Sample Request' : 'Invia una richiesta di esempio', 20 | 'show up to version:' : 'mostra alla versione:', 21 | 'Size range:' : 'Intervallo dimensione:', 22 | 'Type' : 'Tipo', 23 | 'url' : 'url' 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /api/schema/req.query.ListTasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "limit": { 6 | "$ref": "./util/limit.json" 7 | }, 8 | "page": { 9 | "$ref": "./util/page.json" 10 | }, 11 | "order": { 12 | "$ref": "./util/order.json" 13 | }, 14 | "type": { 15 | "type": "string", 16 | "description": "Limit tasks to a specific type", 17 | "enum": [ 18 | "pop", 19 | "ecr", 20 | "vectorize" 21 | ] 22 | }, 23 | "before": { 24 | "type": "string", 25 | "description": "Query users that were created before the given ISO Date" 26 | }, 27 | "after": { 28 | "type": "string", 29 | "description": "Query users that were created after the given ISO Date" 30 | }, 31 | "sort": { 32 | "type": "string", 33 | "default": "created", 34 | "enum": [ 35 | "id", 36 | "created", 37 | "updated", 38 | "type", 39 | "batch_id", 40 | "log_link" 41 | ], 42 | "description": "Field to sort order by" 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /api/schema/projects.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "properties": { 5 | "id": { 6 | "$ref": "./projects/id.json" 7 | }, 8 | "created": { 9 | "$ref": "./projects/created.json" 10 | }, 11 | "updated": { 12 | "$ref": "./projects/updated.json" 13 | }, 14 | "name": { 15 | "$ref": "./projects/name.json" 16 | }, 17 | "source": { 18 | "$ref": "./projects/source.json" 19 | }, 20 | "project_url": { 21 | "$ref": "./projects/project_url.json" 22 | }, 23 | "archived": { 24 | "$ref": "./projects/archived.json" 25 | }, 26 | "tags": { 27 | "$ref": "./projects/tags.json" 28 | }, 29 | "access": { 30 | "$ref": "./projects/access.json" 31 | }, 32 | "notes": { 33 | "$ref": "./projects/notes.json" 34 | }, 35 | "repo": { 36 | "$ref": "./projects/repo.json" 37 | } 38 | }, 39 | "required": [ 40 | "id", 41 | "created", 42 | "updated", 43 | "name", 44 | "source", 45 | "project_url", 46 | "archived", 47 | "tags", 48 | "access", 49 | "notes", 50 | "repo" 51 | ] 52 | } -------------------------------------------------------------------------------- /tasks/task-vectorize/test/feature.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import test from 'tape'; 3 | import os from 'os'; 4 | import Task from '../index.js'; 5 | import AWS from '@mapbox/mock-aws-sdk-js'; 6 | import { Iteration } from '../lib/api.js'; 7 | import Sinon from 'sinon'; 8 | 9 | test('Feature', async (t) => { 10 | AWS.stub('S3', 'putObject', function(params) { 11 | t.equals(params.Bucket, 's3-bucket'); 12 | t.equals(params.ContentType, 'application/octet-stream'); 13 | t.equals(params.Key, 'project/1/iteration/2/submission-3.tilebase'); 14 | t.ok(params.Body); 15 | 16 | return this.request.promise.returns(Promise.resolve({ })); 17 | }); 18 | 19 | Sinon.stub(Iteration.prototype, 'from').callsFake(() => { 20 | return Promise.resolve({ 21 | id: 1 22 | }); 23 | }); 24 | 25 | try { 26 | await Task.vectorize(new URL('./fixtures/feature.json', import.meta.url).pathname, { 27 | tmp: os.tmpdir(), 28 | url: 'http://example.com', 29 | token: '123', 30 | bucket: 's3-bucket', 31 | project: 1, 32 | iteration: 2, 33 | submission: 3 34 | }); 35 | } catch (err) { 36 | t.error(err); 37 | } 38 | 39 | Iteration.prototype.from.restore(); 40 | AWS.S3.restore(); 41 | t.end(); 42 | }); 43 | -------------------------------------------------------------------------------- /.github/workflows/task_vectorize.yml: -------------------------------------------------------------------------------- 1 | name: Task-Vectorize 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Docker Build Task 12 | run: docker build -t task-vectorize tasks/task-vectorize/ 13 | 14 | - name: npm lint 15 | run: docker run task-vectorize npm run lint 16 | 17 | - name: npm test 18 | run: docker run task-vectorize npm test 19 | 20 | - name: Configure AWS Credentials 21 | uses: aws-actions/configure-aws-credentials@v1 22 | with: 23 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 24 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 25 | aws-region: us-east-1 26 | 27 | - name: Login to Amazon ECR 28 | id: login-ecr 29 | uses: aws-actions/amazon-ecr-login@v1 30 | 31 | - name: Docker Tag Task 32 | run: docker tag task-vectorize ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-vectorize-${GITHUB_SHA} 33 | 34 | - name: Docker Push Task 35 | run: docker push ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:task-vectorize-${GITHUB_SHA} 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2022, Development Seed 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /api/web/src/components/util/InfGitSha.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Git Integration 8 | 9 | 10 | 11 | 12 | 13 | GitSha 14 | 15 | 16 | 17 | 18 | 19 | 20 | 48 | -------------------------------------------------------------------------------- /api/doc/locales/locale.js: -------------------------------------------------------------------------------- 1 | define([ 2 | './locales/ca.js', 3 | './locales/cs.js', 4 | './locales/de.js', 5 | './locales/es.js', 6 | './locales/fr.js', 7 | './locales/it.js', 8 | './locales/nl.js', 9 | './locales/pl.js', 10 | './locales/pt_br.js', 11 | './locales/ro.js', 12 | './locales/ru.js', 13 | './locales/tr.js', 14 | './locales/vi.js', 15 | './locales/zh.js', 16 | './locales/zh_cn.js' 17 | ], function() { 18 | var langId = (navigator.language || navigator.userLanguage).toLowerCase().replace('-', '_'); 19 | var language = langId.substr(0, 2); 20 | var locales = {}; 21 | 22 | for (index in arguments) { 23 | for (property in arguments[index]) 24 | locales[property] = arguments[index][property]; 25 | } 26 | if ( ! locales['en']) 27 | locales['en'] = {}; 28 | 29 | if ( ! locales[langId] && ! locales[language]) 30 | language = 'en'; 31 | 32 | var locale = (locales[langId] ? locales[langId] : locales[language]); 33 | 34 | function __(text) { 35 | var index = locale[text]; 36 | if (index === undefined) 37 | return text; 38 | return index; 39 | }; 40 | 41 | function setLanguage(language) { 42 | locale = locales[language]; 43 | } 44 | 45 | return { 46 | __ : __, 47 | locales : locales, 48 | locale : locale, 49 | setLanguage: setLanguage 50 | }; 51 | }); 52 | -------------------------------------------------------------------------------- /api/schema/res.TileJSON.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "tilejson", 5 | "name", 6 | "version", 7 | "scheme", 8 | "tiles", 9 | "bounds", 10 | "center" 11 | ], 12 | "properties": { 13 | "tilejson": { 14 | "type": "string", 15 | "enum": [ 16 | "2.2.0", 17 | "2.1.0" 18 | ], 19 | "description": "TileJSON Spec Version" 20 | }, 21 | "name": { 22 | "type": "string", 23 | "description": "Unique name of layer" 24 | }, 25 | "version": { 26 | "type": "string", 27 | "description": "Style Version" 28 | }, 29 | "scheme": { 30 | "type": "string", 31 | "enum": [ "xyz" ], 32 | "description": "Tile format" 33 | }, 34 | "tiles": { 35 | "type": "array", 36 | "description": "Array of tile URLs", 37 | "items": { 38 | "type": "string", 39 | "description": "Tile URL" 40 | } 41 | }, 42 | "bounds": { 43 | "type": "array", 44 | "items": { 45 | "type": "number" 46 | } 47 | }, 48 | "center": { 49 | "type": "array", 50 | "items": { 51 | "type": "number" 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /api/web/src/components/Admin.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Server Admin: 7 | 8 | 9 | 10 | 11 | 14 | 15 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Admin Access Only 30 | 31 | 32 | 33 | 34 | 49 | -------------------------------------------------------------------------------- /api/schema/res.ListImagery.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "imagery" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "imagery": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | "id", 19 | "name", 20 | "url", 21 | "created", 22 | "updated", 23 | "fmt" 24 | ], 25 | "additionalProperties": false, 26 | "properties": { 27 | "id": { 28 | "type": "integer" 29 | }, 30 | "created": { 31 | "$ref": "./util/created.json" 32 | }, 33 | "updated": { 34 | "$ref": "./util/updated.json" 35 | }, 36 | "name": { 37 | "type": "string" 38 | }, 39 | "url": { 40 | "type": "string" 41 | }, 42 | "fmt": { 43 | "type": "string" 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /api/schema/res.ListSubmission.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "total", 6 | "submissions" 7 | ], 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "submissions": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "additionalProperties": false, 18 | "required": [ 19 | "id", 20 | "created", 21 | "iter_id", 22 | "aoi_id", 23 | "storage", 24 | "tiles" 25 | ], 26 | "properties": { 27 | "id": { 28 | "type": "integer" 29 | }, 30 | "created": { 31 | "$ref": "./util/created.json" 32 | }, 33 | "iter_id": { 34 | "type": "integer" 35 | }, 36 | "aoi_id": { 37 | "type": "integer" 38 | }, 39 | "storage": { 40 | "type": "boolean" 41 | }, 42 | "tiles": { 43 | "type": "boolean" 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /api/schema/res.ListIntegrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "integrations" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "integrations": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | "id", 19 | "created", 20 | "updated", 21 | "name", 22 | "integration", 23 | "url" 24 | ], 25 | "additionalProperties": false, 26 | "properties": { 27 | "id": { 28 | "type": "integer" 29 | }, 30 | "created": { 31 | "$ref": "./util/created.json" 32 | }, 33 | "updated": { 34 | "$ref": "./util/updated.json" 35 | }, 36 | "name": { 37 | "type": "string" 38 | }, 39 | "integration": { 40 | "type": "string" 41 | }, 42 | "url": { 43 | "type": "string" 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tasks/task-build/lib/tfserving.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const CP = require('child_process'); 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | 7 | const VERSION = '2.7.0'; 8 | 9 | function docker(tmp, model, tagged_model) { 10 | const exists = !!String(CP.execSync(` 11 | docker images ${VERSION} 12 | `)).split('\n')[1]; 13 | 14 | 15 | if (!exists) { 16 | console.error('ok - pulling tensorflow/serving docker image'); 17 | 18 | CP.execSync(` 19 | docker pull tensorflow/serving:${VERSION}-gpu 20 | `); 21 | } 22 | 23 | // Ignore errors, these are to ensure the next commands don't err 24 | try { 25 | CP.execSync(` 26 | docker kill serving_base 27 | `); 28 | } catch (err) { 29 | console.error('ok - no old task to stop'); 30 | } 31 | 32 | try { 33 | CP.execSync(` 34 | docker rm serving_base 35 | `); 36 | } catch (err) { 37 | console.error('ok - no old image to remove'); 38 | } 39 | 40 | CP.execSync(` 41 | docker run -d --name serving_base tensorflow/serving:${VERSION}-gpu 42 | `); 43 | 44 | CP.execSync(` 45 | docker cp ${tmp}/MODEL/ serving_base:/models/default/ \ 46 | `); 47 | 48 | const tag = `developmentseed/default:${Math.random().toString(36).substring(2, 15)}`; 49 | 50 | CP.execSync(` 51 | docker commit --change "ENV MODEL_NAME default" serving_base ${tag} 52 | `); 53 | 54 | return tag; 55 | } 56 | 57 | module.exports = docker; 58 | -------------------------------------------------------------------------------- /tasks/task-vectorize/test/image.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import test from 'tape'; 3 | import os from 'os'; 4 | import Task from '../index.js'; 5 | import AWS from '@mapbox/mock-aws-sdk-js'; 6 | import { Iteration } from '../lib/api.js'; 7 | import Sinon from 'sinon'; 8 | 9 | test('Image', async (t) => { 10 | AWS.stub('S3', 'putObject', function(params) { 11 | t.equals(params.Bucket, 's3-bucket'); 12 | t.equals(params.ContentType, 'application/octet-stream'); 13 | t.equals(params.Key, 'project/1/iteration/2/submission-3.tilebase'); 14 | t.ok(params.Body); 15 | 16 | return this.request.promise.returns(Promise.resolve({ })); 17 | }); 18 | 19 | Sinon.stub(Iteration.prototype, 'from').callsFake(() => { 20 | return Promise.resolve({ 21 | id: 1, 22 | inf_list: [{ 23 | name: 'building', 24 | color: '#e01b24' 25 | },{ 26 | name: 'not_building', 27 | color: '#deddda' 28 | }] 29 | }); 30 | }); 31 | 32 | try { 33 | await Task.vectorize(new URL('./fixtures/image.json', import.meta.url).pathname, { 34 | tmp: os.tmpdir(), 35 | url: 'http://example.com', 36 | token: '123', 37 | bucket: 's3-bucket', 38 | project: 1, 39 | iteration: 2, 40 | submission: 3 41 | }); 42 | } catch (err) { 43 | t.error(err); 44 | } 45 | 46 | Iteration.prototype.from.restore(); 47 | AWS.S3.restore(); 48 | t.end(); 49 | }); 50 | -------------------------------------------------------------------------------- /api/schema/res.ListUsers.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "users" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of users with the service" 12 | }, 13 | "users": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | "id", 19 | "username", 20 | "email", 21 | "access", 22 | "validated" 23 | ], 24 | "additionalProperties": false, 25 | "properties": { 26 | "id": { 27 | "type": "integer", 28 | "description": "Unique ID of User" 29 | }, 30 | "username": { 31 | "type": "string", 32 | "description": "Unique Username" 33 | }, 34 | "email": { 35 | "type": "string", 36 | "description": "Unique Email" 37 | }, 38 | "access": { 39 | "$ref": "./util/access.json" 40 | }, 41 | "validated": { 42 | "$ref": "./util/validated.json" 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /api/schema/req.body.CreateIteration.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "model_type", 5 | "tile_zoom", 6 | "inf_list", 7 | "inf_type", 8 | "inf_binary", 9 | "inf_supertile", 10 | "version", 11 | "hint", 12 | "imagery_id" 13 | ], 14 | "additionalProperties": false, 15 | "properties": { 16 | "model_type": { 17 | "type": "string", 18 | "enum": [ 19 | "tensorflow", 20 | "pytorch" 21 | ] 22 | }, 23 | "tile_zoom": { 24 | "type": "integer" 25 | }, 26 | "inf_list": { 27 | "$ref": "util/inf-list.json" 28 | }, 29 | "inf_type": { 30 | "type": "string", 31 | "enum": [ 32 | "segmentation", 33 | "classification", 34 | "detection" 35 | ] 36 | }, 37 | "inf_binary": { 38 | "type": "boolean" 39 | }, 40 | "inf_supertile": { 41 | "type": "boolean" 42 | }, 43 | "version": { 44 | "$ref": "./util/version.json" 45 | }, 46 | "hint": { 47 | "type": "string", 48 | "enum": [ 49 | "iteration", 50 | "training" 51 | ] 52 | }, 53 | "imagery_id": { 54 | "type": "integer" 55 | }, 56 | "gitsha": { 57 | "type": "string", 58 | "minLength": 7, 59 | "maxLength": 40 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /api/web/src/std.js: -------------------------------------------------------------------------------- 1 | function std() { 2 | window.std = async function(url, opts = {}, redirect = true) { 3 | try { 4 | url = new URL(url); 5 | } catch (err) { 6 | url = new URL(url, window.location.origin); 7 | } 8 | 9 | try { 10 | if (!opts.headers) opts.headers = {}; 11 | 12 | if (typeof opts.body === 'object' && !opts.headers['Content-Type']) { 13 | opts.body = JSON.stringify(opts.body); 14 | opts.headers['Content-Type'] = 'application/json'; 15 | } 16 | 17 | if (localStorage.token && !opts.headers.Authorization) { 18 | opts.headers['Authorization'] = 'Bearer ' + localStorage.token; 19 | } 20 | 21 | const res = await fetch(url, opts); 22 | 23 | let bdy = {}; 24 | if ((res.status < 200 || res.status >= 400) && ![401].includes(res.status)) { 25 | try { 26 | bdy = await res.json(); 27 | } catch (err) { 28 | throw new Error(`Status Code: ${res.status}`); 29 | } 30 | 31 | if (bdy.message) throw new Error(bdy.message); 32 | else throw new Error(`Status Code: ${res.status}`); 33 | } else if (redirect && res.status === 401) { 34 | delete localStorage.token; 35 | return window.location.reload(); 36 | } 37 | 38 | return await res.json(); 39 | } catch (err) { 40 | throw new Error(err.message); 41 | } 42 | } 43 | } 44 | 45 | export default std; 46 | -------------------------------------------------------------------------------- /api/schema/res.ListTasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "tasks" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "tasks": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "additionalProperties": false, 18 | "required": [ 19 | "id", 20 | "iter_id", 21 | "created", 22 | "updated", 23 | "type", 24 | "batch_id", 25 | "log_link" 26 | ], 27 | "properties": { 28 | "id": { 29 | "type": "integer" 30 | }, 31 | "iter_id": { 32 | "type": "integer" 33 | }, 34 | "created": { 35 | "$ref": "./util/created.json" 36 | }, 37 | "updated": { 38 | "$ref": "./util/updated.json" 39 | }, 40 | "type": { 41 | "type": "string" 42 | }, 43 | "batch_id": { 44 | "type": "integer" 45 | }, 46 | "log_link": { 47 | "type": "string" 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /api/schema/res.ListStacks.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "required": [ 4 | "total", 5 | "stacks" 6 | ], 7 | "additionalProperties": false, 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "stacks": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "required": [ 18 | "StackId", 19 | "StackName", 20 | "CreationTime", 21 | "StackStatus", 22 | "DriftInformation", 23 | "project", 24 | "iteration" 25 | ], 26 | "additionalProperties": false, 27 | "properties": { 28 | "StackId": { 29 | "type": "string" 30 | }, 31 | "StackName": { 32 | "type": "string" 33 | }, 34 | "CreationTime": { 35 | "type": "string" 36 | }, 37 | "StackStatus": { 38 | "type": "string" 39 | }, 40 | "DriftInformation": { 41 | "type": "object" 42 | }, 43 | "project": { 44 | "type": "integer" 45 | }, 46 | "iteration": { 47 | "type": "integer" 48 | } 49 | } 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tasks/task-build/lib/ptserving.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const CP = require('child_process'); 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | 7 | const VERSION = 'pytorch/torchserve:0.5.0-gpu'; 8 | 9 | function docker(tmp, model, tagged_model) { 10 | const exists = !!String(CP.execSync(` 11 | docker images ${VERSION} 12 | `)).split('\n')[1]; 13 | 14 | 15 | if (!exists) { 16 | console.error(`ok - pulling ${VERSION} docker image`); 17 | 18 | CP.execSync(` 19 | docker pull ${VERSION} 20 | `); 21 | } 22 | 23 | // Ignore errors, these are to ensure the next commands don't err 24 | try { 25 | CP.execSync(` 26 | docker kill serving_base 27 | `); 28 | } catch (err) { 29 | console.error('ok - no old task to stop'); 30 | } 31 | 32 | try { 33 | CP.execSync(` 34 | docker rm serving_base 35 | `); 36 | } catch (err) { 37 | console.error('ok - no old image to remove'); 38 | } 39 | 40 | CP.execSync(` 41 | docker run -d --name serving_base ${base} 42 | `); 43 | 44 | console.error('ok - syncing model'); 45 | CP.execSync(` 46 | docker cp ${tmp}/model.mar serving_base:/home/model-server/model-store/default.mar 47 | `); 48 | 49 | const tag = `developmentseed/default:${Math.random().toString(36).substring(2, 15)}`; 50 | 51 | CP.execSync(` 52 | docker commit --change 'CMD torchserve --start --ncs --model-store=/home/model-server/model-store/ --models default=default.mar' serving_base ${tag} 53 | `); 54 | 55 | console.error('ok - built base image'); 56 | return tag; 57 | } 58 | 59 | module.exports = docker; 60 | -------------------------------------------------------------------------------- /api/routes/stacks.js: -------------------------------------------------------------------------------- 1 | import Err from '@openaddresses/batch-error'; 2 | import Stack from '../lib/stack.js'; 3 | import Auth from '../lib/auth.js'; 4 | 5 | export default async function router(schema, config) { 6 | 7 | /** 8 | * @api {get} /api/stack List Stacks 9 | * @apiVersion 1.0.0 10 | * @apiName ListStacks 11 | * @apiGroup Stacks 12 | * @apiPermission admin 13 | * 14 | * @apiDescription 15 | * Return a list of all inferencing stacks currently running 16 | * 17 | * @apiSchema (Query) {jsonschema=../schema/req.query.ListStacks.json} apiParam 18 | * @apiSchema {jsonschema=../schema/res.ListStacks.json} apiSuccess 19 | */ 20 | await schema.get('/stack', { 21 | query: 'req.query.ListStacks.json', 22 | res: 'res.ListStacks.json' 23 | }, async (req, res) => { 24 | try { 25 | await Auth.is_admin(req); 26 | 27 | if (config.Environment !== 'aws') { 28 | return { 29 | total: 0, 30 | stacks: [] 31 | }; 32 | } 33 | 34 | const list = (await Stack.list(config.StackName + '-')).filter((stack) => { 35 | return stack.StackName.includes(req.query.filter); 36 | }); 37 | 38 | return res.json({ 39 | total: list.length, 40 | stacks: list.map((l) => { 41 | l.project = parseInt(l.StackName.match(/project-(\d+)/)[1]); 42 | l.iteration = parseInt(l.StackName.match(/iteration-(\d+)/)[1]); 43 | return l; 44 | }) 45 | }); 46 | } catch (err) { 47 | return Err.respond(err, res); 48 | } 49 | }); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /api/schema/res.ListAOI.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "additionalProperties": false, 4 | "required": [ 5 | "total", 6 | "aois" 7 | ], 8 | "properties": { 9 | "total": { 10 | "type": "integer", 11 | "description": "Total number of items" 12 | }, 13 | "aois": { 14 | "type": "array", 15 | "items": { 16 | "type": "object", 17 | "additionalProperties": false, 18 | "required": [ 19 | "id", 20 | "pid", 21 | "created", 22 | "updated", 23 | "iter_id", 24 | "bounds", 25 | "name" 26 | ], 27 | "properties": { 28 | "id": { 29 | "type": "integer" 30 | }, 31 | "pid": { 32 | "type": "integer" 33 | }, 34 | "created": { 35 | "$ref": "./util/created.json" 36 | }, 37 | "updated": { 38 | "$ref": "./util/updated.json" 39 | }, 40 | "name": { 41 | "type": "string" 42 | }, 43 | "iter_id": { 44 | "type": "integer" 45 | }, 46 | "bounds": { 47 | "type": "array", 48 | "items": { 49 | "type": "number" 50 | } 51 | } 52 | } 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /.github/workflows/api.yml: -------------------------------------------------------------------------------- 1 | name: API 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Docker Build 12 | working-directory: ./api 13 | run: docker-compose up --build -d postgis 14 | 15 | - name: Docker Build Base 16 | run: docker build -t base api/ 17 | 18 | - name: Test 19 | run: docker run --network api_default 20 | -e "POSTGRES=postgres://docker:docker@postgis:5432/gis" 21 | -e "MAPBOX_TOKEN=${{ secrets.MAPBOX_TOKEN }}" 22 | -e "GitSha=testing" 23 | base npm test 24 | 25 | - name: Configure AWS Credentials 26 | uses: aws-actions/configure-aws-credentials@v1 27 | with: 28 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 29 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 30 | aws-region: us-east-1 31 | 32 | - name: Login to Amazon ECR 33 | id: login-ecr 34 | uses: aws-actions/amazon-ecr-login@v1 35 | 36 | - name: Docker Tag Base 37 | run: docker tag base ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:${GITHUB_SHA} 38 | 39 | - name: Docker Push Base 40 | run: docker push ${{secrets.AWS_ACCOUNT_ID}}.dkr.ecr.us-east-1.amazonaws.com/ml-enabler:${GITHUB_SHA} 41 | 42 | - name: Lint 43 | run: docker run base sh -c "npm run lint" 44 | 45 | - name: Doc 46 | run: docker run base sh -c "npm run doc" 47 | 48 | - name: Docker Cleanup 49 | working-directory: ./api 50 | run: docker-compose kill 51 | 52 | --------------------------------------------------------------------------------