From 50f1a0103171a0f2d23670cee483bb82dfe1bcb6 Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Fri, 22 May 2026 12:10:22 -0700 Subject: [PATCH 1/9] Feat: Added requirements file for easier setup --- requirements.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8c04c06 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +graphene +fastapi +uvicorn From ae1e6679ddde3428da7d4e2aafcac10941e9a257 Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Fri, 22 May 2026 16:36:59 -0700 Subject: [PATCH 2/9] Feat: Updated code to be compatible with python 3.13 libraries --- tutorial1/intro.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tutorial1/intro.py b/tutorial1/intro.py index d60a7f2..0d73888 100644 --- a/tutorial1/intro.py +++ b/tutorial1/intro.py @@ -1,16 +1,24 @@ from fastapi import FastAPI -import graphene -from starlette.graphql import GraphQLApp +import strawberry +from strawberry.fastapi import GraphQLRouter -class calculator(graphene.ObjectType): - concat=graphene.String(a=graphene.String(),b=graphene.String()) - add=graphene.String(a=graphene.Int(),b=graphene.Int()) - def resolve_concat(self,info,a,b): - return a+" "+b - def resolve_add(self,info,a,b): - return a+b +@strawberry.type +class Query: -app=FastAPI() -app.add_route("/",GraphQLApp(schema=graphene.Schema(query=calculator))) - + @strawberry.field + def concat(self, a: str, b: str) -> str: + return a + " " + b + + @strawberry.field + def add(self, a: int, b: int) -> int: + return a + b + + +schema = strawberry.Schema(query=Query) + +graphql_app = GraphQLRouter(schema) + +app = FastAPI() + +app.include_router(graphql_app, prefix="/graphql") From 4adddae91e8b31026a7281f25fcd8c24bc400b42 Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Fri, 22 May 2026 16:38:18 -0700 Subject: [PATCH 3/9] Fix: Updated class name to reflect original tutorial class name --- tutorial1/intro.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial1/intro.py b/tutorial1/intro.py index 0d73888..53288ff 100644 --- a/tutorial1/intro.py +++ b/tutorial1/intro.py @@ -4,7 +4,7 @@ @strawberry.type -class Query: +class calculator: @strawberry.field def concat(self, a: str, b: str) -> str: @@ -15,7 +15,7 @@ def add(self, a: int, b: int) -> int: return a + b -schema = strawberry.Schema(query=Query) +schema = strawberry.Schema(query=calculator) graphql_app = GraphQLRouter(schema) From 95119b89a78580cd8d7e18af3e7d426f18e15a19 Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Thu, 28 May 2026 21:02:22 -0700 Subject: [PATCH 4/9] feat: migrate tutorial GraphQL endpoints to Strawberry GraphQLRouter; remove Graphene MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: replace deprecated `starlette.graphql.GraphQLApp` with `strawberry.fastapi.GraphQLRouter` and provide Strawberry schemas/mounts in: - `tutorial2/usecase1.py`, `tutorial2/usecase2.py` - `tutorial3/main.py` - `tutorial4/main.py` - `tutorial5/main.py` - `tutorial6/main.py` - `tutorial7/main.py` - `tutorial8/main.py` - `tutorial9/main.py` feat: convert Graphene schema modules to Strawberry types: - `tutorial3/schema.py` -> `Course` - `tutorial4/schema.py` -> `Employee` - `tutorial5/schema.py` -> `Weather` - `tutorial8/schema.py` -> `Player` interface, `FootballPlayer`, `CricketPlayer` - `tutorial9/schema.py` -> `FootballPlayer`, `CricketPlayer`, `Invalid` feat: convert Graphene mapping modules to Strawberry `Query` implementations: - `tutorial3/mapping.py`, `tutorial4/mapping.py`, `tutorial5/mapping.py`, `tutorial8/mapping.py`, `tutorial9/mapping.py` fix: correct data and resolver bugs, remove minor issues and cleanup - `tutorial2/usecase1.py`: fix typo `computer sience` → `computer science`; correct resolver parameter `into` → `info`. - `tutorial2/usecase2.py`: remove redundant imports and avoid shadowing built-in `int`; convert to Strawberry types. - `tutorial4/data.py`: use context manager (`with open`) and remove explicit `close()`. - `tutorial5/data.py`, `tutorial9/data.py`: remove duplicated `data=data = [...]`. - formatting/whitespace/trailing-newline cleanups across tutorials. fix: remove all `import graphene` usages across the tutorial modules. Notes: - External packages `fastapi` and `strawberry` are required at runtime; static diagnostics may appear until dependencies are installed. - Functionality preserved: resolvers now return typed Strawberry objects and routes are mounted at `/graphql` consistently. --- .gitignore | 73 +++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 +- tutorial2/usecase1.py | 35 ++++++++++++++------- tutorial2/usecase2.py | 46 ++++++++++++++------------- tutorial3/main.py | 30 ++++++++++++++---- tutorial3/mapping.py | 14 +++++---- tutorial3/schema.py | 12 ++++--- tutorial4/data.py | 25 +++++++++------ tutorial4/main.py | 32 +++++++++++++++---- tutorial4/mapping.py | 14 +++++---- tutorial4/schema.py | 14 +++++---- tutorial5/data.py | 20 ++++++------ tutorial5/main.py | 38 +++++++++++++++++----- tutorial5/mapping.py | 25 ++++++++------- tutorial5/schema.py | 9 +++--- tutorial6/main.py | 33 ++++++++++--------- tutorial7/main.py | 69 ++++++++++++++++++++++------------------ tutorial8/main.py | 44 ++++++++++++++++++++++---- tutorial8/mapping.py | 29 +++++++++-------- tutorial8/schema.py | 26 ++++++++------- tutorial9/data.py | 4 ++- tutorial9/main.py | 58 +++++++++++++++++++++++++++++----- tutorial9/mapping.py | 27 ++++++++-------- tutorial9/schema.py | 49 +++++++++++++---------------- 24 files changed, 491 insertions(+), 238 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3435b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +pip-wheel-metadata/ +share/python-wheels/ + +# Virtual environments +venv/ +ENV/ +env/ +.venv/ +.ENV/ + +# IDEs and editors +.vscode/ +.idea/ + +# Unit test / coverage +.coverage +.coverage.* +.pytest_cache/ +htmlcov/ +.tox/ +.nox/ +.cache/ +nosetests.xml +coverage.xml + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Pyre +.pyre/ + +# MyPy +.mypy_cache/ + +# Jupyter +.ipynb_checkpoints/ + +# SQLite +*.sqlite3 +*.db + +# macOS +.DS_Store + +# Logs +*.log + +# Editor temp files +*~ diff --git a/requirements.txt b/requirements.txt index 8c04c06..ad9c975 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ -graphene fastapi uvicorn +strawberry-graphql +starlette \ No newline at end of file diff --git a/tutorial2/usecase1.py b/tutorial2/usecase1.py index 747c51c..41acd77 100644 --- a/tutorial2/usecase1.py +++ b/tutorial2/usecase1.py @@ -1,15 +1,26 @@ -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp -course_name="computer sience" -course_time_year=1 -class course(graphene.ObjectType): - name= graphene.String() - duration=graphene.Int() - def resolve_name(self,info): +from strawberry.fastapi import GraphQLRouter + +course_name = "computer science" +course_time_year = 1 + + +@strawberry.type +class Query: + @strawberry.field + def name(self) -> str: return course_name - def resolve_duration(self,into): + + @strawberry.field + def duration(self) -> int: return course_time_year -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=course))) -print(graphene.Schema(query=course)) \ No newline at end of file + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) \ No newline at end of file diff --git a/tutorial2/usecase2.py b/tutorial2/usecase2.py index b4f3efb..978dc1f 100644 --- a/tutorial2/usecase2.py +++ b/tutorial2/usecase2.py @@ -1,13 +1,8 @@ -import graphene +import strawberry from fastapi import FastAPI -from graphene.types.objecttype import ObjectType -from starlette.graphql import GraphQLApp -from graphene import ObjectType as ot -from graphene import String as st -from graphene import Int as int -from graphene import List as li - -data=[ +from strawberry.fastapi import GraphQLRouter + +data = [ { "name": "Roni", "city": "Cologne", @@ -27,15 +22,24 @@ } ] -class students(ot): - name=st() - city=st() - country=st() - -class person(ot): - student=li(students) - def resolve_student(self,info): - return data -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=person))) -print(graphene.Schema(query=person)) +@strawberry.type +class Student: + name: str + city: str + country: str + + +@strawberry.type +class Query: + @strawberry.field + def student(self) -> list[Student]: + return [Student(**d) for d in data] + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) diff --git a/tutorial3/main.py b/tutorial3/main.py index c669573..c5499bf 100644 --- a/tutorial3/main.py +++ b/tutorial3/main.py @@ -1,9 +1,27 @@ -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp -from mapping import query +from strawberry.fastapi import GraphQLRouter +from data import read_data -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=query))) -print(graphene.Schema(query=query)) \ No newline at end of file +@strawberry.type +class Course: + name: str + level: str + duration_in_year: int + + +@strawberry.type +class Query: + @strawberry.field + def course(self) -> list[Course]: + return [Course(**c) for c in read_data()] + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) \ No newline at end of file diff --git a/tutorial3/mapping.py b/tutorial3/mapping.py index aa630aa..3ddbae3 100644 --- a/tutorial3/mapping.py +++ b/tutorial3/mapping.py @@ -1,8 +1,10 @@ -import graphene -from schema import courses +import strawberry +from schema import Course from data import read_data -class query(graphene.ObjectType): - course=graphene.List(courses) - def resolve_course(self,info): - return read_data() \ No newline at end of file + +@strawberry.type +class Query: + @strawberry.field + def course(self) -> list[Course]: + return [Course(**c) for c in read_data()] diff --git a/tutorial3/schema.py b/tutorial3/schema.py index 92cb5bb..48d6d48 100644 --- a/tutorial3/schema.py +++ b/tutorial3/schema.py @@ -1,6 +1,8 @@ -import graphene +import strawberry -class courses(graphene.ObjectType): - name=graphene.String() - level=graphene.String() - duration_in_year=graphene.Int() \ No newline at end of file + +@strawberry.type +class Course: + name: str + level: str + duration_in_year: int \ No newline at end of file diff --git a/tutorial4/data.py b/tutorial4/data.py index f2fa423..079e49e 100644 --- a/tutorial4/data.py +++ b/tutorial4/data.py @@ -1,12 +1,19 @@ import csv + + def read_file(): - with open("data.csv")as f1: - data=csv.reader(f1,delimiter=",") - li=[] - i=0 + with open("data.csv") as f1: + data = csv.reader(f1, delimiter=",") + li = [] + i = 0 for row in data: - if(i>0): - li.append({"name":row[0],"city":row[1],"designation":row[2],"experience_in_year":row[3]}) - i=i+1 - f1.close() - return(li) \ No newline at end of file + if i > 0: + li.append({ + "name": row[0], + "city": row[1], + "designation": row[2], + "experience_in_year": row[3], + }) + i += 1 + + return li \ No newline at end of file diff --git a/tutorial4/main.py b/tutorial4/main.py index 5020e36..b109c48 100644 --- a/tutorial4/main.py +++ b/tutorial4/main.py @@ -1,8 +1,28 @@ -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp -from mapping import query +from strawberry.fastapi import GraphQLRouter +from data import read_file -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=query))) -print(graphene.Schema(query=query)) \ No newline at end of file + +@strawberry.type +class Employee: + name: str + city: str + designation: str + experience_in_year: str + + +@strawberry.type +class Query: + @strawberry.field + def employee(self) -> list[Employee]: + return [Employee(**e) for e in read_file()] + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) \ No newline at end of file diff --git a/tutorial4/mapping.py b/tutorial4/mapping.py index 75d5684..7860e4c 100644 --- a/tutorial4/mapping.py +++ b/tutorial4/mapping.py @@ -1,8 +1,10 @@ -import graphene -from schema import emp +import strawberry +from schema import Employee from data import read_file -class query(graphene.ObjectType): - employee=graphene.List(emp) - def resolve_employee(self,info): - return read_file() \ No newline at end of file + +@strawberry.type +class Query: + @strawberry.field + def employee(self) -> list[Employee]: + return [Employee(**e) for e in read_file()] \ No newline at end of file diff --git a/tutorial4/schema.py b/tutorial4/schema.py index 6d784f5..c48ba83 100644 --- a/tutorial4/schema.py +++ b/tutorial4/schema.py @@ -1,7 +1,9 @@ -import graphene +import strawberry -class emp(graphene.ObjectType): - name=graphene.String() - city=graphene.String() - designation=graphene.String() - experience_in_year=graphene.String() \ No newline at end of file + +@strawberry.type +class Employee: + name: str + city: str + designation: str + experience_in_year: str \ No newline at end of file diff --git a/tutorial5/data.py b/tutorial5/data.py index 46855a5..349e9f2 100644 --- a/tutorial5/data.py +++ b/tutorial5/data.py @@ -1,13 +1,13 @@ -data=data=[ -{ - "city":"kolkata", - "temperature":"34" -}, -{ - "city":"mumbai", - "temperature":"29" -}, -{ +data = [ + { + "city": "kolkata", + "temperature": "34", + }, +] + + +def read_data(): + return data "city":"chennai", "temperature":"38" }, diff --git a/tutorial5/main.py b/tutorial5/main.py index e3fb8b8..ba1325a 100644 --- a/tutorial5/main.py +++ b/tutorial5/main.py @@ -1,9 +1,31 @@ +import strawberry from fastapi import FastAPI -import graphene -from graphene.types import schema -from starlette.graphql import GraphQLApp -from mapping import query - -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=query))) -print(graphene.Schema(query=query)) +from strawberry.fastapi import GraphQLRouter +from data import read_data + + +@strawberry.type +class Weather: + city: str + temperature: str + + +@strawberry.type +class Query: + @strawberry.field + def city_temp(self, city: str) -> Weather: + # reuse mapping-style logic if available + data = read_data() + for row in data: + if row["city"] == city: + return Weather(**row) + return Weather(city=city, temperature="not found in the sequence") + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) diff --git a/tutorial5/mapping.py b/tutorial5/mapping.py index 22b979d..a925833 100644 --- a/tutorial5/mapping.py +++ b/tutorial5/mapping.py @@ -1,18 +1,19 @@ -import graphene -from schema import weather +import strawberry +from schema import Weather from data import read_data -class query(graphene.ObjectType): - city_temp=graphene.Field(weather,city=graphene.String()) - def resolve_city_temp(self,info,city): - data=read_data() + +@strawberry.type +class Query: + @strawberry.field + def city_temp(self, city: str) -> Weather: + data = read_data() for row in data: - if row["city"]==city: - return row - return { - "city":city, - "temperature":"not found in the sequence" + if row["city"] == city: + return Weather(**row) + return Weather(city=city, temperature="not found in the sequence") } - \ No newline at end of file + + diff --git a/tutorial5/schema.py b/tutorial5/schema.py index c8b0f1c..e8dc0de 100644 --- a/tutorial5/schema.py +++ b/tutorial5/schema.py @@ -1,6 +1,7 @@ -import graphene +import strawberry -class weather(graphene.ObjectType): - city=graphene.String() - temperature=graphene.String() \ No newline at end of file +@strawberry.type +class Weather: + city: str + temperature: str \ No newline at end of file diff --git a/tutorial6/main.py b/tutorial6/main.py index 41d256a..6b94b5e 100644 --- a/tutorial6/main.py +++ b/tutorial6/main.py @@ -1,18 +1,23 @@ -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp +from strawberry.fastapi import GraphQLRouter -class myquery(graphene.ObjectType): - class Meta: - name="typefrommetaclass1" - description="description from metaclass1" - hello=graphene.String(description="hello string") - bye=graphene.String(description="bye string") - def resolve_hello(self,info): - + +@strawberry.type +class Query: + @strawberry.field(description="hello string") + def hello(self) -> str: return "hello world!!!" - def resolve_bye(self,info): + + @strawberry.field(description="bye string") + def bye(self) -> str: return "good bye!!" -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=myquery))) -print(graphene.Schema(query=myquery)) \ No newline at end of file + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) \ No newline at end of file diff --git a/tutorial7/main.py b/tutorial7/main.py index 1b3632c..96803fb 100644 --- a/tutorial7/main.py +++ b/tutorial7/main.py @@ -1,32 +1,39 @@ -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp - -class player(graphene.Interface): - name=graphene.String() - country=graphene.String() - -class footballplayer(graphene.ObjectType): - class Meta: - interfaces=(player,) - position=graphene.String() - -class cricketplayer(graphene.ObjectType): - class Meta: - interfaces=(player,) - battingorder=graphene.Int() - -class query(graphene.ObjectType): - class Meta: - name="interfacequery" - description="implements field type from interface" - fplayer=graphene.Field(footballplayer,description="coming from football player interface") - def resolve_fplayer(self,info): - return {"name":"player1","country":"Spain","position":"Central Back"} - cplayer=graphene.Field(cricketplayer,description="coming from cricket player interface") - def resolve_cplayer(self,info): - return {"name":"player2","country":"India","battingorder":1} - -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=query))) -print(graphene.Schema(query=query)) +from strawberry.fastapi import GraphQLRouter + + +@strawberry.interface +class Player: + name: str + country: str + + +@strawberry.type +class FootballPlayer(Player): + position: str + + +@strawberry.type +class CricketPlayer(Player): + battingorder: int + + +@strawberry.type +class Query: + @strawberry.field(description="coming from football player interface") + def fplayer(self) -> FootballPlayer: + return FootballPlayer(name="player1", country="Spain", position="Central Back") + + @strawberry.field(description="coming from cricket player interface") + def cplayer(self) -> CricketPlayer: + return CricketPlayer(name="player2", country="India", battingorder=1) + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) diff --git a/tutorial8/main.py b/tutorial8/main.py index 5020e36..2b66d2b 100644 --- a/tutorial8/main.py +++ b/tutorial8/main.py @@ -1,8 +1,40 @@ -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp -from mapping import query +from strawberry.fastapi import GraphQLRouter +from data import read_data -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=query))) -print(graphene.Schema(query=query)) \ No newline at end of file + +@strawberry.type +class FootballPlayer: + name: str + country: str + position: str + + +@strawberry.type +class CricketPlayer: + name: str + country: str + battingorder: int + + +@strawberry.type +class Query: + @strawberry.field(description="list object type implements interface") + def fplayer(self) -> list[FootballPlayer]: + data = read_data() + return [FootballPlayer(**p) for p in data[0]["footballplayer"]] + + @strawberry.field(description="list object type implements interface") + def cplayer(self) -> list[CricketPlayer]: + data = read_data() + return [CricketPlayer(**p) for p in data[0]["cricketplayer"]] + + +schema = strawberry.Schema(query=Query) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) \ No newline at end of file diff --git a/tutorial8/mapping.py b/tutorial8/mapping.py index c135d11..9b10f94 100644 --- a/tutorial8/mapping.py +++ b/tutorial8/mapping.py @@ -1,17 +1,16 @@ -import graphene -from schema import footballplayer,cricketplayer +import strawberry +from schema import FootballPlayer, CricketPlayer from data import read_data -class query(graphene.ObjectType): - class Meta: - name="interfacequery" - description="list with interface" - fplayer=graphene.List(footballplayer,description="list object type implements interface") - def resolve_fplayer(self,info): - data=read_data() - return data[0]["footballplayer"] - - cplayer=graphene.List(cricketplayer,description="list object type implements interface") - def resolve_cplayer(self,info): - data=read_data() - return data[0]["cricketplayer"] \ No newline at end of file + +@strawberry.type +class Query: + @strawberry.field(description="list object type implements interface") + def fplayer(self) -> list[FootballPlayer]: + data = read_data() + return [FootballPlayer(**p) for p in data[0]["footballplayer"]] + + @strawberry.field(description="list object type implements interface") + def cplayer(self) -> list[CricketPlayer]: + data = read_data() + return [CricketPlayer(**p) for p in data[0]["cricketplayer"]] \ No newline at end of file diff --git a/tutorial8/schema.py b/tutorial8/schema.py index 7854627..b6adfef 100644 --- a/tutorial8/schema.py +++ b/tutorial8/schema.py @@ -1,15 +1,17 @@ -import graphene +import strawberry -class player(graphene.Interface): - name=graphene.String() - country=graphene.String() -class footballplayer(graphene.ObjectType): - class Meta: - interfaces=(player,) - position=graphene.String() +@strawberry.interface +class Player: + name: str + country: str -class cricketplayer(graphene.ObjectType): - class Meta: - interfaces=(player,) - battingorder=graphene.Int() \ No newline at end of file + +@strawberry.type +class FootballPlayer(Player): + position: str + + +@strawberry.type +class CricketPlayer(Player): + battingorder: int \ No newline at end of file diff --git a/tutorial9/data.py b/tutorial9/data.py index 1ebef3f..49a511a 100644 --- a/tutorial9/data.py +++ b/tutorial9/data.py @@ -1,4 +1,4 @@ -data=data=[ +data = [ { "footballplayer":[ { @@ -52,5 +52,7 @@ } ] + + def read_data(): return data \ No newline at end of file diff --git a/tutorial9/main.py b/tutorial9/main.py index 50b5426..6ecf427 100644 --- a/tutorial9/main.py +++ b/tutorial9/main.py @@ -1,9 +1,53 @@ -from schema import cricketplayer, footballplayer, invalid -import graphene +import strawberry from fastapi import FastAPI -from starlette.graphql import GraphQLApp -from mapping import query +from strawberry.fastapi import GraphQLRouter +from data import read_data -app=FastAPI() -app.add_route("/graphql",GraphQLApp(schema=graphene.Schema(query=query,types=[footballplayer,cricketplayer,invalid]))) -print(graphene.Schema(query=query)) + +@strawberry.type +class FootballPlayer: + name: str + country: str + position: str + type: str + + +@strawberry.type +class CricketPlayer: + name: str + country: str + battingorder: int + type: str + + +@strawberry.type +class Invalid: + name: str + country: str + type: str + invalid_data: str + + +Player = strawberry.union("Player", (FootballPlayer, CricketPlayer, Invalid)) + + +@strawberry.type +class Query: + @strawberry.field + def player(self, playertype: str) -> list[Player]: + data = read_data() + if playertype == "fplayer": + return [FootballPlayer(**p) for p in data[0]["footballplayer"]] + elif playertype == "cplayer": + return [CricketPlayer(**p) for p in data[0]["cricketplayer"]] + else: + return [Invalid(**p) for p in data[0]["invalid"]] + + +schema = strawberry.Schema(query=Query, types=[FootballPlayer, CricketPlayer, Invalid]) +graphql_app = GraphQLRouter(schema) + +app = FastAPI() +app.include_router(graphql_app, prefix="/graphql") + +print(schema) diff --git a/tutorial9/mapping.py b/tutorial9/mapping.py index 1955a27..7322f79 100644 --- a/tutorial9/mapping.py +++ b/tutorial9/mapping.py @@ -1,17 +1,18 @@ -import graphene -from graphene import String -from schema import player +import strawberry +from schema import FootballPlayer, CricketPlayer, Invalid from data import read_data -class query(graphene.ObjectType): - player=graphene.List(player,required=True,playertype=String(required=True)) - def resolve_player(self,info,playertype): - data=read_data() - if playertype=="fplayer": - return data[0]["footballplayer"] - elif playertype=="cplayer": - return data[0]["cricketplayer"] + +@strawberry.type +class Query: + @strawberry.field + def player(self, playertype: str) -> list: + data = read_data() + if playertype == "fplayer": + return [FootballPlayer(**p) for p in data[0]["footballplayer"]] + elif playertype == "cplayer": + return [CricketPlayer(**p) for p in data[0]["cricketplayer"]] else: - return data[0]["invalid"] - + return [Invalid(**p) for p in data[0]["invalid"]] + diff --git a/tutorial9/schema.py b/tutorial9/schema.py index 2299a3d..c186bad 100644 --- a/tutorial9/schema.py +++ b/tutorial9/schema.py @@ -1,30 +1,25 @@ -import graphene -from graphene import String -class player(graphene.Interface): - name=String() - country=String() - type=String() - @classmethod - def resolve_type(cls, instance, info): - if(instance["type"]=="footballplayer"): - return footballplayer - elif(instance["type"]=="cricketplayer"): - return cricketplayer - else: - return invalid - +import strawberry -class footballplayer(graphene.ObjectType): - class Meta: - interfaces=(player,) - position=String() -class cricketplayer(graphene.ObjectType): - class Meta: - interfaces=(player,) - battingorder=String() +@strawberry.type +class FootballPlayer: + name: str + country: str + type: str + position: str -class invalid(graphene.ObjectType): - class Meta: - interfaces=(player,) - invalid_data=String() + +@strawberry.type +class CricketPlayer: + name: str + country: str + type: str + battingorder: int + + +@strawberry.type +class Invalid: + name: str + country: str + type: str + invalid_data: str From a8bd2a3a22fede1e6fa385537f47269c79c5e134 Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Thu, 28 May 2026 21:11:13 -0700 Subject: [PATCH 5/9] Fix: Fixed import issue when uvicorn runs main.py, import data throws error, but import .data does not --- tutorial3/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial3/main.py b/tutorial3/main.py index c5499bf..8e4f93a 100644 --- a/tutorial3/main.py +++ b/tutorial3/main.py @@ -1,7 +1,7 @@ import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter -from data import read_data +from .data import read_data @strawberry.type From 385e18aac3378827623b8d99621b96645f9a6b40 Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Thu, 28 May 2026 21:19:18 -0700 Subject: [PATCH 6/9] Fix: Included schema and mapping modules into main and removed redundant definitions in main --- tutorial3/main.py | 16 +--------------- tutorial3/mapping.py | 4 ++-- tutorial3/schema.py | 2 +- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/tutorial3/main.py b/tutorial3/main.py index 8e4f93a..29722f4 100644 --- a/tutorial3/main.py +++ b/tutorial3/main.py @@ -1,21 +1,7 @@ import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter -from .data import read_data - - -@strawberry.type -class Course: - name: str - level: str - duration_in_year: int - - -@strawberry.type -class Query: - @strawberry.field - def course(self) -> list[Course]: - return [Course(**c) for c in read_data()] +from .mapping import Query schema = strawberry.Schema(query=Query) diff --git a/tutorial3/mapping.py b/tutorial3/mapping.py index 3ddbae3..99b7497 100644 --- a/tutorial3/mapping.py +++ b/tutorial3/mapping.py @@ -1,6 +1,6 @@ import strawberry -from schema import Course -from data import read_data +from .schema import Course +from .data import read_data @strawberry.type diff --git a/tutorial3/schema.py b/tutorial3/schema.py index 48d6d48..e465222 100644 --- a/tutorial3/schema.py +++ b/tutorial3/schema.py @@ -5,4 +5,4 @@ class Course: name: str level: str - duration_in_year: int \ No newline at end of file + duration_in_year: int From 4e2ed8518cdb22d4bf97c9d9804acf7512f885cb Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Thu, 28 May 2026 21:27:39 -0700 Subject: [PATCH 7/9] Feat: Incorporated the mapping module into main; fixed path issues for the data.csv file in tutorial4/data.csv where data.py could not find data.csv --- tutorial4/data.py | 4 +++- tutorial4/main.py | 17 +---------------- tutorial4/mapping.py | 4 ++-- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/tutorial4/data.py b/tutorial4/data.py index 079e49e..cb3d20f 100644 --- a/tutorial4/data.py +++ b/tutorial4/data.py @@ -1,8 +1,10 @@ import csv +from pathlib import Path def read_file(): - with open("data.csv") as f1: + file_path = Path(__file__).resolve().parent / "data.csv" + with open(file_path) as f1: data = csv.reader(f1, delimiter=",") li = [] i = 0 diff --git a/tutorial4/main.py b/tutorial4/main.py index b109c48..29722f4 100644 --- a/tutorial4/main.py +++ b/tutorial4/main.py @@ -1,22 +1,7 @@ import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter -from data import read_file - - -@strawberry.type -class Employee: - name: str - city: str - designation: str - experience_in_year: str - - -@strawberry.type -class Query: - @strawberry.field - def employee(self) -> list[Employee]: - return [Employee(**e) for e in read_file()] +from .mapping import Query schema = strawberry.Schema(query=Query) diff --git a/tutorial4/mapping.py b/tutorial4/mapping.py index 7860e4c..fe2c6eb 100644 --- a/tutorial4/mapping.py +++ b/tutorial4/mapping.py @@ -1,6 +1,6 @@ import strawberry -from schema import Employee -from data import read_file +from .schema import Employee +from .data import read_file @strawberry.type From 5964f26102e39676f5537824bd86ee5382455ddf Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Thu, 28 May 2026 21:38:09 -0700 Subject: [PATCH 8/9] Feat: included use of mapping.py in main.py, changed import paths to not through import errors duing app startup in uvicorn when running uvicorn from the root directory --- tutorial5/data.py | 38 +++++++++++++++++--------------------- tutorial5/main.py | 20 +------------------- tutorial5/mapping.py | 14 ++++++-------- 3 files changed, 24 insertions(+), 48 deletions(-) diff --git a/tutorial5/data.py b/tutorial5/data.py index 349e9f2..130c63b 100644 --- a/tutorial5/data.py +++ b/tutorial5/data.py @@ -3,27 +3,23 @@ "city": "kolkata", "temperature": "34", }, -] - - -def read_data(): - return data - "city":"chennai", - "temperature":"38" -}, -{ - "city":"banglore", - "temperature":"24" -}, -{ - "city":"pune", - "temperature":"30" -}, -{ - "city":"hyderabad", - "temperature":"32" -}, + { + "city":"chennai", + "temperature":"38" + }, + { + "city":"banglore", + "temperature":"24" + }, + { + "city":"pune", + "temperature":"30" + }, + { + "city":"hyderabad", + "temperature":"32" + }, ] def read_data(): - return data \ No newline at end of file + return data diff --git a/tutorial5/main.py b/tutorial5/main.py index ba1325a..c97f51f 100644 --- a/tutorial5/main.py +++ b/tutorial5/main.py @@ -1,25 +1,7 @@ import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter -from data import read_data - - -@strawberry.type -class Weather: - city: str - temperature: str - - -@strawberry.type -class Query: - @strawberry.field - def city_temp(self, city: str) -> Weather: - # reuse mapping-style logic if available - data = read_data() - for row in data: - if row["city"] == city: - return Weather(**row) - return Weather(city=city, temperature="not found in the sequence") +from .mapping import Query schema = strawberry.Schema(query=Query) diff --git a/tutorial5/mapping.py b/tutorial5/mapping.py index a925833..32b06a5 100644 --- a/tutorial5/mapping.py +++ b/tutorial5/mapping.py @@ -1,6 +1,6 @@ import strawberry -from schema import Weather -from data import read_data +from .schema import Weather +from .data import read_data @strawberry.type @@ -11,9 +11,7 @@ def city_temp(self, city: str) -> Weather: for row in data: if row["city"] == city: return Weather(**row) - return Weather(city=city, temperature="not found in the sequence") - } - - - - + return Weather( + city=city, + temperature="not found in the sequence" + ) From 1a9b70d97523e24abc26dc23838fda258052e4be Mon Sep 17 00:00:00 2001 From: Ryan Schostag Date: Thu, 28 May 2026 22:30:51 -0700 Subject: [PATCH 9/9] Fix: Updated the files to fix import path issues when running uvicorn: Feat: replaced graphene with strawberry in tutorial modules --- tutorial6/main.py | 17 +++-------------- tutorial6/mapping.py | 12 ++++++++++++ tutorial7/main.py | 29 +---------------------------- tutorial7/mapping.py | 28 ++++++++++++++++++++++++++++ tutorial8/data.py | 2 +- tutorial8/main.py | 34 +++------------------------------- tutorial8/mapping.py | 4 ++-- tutorial9/data.py | 2 +- tutorial9/main.py | 44 ++------------------------------------------ tutorial9/mapping.py | 6 +++--- tutorial9/schema.py | 18 ++++++++---------- youtube-playlist.txt | 1 + 12 files changed, 65 insertions(+), 132 deletions(-) create mode 100644 tutorial6/mapping.py create mode 100644 tutorial7/mapping.py create mode 100644 youtube-playlist.txt diff --git a/tutorial6/main.py b/tutorial6/main.py index 6b94b5e..950161b 100644 --- a/tutorial6/main.py +++ b/tutorial6/main.py @@ -1,18 +1,7 @@ -import strawberry +import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter - - -@strawberry.type -class Query: - @strawberry.field(description="hello string") - def hello(self) -> str: - return "hello world!!!" - - @strawberry.field(description="bye string") - def bye(self) -> str: - return "good bye!!" - +from .mapping import Query schema = strawberry.Schema(query=Query) graphql_app = GraphQLRouter(schema) @@ -20,4 +9,4 @@ def bye(self) -> str: app = FastAPI() app.include_router(graphql_app, prefix="/graphql") -print(schema) \ No newline at end of file +print(schema) diff --git a/tutorial6/mapping.py b/tutorial6/mapping.py new file mode 100644 index 0000000..da685bf --- /dev/null +++ b/tutorial6/mapping.py @@ -0,0 +1,12 @@ +import strawberry + + +@strawberry.type +class Query: + @strawberry.field(description="hello string") + def hello(self) -> str: + return "hello world!!!" + + @strawberry.field(description="bye string") + def bye(self) -> str: + return "good bye!!" diff --git a/tutorial7/main.py b/tutorial7/main.py index 96803fb..0a308f9 100644 --- a/tutorial7/main.py +++ b/tutorial7/main.py @@ -1,34 +1,7 @@ import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter - - -@strawberry.interface -class Player: - name: str - country: str - - -@strawberry.type -class FootballPlayer(Player): - position: str - - -@strawberry.type -class CricketPlayer(Player): - battingorder: int - - -@strawberry.type -class Query: - @strawberry.field(description="coming from football player interface") - def fplayer(self) -> FootballPlayer: - return FootballPlayer(name="player1", country="Spain", position="Central Back") - - @strawberry.field(description="coming from cricket player interface") - def cplayer(self) -> CricketPlayer: - return CricketPlayer(name="player2", country="India", battingorder=1) - +from .mapping import Query schema = strawberry.Schema(query=Query) graphql_app = GraphQLRouter(schema) diff --git a/tutorial7/mapping.py b/tutorial7/mapping.py new file mode 100644 index 0000000..1d29e0a --- /dev/null +++ b/tutorial7/mapping.py @@ -0,0 +1,28 @@ +import strawberry + + +@strawberry.interface +class Player: + name: str + country: str + + +@strawberry.type +class FootballPlayer(Player): + position: str + + +@strawberry.type +class CricketPlayer(Player): + battingorder: int + + +@strawberry.type +class Query: + @strawberry.field(description="coming from football player interface") + def fplayer(self) -> FootballPlayer: + return FootballPlayer(name="player1", country="Spain", position="Central Back") + + @strawberry.field(description="coming from cricket player interface") + def cplayer(self) -> CricketPlayer: + return CricketPlayer(name="player2", country="India", battingorder=1) diff --git a/tutorial8/data.py b/tutorial8/data.py index bc9f977..cc2159c 100644 --- a/tutorial8/data.py +++ b/tutorial8/data.py @@ -26,7 +26,7 @@ }, { "name":"virat", - "country":"indian", + "country":"india", "battingorder":2 }, { diff --git a/tutorial8/main.py b/tutorial8/main.py index 2b66d2b..950161b 100644 --- a/tutorial8/main.py +++ b/tutorial8/main.py @@ -1,35 +1,7 @@ -import strawberry +import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter -from data import read_data - - -@strawberry.type -class FootballPlayer: - name: str - country: str - position: str - - -@strawberry.type -class CricketPlayer: - name: str - country: str - battingorder: int - - -@strawberry.type -class Query: - @strawberry.field(description="list object type implements interface") - def fplayer(self) -> list[FootballPlayer]: - data = read_data() - return [FootballPlayer(**p) for p in data[0]["footballplayer"]] - - @strawberry.field(description="list object type implements interface") - def cplayer(self) -> list[CricketPlayer]: - data = read_data() - return [CricketPlayer(**p) for p in data[0]["cricketplayer"]] - +from .mapping import Query schema = strawberry.Schema(query=Query) graphql_app = GraphQLRouter(schema) @@ -37,4 +9,4 @@ def cplayer(self) -> list[CricketPlayer]: app = FastAPI() app.include_router(graphql_app, prefix="/graphql") -print(schema) \ No newline at end of file +print(schema) diff --git a/tutorial8/mapping.py b/tutorial8/mapping.py index 9b10f94..4418358 100644 --- a/tutorial8/mapping.py +++ b/tutorial8/mapping.py @@ -1,6 +1,6 @@ import strawberry -from schema import FootballPlayer, CricketPlayer -from data import read_data +from .schema import FootballPlayer, CricketPlayer +from .data import read_data @strawberry.type diff --git a/tutorial9/data.py b/tutorial9/data.py index 49a511a..a3fc66f 100644 --- a/tutorial9/data.py +++ b/tutorial9/data.py @@ -30,7 +30,7 @@ }, { "name":"virat", - "country":"indian", + "country":"india", "battingorder":2, "type":"cricketplayer" }, diff --git a/tutorial9/main.py b/tutorial9/main.py index 6ecf427..c2a6866 100644 --- a/tutorial9/main.py +++ b/tutorial9/main.py @@ -1,48 +1,8 @@ import strawberry from fastapi import FastAPI from strawberry.fastapi import GraphQLRouter -from data import read_data - - -@strawberry.type -class FootballPlayer: - name: str - country: str - position: str - type: str - - -@strawberry.type -class CricketPlayer: - name: str - country: str - battingorder: int - type: str - - -@strawberry.type -class Invalid: - name: str - country: str - type: str - invalid_data: str - - -Player = strawberry.union("Player", (FootballPlayer, CricketPlayer, Invalid)) - - -@strawberry.type -class Query: - @strawberry.field - def player(self, playertype: str) -> list[Player]: - data = read_data() - if playertype == "fplayer": - return [FootballPlayer(**p) for p in data[0]["footballplayer"]] - elif playertype == "cplayer": - return [CricketPlayer(**p) for p in data[0]["cricketplayer"]] - else: - return [Invalid(**p) for p in data[0]["invalid"]] - +from .mapping import Query +from .schema import FootballPlayer, CricketPlayer, Invalid schema = strawberry.Schema(query=Query, types=[FootballPlayer, CricketPlayer, Invalid]) graphql_app = GraphQLRouter(schema) diff --git a/tutorial9/mapping.py b/tutorial9/mapping.py index 7322f79..24c73e6 100644 --- a/tutorial9/mapping.py +++ b/tutorial9/mapping.py @@ -1,12 +1,12 @@ import strawberry -from schema import FootballPlayer, CricketPlayer, Invalid -from data import read_data +from .schema import FootballPlayer, CricketPlayer, Invalid, Player +from .data import read_data @strawberry.type class Query: @strawberry.field - def player(self, playertype: str) -> list: + def player(self, playertype: str) -> list[Player]: data = read_data() if playertype == "fplayer": return [FootballPlayer(**p) for p in data[0]["footballplayer"]] diff --git a/tutorial9/schema.py b/tutorial9/schema.py index c186bad..92ad498 100644 --- a/tutorial9/schema.py +++ b/tutorial9/schema.py @@ -1,25 +1,23 @@ import strawberry -@strawberry.type -class FootballPlayer: +@strawberry.interface +class Player: name: str country: str type: str + + +@strawberry.type +class FootballPlayer(Player): position: str @strawberry.type -class CricketPlayer: - name: str - country: str - type: str +class CricketPlayer(Player): battingorder: int @strawberry.type -class Invalid: - name: str - country: str - type: str +class Invalid(Player): invalid_data: str diff --git a/youtube-playlist.txt b/youtube-playlist.txt new file mode 100644 index 0000000..d6b5986 --- /dev/null +++ b/youtube-playlist.txt @@ -0,0 +1 @@ +playlist: https://www.youtube.com/playlist?list=PLI8raxzYtfGxVDsdOBuJvRjMK8n0ffWVb