{"id":50969288,"url":"https://github.com/cannlytics/cannlytics-website","last_synced_at":"2026-06-19T00:03:56.143Z","repository":{"id":260114628,"uuid":"304917362","full_name":"cannlytics/cannlytics-website","owner":"cannlytics","description":"The 🔥 Cannlytics Website 🌎 provides people with information about Cannlytics, cannabis analytics, and boasts a cannabis data market 🛍️","archived":false,"fork":false,"pushed_at":"2025-01-08T05:40:49.000Z","size":21530,"stargazers_count":5,"open_issues_count":20,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-27T18:36:55.681Z","etag":null,"topics":["analytics","cannabis","cannabis-api","cannabis-app","cannabis-data","cannabisapp","data-marketplace","django","firebase","metrc","python","statistics"],"latest_commit_sha":null,"homepage":"https://cannlytics.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cannlytics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-17T16:12:23.000Z","updated_at":"2025-08-06T07:59:57.000Z","dependencies_parsed_at":"2025-01-12T11:01:41.191Z","dependency_job_id":"1522401d-1063-4c1b-94d4-500c5c1cb306","html_url":"https://github.com/cannlytics/cannlytics-website","commit_stats":{"total_commits":154,"total_committers":2,"mean_commits":77.0,"dds":0.01948051948051943,"last_synced_commit":"692b5c517adb8a0887ea03475491b8a5bdb0a3d5"},"previous_names":["cannlytics/cannlytics-website"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cannlytics/cannlytics-website","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cannlytics%2Fcannlytics-website","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cannlytics%2Fcannlytics-website/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cannlytics%2Fcannlytics-website/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cannlytics%2Fcannlytics-website/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cannlytics","download_url":"https://codeload.github.com/cannlytics/cannlytics-website/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cannlytics%2Fcannlytics-website/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34511622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","cannabis","cannabis-api","cannabis-app","cannabis-data","cannabisapp","data-marketplace","django","firebase","metrc","python","statistics"],"created_at":"2026-06-19T00:03:55.302Z","updated_at":"2026-06-19T00:03:56.132Z","avatar_url":"https://github.com/cannlytics.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\" style=\"text-align:center; margin-top:1rem; margin-bottom: 1rem;\"\u003e\n  \u003cimg style=\"max-width:420px\" width=\"420px\" alt=\"\" src=\"https://firebasestorage.googleapis.com/v0/b/cannlytics.appspot.com/o/public%2Fimages%2Flogos%2Fcannlytics-website-logo.png?alt=media\u0026token=3dc8ee8c-77ed-4ac2-b42e-b24c416911d3\"\u003e\n  \u003cdiv style=\"margin-top:0.5rem;\"\u003e\n    \u003ch3\u003eSimple, easy, cannabis analytics.\u003c/h3\u003e\n  \u003c/div\u003e\n\n  \u003chttps://cannlytics.com\u003e\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-darkgreen.svg)](https://opensource.org/licenses/MIT)\n[![Version](https://img.shields.io/pypi/v/cannlytics.svg)](https://pypi.org/project/cannlytics)\n[![PyPI download month](https://img.shields.io/pypi/dm/cannlytics.svg)](https://pypi.python.org/pypi/cannlytics/)\n\n\u003c/div\u003e\n\nThe 🔥 Cannlytics Website provides an aesthetic user interface for users to learn about Cannlytics and get set up with everything that they need to utilize Cannlytics to its fullest extent. This documentation explains the Cannlytics Website architecture and how to build, develop, and publish the website.\n\n- [🔥 Introduction](#introduction)\n- [🪴 Installation](#installation)\n- [🏗️ Architecture](#architecture)\n- [🚜 Development](#development)\n  * [Editing](#editing)\n  * [Running](#running)\n  * [Serving](#serving)\n- [🧪 Testing](#testing)\n- [🚀 Publishing](#publishing)\n\n## 🔥 Introduction \u003ca name=\"introduction\"\u003e\u003c/a\u003e\n\nThe `cannlytics` package is the core module implementing cannabis analytics logic. The `cannlytics` module handles [database interactions](#data), [file management](#storage), [authentication and authorization](#authentication), traceability, data importing and exporting, and the logic for all workflows, such as certificate creation, item transfers, and publishing results. The `api` is the interface between the user application and the cannabis analytics logic of `cannlytics`. The `console` is the user application where user's can interface with the infrastructure, such as the database, and utilize the cannabis analytics logic. The `docs` provide information about the project and the `website` provides people with information about cannabis analytics. You can also use the `ai` to automatically collect, augment, and make inferences from data.\n\n## 🪴 Installation \u003ca name=\"installation\"\u003e\u003c/a\u003e\n\nIn brief, installation entails:\n\n1. [Cloning the repository.](#cloning-the-repository)\n2. [Setting your Firebase account credentials.](#setting-your-account-credentials)\n3. [Installing project dependencies and development tools.](#installing-dependencies)\n\n### 1. Cloning the repository \u003ca name=\"cloning-the-repository\"\u003e\u003c/a\u003e\n\nThe best place to begin is to clone the repository and get a lay of the architecture.\n\n```shell\ngit clone https://github.com/cannlytics/cannlytics.git\n```\n\nThe architecture of the Cannlytics codebase is as follows.\n\n```bash\n├── .admin\n│   └── tokens\n│       └── your-firebase-service-account.json\n├── .firebase\n│   ├── firestore.indexes # Available database queries.\n│   ├── firestore.rules # Database access control and data validation.\n|   └── storage.rules # File storage access control and validation.\n├── ai\n│   ├── curation # Tools for automatically cleaning and augmenting data.\n│   ├── functions # Tools for automatically collecting data.\n|   └── inference # Tools for automatically making inferences from data.\n├── api\n│   ├── {endpoint}\n│   |   └── {endpoint}.py # Implementation of specific API endpoints.\n│   ├── urls.py # Defined API endpoints.\n|   └── views.py # Implementation of general API endpoints.\n├── cannlytics\n│   ├── auth # Core authentication logic.\n│   ├── ccrs # Interface to Washington State's traceability system.\n│   ├── charts # Crispy, ready-to-use charts.\n│   ├── data # Data logic, from wrangling to market.\n│   ├── firebase # Interface to Firebase.\n│   ├── lims # All laboratory information management (LIMS) logic.\n│   ├── metrc # Interface to the Metrc traceability system.\n│   ├── models # Defined models.\n│   ├── paypal # Interface to PayPal.\n│   ├── quickbooks # Interface to QuickBooks.\n│   ├── stats # Nifty, ready-to-use statistical models.\n│   ├── utils # General utility functions.\n│   ├── cannlytics.py # Core Cannlytics interface.\n|   └── requirements.txt # Package-specific requirements.\n├── console\n│   ├── assets\n│   |   ├── css # Stylesheets that will be minified and bundled.\n│   |   └── js # JavaScript that will be bundled into a `cannlytics.min.js` module.\n│   ├── core # Required Django configuration.\n│   ├── static/console # Static files, such as images and Excel templates.\n│   ├── templates/console # User interface templates.\n│   ├── templatetags # Custom Django template utility functions.\n│   ├── views # Implementation of user interfaces and their context.\n│   |   └── {view}.py # Views for specific purposes.\n│   ├── db.sqlite3 # Unused SQL database.\n│   ├── Dockerfile # Production configuration.\n│   ├── requirements.txt # Console-specific requirements.\n│   ├── settings.py # Django configuration.\n│   ├── state.py # Static text for certain pages and sections.\n│   ├── urls.py # Console navigation.\n|   └── webpack.config.js # Build configuration.\n├── docs\n│   ├── {src} # Specific documentation.\n│   ├── theme # The style of the documentation site.\n|   └── Dockerfile # Documentation container configuration.\n├── node_modules\n├── public # Files hosted with Firebase hosting.\n├── tests # Tests for all features and functionality.\n├── tools # Administrative, developer, and data management tools.\n├── website # A company website with the same structure as the `console`.\n├── .env # Your secrets.\n├── .firebasesrc # Firebase hosting sources.\n├── .gitignore # Files not committed to GitHub.\n├── firebase.json # Firebase configuration file.\n├── manage.py # Django utility script.\n├── mkdocs.yaml # Documentation configuration.\n├── package.json # Node.js dependencies and scripts.\n├── requirements.txt # All Python requirements.\n└── setup.py # Python SDK configuration.\n```\n\n### 2. Installing project dependencies and development tools \u003ca name=\"installing-dependencies\"\u003e\u003c/a\u003e\n\nYou will need to install the following technologies when developing or creating an installation of Cannlytics. We recommend using the latest stable version of each piece of software whenever possible. Cannlytics has been tested with Python 3.9.\n\n* [Python](https://www.python.org/psf/)\n* [Docker](https://docs.docker.com/get-docker/)\n* [Node.js](https://nodejs.org/en/about/)\n\nThe standard installation requires that you have an account with:\n\n* [Firebase](https://firebase.google.com/)\n* [Google Cloud Platform](https://cloud.google.com/gcp)\n\nIf you are developing Cannlytics, then you will need a couple extra tools:\n\n* [Firebase Tools](https://firebase.google.com/docs/cli)\n* [Google Cloud SDK](https://dl.google.com/dl/cloudsdk/channels/rapid/GoogleCloudSDKInstaller.exe)\n\nWe recommend using [Anaconda](https://docs.anaconda.com/anaconda/install/index.html) if you are developing Cannlytics so that you can create a virtual environment to test, develop, and use the Cannlytics Console in isolation and in a reproducible manner. After installing Anaconda, you can open a terminal and run the following commands to create a ready-to-go environment.\n\n\u003c!-- Is this needed? npm install webpack-dev-server --save-dev --\u003e\n```bash\nconda create --name cannlytics python=3.9\nconda activate cannlytics\npip install -r requirements.txt\npython manage.py migrate\nnpm install\n```\n\n\u003e Note that `python manage.py migrate` creates a new `db.sqlite3` file if you do not have one already.\n\n### 3. Setting your account credentials \u003ca name=\"setting-your-account-credentials\"\u003e\u003c/a\u003e\n\nFor a standard setup, you will need to [create a Firebase account and a project](https://console.firebase.google.com/). We recommend choosing a project name that is in kebab-case, e.g. `your-lims`, so that you can safely use the project name in many places. Now, follow these steps to fill in your environment variables. When publishing, you will need to copy pertinent environment variables to a [Google Cloud Secret](https://codelabs.developers.google.com/codelabs/cloud-run-django/index.html?index=..%2F..index#4).\n\n1. Create an `.env` file in your project's root directory. See `.env.example` for an example with all credentials.\n2. Create a Django secret key:\n    ```py\n    # tools/quickstart.py\n    from django.utils.crypto import get_random_string\n\n    # Generate a secret key for your project.\n    chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^\u0026*(-_=+)'\n    generated_secret_key = get_random_string(50, chars)\n    print(generated_secret_key)\n    ```\n\n    And save it in your `.env` file:\n\n    ```bash\n    # .env\n    SECRET_KEY=xyz\n    ```\n3. [Create a Firebase web app](https://firebase.google.com/docs/web/setup). We recommend using the same namespace you chose for your project, e.g. `your-lims` or `your-lims-dev`, and setting up [Firebase Hosting](https://firebase.google.com/docs/hosting) with your app. Once you have created a Firebase web app, navigate to your Firebase project settings, find your Firebase App Config, and set your Firebase configuration in your `.env` file.\n    ```bash\n    # .env\n    FIREBASE_API_KEY=xyz\n    FIREBASE_AUTH_DOMAIN=your-lims.firebaseapp.com\n    FIREBASE_DATABASE_URL=https://your-lims.firebaseio.com\n    FIREBASE_PROJECT_ID=your-lims\n    FIREBASE_STORAGE_BUCKET=your-lims.appspot.com\n    FIREBASE_MESSAGING_SENDER_ID=123\n    FIREBASE_APP_ID=123\n    FIREBASE_MEASUREMENT_ID=G-abc\n    ```\n4. If you wish to leverage Cannlytics' email capabilities, then set `EMAIL_HOST_USER` and `EMAIL_HOST_PASSWORD` environment variables in your `.env` file. It is recommended that you [create an app password](https://support.google.com/accounts/answer/185833/sign-in-with-app-passwords?hl=en) if you are using Gmail. After you have created your app password, set your email and app password as environment variables, `EMAIL_HOST_USER` and `EMAIL_HOST_PASSWORD` respectively.\n    ```bash\n    # .env\n    EMAIL_HOST_USER=admin@your-company.com\n    EMAIL_HOST_PASSWORD=your-app-password\n    ```\n5. Finally, to facilitate Firebase management, create and download a service account and save the path to your service account as a `GOOGLE_APPLICATION_CREDENTIALS` environment variable. For accessing [secrets](https://cloud.google.com/secret-manager), you will need to grant your service key *Secret Manager Admin* permissions in [Cloud IAM Admin](https://console.cloud.google.com/iam-admin/iam). For your security, this configuration file needs to be kept in a safe place.\n    ```bash\n    # .env\n    GOOGLE_APPLICATION_CREDENTIALS=path/to/your/service/account.json\n    ```\n6. Finish by creating a `.firebaserc` in the root directory with your [Firebase Hosting](https://firebase.google.com/docs/hosting) references. See `example.firebaserc` for an example.\n\nYou are now ready to develop!\n\n## 🏗️ Architecture \u003ca name=\"architecture\"\u003e\u003c/a\u003e\n\nThe Cannlytics Console and Cannlytics Website are built with the [Django](https://www.djangoproject.com/) framework and generally follow a model-template-view (MTV) architectural pattern, where:\n\n| Abstraction | Description |\n|-|-|\n| **Model** | The `cannlytics` package, Django, and all `assets`, such as JavaScript and CSS, that contain the core logic, which is provided to the views.|\n| **Template** | Django HTML files that describe the display and how data are presented. |\n| **View** | Python functions that control the model's logic, specify and provide data to templates, and manage user requests. [Django describes views](https://docs.djangoproject.com/en/3.1/intro/tutorial03/#write-views-that-actually-do-something) as follows: *\"Your view can read records from a database, or not. It can use a template system such as Django's – or a third-party Python template system – or not. It can generate a PDF file, output XML, create a ZIP file on the fly, anything you want, using whatever Python libraries you want.\"* |\n\nCannlytics utilizes a number of [Google Cloud](https://console.cloud.google.com/) services, including:\n\n| Service | Purpose |\n|---------|---------|\n| [Firebase](https://firebase.google.com/) | Cloud services, such as [dynamic links](https://firebase.google.com/docs/dynamic-links). |\n| [Firebase Authentication](https://firebase.google.com/docs/auth) | User authentication. |\n| [Firebase Firestore](https://firebase.google.com/docs/firestore) | NoSQL database for real-time data management. |\n| [Firebase Storage](https://firebase.google.com/docs/storage) | File storage. |\n| [Firebase Hosting](https://firebase.google.com/docs/hosting) | Console, website, and documentation hosting. |\n| [Cloud Build](https://cloud.google.com/build) | Used to containerize the app. |\n| [Cloud Registry](https://cloud.google.com/container-registry) | Used to upload the app to storage. |\n| [Cloud Run](https://cloud.google.com/run) | Used to run the app as a stateless container. |\n| [Cloud Storage](https://cloud.google.com/storage) | Used for console and website file storage. |\n| [Cloud Secret Manager](https://cloud.google.com/secret-manager) | Used for storing configurations and keeping secrets secret. |\n\nThe [standard Cannlytics data models](https://firebasestorage.googleapis.com/v0/b/cannlytics.appspot.com/o/public%2Flims%2Fdiagrams%2Fcannlytics_standard_data_models_0_0_8.svg?alt=media\u0026token=de8e81a9-6250-4aac-857e-3936d26b4f1b) and their default fields are shown below. Cannlytics data models are highly flexible and can contain fewer, different, or additional fields.\n\n\u003cimg width=\"100%\" alt=\"\" src=\"https://firebasestorage.googleapis.com/v0/b/cannlytics.appspot.com/o/public%2Flims%2Fdiagrams%2Fcannlytics_standard_data_models_0_0_8.svg?alt=media\u0026token=de8e81a9-6250-4aac-857e-3936d26b4f1b\"\u003e\n\n## 🚜 Development \u003ca name=\"development\"\u003e\u003c/a\u003e\n\nDevelopment can happen in many avenues. Frequent, small scope pull requests are encouraged. Any contribution, even if it needs future polishing, helps build the project and advance cannabis science. In general;\n\n1. [Create a fork](https://docs.github.com/en/github/getting-started-with-github/quickstart/fork-a-repo) of the repository.\n2. [Edit the project](#edit) by improving the codebase in some manner. Be creative.\n3. [Create a pull request](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) for your changes to be reviewed and merged into the project upon approval or for you to receive feedback on how your changes can be approved.\n\nThe table below lists available development commands.\n\n| Command | Purpose |\n|---------|---------|\n| `start` | Start the complete website development environment. |\n| `serve` | Serve the assets with `webpack-dev-server`. |\n| `livereload` | Serve Django with `django-livereload-server`. |\n| `dev` | Serve Django with `runserver`. |\n| `build` | Build the assets for production with `webpack`. |\n| `collectstatic` | Gather all of the Django static files into the `public` directory. |\n| `container` | Build a container image for the app. |\n| `cloud` | Run the container image in the cloud. |\n| `deploy` | Direct requests to the running container image. |\n| `publish` | Perform all publishing steps: `build`, `container`, `cloud`, and `deploy`.\n\n### Editing the project \u003ca name=\"editing\"\u003e\u003c/a\u003e\n\nAll text material is either stored in JSON in `state.py` or written in Markdown in `docs` directories. See [`python-markdown` Extensions](https://python-markdown.github.io/extensions/) for more information on rendering Markdown. For help with storing static files, see [serving static files on App Engine](https://cloud.google.com/appengine/docs/standard/python3/serving-static-files). You can configure static files to be served from [Firebase Storage](https://firebase.google.com/docs/storage) instead of from [Firebase Hosting](https://firebase.google.com/docs/hosting) in `console/settings.py` or `website/settings.py`. If you modify assets, then you can gather all supporting files, located in each app's `static` directory, into the `public/static` directory with:\n\n```shell\nset PROJECT=website\npython manage.py collectstatic --noinput\n```\n\nor\n\n```shell\nnpm run collectstatic\n```\n\n### Running the project \u003ca name=\"running\"\u003e\u003c/a\u003e\n\nThe simplest way to run the app is to open a command line from the project's root directory, set a `PROJECT` environment variable, and run:\n\n```shell\nset PROJECT=website\npython manage.py runserver\n```\n\nor\n\n```shell\nnpm run dev\n```\n\nYou can also leverage [django-livereload-server](https://github.com/tjwalch/django-livereload-server) for hot-reloading while you develop.\n\n```shell\nnpm run start\n```\n\nHot-reloading is an important tool of development. You can use `django-livereload-server`, which uses both [python-livereload](https://github.com/lepture/python-livereload) and [django-livereload](https://github.com/Fantomas42/django-livereload), for smooth reloading. You can install [django-live-reload-server](https://github.com/tjwalch/django-livereload-server) with:\n\n```shell\npip install django-livereload-server\n```\n\nYou can start hot-reloading by starting the `livereload` server:\n\n```shell\nset PROJECT=website\npython manage.py livereload\n```\n\nIn another console, you start the Django development server as usual:\n\n```shell\nset PROJECT=website\npython manage.py runserver\n```\n\nYou can build the static assets, JavaScript and CSS, utilizing [Webpack](https://webpack.js.org/). The JavaScript bundle is a JavaScript module and is callable from the user interface with the `cannlytics` namespace. You can run the build for development with:\n\n```shell\nwebpack-dev-server --env production=False\n```\n\nor\n\n```shell\nnpm run serve\n```\n\nIt is an inconvenience to run multiple consoles, but a major convenience to have smooth hot-reloading. So, [`npm-run-all`](https://www.npmjs.com/package/npm-run-all) is used to run multiple servers in the same console for smooth development. When you are setup, you can run the project for development simply with:\n\n```shell\nnpm run start\n```\n\n### Serving the project \u003ca name=\"serving\"\u003e\u003c/a\u003e\n\nYou can serve the built project from anywhere you desire. The default option is to serve the project from Google App Engine, outlined below in [publishing](#publishing). Below are general instructions for building and serving the project in a [Docker container image](https://docs.docker.com/get-started/02_our_app/#build-the-apps-container-image).\n\nFirst, build the Docker container image:\n\n```shell\n# build docker image\ndocker build -t cannlytics .\n```\n\nYou can register the container with:\n\n```shell\n# docker push to container registry. \ndocker push cannlytics \n```\n\nYou can [run the application container](https://docs.docker.com/get-started/02_our_app/#start-an-app-container) locally with:\n\n```shell\n# run docker\ndocker run -dp 8080:8080 --env-file docker.env cannlytics\n```\n\nFinally, you can quickly run the container, or multiple containers, with:\n\n```shell\n# bring up containers\ndocker-compose up -d --build\n\n# bring down\ndocker-compose down\n\n# logs\ndocker-compose logs\n```\n\nCongratulations, you can now build and run Cannlytics just about anywhere! The sky is the limit.\n\n## 🧪 Testing \u003ca name=\"testing\"\u003e\u003c/a\u003e\n\nYou can check for errors detectable by Django with:\n\n```shell\npython manage.py check\n```\n\nYou can run tests for a specific app with.\n\n```shell\npython manage.py test your_app_name\n```\n\nYou can also build the platform in a docker container for your specific purposes:\n\n```shell\ndocker build . --tag gcr.io/your-lims/cannlytics\ngcloud auth configure-docker\ndocker push gcr.io/your-lims/cannlytics\n```\n\nPerusing the `tests` directory is actually a good place to find examples on how to use Cannlytics and can be a good place to begin your explorations.\n\n## 🚀 Publishing \u003ca name=\"publishing\"\u003e\u003c/a\u003e\n\nSee [the publishing guide](https://docs.cannlytics.com/developers/publishing/) for complete instructions on how to publish Cannlytics for production. The guide is based on the [Running Django on Cloud Run guide](https://cloud.google.com/python/django/run#windows). After setup, publishing is done with one command:\n\n```shell\nnpm run publish\n```\n\nIf you need to change accounts or projects, then you can use:\n\n```shell\ngcloud config set account `ACCOUNT`\ngcloud config set project `PROJECT ID`\n```\n\nThe build process contains three steps:\n\n1. Containerize the app and upload it to Container Registry.\n\nBuild your container image using [Cloud Build](https://cloud.google.com/build) by running the following command from the directory containing the Dockerfile:\n\n```shell\ngcloud builds submit --tag gcr.io/your-lims/cannlytics\n```\n\n2. Deploy the container image to Cloud Run.\n\n```shell\ngcloud beta run deploy your-lims --image gcr.io/your-lims/cannlytics --region us-central1 --allow-unauthenticated --service-account=${GCS_SA}\n```\n\n3. Direct hosting requests to the containerized app.\n\nThis step provides access to this containerized app from a [Firebase Hosting] URL, so the app can generate dynamic content for the Firebase-hosted site.\n\n```shell\nfirebase deploy --only hosting:production\n```\n\n\u003c!-- \n\nPublishing NEW\n\nFirst, update `gcloud` and login:\n\n```bash\ngcloud components update\ngcloud auth login\n```\n\nCheck if vector indexes have been created:\n\n```bash\ngcloud firestore indexes composite list --database=cannlytics\n```\n\nCreate vector indexes if needed:\n\n```bash\ngcloud firestore indexes composite create \\\n--collection-group='coas' \\\n--query-scope=COLLECTION \\\n--field-config field-path='results_embedding',vector-config='{\"dimension\":\"1536\", \"flat\": \"{}\"}' \\\n--database=cannlytics\n\ngcloud firestore indexes composite create \\\n--collection-group='coas' \\\n--query-scope=COLLECTION \\\n--field-config field-path='product_name_embedding',vector-config='{\"dimension\":\"1536\", \"flat\": \"{}\"}' \\\n--database=cannlytics\n\ngcloud firestore indexes composite create \\\n--collection-group='coas' \\\n--query-scope=COLLECTION \\\n--field-config field-path='strain_name_embedding',vector-config='{\"dimension\":\"1536\", \"flat\": \"{}\"}' \\\n--database=cannlytics\n```\n\nNote, the dimensions should match those of the embedding model. At the moment, `2048` is the maximum allowed.\n\n\n\n--\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcannlytics%2Fcannlytics-website","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcannlytics%2Fcannlytics-website","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcannlytics%2Fcannlytics-website/lists"}