diff --git a/app/routes/character_routes.py b/app/routes/character_routes.py index 2892a23..ad1fd59 100644 --- a/app/routes/character_routes.py +++ b/app/routes/character_routes.py @@ -1,12 +1,15 @@ -from flask import Blueprint, jsonify, request, abort, make_response +from flask import Blueprint, request, abort, make_response from ..db import db from ..models.character import Character from ..models.greeting import Greeting from sqlalchemy import func, union, except_ -from openai import OpenAI + +import google.generativeai as genai +import os + +genai.configure(api_key=os.environ.get("GEMINI_API_KEY")) bp = Blueprint("characters", __name__, url_prefix="/characters") -client = OpenAI() @bp.post("") def create_character(): @@ -17,7 +20,7 @@ def create_character(): db.session.add(new_character) db.session.commit() - return make_response(new_character.to_dict(), 201) + return new_character.to_dict(), 201 except KeyError as e: abort(make_response({"message": f"missing required value: {e}"}, 400)) @@ -30,24 +33,16 @@ def get_characters(): response = [] for character in characters: - response.append( - { - "id" : character.id, - "name" : character.name, - "personality" : character.personality, - "occupation" : character.occupation, - "age" : character.age - } - ) + response.append(character.to_dict()) - return jsonify(response) + return response @bp.get("//greetings") def get_greetings(char_id): character = validate_model(Character, char_id) if not character.greetings: - return make_response(jsonify(f"No greetings found for {character.name} "), 201) + return {"message": f"No greetings found for {character.name} "}, 201 response = {"Character Name" : character.name, "Greetings" : []} @@ -56,23 +51,22 @@ def get_greetings(char_id): "greeting" : greeting.greeting_text }) - return jsonify(response) + return response + @bp.post("//generate") def add_greetings(char_id): character_obj = validate_model(Character, char_id) greetings = generate_greetings(character_obj) - print(greetings) if character_obj.greetings: - return make_response(jsonify(f"Greetings already generated for {character_obj.name} "), 201) + return {"message": f"Greetings already generated for {character_obj.name} "}, 201 new_greetings = [] for greeting in greetings: - text = greeting[greeting.find(" ")+1:] new_greeting = Greeting( - greeting_text = text.strip("\""), + greeting_text = greeting.strip("\""), #Removes quotes from each string character = character_obj ) new_greetings.append(new_greeting) @@ -80,24 +74,21 @@ def add_greetings(char_id): db.session.add_all(new_greetings) db.session.commit() - return make_response(jsonify(f"Greetings successfully added to {character_obj.name}"), 201) + return {"message": f"Greetings successfully added to {character_obj.name}"}, 201 def generate_greetings(character): + model = genai.GenerativeModel("gemini-1.5-flash") + input_message = f"I am writing a fantasy RPG video game. I have an npc named {character.name} who is {character.age} years old. They are a {character.occupation} who has a {character.personality} personality. Please generate a Python style list of 10 stock phrases they might use when the main character talks to them. Please return just the list without a variable name and square brackets." + response = model.generate_content(input_message) + response_split = response.text.split("\n") #Splits response into a list of stock phrases, ends up with an empty string at index -1 + return response_split[:-1] #Returns the stock phrases list, just without the empty string at the end - input_message = f"I am writing a video game in the style of The Witcher. I have an npc named {character.name} who is {character.age} years old. They are a {character.occupation} who has a {character.personality} personality. Please generate a python style list of 10 stock phrases they might use when the main character talks to them" - completion = client.chat.completions.create( - model="gpt-3.5-turbo", - messages=[ - {"role": "user", "content": input_message} - ] - ) - return(completion.choices[0].message.content.split("\n")) def validate_model(cls,id): try: id = int(id) except: - response = response = {"message": f"{cls.__name__} {id} invalid"} + response = {"message": f"{cls.__name__} {id} invalid"} abort(make_response(response , 400)) query = db.select(cls).where(cls.id == id) diff --git a/migrations/versions/d7a96ea32a49_add_character_model.py b/migrations/versions/0344241db67d_.py similarity index 62% rename from migrations/versions/d7a96ea32a49_add_character_model.py rename to migrations/versions/0344241db67d_.py index 43d6168..47a14f8 100644 --- a/migrations/versions/d7a96ea32a49_add_character_model.py +++ b/migrations/versions/0344241db67d_.py @@ -1,8 +1,8 @@ -"""Add character model +"""empty message -Revision ID: d7a96ea32a49 +Revision ID: 0344241db67d Revises: -Create Date: 2024-06-11 11:15:08.811220 +Create Date: 2024-11-05 16:05:21.795648 """ from alembic import op @@ -10,7 +10,7 @@ # revision identifiers, used by Alembic. -revision = 'd7a96ea32a49' +revision = '0344241db67d' down_revision = None branch_labels = None depends_on = None @@ -26,10 +26,18 @@ def upgrade(): sa.Column('age', sa.Integer(), nullable=False), sa.PrimaryKeyConstraint('id') ) + op.create_table('greeting', + sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), + sa.Column('greeting_text', sa.String(), nullable=False), + sa.Column('character_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['character_id'], ['character.id'], ), + sa.PrimaryKeyConstraint('id') + ) # ### end Alembic commands ### def downgrade(): # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('greeting') op.drop_table('character') # ### end Alembic commands ### diff --git a/migrations/versions/657ab8362756_.py b/migrations/versions/657ab8362756_.py deleted file mode 100644 index b5baa66..0000000 --- a/migrations/versions/657ab8362756_.py +++ /dev/null @@ -1,34 +0,0 @@ -"""empty message - -Revision ID: 657ab8362756 -Revises: e06848138ff6 -Create Date: 2024-06-14 10:29:34.966812 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '657ab8362756' -down_revision = 'e06848138ff6' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table('greeting', schema=None) as batch_op: - batch_op.add_column(sa.Column('character_id', sa.Integer(), nullable=False)) - batch_op.create_foreign_key(None, 'character', ['character_id'], ['id']) - - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table('greeting', schema=None) as batch_op: - batch_op.drop_constraint(None, type_='foreignkey') - batch_op.drop_column('character_id') - - # ### end Alembic commands ### diff --git a/migrations/versions/8ed7775249e9_.py b/migrations/versions/8ed7775249e9_.py deleted file mode 100644 index b0070e1..0000000 --- a/migrations/versions/8ed7775249e9_.py +++ /dev/null @@ -1,34 +0,0 @@ -"""empty message - -Revision ID: 8ed7775249e9 -Revises: d7a96ea32a49 -Create Date: 2024-06-11 17:29:06.612117 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '8ed7775249e9' -down_revision = 'd7a96ea32a49' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('greeting', - sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), - sa.Column('greeting_text', sa.String(), nullable=False), - sa.Column('character_id', sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(['character_id'], ['character.id'], ), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('greeting') - # ### end Alembic commands ### diff --git a/migrations/versions/e06848138ff6_.py b/migrations/versions/e06848138ff6_.py deleted file mode 100644 index 8db8df3..0000000 --- a/migrations/versions/e06848138ff6_.py +++ /dev/null @@ -1,34 +0,0 @@ -"""empty message - -Revision ID: e06848138ff6 -Revises: 8ed7775249e9 -Create Date: 2024-06-13 17:12:14.268947 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'e06848138ff6' -down_revision = '8ed7775249e9' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table('greeting', schema=None) as batch_op: - batch_op.drop_constraint('greeting_character_id_fkey', type_='foreignkey') - batch_op.drop_column('character_id') - - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table('greeting', schema=None) as batch_op: - batch_op.add_column(sa.Column('character_id', sa.INTEGER(), autoincrement=False, nullable=False)) - batch_op.create_foreign_key('greeting_character_id_fkey', 'character', ['character_id'], ['id']) - - # ### end Alembic commands ### diff --git a/requirements.txt b/requirements.txt index f9c8b70..d3d48f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,15 +2,27 @@ alembic==1.13.1 annotated-types==0.6.0 anyio==4.3.0 blinker==1.7.0 +cachetools==5.5.0 certifi==2024.2.2 +charset-normalizer==3.4.0 click==8.1.7 distro==1.9.0 Flask==3.0.2 Flask-Migrate==4.0.5 Flask-SQLAlchemy==3.1.1 +google-ai-generativelanguage==0.6.10 +google-api-core==2.22.0 +google-api-python-client==2.151.0 +google-auth==2.35.0 +google-auth-httplib2==0.2.0 +google-generativeai==0.8.3 +googleapis-common-protos==1.65.0 greenlet==3.0.3 +grpcio==1.67.1 +grpcio-status==1.67.1 h11==0.14.0 httpcore==1.0.5 +httplib2==0.22.0 httpx==0.27.0 idna==3.7 iniconfig==2.0.0 @@ -18,15 +30,26 @@ itsdangerous==2.1.2 Jinja2==3.1.3 Mako==1.3.2 MarkupSafe==2.1.5 +openai==1.35.3 packaging==23.2 pluggy==1.4.0 +proto-plus==1.25.0 +protobuf==5.28.3 psycopg2-binary==2.9.9 +pyasn1==0.6.1 +pyasn1_modules==0.4.1 pydantic==2.7.1 pydantic_core==2.18.2 +pyparsing==3.2.0 pytest==8.0.0 python-dotenv==1.0.1 +requests==2.32.3 +rsa==4.9 sniffio==1.3.1 SQLAlchemy==2.0.25 tqdm==4.66.4 typing_extensions==4.9.0 +uritemplate==4.1.1 +urllib3==2.2.3 Werkzeug==3.0.1 +wonderwords==2.2.0 diff --git a/reset_db.py b/reset_db.py new file mode 100644 index 0000000..105f11d --- /dev/null +++ b/reset_db.py @@ -0,0 +1,7 @@ +from app import create_app, db + + +my_app = create_app() +with my_app.app_context(): + db.session.clear() + print("Session cleared.") \ No newline at end of file