{"id":19278465,"url":"https://github.com/manesioz/secure-graphene","last_synced_at":"2025-04-22T00:31:55.379Z","repository":{"id":57465195,"uuid":"204603254","full_name":"manesioz/secure-graphene","owner":"manesioz","description":"Python library that assists you in securing your GraphQL API against malicious queries via Depth Limiting, etc","archived":false,"fork":false,"pushed_at":"2019-12-13T04:27:16.000Z","size":64,"stargazers_count":10,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-28T14:18:02.987Z","etag":null,"topics":["api","graphene-python","graphql","python","security"],"latest_commit_sha":null,"homepage":"","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/manesioz.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}},"created_at":"2019-08-27T02:31:56.000Z","updated_at":"2022-04-07T00:22:58.000Z","dependencies_parsed_at":"2022-08-31T03:11:42.003Z","dependency_job_id":null,"html_url":"https://github.com/manesioz/secure-graphene","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manesioz%2Fsecure-graphene","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manesioz%2Fsecure-graphene/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manesioz%2Fsecure-graphene/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manesioz%2Fsecure-graphene/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manesioz","download_url":"https://codeload.github.com/manesioz/secure-graphene/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223883721,"owners_count":17219270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api","graphene-python","graphql","python","security"],"created_at":"2024-11-09T21:09:46.564Z","updated_at":"2024-11-09T21:09:47.177Z","avatar_url":"https://github.com/manesioz.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/manesioz/secure-graphene/blob/master/assets/secure-graphene3.png\"\u003e\n  \u003cbr\u003e\u003cbr\u003e\n  An extension of \u003ca href=https://github.com/graphql-python/graphene\u003eGraphene\u003c/a\u003e which allows you to secure your GraphQL API against malicious queries.\n\u003c/p\u003e\n\n\nFeatures included: \n- Limit Query Depth\n\n\nOther features (limiting query complexity, etc) are under development. \n\n\n### Prerequisites \n\n- [graphql-core](https://github.com/graphql-python/graphql-core) \n\n\n### Installation \n\n-  `pip install secure-graphene` \n\n\n### Detailed Example \n\nGiven the following schema: \n\n```python\nimport graphene\nfrom secure_graphene import depth\n\nclass Episode(graphene.Enum):\n    NEWHOPE = 4\n    EMPIRE = 5\n    JEDI = 6\n\n\nclass Character(graphene.Interface):\n    id = graphene.ID()\n    name = graphene.String()\n    friends = graphene.List(lambda: Character)\n    appears_in = graphene.List(Episode)\n\n    def resolve_friends(self, info):\n        # The character friends is a list of strings\n        return [get_character(f) for f in self.friends]\n\n\nclass Human(graphene.ObjectType):\n    class Meta:\n        interfaces = (Character,)\n\n    home_planet = graphene.String()\n\n\nclass Droid(graphene.ObjectType):\n    class Meta:\n        interfaces = (Character,)\n\n    primary_function = graphene.String()\n\n\nclass Query(graphene.ObjectType):\n    hero = graphene.Field(Character, episode=Episode())\n    human = graphene.Field(Human, id=graphene.String())\n    droid = graphene.Field(Droid, id=graphene.String())\n\n    def resolve_hero(self, info, episode=None):\n        return get_hero(episode)\n\n    def resolve_human(self, info, id):\n        return get_human(id)\n\n    def resolve_droid(self, info, id):\n        return get_droid(id)\n\n```\n\n\nAnd the resolver functions and data: \n\n```python\nhuman_data = {}\ndroid_data = {}\n\nluke = Human(\n    id=\"1000\",\n    name=\"Luke Skywalker\",\n    friends=[\"1002\", \"1003\", \"2000\", \"2001\"],\n    appears_in=[4, 5, 6],\n    home_planet=\"Tatooine\",\n)\n\nvader = Human(\n    id=\"1001\",\n    name=\"Darth Vader\",\n    friends=[\"1004\"],\n    appears_in=[4, 5, 6],\n    home_planet=\"Tatooine\",\n)\n\nhan = Human(\n    id=\"1002\",\n    name=\"Han Solo\",\n    friends=[\"1000\", \"1003\", \"2001\"],\n    appears_in=[4, 5, 6],\n    home_planet=None,\n)\n\nleia = Human(\n    id=\"1003\",\n    name=\"Leia Organa\",\n    friends=[\"1000\", \"1002\", \"2000\", \"2001\"],\n    appears_in=[4, 5, 6],\n    home_planet=\"Alderaan\",\n)\n\ntarkin = Human(\n    id=\"1004\",\n    name=\"Wilhuff Tarkin\",\n    friends=[\"1001\"],\n    appears_in=[4],\n    home_planet=None,\n)\n\nhuman_data = {\n    \"1000\": luke,\n    \"1001\": vader,\n    \"1002\": han,\n    \"1003\": leia,\n    \"1004\": tarkin,\n}\n\nc3po = Droid(\n    id=\"2000\",\n    name=\"C-3PO\",\n    friends=[\"1000\", \"1002\", \"1003\", \"2001\"],\n    appears_in=[4, 5, 6],\n    primary_function=\"Protocol\",\n)\n\nr2d2 = Droid(\n    id=\"2001\",\n    name=\"R2-D2\",\n    friends=[\"1000\", \"1002\", \"1003\"],\n    appears_in=[4, 5, 6],\n    primary_function=\"Astromech\",\n)\n\ndroid_data = {\"2000\": c3po, \"2001\": r2d2}\n\n\ndef get_character(id):\n    return human_data.get(id) or droid_data.get(id)\n\n\ndef get_friends(character):\n    return map(get_character, character.friends)\n\n\ndef get_hero(episode):\n    if episode == 5:\n        return human_data[\"1000\"]\n    return droid_data[\"2001\"]\n\n\ndef get_human(id):\n    return human_data.get(id)\n\n\ndef get_droid(id):\n    return droid_data.get(id)\n```\nLet's run this query\n\n```python\nquery_string = \"\"\"\n            query HeroNameAndFriendsQuery {\n              hero {\n                id\n                name\n                friends {\n                  name\n                }\n              }\n            }\n        \"\"\"\n```\n\nBy doing the following: \n\n```python\nbackend = depth.DepthAnalysisBackend(max_depth=2, execute_params={'executor': None}) \nschema = graphene.Schema(query=Query)\nresult = schema.execute(query_string, backend=backend)\nresult.errors\n```\nWhich returns the following: \n```python\n[Exception('Query is too deep - your depth is 3 and the max depth is 2')]\n```\n    \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanesioz%2Fsecure-graphene","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanesioz%2Fsecure-graphene","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanesioz%2Fsecure-graphene/lists"}