We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Return user's geolocalization based on IP
API should return geolocalization data guessed from users's IP. We already have all the logic in the `saleor.core.middleware.country` function. What needs to be done is to wrap this data in a GraphQL type and tie it up to the API. 

E.g.:
```
shop {
  geolocalization {
    countryCode
  }
}
```

Should it return DEFAULT_COUNTRY from settings as a fallback?

@mociepka Please provide more information about what data you'd need in the storefront.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `saleor/graphql/shop/types.py`
Content:
```
1 import graphene
2 from django.conf import settings
3 from django_countries import countries
4 from graphql_jwt.decorators import permission_required
5 from phonenumbers import COUNTRY_CODE_TO_REGION_CODE
6 
7 from ...core.permissions import get_permissions
8 from ...site import models as site_models
9 from ..core.types.common import (
10     CountryDisplay, LanguageDisplay, PermissionDisplay, WeightUnitsEnum)
11 from ..menu.types import Menu
12 from ..product.types import Collection
13 from ..utils import format_permissions_for_display
14 
15 
16 class Navigation(graphene.ObjectType):
17     main = graphene.Field(Menu, description='Main navigation bar.')
18     secondary = graphene.Field(Menu, description='Secondary navigation bar.')
19 
20     class Meta:
21         description = 'Represents shop\'s navigation menus.'
22 
23 
24 class AuthorizationKey(graphene.ObjectType):
25     name = graphene.String(description='Name of the key.', required=True)
26     key = graphene.String(description='Value of the key.', required=True)
27 
28 
29 class Domain(graphene.ObjectType):
30     host = graphene.String(
31         description='The host name of the domain.', required=True)
32     ssl_enabled = graphene.Boolean(
33         description='Inform if SSL is enabled.', required=True)
34     url = graphene.String(
35         description='Shop\'s absolute URL.', required=True)
36 
37     class Meta:
38         description = 'Represents shop\'s domain.'
39 
40 
41 class Shop(graphene.ObjectType):
42     authorization_keys = graphene.List(
43         AuthorizationKey, description='List of configured authorization keys.',
44         required=True)
45     countries = graphene.List(
46         CountryDisplay, description='List of countries available in the shop.',
47         required=True)
48     currencies = graphene.List(
49         graphene.String, description='List of available currencies.',
50         required=True)
51     default_currency = graphene.String(
52         description='Default shop\'s currency.', required=True)
53     default_country = graphene.Field(
54         CountryDisplay, description='Default shop\'s country')
55     description = graphene.String(description='Shop\'s description.')
56     domain = graphene.Field(
57         Domain, required=True, description='Shop\'s domain data.')
58     homepage_collection = graphene.Field(
59         Collection, description='Collection displayed on homepage')
60     languages = graphene.List(
61         LanguageDisplay,
62         description='List of the shops\'s supported languages.', required=True)
63     name = graphene.String(description='Shop\'s name.', required=True)
64     navigation = graphene.Field(
65         Navigation, description='Shop\'s navigation.')
66     permissions = graphene.List(
67         PermissionDisplay, description='List of available permissions.',
68         required=True)
69     phone_prefixes = graphene.List(
70         graphene.String, description='List of possible phone prefixes.',
71         required=True)
72     header_text = graphene.String(description='Header text')
73     include_taxes_in_prices = graphene.Boolean(
74         description='Include taxes in prices')
75     display_gross_prices = graphene.Boolean(
76         description='Display prices with tax in store')
77     track_inventory_by_default = graphene.Boolean(
78         description='Enable inventory tracking')
79     default_weight_unit = WeightUnitsEnum(description='Default weight unit')
80 
81     class Meta:
82         description = '''
83         Represents a shop resource containing general shop\'s data
84         and configuration.'''
85 
86     @permission_required('site.manage_settings')
87     def resolve_authorization_keys(self, info):
88         return site_models.AuthorizationKey.objects.all()
89 
90     def resolve_countries(self, info):
91         return [
92             CountryDisplay(code=country[0], country=country[1])
93             for country in countries]
94 
95     def resolve_currencies(self, info):
96         return settings.AVAILABLE_CURRENCIES
97 
98     def resolve_domain(self, info):
99         site = info.context.site
100         return Domain(
101             host=site.domain,
102             ssl_enabled=settings.ENABLE_SSL,
103             url=info.context.build_absolute_uri('/'))
104 
105     def resolve_default_currency(self, info):
106         return settings.DEFAULT_CURRENCY
107 
108     def resolve_description(self, info):
109         return info.context.site.settings.description
110 
111     def resolve_homepage_collection(self, info):
112         return info.context.site.settings.homepage_collection
113 
114     def resolve_languages(self, info):
115         return [
116             LanguageDisplay(code=language[0], language=language[1])
117             for language in settings.LANGUAGES]
118 
119     def resolve_name(self, info):
120         return info.context.site.name
121 
122     def resolve_navigation(self, info):
123         site_settings = info.context.site.settings
124         return Navigation(
125             main=site_settings.top_menu, secondary=site_settings.bottom_menu)
126 
127     @permission_required('site.manage_settings')
128     def resolve_permissions(self, info):
129         permissions = get_permissions()
130         return format_permissions_for_display(permissions)
131 
132     def resolve_phone_prefixes(self, info):
133         return list(COUNTRY_CODE_TO_REGION_CODE.keys())
134 
135     def resolve_header_text(self, info):
136         return info.context.site.settings.header_text
137 
138     def resolve_include_taxes_in_prices(self, info):
139         return info.context.site.settings.include_taxes_in_prices
140 
141     def resolve_display_gross_prices(self, info):
142         return info.context.site.settings.display_gross_prices
143 
144     def resolve_track_inventory_by_default(self, info):
145         return info.context.site.settings.track_inventory_by_default
146 
147     def resolve_default_weight_unit(self, info):
148         return info.context.site.settings.default_weight_unit
149 
150     def resolve_default_country(self, info):
151         default_country_code = settings.DEFAULT_COUNTRY
152         default_country_name = countries.countries.get(default_country_code)
153         if default_country_name:
154             default_country = CountryDisplay(
155                 code=default_country_code, country=default_country_name)
156         else:
157             default_country = None
158         return default_country
159
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/saleor/graphql/shop/types.py b/saleor/graphql/shop/types.py
--- a/saleor/graphql/shop/types.py
+++ b/saleor/graphql/shop/types.py
@@ -5,6 +5,7 @@
 from phonenumbers import COUNTRY_CODE_TO_REGION_CODE
 
 from ...core.permissions import get_permissions
+from ...core.utils import get_client_ip, get_country_by_ip
 from ...site import models as site_models
 from ..core.types.common import (
     CountryDisplay, LanguageDisplay, PermissionDisplay, WeightUnitsEnum)
@@ -38,7 +39,19 @@
         description = 'Represents shop\'s domain.'
 
 
+class Geolocalization(graphene.ObjectType):
+    country = graphene.Field(
+        CountryDisplay,
+        description='Country of the user acquired by his IP address.')
+
+    class Meta:
+        description = 'Represents customers\'s geolocalization data.'
+
+
 class Shop(graphene.ObjectType):
+    geolocalization = graphene.Field(
+        Geolocalization,
+        description='Customer\'s geolocalization data.')
     authorization_keys = graphene.List(
         AuthorizationKey, description='List of configured authorization keys.',
         required=True)
@@ -102,6 +115,15 @@
             ssl_enabled=settings.ENABLE_SSL,
             url=info.context.build_absolute_uri('/'))
 
+    def resolve_geolocalization(self, info):
+        client_ip = get_client_ip(info.context)
+        country = get_country_by_ip(client_ip)
+        if country:
+            return Geolocalization(
+                country=CountryDisplay(
+                    code=country.code, country=country.name))
+        return Geolocalization(country=None)
+
     def resolve_default_currency(self, info):
         return settings.DEFAULT_CURRENCY

{"golden_diff": "diff --git a/saleor/graphql/shop/types.py b/saleor/graphql/shop/types.py\n--- a/saleor/graphql/shop/types.py\n+++ b/saleor/graphql/shop/types.py\n@@ -5,6 +5,7 @@\n from phonenumbers import COUNTRY_CODE_TO_REGION_CODE\n \n from ...core.permissions import get_permissions\n+from ...core.utils import get_client_ip, get_country_by_ip\n from ...site import models as site_models\n from ..core.types.common import (\n     CountryDisplay, LanguageDisplay, PermissionDisplay, WeightUnitsEnum)\n@@ -38,7 +39,19 @@\n         description = 'Represents shop\\'s domain.'\n \n \n+class Geolocalization(graphene.ObjectType):\n+    country = graphene.Field(\n+        CountryDisplay,\n+        description='Country of the user acquired by his IP address.')\n+\n+    class Meta:\n+        description = 'Represents customers\\'s geolocalization data.'\n+\n+\n class Shop(graphene.ObjectType):\n+    geolocalization = graphene.Field(\n+        Geolocalization,\n+        description='Customer\\'s geolocalization data.')\n     authorization_keys = graphene.List(\n         AuthorizationKey, description='List of configured authorization keys.',\n         required=True)\n@@ -102,6 +115,15 @@\n             ssl_enabled=settings.ENABLE_SSL,\n             url=info.context.build_absolute_uri('/'))\n \n+    def resolve_geolocalization(self, info):\n+        client_ip = get_client_ip(info.context)\n+        country = get_country_by_ip(client_ip)\n+        if country:\n+            return Geolocalization(\n+                country=CountryDisplay(\n+                    code=country.code, country=country.name))\n+        return Geolocalization(country=None)\n+\n     def resolve_default_currency(self, info):\n         return settings.DEFAULT_CURRENCY\n", "issue": "Return user's geolocalization based on IP\nAPI should return geolocalization data guessed from users's IP. We already have all the logic in the `saleor.core.middleware.country` function. What needs to be done is to wrap this data in a GraphQL type and tie it up to the API. \r\n\r\nE.g.:\r\n```\r\nshop {\r\n  geolocalization {\r\n    countryCode\r\n  }\r\n}\r\n```\r\n\r\nShould it return DEFAULT_COUNTRY from settings as a fallback?\r\n\r\n@mociepka Please provide more information about what data you'd need in the storefront.\n", "before_files": [{"content": "import graphene\nfrom django.conf import settings\nfrom django_countries import countries\nfrom graphql_jwt.decorators import permission_required\nfrom phonenumbers import COUNTRY_CODE_TO_REGION_CODE\n\nfrom ...core.permissions import get_permissions\nfrom ...site import models as site_models\nfrom ..core.types.common import (\n    CountryDisplay, LanguageDisplay, PermissionDisplay, WeightUnitsEnum)\nfrom ..menu.types import Menu\nfrom ..product.types import Collection\nfrom ..utils import format_permissions_for_display\n\n\nclass Navigation(graphene.ObjectType):\n    main = graphene.Field(Menu, description='Main navigation bar.')\n    secondary = graphene.Field(Menu, description='Secondary navigation bar.')\n\n    class Meta:\n        description = 'Represents shop\\'s navigation menus.'\n\n\nclass AuthorizationKey(graphene.ObjectType):\n    name = graphene.String(description='Name of the key.', required=True)\n    key = graphene.String(description='Value of the key.', required=True)\n\n\nclass Domain(graphene.ObjectType):\n    host = graphene.String(\n        description='The host name of the domain.', required=True)\n    ssl_enabled = graphene.Boolean(\n        description='Inform if SSL is enabled.', required=True)\n    url = graphene.String(\n        description='Shop\\'s absolute URL.', required=True)\n\n    class Meta:\n        description = 'Represents shop\\'s domain.'\n\n\nclass Shop(graphene.ObjectType):\n    authorization_keys = graphene.List(\n        AuthorizationKey, description='List of configured authorization keys.',\n        required=True)\n    countries = graphene.List(\n        CountryDisplay, description='List of countries available in the shop.',\n        required=True)\n    currencies = graphene.List(\n        graphene.String, description='List of available currencies.',\n        required=True)\n    default_currency = graphene.String(\n        description='Default shop\\'s currency.', required=True)\n    default_country = graphene.Field(\n        CountryDisplay, description='Default shop\\'s country')\n    description = graphene.String(description='Shop\\'s description.')\n    domain = graphene.Field(\n        Domain, required=True, description='Shop\\'s domain data.')\n    homepage_collection = graphene.Field(\n        Collection, description='Collection displayed on homepage')\n    languages = graphene.List(\n        LanguageDisplay,\n        description='List of the shops\\'s supported languages.', required=True)\n    name = graphene.String(description='Shop\\'s name.', required=True)\n    navigation = graphene.Field(\n        Navigation, description='Shop\\'s navigation.')\n    permissions = graphene.List(\n        PermissionDisplay, description='List of available permissions.',\n        required=True)\n    phone_prefixes = graphene.List(\n        graphene.String, description='List of possible phone prefixes.',\n        required=True)\n    header_text = graphene.String(description='Header text')\n    include_taxes_in_prices = graphene.Boolean(\n        description='Include taxes in prices')\n    display_gross_prices = graphene.Boolean(\n        description='Display prices with tax in store')\n    track_inventory_by_default = graphene.Boolean(\n        description='Enable inventory tracking')\n    default_weight_unit = WeightUnitsEnum(description='Default weight unit')\n\n    class Meta:\n        description = '''\n        Represents a shop resource containing general shop\\'s data\n        and configuration.'''\n\n    @permission_required('site.manage_settings')\n    def resolve_authorization_keys(self, info):\n        return site_models.AuthorizationKey.objects.all()\n\n    def resolve_countries(self, info):\n        return [\n            CountryDisplay(code=country[0], country=country[1])\n            for country in countries]\n\n    def resolve_currencies(self, info):\n        return settings.AVAILABLE_CURRENCIES\n\n    def resolve_domain(self, info):\n        site = info.context.site\n        return Domain(\n            host=site.domain,\n            ssl_enabled=settings.ENABLE_SSL,\n            url=info.context.build_absolute_uri('/'))\n\n    def resolve_default_currency(self, info):\n        return settings.DEFAULT_CURRENCY\n\n    def resolve_description(self, info):\n        return info.context.site.settings.description\n\n    def resolve_homepage_collection(self, info):\n        return info.context.site.settings.homepage_collection\n\n    def resolve_languages(self, info):\n        return [\n            LanguageDisplay(code=language[0], language=language[1])\n            for language in settings.LANGUAGES]\n\n    def resolve_name(self, info):\n        return info.context.site.name\n\n    def resolve_navigation(self, info):\n        site_settings = info.context.site.settings\n        return Navigation(\n            main=site_settings.top_menu, secondary=site_settings.bottom_menu)\n\n    @permission_required('site.manage_settings')\n    def resolve_permissions(self, info):\n        permissions = get_permissions()\n        return format_permissions_for_display(permissions)\n\n    def resolve_phone_prefixes(self, info):\n        return list(COUNTRY_CODE_TO_REGION_CODE.keys())\n\n    def resolve_header_text(self, info):\n        return info.context.site.settings.header_text\n\n    def resolve_include_taxes_in_prices(self, info):\n        return info.context.site.settings.include_taxes_in_prices\n\n    def resolve_display_gross_prices(self, info):\n        return info.context.site.settings.display_gross_prices\n\n    def resolve_track_inventory_by_default(self, info):\n        return info.context.site.settings.track_inventory_by_default\n\n    def resolve_default_weight_unit(self, info):\n        return info.context.site.settings.default_weight_unit\n\n    def resolve_default_country(self, info):\n        default_country_code = settings.DEFAULT_COUNTRY\n        default_country_name = countries.countries.get(default_country_code)\n        if default_country_name:\n            default_country = CountryDisplay(\n                code=default_country_code, country=default_country_name)\n        else:\n            default_country = None\n        return default_country\n", "path": "saleor/graphql/shop/types.py"}], "after_files": [{"content": "import graphene\nfrom django.conf import settings\nfrom django_countries import countries\nfrom graphql_jwt.decorators import permission_required\nfrom phonenumbers import COUNTRY_CODE_TO_REGION_CODE\n\nfrom ...core.permissions import get_permissions\nfrom ...core.utils import get_client_ip, get_country_by_ip\nfrom ...site import models as site_models\nfrom ..core.types.common import (\n    CountryDisplay, LanguageDisplay, PermissionDisplay, WeightUnitsEnum)\nfrom ..menu.types import Menu\nfrom ..product.types import Collection\nfrom ..utils import format_permissions_for_display\n\n\nclass Navigation(graphene.ObjectType):\n    main = graphene.Field(Menu, description='Main navigation bar.')\n    secondary = graphene.Field(Menu, description='Secondary navigation bar.')\n\n    class Meta:\n        description = 'Represents shop\\'s navigation menus.'\n\n\nclass AuthorizationKey(graphene.ObjectType):\n    name = graphene.String(description='Name of the key.', required=True)\n    key = graphene.String(description='Value of the key.', required=True)\n\n\nclass Domain(graphene.ObjectType):\n    host = graphene.String(\n        description='The host name of the domain.', required=True)\n    ssl_enabled = graphene.Boolean(\n        description='Inform if SSL is enabled.', required=True)\n    url = graphene.String(\n        description='Shop\\'s absolute URL.', required=True)\n\n    class Meta:\n        description = 'Represents shop\\'s domain.'\n\n\nclass Geolocalization(graphene.ObjectType):\n    country = graphene.Field(\n        CountryDisplay,\n        description='Country of the user acquired by his IP address.')\n\n    class Meta:\n        description = 'Represents customers\\'s geolocalization data.'\n\n\nclass Shop(graphene.ObjectType):\n    geolocalization = graphene.Field(\n        Geolocalization,\n        description='Customer\\'s geolocalization data.')\n    authorization_keys = graphene.List(\n        AuthorizationKey, description='List of configured authorization keys.',\n        required=True)\n    countries = graphene.List(\n        CountryDisplay, description='List of countries available in the shop.',\n        required=True)\n    currencies = graphene.List(\n        graphene.String, description='List of available currencies.',\n        required=True)\n    default_currency = graphene.String(\n        description='Default shop\\'s currency.', required=True)\n    default_country = graphene.Field(\n        CountryDisplay, description='Default shop\\'s country')\n    description = graphene.String(description='Shop\\'s description.')\n    domain = graphene.Field(\n        Domain, required=True, description='Shop\\'s domain data.')\n    homepage_collection = graphene.Field(\n        Collection, description='Collection displayed on homepage')\n    languages = graphene.List(\n        LanguageDisplay,\n        description='List of the shops\\'s supported languages.', required=True)\n    name = graphene.String(description='Shop\\'s name.', required=True)\n    navigation = graphene.Field(\n        Navigation, description='Shop\\'s navigation.')\n    permissions = graphene.List(\n        PermissionDisplay, description='List of available permissions.',\n        required=True)\n    phone_prefixes = graphene.List(\n        graphene.String, description='List of possible phone prefixes.',\n        required=True)\n    header_text = graphene.String(description='Header text')\n    include_taxes_in_prices = graphene.Boolean(\n        description='Include taxes in prices')\n    display_gross_prices = graphene.Boolean(\n        description='Display prices with tax in store')\n    track_inventory_by_default = graphene.Boolean(\n        description='Enable inventory tracking')\n    default_weight_unit = WeightUnitsEnum(description='Default weight unit')\n\n    class Meta:\n        description = '''\n        Represents a shop resource containing general shop\\'s data\n        and configuration.'''\n\n    @permission_required('site.manage_settings')\n    def resolve_authorization_keys(self, info):\n        return site_models.AuthorizationKey.objects.all()\n\n    def resolve_countries(self, info):\n        return [\n            CountryDisplay(code=country[0], country=country[1])\n            for country in countries]\n\n    def resolve_currencies(self, info):\n        return settings.AVAILABLE_CURRENCIES\n\n    def resolve_domain(self, info):\n        site = info.context.site\n        return Domain(\n            host=site.domain,\n            ssl_enabled=settings.ENABLE_SSL,\n            url=info.context.build_absolute_uri('/'))\n\n    def resolve_geolocalization(self, info):\n        client_ip = get_client_ip(info.context)\n        country = get_country_by_ip(client_ip)\n        if country:\n            return Geolocalization(\n                country=CountryDisplay(\n                    code=country.code, country=country.name))\n        return Geolocalization(country=None)\n\n    def resolve_default_currency(self, info):\n        return settings.DEFAULT_CURRENCY\n\n    def resolve_description(self, info):\n        return info.context.site.settings.description\n\n    def resolve_homepage_collection(self, info):\n        return info.context.site.settings.homepage_collection\n\n    def resolve_languages(self, info):\n        return [\n            LanguageDisplay(code=language[0], language=language[1])\n            for language in settings.LANGUAGES]\n\n    def resolve_name(self, info):\n        return info.context.site.name\n\n    def resolve_navigation(self, info):\n        site_settings = info.context.site.settings\n        return Navigation(\n            main=site_settings.top_menu, secondary=site_settings.bottom_menu)\n\n    @permission_required('site.manage_settings')\n    def resolve_permissions(self, info):\n        permissions = get_permissions()\n        return format_permissions_for_display(permissions)\n\n    def resolve_phone_prefixes(self, info):\n        return list(COUNTRY_CODE_TO_REGION_CODE.keys())\n\n    def resolve_header_text(self, info):\n        return info.context.site.settings.header_text\n\n    def resolve_include_taxes_in_prices(self, info):\n        return info.context.site.settings.include_taxes_in_prices\n\n    def resolve_display_gross_prices(self, info):\n        return info.context.site.settings.display_gross_prices\n\n    def resolve_track_inventory_by_default(self, info):\n        return info.context.site.settings.track_inventory_by_default\n\n    def resolve_default_weight_unit(self, info):\n        return info.context.site.settings.default_weight_unit\n\n    def resolve_default_country(self, info):\n        default_country_code = settings.DEFAULT_COUNTRY\n        default_country_name = countries.countries.get(default_country_code)\n        if default_country_name:\n            default_country = CountryDisplay(\n                code=default_country_code, country=default_country_name)\n        else:\n            default_country = None\n        return default_country\n", "path": "saleor/graphql/shop/types.py"}]}