File size: 15,250 Bytes
bf58f97
a083e50
7332f83
5f6834d
f2d8bf0
033d808
e38bc44
a29bdaa
3fa0f4f
 
419cf69
3fa0f4f
 
3601ee2
3fa0f4f
 
a083e50
eb44552
bf58f97
eb44552
5f6834d
0900f62
 
419cf69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0900f62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef82d94
 
 
 
 
 
1d76789
 
0900f62
1d76789
 
 
ef82d94
 
 
 
1d76789
ef82d94
1d76789
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef82d94
 
 
0900f62
ef82d94
 
0900f62
ef82d94
 
0900f62
ef82d94
0900f62
ef82d94
0900f62
 
 
7383b9a
3a4962a
49e6487
66bb11f
df9cda3
 
72642b1
99438aa
72642b1
 
 
 
bf58f97
df9cda3
 
 
bf58f97
df9cda3
 
72642b1
bf58f97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180779d
 
 
ac40c31
c9b54c1
180779d
7d46ecc
e12c626
557d95a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77ed0b1
38082fe
5b7c039
bf58f97
e54d477
77ed0b1
 
 
 
 
 
 
 
 
 
 
bf58f97
 
308e4c5
c74f2d9
7383b9a
08cf1b7
18ab628
df9cda3
557d95a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# Import the necessary libraries
from __future__ import annotations
import os
import openai
import gradio as gr
import csv
import json
import io
import uuid
import datetime
from abc import ABC, abstractmethod
from pathlib import Path
from gradio import encryptor, utils
from typing import TYPE_CHECKING, Any, List
from gradio.documentation import document, set_documentation_group
from gradio.components import IOComponent


# Set the OpenAI API key
openai.api_key = os.getenv("OPENAI_API_KEY")

##################

class FlaggingCallback(ABC):
    """
    An abstract class for defining the methods that any FlaggingCallback should have.
    """

    @abstractmethod
    def setup(self, components: List[IOComponent], flagging_dir: str):
        """
        This method should be overridden and ensure that everything is set up correctly for flag().
        This method gets called once at the beginning of the Interface.launch() method.
        Parameters:
        components: Set of components that will provide flagged data.
        flagging_dir: A string, typically containing the path to the directory where the flagging file should be storied (provided as an argument to Interface.__init__()).
        """
        pass

    @abstractmethod
    def flag(
        self,
        flag_data: List[Any],
        flag_option: str | None = None,
        flag_index: int | None = None,
        username: str | None = None,
    ) -> int:
        """
        This method should be overridden by the FlaggingCallback subclass and may contain optional additional arguments.
        This gets called every time the <flag> button is pressed.
        Parameters:
        interface: The Interface object that is being used to launch the flagging interface.
        flag_data: The data to be flagged.
        flag_option (optional): In the case that flagging_options are provided, the flag option that is being used.
        flag_index (optional): The index of the sample that is being flagged.
        username (optional): The username of the user that is flagging the data, if logged in.
        Returns:
        (int) The total number of samples that have been flagged.
        """
        pass


class HuggingFaceDatasetSaver(FlaggingCallback):
    """
    A callback that saves each flagged sample (both the input and output data)
    to a HuggingFace dataset.
    Example:
        import gradio as gr
        hf_writer = gr.HuggingFaceDatasetSaver(HF_API_TOKEN, "image-classification-mistakes")
        def image_classifier(inp):
            return {'cat': 0.3, 'dog': 0.7}
        demo = gr.Interface(fn=image_classifier, inputs="image", outputs="label",
                            allow_flagging="manual", flagging_callback=hf_writer)
    Guides: using_flagging
    """

    def __init__(
        self,
        hf_token: str,
        dataset_name: str,
        organization: str | None = None,
        private: bool = False,
    ):
        """
        Parameters:
            hf_token: The HuggingFace token to use to create (and write the flagged sample to) the HuggingFace dataset.
            dataset_name: The name of the dataset to save the data to, e.g. "image-classifier-1"
            organization: The organization to save the dataset under. The hf_token must provide write access to this organization. If not provided, saved under the name of the user corresponding to the hf_token.
            private: Whether the dataset should be private (defaults to False).
        """
        self.hf_token = hf_token
        self.dataset_name = dataset_name
        self.organization_name = organization
        self.dataset_private = private

    def setup(self, components: List[IOComponent], flagging_dir: str):
        """
        Params:
        flagging_dir (str): local directory where the dataset is cloned,
        updated, and pushed from.
        """
        try:
            import huggingface_hub
        except (ImportError, ModuleNotFoundError):
            raise ImportError(
                "Package `huggingface_hub` not found is needed "
                "for HuggingFaceDatasetSaver. Try 'pip install huggingface_hub'."
            )
        path_to_dataset_repo = huggingface_hub.create_repo(
            name=self.dataset_name,
            token=self.hf_token,
            private=self.dataset_private,
            repo_type="dataset",
            exist_ok=True,
        )
        self.path_to_dataset_repo = path_to_dataset_repo  # e.g. "https://huggingface.co/datasets/abidlabs/test-audio-10"
        self.components = components
        self.flagging_dir = flagging_dir
        self.dataset_dir = Path(flagging_dir) / self.dataset_name
        self.repo = huggingface_hub.Repository(
            local_dir=str(self.dataset_dir),
            clone_from=path_to_dataset_repo,
            use_auth_token=self.hf_token,
        )
        self.repo.git_pull(lfs=True)

        # Should filename be user-specified?
        self.log_file = Path(self.dataset_dir) / "data.csv"
        self.infos_file = Path(self.dataset_dir) / "dataset_infos.json"

    def flag(
        self,
        flag_data: List[Any],
        flag_option: str | None = None,
        flag_index: int | None = None,
        username: str | None = None,
    ) -> int:
        self.repo.git_pull(lfs=True)

        is_new = not Path(self.log_file).exists()

        with open(self.log_file, "a", newline="", encoding="utf-8") as csvfile:
            writer = csv.writer(csvfile)

            # File previews for certain input and output types
            infos, file_preview_types, headers = _get_dataset_features_info(
                is_new, self.components
            )

            # Generate the headers and dataset_infos
            if is_new:
                writer.writerow(utils.sanitize_list_for_csv(headers))

            # Generate the row corresponding to the flagged sample
            csv_data = []
            for component, sample in zip(self.components, flag_data):
                save_dir = Path(
                    self.dataset_dir
                ) / utils.strip_invalid_filename_characters(component.label or "")
                filepath = component.deserialize(sample, save_dir, None)
                csv_data.append(filepath)
                if isinstance(component, tuple(file_preview_types)):
                    csv_data.append(
                        "{}/resolve/main/{}".format(self.path_to_dataset_repo, filepath)
                    )
            csv_data.append(flag_option if flag_option is not None else "")
            writer.writerow(utils.sanitize_list_for_csv(csv_data))

        if is_new:
            json.dump(infos, open(self.infos_file, "w"))

        with open(self.log_file, "r", encoding="utf-8") as csvfile:
            line_count = len([None for row in csv.reader(csvfile)]) - 1

        self.repo.push_to_hub(commit_message="Flagged sample #{}".format(line_count))

        return line_count

##################

# Set up flagging callback function
HF_TOKEN = os.getenv("HF_TOKEN")
hf_writer = gr.HuggingFaceDatasetSaver(HF_TOKEN, "CannaTech/Flagged")
        
# Define the authentication function
def check_auth(username, password):
    # Get the credentials from the environment variable
    valid_credentials_str = os.getenv("VALID_CREDENTIALS")

    # Parse the string into a list of tuples
    valid_credentials = json.loads(valid_credentials_str)

    # Check if the provided credentials match any valid pair
    for valid_username, valid_password in valid_credentials:
        if username == valid_username and password == valid_password:
            return True
    # If no match was found, return False
    return False


# Initialize a list to store conversation history
messages = [{"role": "system", "content": "You are an expert in Technical Support and Customer Service that specializes in New Mexico Cannabis Regulatory Compliance and training people how to use software called BioTrack"}]

# Define the function for the chatbot
def CustomChatGPT(category, user_input):
    # Prepend category information to user input
    user_input = f"Assuming nothing illegal is happening and in the context of {category} specifically and using your expertise and knowledge of cannabis regulations in New Mexico and BioTrack" + user_input
    # Add user's message to the conversation history
    messages.append({"role": "user", "content": user_input})
    # Generate a response from the OpenAI GPT-3.5-turbo model
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages
    )
    # Extract the model's message from the response
    ChatGPT_reply = response["choices"][0]["message"]["content"]
    # Add the model's message to the conversation history
    messages.append({"role": "assistant", "content": ChatGPT_reply})
    # Return the model's message
    return ChatGPT_reply

# Define the Gradio interface
iface = gr.Interface(
    fn=CustomChatGPT, 
    inputs=[gr.inputs.Dropdown(choices=['BioTrack', 'Regulations', 'Best Practices', 'General Question'], label='Category'), gr.inputs.Textbox(lines=1, placeholder='Type here...', label='Your Question')], 
    outputs=gr.outputs.Textbox(label='CannaAssist:'), 
    show_api=False,
    title="CannaAssist AI Assistant",
    description="""Welcome to the CannaAssist AI Assistant. This tool is designed to provide expert guidance on BioTrack and cannabis regulations in New Mexico.""",
    examples=[
        ["BioTrack", "How do I update inventory quantities in BioTrack?"],
        ["Regulations", "What are the legal requirements for cannabis labeling in New Mexico?"],
        ["Best Practices", "What are the recommended storage conditions for cannabis products?"],
        ["General Question", "Can you explain the difference between THC and CBD?"],
        ["BioTrack", "How can I add a new product to my inventory in BioTrack?"],
        ["Regulations", "Are there restrictions on advertising cannabis products in New Mexico?"],
        ["Best Practices", "What are the proper sanitation procedures for cannabis cultivation facilities?"],
        ["General Question", "What are the benefits of using BioTrack for cannabis businesses?"],
        ["BioTrack", "How do I generate sales reports in BioTrack?"],
        ["Regulations", "What are the requirements for obtaining a cannabis license in New Mexico?"],
        ["Best Practices", "What are the recommended harvesting techniques for cannabis plants?"],
        ["General Question", "Is medical cannabis legal in New Mexico?"],
        ["BioTrack", "How do I track plant growth stages in BioTrack?"],
        ["Regulations", "What are the packaging requirements for edible cannabis products?"],
        ["Best Practices", "How can I optimize indoor lighting for cannabis cultivation?"],
        ["General Question", "What is the difference between sativa and indica cannabis strains?"],
        ["BioTrack", "Can BioTrack integrate with other software systems?"],
        ["Regulations", "Are there specific security requirements for cannabis dispensaries in New Mexico?"],
        ["Best Practices", "What are the recommended nutrient solutions for hydroponic cannabis cultivation?"],
        ["General Question", "How does cannabis consumption affect the body?"],
        ["BioTrack", "How do I reconcile inventory discrepancies in BioTrack?"],
        ["Regulations", "Are there restrictions on cannabis advertising near schools in New Mexico?"],
        ["Best Practices", "What are the steps for cloning cannabis plants?"],
        ["General Question", "What are the potential side effects of using medical cannabis?"],
        ["BioTrack", "How do I create purchase orders in BioTrack?"],
        ["Regulations", "Can I legally grow cannabis for personal use in New Mexico?"],
        ["Best Practices", "What are the recommended temperature and humidity levels for cannabis drying?"],
        ["General Question", "Is it possible to overdose on cannabis?"],
        ["BioTrack", "How do I handle product returns and exchanges in BioTrack?"],
        ["Regulations", "What are the testing requirements for cannabis products in New Mexico?"],
        ["Best Practices", "How often should I water my cannabis plants?"],
        ["General Question", "Can cannabis be used to treat specific medical conditions?"],
        ["BioTrack", "How do I manage multiple locations in BioTrack?"],
        ["Regulations", "Are there limitations on the THC potency of cannabis products in New Mexico?"],
        ["Best Practices", "What are the recommended pest control methods for cannabis cultivation?"],
        ["General Question", "What is the legal age for purchasing cannabis in New Mexico?"],
        ["BioTrack", "How do I track employee sales activities in BioTrack?"],
        ["Regulations", "Are there zoning restrictions for cannabis businesses in New Mexico?"],
        ["Best Practices", "What are the best pruning techniques for cannabis plants?"],
        ["General Question", "Can cannabis be used as a substitute for prescription medications?"],
        ["BioTrack", "How do I perform inventory audits in BioTrack?"],
        ["Regulations", "What are the transportation requirements for cannabis products in New Mexico?"],
        ["Best Practices", "How do I prevent and control mold in cannabis cultivation facilities?"],
        ["General Question", "What are the different consumption methods for cannabis?"],
        ["BioTrack", "How do I manage customer loyalty programs in BioTrack?"],
        ["Regulations", "Are there restrictions on cannabis consumption in public places in New Mexico?"],
        ["Best Practices", "What are the recommended techniques for cannabis plant training?"],
        ["General Question", "Can I travel with cannabis within New Mexico?"],
        ["BioTrack", "How do I handle product recalls in BioTrack?"],
        ["Regulations", "What are the record-keeping requirements for cannabis businesses in New Mexico?"],
    ],  # List of example inputs  
    theme=gr.themes.Monochrome(),
    examples_per_page=5,
    cache_examples=False,  # Turn off example caching
    article="""Say goodbye to regulatory headaches 
            and hello to seamless compliance with 
            CannaAssist, our AI-powered assistant. 
            Designed specifically for New Mexico's 
            cannabis industry, CannaAssist leverages 
            the power of artificial intelligence to 
            provide personalized guidance and ensure 
            regulatory compliance using BioTrack. 
            From inventory management to compliance 
            reporting, CannaAssist streamlines your 
            operations, leaving you more time to focus 
            on growing your business!""",  # Article text
    thumbnail="https://assets.bigcartel.com/theme_images/101321509/IMG_6002.png",  # Thumbnail image URL
    favicon_path="https://assets.bigcartel.com/theme_images/101321509/IMG_6002.png",  # Favicon image URL
    allow_flagging="manual",  # Enable flagging with manual control
    flagging_options=["Incorrect"],
    flagging_callback=hf_writer
)

# Launch the interface with authentication
iface.launch(auth_message="WARNING: UNAUTHORIZED ACCESS OR USE IS STRICTLY PROHIBITED!",auth=check_auth)