Next, in the
1. Import load_dotenv.
2. Call the load_dotenv() function to load variables from the .env file.
3. Declare a Config class, where we will store API keys and other settings in its attributes.
4. Declare class attributes corresponding to the required API keys and retrieve their values using os.getenv.
5. Additionally, you can store other settings, such as video parameters, in the attributes of this class.
* Pay attention to this class. Since this class is only needed for storing data, there's no need to create a class constructor here; we can simply store the data in class attributes, as we have done in this case.
Also, note that attributes created outside the class constructor (the init method) are called class attributes, not instance attributes. Class attributes are the same for all instances of the class (objects), unlike instance attributes, which are created in the constructor and can be unique for each object.
config.py file:1. Import load_dotenv.
2. Call the load_dotenv() function to load variables from the .env file.
3. Declare a Config class, where we will store API keys and other settings in its attributes.
4. Declare class attributes corresponding to the required API keys and retrieve their values using os.getenv.
5. Additionally, you can store other settings, such as video parameters, in the attributes of this class.
* Pay attention to this class. Since this class is only needed for storing data, there's no need to create a class constructor here; we can simply store the data in class attributes, as we have done in this case.
Also, note that attributes created outside the class constructor (the init method) are called class attributes, not instance attributes. Class attributes are the same for all instances of the class (objects), unlike instance attributes, which are created in the constructor and can be unique for each object.
π₯13
Now, to use these parameters in other parts of the code, simply import the Config class and access its attributes.
For example, we import this class in the
* Note that in this case, we are accessing the attributes of the Config class directly without creating an instance of this class:
This is possible because OPENAI_API_KEY is a class attribute in the Config class, and we can access it through the class itself rather than through an instance.
However, we can also create an object and then access the class attributes through the object:
But if the OPENAI_API_KEY attribute were declared in the constructor of the Config class, we would only be able to access it through an instance (object) of the class.
For example, we import this class in the
main.py file, retrieve the value of the Config.OPENAI_API_KEY attribute, and pass it to the ScriptWriter class constructor when creating an object.* Note that in this case, we are accessing the attributes of the Config class directly without creating an instance of this class:
Config.OPENAI_API_KEY
This is possible because OPENAI_API_KEY is a class attribute in the Config class, and we can access it through the class itself rather than through an instance.
However, we can also create an object and then access the class attributes through the object:
config = Config()
api_key = config.OPENAI_API_KEYBut if the OPENAI_API_KEY attribute were declared in the constructor of the Config class, we would only be able to access it through an instance (object) of the class.
π₯12π1
The foundation of our bot is now complete.
We've done a lot of work and learned a lot. Now let's take a break for 1-2 days and then start putting meat on the skeleton of our Shorts Monster.
We'll fully develop the ScriptWriter class. After that, I'll give you recommendations for the remaining classes and set you free to swim on your own, so you can finish the rest independently.
We've done a lot of work and learned a lot. Now let's take a break for 1-2 days and then start putting meat on the skeleton of our Shorts Monster.
We'll fully develop the ScriptWriter class. After that, I'll give you recommendations for the remaining classes and set you free to swim on your own, so you can finish the rest independently.
π13π₯8π5π€―2π€1π±1
βοΈ The basis of the bot we've written can serve as the basis for many other projects. Especially those where multi-project capability is important.
For example, for generating WordPress websites.
For example, for generating WordPress websites.
π₯22
So, let's begin developing the ScriptWriter class.
How can we implement this task?
1. By using the API of one of the AI assistants, such as ChatGPT or Claude. We'll choose ChatGPT.
2. We'll also add the option to use the g4f library, which allows access to various AI models for free.
Let's start by installing the necessary packages:
How can we implement this task?
1. By using the API of one of the AI assistants, such as ChatGPT or Claude. We'll choose ChatGPT.
2. We'll also add the option to use the g4f library, which allows access to various AI models for free.
Let's start by installing the necessary packages:
pip install openai
pip install g4fπ₯14π1
In the ScriptWriter class, we have declared the execute method. This will be the central hub method where we build a pipeline to run other helper methods that we will write now.
To begin, let's decompose the tasks of the execute method into smaller steps.
We need to:
1. Accept the initial data in the method (a prompt for the request to the AI assistant).
2. Send a request to the AI assistant's API and save the response to a variable.
3. Write the result to a CSV file named script.csv and save it in the project folder.
To begin, let's decompose the tasks of the execute method into smaller steps.
We need to:
1. Accept the initial data in the method (a prompt for the request to the AI assistant).
2. Send a request to the AI assistant's API and save the response to a variable.
3. Write the result to a CSV file named script.csv and save it in the project folder.
π11π₯6
But before we develop the method, let's refine the class constructor.
What arguments should it accept besides
First, we need to pass the OpenAI API key. To do this, we'll accept an
We'll also set a
* I will provide the code a bit later
What arguments should it accept besides
project_folder?First, we need to pass the OpenAI API key. To do this, we'll accept an
api_key argument.We'll also set a
model parameter to specify the OpenAI model, with a default value of "gpt-4".* I will provide the code a bit later
π₯15
Once again, pay attention to the parameters in the class constructor.
β’ The parameters
β’ The parameter
β’ The parameters
project_folder and api_key are defined without default values. These are called required parameters, meaning they must be provided when creating an object.β’ The parameter
model has a default value ("gpt-4"). Such parameters are called optional. This means that if no value is provided for model when creating an object, the default value ("gpt-4") will be used.π₯11π2
Now, based on the arguments passed to the constructor, we will create attributes of the ScriptWriter class object.
1. First, weβll create an OpenAI client object (
According to the documentation of the openai-python library or the OpenAI API documentation, we can do this by passing the API key to the constructor of the OpenAI class.
2. Next, we will create an attribute for setting the model (
* Note that object attributes should be initialized after calling the parent class constructor (super function). We discussed this earlier in one of the previous posts.
1. First, weβll create an OpenAI client object (
self.client).According to the documentation of the openai-python library or the OpenAI API documentation, we can do this by passing the API key to the constructor of the OpenAI class.
2. Next, we will create an attribute for setting the model (
self.model) and assign it the value of the model argument.* Note that object attributes should be initialized after calling the parent class constructor (super function). We discussed this earlier in one of the previous posts.
π₯15
In the execute method, we will accept the
Next, we need to write a method to send a request to the OpenAI API and return the response. This method should also take the prompt as an argument.
We will name this method
prompt value as an argument.Next, we need to write a method to send a request to the OpenAI API and return the response. This method should also take the prompt as an argument.
We will name this method
generate_text and write it in the next post. For now, in the execute method, letβs simply call this method, pass the prompt as an argument, and store the result in the response variable.π8π₯6
Now let's write the method for generating text via the OpenAI API.
According to the documentation of the openai-python library or the OpenAI API documentation, the implementation of this method could be as follows.
1. In the
2. We assign the value of the
3. We place the value of the
4. The model returns a response object that contains the response options. We take the first item from the
According to the documentation of the openai-python library or the OpenAI API documentation, the implementation of this method could be as follows.
1. In the
generate_text method, we call the chat.completions.create method via self.client, which we created in the class constructor, to send a request to the model for text generation.2. We assign the value of the
self.model attribute to the model parameter of the chat.completions.create method.3. We place the value of the
prompt argument into a dictionary that describes the message for the model.4. The model returns a response object that contains the response options. We take the first item from the
choices list and extract the response text.π₯12π1
Now let's add the option to use
According to the documentation of the g4f library, the method for generating text can be the same as our
However, for g4f, we need to create a separate client, an instance of the Client class:
At any given time, the bot will work with only one client, so creating two clients simultaneously in the class constructor would be inefficient.
To avoid creating two clients at once in the class constructor, we will add a new parameter
Thus, the class constructor needs to be modified as follows.
gpt4free instead of the official API.According to the documentation of the g4f library, the method for generating text can be the same as our
generate_text method.However, for g4f, we need to create a separate client, an instance of the Client class:
self.client = Client()At any given time, the bot will work with only one client, so creating two clients simultaneously in the class constructor would be inefficient.
To avoid creating two clients at once in the class constructor, we will add a new parameter
use_g4f to the constructor and initialize only the necessary client based on the value of this parameter.Thus, the class constructor needs to be modified as follows.
π₯12
Now the generate_text method will use the
If the methods for OpenAI API and g4f had different logic, we would need to separate them to maintain the specific logic for each client.
In that case, we would need to implement different methods for working with each API. I'll show an example of this in the next post.
self.client chosen in the constructor. Note that the logic of the method for both OpenAI API and g4f is the same in our case.If the methods for OpenAI API and g4f had different logic, we would need to separate them to maintain the specific logic for each client.
In that case, we would need to implement different methods for working with each API. I'll show an example of this in the next post.
π₯13
The work on the ScriptWriter class is complete.
We just need to make some changes to the
Our course is coming to an end.
We just need to make some changes to the
main.py file to run and test this mode of the bot.Our course is coming to an end.
π₯7π1
Additional recommendations for the class code:
1. File paths will need to be used repeatedly and across different classes, so they can be made into object attributes and moved to the base class.
2. Where necessary, add exception handling using try-except.
3. Add logging (messages about the start and end of tasks or errors).
1. File paths will need to be used repeatedly and across different classes, so they can be made into object attributes and moved to the base class.
2. Where necessary, add exception handling using try-except.
3. Add logging (messages about the start and end of tasks or errors).
π9π₯3