コード例 #1
0
ファイル: mutation.py プロジェクト: vitorarrais/dagster
 class Arguments:
     backfillParams = graphene.NonNull(GraphenePartitionBackfillParams)
コード例 #2
0
class ProductWithoutVariantError(Error):
    products = graphene.List(
        graphene.NonNull(graphene.ID),
        description="List of products IDs which causes the error.",
    )
コード例 #3
0
class BaseMutation(graphene.Mutation):
    errors = graphene.List(
        graphene.NonNull(Error),
        description='List of errors that occurred executing the mutation.')

    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(cls, description=None, **options):
        if not description:
            raise ImproperlyConfigured('No description provided in Meta')
        description = dedent(description)
        super().__init_subclass_with_meta__(description=description, **options)

    @classmethod
    def _update_mutation_arguments_and_fields(cls, arguments, fields):
        cls._meta.arguments.update(arguments)
        cls._meta.fields.update(fields)

    @classmethod
    def add_error(cls, errors, field, message):
        """Add a mutation user error.

        `errors` is the list of errors that happened during the execution of
        the mutation. `field` is the name of an input field the error is
        related to. `None` value is allowed and it indicates that the error
        is general and is not related to any of the input fields. `message`
        is the actual error message to be returned in the response.

        As a result of this method, the `errors` list is updated with an Error
        object to be returned as mutation result.
        """
        field = snake_to_camel_case(field)
        errors.append(Error(field=field, message=message))

    @classmethod
    def get_node_or_error(cls, info, global_id, errors, field, only_type=None):
        if not global_id:
            return None

        node = None
        try:
            node = graphene.Node.get_node_from_global_id(
                info, global_id, only_type)
        except (AssertionError, GraphQLError) as e:
            cls.add_error(errors, field, str(e))
        else:
            if node is None:
                message = "Couldn't resolve to a node: %s" % global_id
                cls.add_error(errors, field, message)
        return node

    @classmethod
    def get_nodes_or_error(cls, ids, errors, field, only_type=None):
        instances = None
        try:
            instances = get_nodes(ids, only_type)
        except GraphQLError as e:
            cls.add_error(field=field, message=str(e), errors=errors)
        return instances

    @classmethod
    def clean_instance(cls, instance, errors):
        """Clean the instance that was created using the input data.

        Once a instance is created, this method runs `full_clean()` to perform
        model fields' validation. Returns errors ready to be returned by
        the GraphQL response (if any occurred).
        """
        try:
            instance.full_clean()
        except ValidationError as validation_errors:
            message_dict = validation_errors.message_dict
            for field in message_dict:
                if hasattr(cls._meta,
                           'exclude') and field in cls._meta.exclude:
                    continue
                for message in message_dict[field]:
                    field = snake_to_camel_case(field)
                    cls.add_error(errors, field, message)
        return errors

    @classmethod
    def construct_instance(cls, instance, cleaned_data):
        """Fill instance fields with cleaned data.

        The `instance` argument is either an empty instance of a already
        existing one which was fetched from the database. `cleaned_data` is
        data to be set in instance fields. Returns `instance` with filled
        fields, but not saved to the database.
        """
        from django.db import models
        opts = instance._meta

        for f in opts.fields:
            if any([
                    not f.editable,
                    isinstance(f, models.AutoField), f.name not in cleaned_data
            ]):
                continue
            data = cleaned_data[f.name]
            if data is None:
                # We want to reset the file field value when None was passed
                # in the input, but `FileField.save_form_data` ignores None
                # values. In that case we manually pass False which clears
                # the file.
                if isinstance(f, FileField):
                    data = False
                if not f.null:
                    data = f._get_default()
            f.save_form_data(instance, data)
        return instance
コード例 #4
0
class Shop(graphene.ObjectType):
    available_payment_gateways = graphene.List(
        graphene.NonNull(PaymentGateway),
        currency=graphene.Argument(
            graphene.String,
            description="A currency for which gateways will be returned.",
            required=False,
        ),
        description="List of available payment gateways.",
        required=True,
    )
    geolocalization = graphene.Field(
        Geolocalization, description="Customer's geolocalization data."
    )
    authorization_keys = graphene.List(
        AuthorizationKey,
        description=(
            "List of configured authorization keys. Authorization keys are used to "
            "enable third-party OAuth authorization (currently Facebook or Google)."
        ),
        required=True,
    )
    countries = graphene.List(
        graphene.NonNull(CountryDisplay),
        language_code=graphene.Argument(
            LanguageCodeEnum,
            description="A language code to return the translation for.",
        ),
        description="List of countries available in the shop.",
        required=True,
    )
    currencies = graphene.List(
        graphene.String, description="List of available currencies.", required=True
    )
    default_currency = graphene.String(
        description="Shop's default currency.", required=True
    )
    default_country = graphene.Field(
        CountryDisplay, description="Shop's default country."
    )
    default_mail_sender_name = graphene.String(
        description="Default shop's email sender's name."
    )
    default_mail_sender_address = graphene.String(
        description="Default shop's email sender's address."
    )
    description = graphene.String(description="Shop's description.")
    domain = graphene.Field(Domain, required=True, description="Shop's domain data.")
    homepage_collection = graphene.Field(
        Collection, description="Collection displayed on homepage."
    )
    languages = graphene.List(
        LanguageDisplay,
        description="List of the shops's supported languages.",
        required=True,
    )
    name = graphene.String(description="Shop's name.", required=True)
    navigation = graphene.Field(Navigation, description="Shop's navigation.")
    permissions = graphene.List(
        Permission, description="List of available permissions.", required=True
    )
    phone_prefixes = graphene.List(
        graphene.String, description="List of possible phone prefixes.", required=True
    )
    header_text = graphene.String(description="Header text.")
    include_taxes_in_prices = graphene.Boolean(
        description="Include taxes in prices.", required=True
    )
    display_gross_prices = graphene.Boolean(
        description="Display prices with tax in store.", required=True
    )
    charge_taxes_on_shipping = graphene.Boolean(
        description="Charge taxes on shipping.", required=True
    )
    track_inventory_by_default = graphene.Boolean(
        description="Enable inventory tracking."
    )
    default_weight_unit = WeightUnitsEnum(description="Default weight unit.")
    translation = TranslationField(ShopTranslation, type_name="shop", resolver=None)
    automatic_fulfillment_digital_products = graphene.Boolean(
        description="Enable automatic fulfillment for all digital products."
    )

    default_digital_max_downloads = graphene.Int(
        description="Default number of max downloads per digital content URL."
    )
    default_digital_url_valid_days = graphene.Int(
        description="Default number of days which digital content URL will be valid."
    )
    company_address = graphene.Field(
        Address, description="Company address.", required=False
    )
    customer_set_password_url = graphene.String(
        description="URL of a view where customers can set their password.",
        required=False,
    )
    staff_notification_recipients = graphene.List(
        StaffNotificationRecipient,
        description="List of staff notification recipients.",
        required=False,
    )

    class Meta:
        description = (
            "Represents a shop resource containing general shop data and configuration."
        )

    @staticmethod
    def resolve_available_payment_gateways(_, _info, currency: Optional[str] = None):
        return get_plugins_manager().list_payment_gateways(currency=currency)

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_authorization_keys(_, _info):
        return site_models.AuthorizationKey.objects.all()

    @staticmethod
    def resolve_countries(_, _info, language_code=None):
        taxes = {vat.country_code: vat for vat in VAT.objects.all()}
        with translation.override(language_code):
            return [
                CountryDisplay(
                    code=country[0], country=country[1], vat=taxes.get(country[0])
                )
                for country in filter(lambda c: c[0] == "MN" or c[0] == "GB", countries)
            ]

    @staticmethod
    def resolve_currencies(_, _info):
        return settings.AVAILABLE_CURRENCIES

    @staticmethod
    def resolve_domain(_, info):
        site = info.context.site
        return Domain(
            host=site.domain,
            ssl_enabled=settings.ENABLE_SSL,
            url=info.context.build_absolute_uri("/"),
        )

    @staticmethod
    def resolve_geolocalization(_, 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)

    @staticmethod
    def resolve_default_currency(_, _info):
        return settings.DEFAULT_CURRENCY

    @staticmethod
    def resolve_description(_, info):
        return info.context.site.settings.description

    @staticmethod
    def resolve_homepage_collection(_, info):
        collection_pk = info.context.site.settings.homepage_collection_id
        qs = product_models.Collection.objects.all()
        return qs.filter(pk=collection_pk).first()

    @staticmethod
    def resolve_languages(_, _info):
        return [
            LanguageDisplay(
                code=LanguageCodeEnum[str_to_enum(language[0])], language=language[1]
            )
            for language in settings.LANGUAGES
        ]

    @staticmethod
    def resolve_name(_, info):
        return info.context.site.name

    @staticmethod
    def resolve_navigation(_, info):
        site_settings = info.context.site.settings
        main = (
            MenuByIdLoader(info.context).load(site_settings.top_menu_id)
            if site_settings.top_menu_id
            else None
        )
        secondary = (
            MenuByIdLoader(info.context).load(site_settings.bottom_menu_id)
            if site_settings.bottom_menu_id
            else None
        )
        return Navigation(main=main, secondary=secondary)

    @staticmethod
    def resolve_permissions(_, _info):
        permissions = get_permissions()
        return format_permissions_for_display(permissions)

    @staticmethod
    def resolve_phone_prefixes(_, _info):
        return list(COUNTRY_CODE_TO_REGION_CODE.keys())

    @staticmethod
    def resolve_header_text(_, info):
        return info.context.site.settings.header_text

    @staticmethod
    def resolve_include_taxes_in_prices(_, info):
        return info.context.site.settings.include_taxes_in_prices

    @staticmethod
    def resolve_display_gross_prices(_, info):
        return info.context.site.settings.display_gross_prices

    @staticmethod
    def resolve_charge_taxes_on_shipping(_, info):
        return info.context.site.settings.charge_taxes_on_shipping

    @staticmethod
    def resolve_track_inventory_by_default(_, info):
        return info.context.site.settings.track_inventory_by_default

    @staticmethod
    def resolve_default_weight_unit(_, info):
        return info.context.site.settings.default_weight_unit

    @staticmethod
    def resolve_default_country(_, _info):
        default_country_code = settings.DEFAULT_COUNTRY
        default_country_name = countries.countries.get(default_country_code)
        if default_country_name:
            vat = VAT.objects.filter(country_code=default_country_code).first()
            default_country = CountryDisplay(
                code=default_country_code, country=default_country_name, vat=vat
            )
        else:
            default_country = None
        return default_country

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_default_mail_sender_name(_, info):
        return info.context.site.settings.default_mail_sender_name

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_default_mail_sender_address(_, info):
        return info.context.site.settings.default_mail_sender_address

    @staticmethod
    def resolve_company_address(_, info):
        return info.context.site.settings.company_address

    @staticmethod
    def resolve_customer_set_password_url(_, info):
        return info.context.site.settings.customer_set_password_url

    @staticmethod
    def resolve_translation(_, info, language_code):
        return resolve_translation(info.context.site.settings, info, language_code)

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_automatic_fulfillment_digital_products(_, info):
        site_settings = info.context.site.settings
        return site_settings.automatic_fulfillment_digital_products

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_default_digital_max_downloads(_, info):
        return info.context.site.settings.default_digital_max_downloads

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_default_digital_url_valid_days(_, info):
        return info.context.site.settings.default_digital_url_valid_days

    @staticmethod
    @permission_required(SitePermissions.MANAGE_SETTINGS)
    def resolve_staff_notification_recipients(_, info):
        return account_models.StaffNotificationRecipient.objects.all()
コード例 #5
0
ファイル: schema.py プロジェクト: ma8642/tenants2
class LatestTextMessagesResult(graphene.ObjectType):
    messages = graphene.List(graphene.NonNull(LatestTextMessage),
                             required=True)
    has_next_page = graphene.Boolean(required=True)
コード例 #6
0
 class Arguments:
     email = graphene.NonNull(Email)
     password = graphene.NonNull(graphene.String)
コード例 #7
0
class GraphenePartitionRunConfig(graphene.ObjectType):
    yaml = graphene.NonNull(graphene.String)

    class Meta:
        name = "PartitionRunConfig"
コード例 #8
0
class Product(CountableDjangoObjectType):
    url = graphene.String(
        description="The storefront URL for the product.",
        required=True,
        deprecation_reason="This field will be removed after 2020-07-31.",
    )
    thumbnail = graphene.Field(
        Image,
        description="The main thumbnail for a product.",
        size=graphene.Argument(graphene.Int, description="Size of thumbnail."),
    )
    pricing = graphene.Field(
        ProductPricingInfo,
        description=(
            "Lists the storefront product's pricing, the current price and discounts, "
            "only meant for displaying."
        ),
    )
    is_available = graphene.Boolean(
        description="Whether the product is in stock and visible or not."
    )
    base_price = graphene.Field(Money, description="The product's default base price.")
    minimal_variant_price = graphene.Field(
        Money, description="The price of the cheapest variant (including discounts)."
    )
    tax_type = graphene.Field(
        TaxType, description="A type of tax. Assigned by enabled tax gateway"
    )
    attributes = graphene.List(
        graphene.NonNull(SelectedAttribute),
        required=True,
        description="List of attributes assigned to this product.",
    )
    purchase_cost = graphene.Field(MoneyRange)
    margin = graphene.Field(Margin)
    image_by_id = graphene.Field(
        lambda: ProductImage,
        id=graphene.Argument(graphene.ID, description="ID of a product image."),
        description="Get a single product image by ID.",
    )
    variants = graphene.List(
        ProductVariant, description="List of variants for the product."
    )
    images = graphene.List(
        lambda: ProductImage, description="List of images for the product."
    )
    collections = graphene.List(
        lambda: Collection, description="List of collections for the product."
    )
    translation = TranslationField(ProductTranslation, type_name="product")

    class Meta:
        description = "Represents an individual item for sale in the storefront."
        interfaces = [relay.Node, ObjectWithMetadata]
        model = models.Product
        only_fields = [
            "category",
            "charge_taxes",
            "description",
            "description_json",
            "id",
            "is_published",
            "name",
            "slug",
            "product_type",
            "publication_date",
            "seo_description",
            "seo_title",
            "updated_at",
            "weight",
        ]

    @staticmethod
    def resolve_category(root: models.Product, info):
        category_id = root.category_id
        if category_id is None:
            return None

        return CategoryByIdLoader(info.context).load(category_id)

    @staticmethod
    def resolve_tax_type(root: models.Product, info):
        tax_data = info.context.plugins.get_tax_code_from_object_meta(root)
        return TaxType(tax_code=tax_data.code, description=tax_data.description)

    @staticmethod
    def resolve_thumbnail(root: models.Product, info, *, size=255):
        def return_first_thumbnail(images):
            image = images[0] if images else None
            if image:
                url = get_product_image_thumbnail(image, size, method="thumbnail")
                alt = image.alt
                return Image(alt=alt, url=info.context.build_absolute_uri(url))
            return None

        return (
            ImagesByProductIdLoader(info.context)
            .load(root.id)
            .then(return_first_thumbnail)
        )

    @staticmethod
    def resolve_url(root: models.Product, *_args):
        return ""

    @staticmethod
    def resolve_pricing(root: models.Product, info):
        context = info.context
        variants = ProductVariantsByProductIdLoader(context).load(root.id)
        collections = CollectionsByProductIdLoader(context).load(root.id)

        def calculate_pricing_info(discounts):
            def calculate_pricing_with_variants(variants):
                def calculate_pricing_with_collections(collections):
                    availability = get_product_availability(
                        product=root,
                        variants=variants,
                        collections=collections,
                        discounts=discounts,
                        country=context.country,
                        local_currency=context.currency,
                        plugins=context.plugins,
                    )
                    return ProductPricingInfo(**asdict(availability))

                return collections.then(calculate_pricing_with_collections)

            return variants.then(calculate_pricing_with_variants)

        return (
            DiscountsByDateTimeLoader(context)
            .load(info.context.request_time)
            .then(calculate_pricing_info)
        )

    @staticmethod
    def resolve_is_available(root: models.Product, info):
        country = info.context.country
        in_stock = is_product_in_stock(root, country)
        return root.is_visible and in_stock

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_base_price(root: models.Product, _info):
        return root.price

    @staticmethod
    def resolve_price(root: models.Product, info):
        context = info.context

        def calculate_price(discounts):
            price_range = root.get_price_range(discounts)
            price = info.context.plugins.apply_taxes_to_product(
                root, price_range.start, info.context.country
            )
            return price.net

        return (
            DiscountsByDateTimeLoader(context)
            .load(info.context.request_time)
            .then(calculate_price)
        )

    @staticmethod
    def resolve_attributes(root: models.Product, info):
        return SelectedAttributesByProductIdLoader(info.context).load(root.id)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_purchase_cost(root: models.Product, *_args):
        purchase_cost, _ = get_product_costs_data(root)
        return purchase_cost

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_margin(root: models.Product, *_args):
        _, margin = get_product_costs_data(root)
        return Margin(margin[0], margin[1])

    @staticmethod
    def resolve_image_by_id(root: models.Product, info, id):
        pk = get_database_id(info, id, ProductImage)
        try:
            return root.images.get(pk=pk)
        except models.ProductImage.DoesNotExist:
            raise GraphQLError("Product image not found.")

    @staticmethod
    def resolve_images(root: models.Product, info, **_kwargs):
        return ImagesByProductIdLoader(info.context).load(root.id)

    @staticmethod
    def resolve_variants(root: models.Product, info, **_kwargs):
        return ProductVariantsByProductIdLoader(info.context).load(root.id)

    @staticmethod
    def resolve_collections(root: models.Product, *_args):
        return root.collections.all()

    @classmethod
    def get_node(cls, info, pk):
        if info.context:
            qs = cls._meta.model.objects.visible_to_user(info.context.user)
            return qs.filter(pk=pk).first()
        return None

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_private_meta(root: models.Product, _info):
        return resolve_private_meta(root, _info)

    @staticmethod
    def resolve_meta(root: models.Product, _info):
        return resolve_meta(root, _info)

    @staticmethod
    def __resolve_reference(root, _info, **_kwargs):
        return graphene.Node.get_node_from_global_id(_info, root.id)
コード例 #9
0
 class Input:
     username = graphene.NonNull(graphene.String)
     password = graphene.NonNull(graphene.String)
コード例 #10
0
ファイル: token.py プロジェクト: prin-r/tcrapi
class Token(graphene.ObjectType):
    """ self = CommunityDB Object """
    class Meta:
        description = "Representds an ERC-20 token contract in Band ecosystem, including Band native token and community tokens."

    address = graphene.String(required=True,
                              description="This token's ERC-20 address.")

    community = graphene.Field(
        lambda: community_module.Community,
        description=
        "The community of this token, in the case of community token.",
    )

    balances = graphene.List(
        lambda: graphene.NonNull(user_balance_module.UserBalance),
        filtered_by=graphene.Argument(
            lambda: user_balance_module.UserBalanceFilters),
        required=True,
        description="The list of user balances of this token.",
    )

    transfer_history = graphene.List(
        lambda: transfer_module.Transfer,
        filtered_by=graphene.Argument(lambda: transfer_module.TransferFilters),
        required=True,
        description="The list of transfers of this token.",
    )

    name = graphene.String(required=True,
                           description="The name of this token.")

    symbol = graphene.String(required=True,
                             description="The symbol of this token.")

    def resolve_address(self, info):
        contract = (db.session.query(Contract).filter(
            Contract.contract_type == "TOKEN").filter(
                Contract.community_id == self.id).one())
        return contract.address

    def resolve_community(self, info):
        if self.id == 1:
            return None
        return self

    def resolve_balances(self, info, filtered_by={}):
        if "users" in filtered_by:
            return [(address, self) for address in filtered_by["users"]]
        addresses = (db.session.query(func.distinct(
            TransferDB.receiver)).filter(
                TransferDB.receiver !=
                "0x0000000000000000000000000000000000000000").filter(
                    TransferDB.community_id == self.id).all())
        return [(address[0], self) for address in addresses]

    def resolve_transfer_history(self, info, filtered_by={}):
        return get_transfer_history(**filtered_by, tokens=[self])

    def resolve_name(self, info):
        return self.name

    def resolve_symbol(self, info):
        return self.symbol
コード例 #11
0
class ProductVariant(CountableDjangoObjectType):
    quantity = graphene.Int(
        required=True,
        description="Quantity of a product available for sale.",
        deprecation_reason=(
            "Use the stock field instead. This field will be removed after 2020-07-31."
        ),
    )
    quantity_allocated = graphene.Int(
        required=False,
        description="Quantity allocated for orders.",
        deprecation_reason=(
            "Use the stock field instead. This field will be removed after 2020-07-31."
        ),
    )
    stock_quantity = graphene.Int(
        required=True,
        description="Quantity of a product available for sale.",
        deprecation_reason=(
            "Use the quantityAvailable field instead. "
            "This field will be removed after 2020-07-31."
        ),
    )
    price_override = graphene.Field(
        Money,
        description=(
            "Override the base price of a product if necessary. A value of `null` "
            "indicates that the default product price is used."
        ),
    )
    pricing = graphene.Field(
        VariantPricingInfo,
        description=(
            "Lists the storefront variant's pricing, the current price and discounts, "
            "only meant for displaying."
        ),
    )
    is_available = graphene.Boolean(
        description="Whether the variant is in stock and visible or not.",
        deprecation_reason=(
            "Use the stock field instead. This field will be removed after 2020-07-31."
        ),
    )

    attributes = graphene.List(
        graphene.NonNull(SelectedAttribute),
        required=True,
        description="List of attributes assigned to this variant.",
    )
    cost_price = graphene.Field(Money, description="Cost price of the variant.")
    margin = graphene.Int(description="Gross margin percentage value.")
    quantity_ordered = graphene.Int(description="Total quantity ordered.")
    revenue = graphene.Field(
        TaxedMoney,
        period=graphene.Argument(ReportingPeriod),
        description=(
            "Total revenue generated by a variant in given period of time. Note: this "
            "field should be queried using `reportProductSales` query as it uses "
            "optimizations suitable for such calculations."
        ),
    )
    images = graphene.List(
        lambda: ProductImage, description="List of images for the product variant."
    )
    translation = TranslationField(
        ProductVariantTranslation, type_name="product variant"
    )
    digital_content = graphene.Field(
        DigitalContent, description="Digital content for the product variant."
    )
    stocks = graphene.Field(
        graphene.List(Stock),
        description="Stocks for the product variant.",
        country_code=graphene.Argument(
            CountryCodeEnum,
            description="Two-letter ISO 3166-1 country code.",
            required=False,
        ),
    )
    quantity_available = graphene.Int(
        required=True,
        description="Quantity of a product available for sale in one checkout.",
        country_code=graphene.Argument(
            CountryCodeEnum,
            description=(
                "Two-letter ISO 3166-1 country code. When provided, the exact quantity "
                "from a warehouse operating in shipping zones that contain this "
                "country will be returned. Otherwise, it will return the maximum "
                "quantity from all shipping zones."
            ),
        ),
    )

    class Meta:
        description = (
            "Represents a version of a product such as different size or color."
        )
        only_fields = ["id", "name", "product", "sku", "track_inventory", "weight"]
        interfaces = [relay.Node, ObjectWithMetadata]
        model = models.ProductVariant

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_stocks(root: models.ProductVariant, info, country_code=None):
        if not country_code:
            return root.stocks.annotate_available_quantity().all()
        return root.stocks.annotate_available_quantity().for_country(country_code).all()

    @staticmethod
    def resolve_quantity_available(
        root: models.ProductVariant, info, country_code=None
    ):
        return get_available_quantity_for_customer(root, country_code)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_digital_content(root: models.ProductVariant, *_args):
        return getattr(root, "digital_content", None)

    @staticmethod
    def resolve_stock_quantity(root: models.ProductVariant, info):
        return get_available_quantity_for_customer(root, info.context.country)

    @staticmethod
    def resolve_attributes(root: models.ProductVariant, info):
        return SelectedAttributesByProductVariantIdLoader(info.context).load(root.id)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_margin(root: models.ProductVariant, *_args):
        return get_margin_for_variant(root)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_cost_price(root: models.ProductVariant, *_args):
        return root.cost_price

    @staticmethod
    def resolve_price(root: models.ProductVariant, *_args):
        return root.base_price

    @staticmethod
    def resolve_pricing(root: models.ProductVariant, info):
        context = info.context
        product = ProductByIdLoader(context).load(root.product_id)
        collections = CollectionsByProductIdLoader(context).load(root.product_id)

        def calculate_pricing_info(discounts):
            def calculate_pricing_with_product(product):
                def calculate_pricing_with_collections(collections):
                    availability = get_variant_availability(
                        variant=root,
                        product=product,
                        collections=collections,
                        discounts=discounts,
                        country=context.country,
                        local_currency=context.currency,
                        plugins=context.plugins,
                    )
                    return VariantPricingInfo(**asdict(availability))

                return collections.then(calculate_pricing_with_collections)

            return product.then(calculate_pricing_with_product)

        return (
            DiscountsByDateTimeLoader(context)
            .load(info.context.request_time)
            .then(calculate_pricing_info)
        )

    @staticmethod
    def resolve_product(root: models.ProductVariant, info):
        return ProductByIdLoader(info.context).load(root.product_id)

    @staticmethod
    def resolve_is_available(root: models.ProductVariant, info):
        country = info.context.country
        return is_variant_in_stock(root, country)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_price_override(root: models.ProductVariant, *_args):
        return root.price_override

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_quantity(root: models.ProductVariant, info):
        return get_available_quantity(root, info.context.country)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_quantity_ordered(root: models.ProductVariant, *_args):
        # This field is added through annotation when using the
        # `resolve_report_product_sales` resolver.
        return getattr(root, "quantity_ordered", None)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_quantity_allocated(root: models.ProductVariant, info):
        country = info.context.country
        return get_quantity_allocated(root, country)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_revenue(root: models.ProductVariant, *_args, period):
        start_date = reporting_period_to_date(period)
        return calculate_revenue_for_variant(root, start_date)

    @staticmethod
    def resolve_images(root: models.ProductVariant, *_args):
        return root.images.all()

    @classmethod
    def get_node(cls, info, pk):
        user = info.context.user
        visible_products = models.Product.objects.visible_to_user(user).values_list(
            "pk", flat=True
        )
        qs = cls._meta.model.objects.filter(product__id__in=visible_products)
        return qs.filter(pk=pk).first()

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_private_meta(root: models.ProductVariant, _info):
        return resolve_private_meta(root, _info)

    @staticmethod
    def resolve_meta(root: models.ProductVariant, _info):
        return resolve_meta(root, _info)

    @staticmethod
    def __resolve_reference(root, _info, **_kwargs):
        return graphene.Node.get_node_from_global_id(_info, root.id)
コード例 #12
0
ファイル: mutation.py プロジェクト: vitorarrais/dagster
 class Arguments:
     repositoryLocationName = graphene.NonNull(graphene.String)
コード例 #13
0
ファイル: mutation.py プロジェクト: vitorarrais/dagster
 class Arguments:
     runId = graphene.NonNull(graphene.String)
     terminatePolicy = graphene.Argument(GrapheneTerminatePipelinePolicy)
コード例 #14
0
ファイル: mutation.py プロジェクト: vitorarrais/dagster
 class Arguments:
     executionParams = graphene.NonNull(GrapheneExecutionParams)
コード例 #15
0
ファイル: auth.py プロジェクト: cisagov/cyhy-api
 class Arguments(object):
     email = graphene.NonNull(graphene.String)
     password = graphene.NonNull(graphene.String)
コード例 #16
0
import graphene
from graphene.types.objecttype import ObjectTypeOptions
from .utils import camelize
from .settings import graphene_settings

ErrorType = graphene.List(graphene.NonNull(graphene.String), required=True)


class ValidationErrorType(graphene.ObjectType):
    field = graphene.String(required=True)
    messages = graphene.List(graphene.NonNull(graphene.String), required=True)

    @classmethod
    def from_errors(cls, errors):
        data = camelize(
            errors) if graphene_settings.CAMELCASE_ERRORS else errors
        return [cls(field=key, messages=value) for key, value in data.items()]


class BaseObjectTypeOptions(ObjectTypeOptions):
    view_factory = None
    filter_class = None


class BaseType(graphene.ObjectType):
    created_at = graphene.String()
    updated_at = graphene.String()
    deleted_at = graphene.String()
    is_deleted = graphene.Boolean()

    @classmethod
コード例 #17
0
 class Input:
     lease_ids = graphene.List(graphene.NonNull(graphene.String), required=True)
     date = graphene.Date(required=True)
コード例 #18
0
class ProductVariant(CountableDjangoObjectType, MetadataObjectType):
    quantity = graphene.Int(
        required=True,
        description="Quantity of a product in the store's possession, "
        "including the allocated stock that is waiting for shipment.",
        deprecation_reason="This field will be removed in Saleor 2.11. "
        "Use the stock field instead.",
    )
    quantity_allocated = graphene.Int(
        required=False,
        description="Quantity allocated for orders",
        deprecation_reason="This field will be removed in Saleor 2.11. "
        "Use the stock field instead.",
    )
    stock_quantity = graphene.Int(
        required=True,
        description="Quantity of a product available for sale.",
        deprecation_reason="This field will be removed in Saleor 2.11. "
        "Use the stock field instead.",
    )
    price_override = graphene.Field(
        Money,
        description=
        ("Override the base price of a product if necessary. A value of `null` "
         "indicates that the default product price is used."),
    )
    pricing = graphene.Field(
        VariantPricingInfo,
        description=
        ("Lists the storefront variant's pricing, the current price and discounts, "
         "only meant for displaying."),
    )
    is_available = graphene.Boolean(
        description="Whether the variant is in stock and visible or not.",
        deprecation_reason="This field will be removed in Saleor 2.11. "
        "Use the stock field instead.",
    )

    attributes = gql_optimizer.field(
        graphene.List(
            graphene.NonNull(SelectedAttribute),
            required=True,
            description="List of attributes assigned to this variant.",
        ))
    cost_price = graphene.Field(Money,
                                description="Cost price of the variant.")
    margin = graphene.Int(description="Gross margin percentage value.")
    quantity_ordered = graphene.Int(description="Total quantity ordered.")
    revenue = graphene.Field(
        TaxedMoney,
        period=graphene.Argument(ReportingPeriod),
        description=
        ("Total revenue generated by a variant in given period of time. Note: this "
         "field should be queried using `reportProductSales` query as it uses "
         "optimizations suitable for such calculations."),
    )
    images = gql_optimizer.field(
        graphene.List(lambda: ProductImage,
                      description="List of images for the product variant."),
        model_field="images",
    )
    translation = TranslationField(ProductVariantTranslation,
                                   type_name="product variant")
    digital_content = gql_optimizer.field(
        graphene.Field(DigitalContent,
                       description="Digital content for the product variant."),
        model_field="digital_content",
    )

    stock = gql_optimizer.field(
        graphene.Field(
            graphene.List(Stock),
            description="Stocks for the product variant.",
            country=graphene.String(required=False),
        ))

    class Meta:
        description = (
            "Represents a version of a product such as different size or color."
        )
        only_fields = [
            "id", "name", "product", "sku", "track_inventory", "weight"
        ]
        interfaces = [relay.Node]
        model = models.ProductVariant

    @staticmethod
    def resolve_stock(root: models.ProductVariant, info, country=None):
        if country is None:
            return gql_optimizer.query(
                root.stock.annotate_available_quantity().all(), info)
        return gql_optimizer.query(
            root.stock.annotate_available_quantity().for_country(
                "country").all(), info)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_digital_content(root: models.ProductVariant, *_args):
        return getattr(root, "digital_content", None)

    @staticmethod
    def resolve_stock_quantity(root: models.ProductVariant, info):
        country = info.context.country
        try:
            stock = stock_models.Stock.objects.get_variant_stock_for_country(
                country, root)
        except stock_models.Stock.DoesNotExist:
            return 0
        return get_available_quantity_for_customer(stock)

    @staticmethod
    @gql_optimizer.resolver_hints(prefetch_related=[
        "attributes__values", "attributes__assignment__attribute"
    ])
    def resolve_attributes(root: models.ProductVariant, info):
        return resolve_attribute_list(root, user=info.context.user)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_margin(root: models.ProductVariant, *_args):
        return get_margin_for_variant(root)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_cost_price(root: models.ProductVariant, *_args):
        return root.cost_price

    @staticmethod
    def resolve_price(root: models.ProductVariant, *_args):
        return root.base_price

    @staticmethod
    @gql_optimizer.resolver_hints(prefetch_related=("product", ),
                                  only=["price_override_amount", "currency"])
    def resolve_pricing(root: models.ProductVariant, info):
        context = info.context
        availability = get_variant_availability(
            root,
            context.discounts,
            context.country,
            context.currency,
            extensions=context.extensions,
        )
        return VariantPricingInfo(**asdict(availability))

    @staticmethod
    def resolve_is_available(root: models.ProductVariant, info):
        country = info.context.country
        return is_variant_in_stock(root, country)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_price_override(root: models.ProductVariant, *_args):
        return root.price_override

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_quantity(root: models.ProductVariant, info):
        return get_available_quantity(root, info.context.country)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_quantity_ordered(root: models.ProductVariant, *_args):
        # This field is added through annotation when using the
        # `resolve_report_product_sales` resolver.
        return getattr(root, "quantity_ordered", None)

    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_quantity_allocated(root: models.ProductVariant, info):
        country = info.context.country
        return get_quantity_allocated(root, country)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_revenue(root: models.ProductVariant, *_args, period):
        start_date = reporting_period_to_date(period)
        return calculate_revenue_for_variant(root, start_date)

    @staticmethod
    def resolve_images(root: models.ProductVariant, *_args):
        return root.images.all()

    @classmethod
    def get_node(cls, info, id):
        user = info.context.user
        visible_products = models.Product.objects.visible_to_user(
            user).values_list("pk", flat=True)
        qs = cls._meta.model.objects.filter(product__id__in=visible_products)
        return cls.maybe_optimize(info, qs, id)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_private_meta(root, _info):
        return resolve_private_meta(root, _info)

    @staticmethod
    def resolve_meta(root, _info):
        return resolve_meta(root, _info)

    @staticmethod
    def __resolve_reference(root, _info, **_kwargs):
        return graphene.Node.get_node_from_global_id(_info, root.id)
コード例 #19
0
class GraphenePartitionSet(graphene.ObjectType):
    id = graphene.NonNull(graphene.ID)
    name = graphene.NonNull(graphene.String)
    pipeline_name = graphene.NonNull(graphene.String)
    solid_selection = graphene.List(graphene.NonNull(graphene.String))
    mode = graphene.NonNull(graphene.String)
    partitionsOrError = graphene.Field(
        graphene.NonNull(GraphenePartitionsOrError),
        cursor=graphene.String(),
        limit=graphene.Int(),
        reverse=graphene.Boolean(),
    )
    partition = graphene.Field(GraphenePartition, partition_name=graphene.NonNull(graphene.String))
    partitionStatusesOrError = graphene.NonNull(GraphenePartitionStatusesOrError)
    repositoryOrigin = graphene.NonNull(GrapheneRepositoryOrigin)

    class Meta:
        name = "PartitionSet"

    def __init__(self, external_repository_handle, external_partition_set):
        self._external_repository_handle = check.inst_param(
            external_repository_handle, "external_respository_handle", RepositoryHandle
        )
        self._external_partition_set = check.inst_param(
            external_partition_set, "external_partition_set", ExternalPartitionSet
        )

        super().__init__(
            name=external_partition_set.name,
            pipeline_name=external_partition_set.pipeline_name,
            solid_selection=external_partition_set.solid_selection,
            mode=external_partition_set.mode,
        )

    def resolve_id(self, _graphene_info):
        return self._external_partition_set.get_external_origin_id()

    def resolve_partitionsOrError(self, graphene_info, **kwargs):
        return get_partitions(
            graphene_info,
            self._external_repository_handle,
            self._external_partition_set,
            cursor=kwargs.get("cursor"),
            limit=kwargs.get("limit"),
            reverse=kwargs.get("reverse"),
        )

    def resolve_partition(self, graphene_info, partition_name):
        return get_partition_by_name(
            graphene_info,
            self._external_repository_handle,
            self._external_partition_set,
            partition_name,
        )

    def resolve_partitionStatusesOrError(self, graphene_info):
        return get_partition_set_partition_statuses(
            graphene_info, self._external_repository_handle, self._external_partition_set.name
        )

    def resolve_repositoryOrigin(self, _):
        origin = self._external_partition_set.get_external_origin().external_repository_origin
        return GrapheneRepositoryOrigin(origin)
コード例 #20
0
class Product(CountableDjangoObjectType, MetadataObjectType):
    url = graphene.String(description="The storefront URL for the product.",
                          required=True)
    thumbnail = graphene.Field(
        Image,
        description="The main thumbnail for a product.",
        size=graphene.Argument(graphene.Int, description="Size of thumbnail."),
    )
    pricing = graphene.Field(
        ProductPricingInfo,
        description=
        ("Lists the storefront product's pricing, the current price and discounts, "
         "only meant for displaying."),
    )
    is_available = graphene.Boolean(
        description="Whether the product is in stock and visible or not.")
    base_price = graphene.Field(
        Money, description="The product's default base price.")
    minimal_variant_price = graphene.Field(
        Money,
        description="The price of the cheapest variant (including discounts).")
    tax_type = graphene.Field(
        TaxType, description="A type of tax. Assigned by enabled tax gateway")
    attributes = graphene.List(
        graphene.NonNull(SelectedAttribute),
        required=True,
        description="List of attributes assigned to this product.",
    )
    purchase_cost = graphene.Field(MoneyRange)
    margin = graphene.Field(Margin)
    image_by_id = graphene.Field(
        lambda: ProductImage,
        id=graphene.Argument(graphene.ID,
                             description="ID of a product image."),
        description="Get a single product image by ID.",
    )
    variants = gql_optimizer.field(
        graphene.List(ProductVariant,
                      description="List of variants for the product."),
        model_field="variants",
    )
    images = gql_optimizer.field(
        graphene.List(lambda: ProductImage,
                      description="List of images for the product."),
        model_field="images",
    )
    collections = gql_optimizer.field(
        graphene.List(lambda: Collection,
                      description="List of collections for the product."),
        model_field="collections",
    )
    translation = TranslationField(ProductTranslation, type_name="product")

    slug = graphene.String(required=True, description="The slug of a product.")

    class Meta:
        description = "Represents an individual item for sale in the storefront."
        interfaces = [relay.Node]
        model = models.Product
        only_fields = [
            "category",
            "charge_taxes",
            "description",
            "description_json",
            "id",
            "is_published",
            "name",
            "product_type",
            "publication_date",
            "seo_description",
            "seo_title",
            "updated_at",
            "weight",
        ]

    @staticmethod
    def resolve_tax_type(root: models.Product, info):
        tax_data = info.context.extensions.get_tax_code_from_object_meta(root)
        return TaxType(tax_code=tax_data.code,
                       description=tax_data.description)

    @staticmethod
    @gql_optimizer.resolver_hints(prefetch_related="images")
    def resolve_thumbnail(root: models.Product, info, *, size=255):
        image = root.get_first_image()
        if image:
            url = get_product_image_thumbnail(image, size, method="thumbnail")
            alt = image.alt
            return Image(alt=alt, url=info.context.build_absolute_uri(url))
        return None

    @staticmethod
    def resolve_url(root: models.Product, *_args):
        return root.get_absolute_url()

    @staticmethod
    @gql_optimizer.resolver_hints(
        prefetch_related=("variants", "collections"),
        only=[
            "publication_date", "charge_taxes", "price_amount", "currency",
            "meta"
        ],
    )
    def resolve_pricing(root: models.Product, info):
        context = info.context
        availability = get_product_availability(
            root,
            context.discounts,
            context.country,
            context.currency,
            context.extensions,
        )
        return ProductPricingInfo(**asdict(availability))

    @staticmethod
    @gql_optimizer.resolver_hints(prefetch_related=("variants"))
    def resolve_is_available(root: models.Product, _info):
        country = _info.context.country
        in_stock = is_product_in_stock(root, country)
        return root.is_visible and in_stock

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_base_price(root: models.Product, _info):
        return root.price

    @staticmethod
    @gql_optimizer.resolver_hints(
        prefetch_related=("variants", "collections"),
        only=[
            "publication_date", "charge_taxes", "price_amount", "currency",
            "meta"
        ],
    )
    def resolve_price(root: models.Product, info):
        price_range = root.get_price_range(info.context.discounts)
        price = info.context.extensions.apply_taxes_to_product(
            root, price_range.start, info.context.country)
        return price.net

    @staticmethod
    @gql_optimizer.resolver_hints(prefetch_related=[
        Prefetch(
            "product_type__attributeproduct",
            queryset=models.AttributeProduct.objects.filter(
                attribute__visible_in_storefront=True).prefetch_related(
                    "productassignments__values", "attribute"),
            to_attr="storefront_attributes",
        )
    ])
    def resolve_attributes(root: models.Product, info):
        return resolve_attribute_list(root, user=info.context.user)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_purchase_cost(root: models.Product, *_args):
        purchase_cost, _ = get_product_costs_data(root)
        return purchase_cost

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_margin(root: models.Product, *_args):
        _, margin = get_product_costs_data(root)
        return Margin(margin[0], margin[1])

    @staticmethod
    def resolve_image_by_id(root: models.Product, info, id):
        pk = get_database_id(info, id, ProductImage)
        try:
            return root.images.get(pk=pk)
        except models.ProductImage.DoesNotExist:
            raise GraphQLError("Product image not found.")

    @staticmethod
    @gql_optimizer.resolver_hints(model_field="images")
    def resolve_images(root: models.Product, *_args, **_kwargs):
        return root.images.all()

    @staticmethod
    def resolve_variants(root: models.Product, *_args, **_kwargs):
        return root.variants.all()

    @staticmethod
    def resolve_collections(root: models.Product, *_args):
        return root.collections.all()

    @classmethod
    def get_node(cls, info, pk):
        if info.context:
            qs = cls._meta.model.objects.visible_to_user(info.context.user)
            return cls.maybe_optimize(info, qs, pk)
        return None

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_private_meta(root, _info):
        return resolve_private_meta(root, _info)

    @staticmethod
    def resolve_meta(root, _info):
        return resolve_meta(root, _info)

    @staticmethod
    def resolve_slug(root: models.Product, *_args):
        return root.get_slug()

    @staticmethod
    def __resolve_reference(root, _info, **_kwargs):
        return graphene.Node.get_node_from_global_id(_info, root.id)
コード例 #21
0
class GraphenePartition(graphene.ObjectType):
    name = graphene.NonNull(graphene.String)
    partition_set_name = graphene.NonNull(graphene.String)
    solid_selection = graphene.List(graphene.NonNull(graphene.String))
    mode = graphene.NonNull(graphene.String)
    runConfigOrError = graphene.NonNull(GraphenePartitionRunConfigOrError)
    tagsOrError = graphene.NonNull(GraphenePartitionTagsOrError)
    runs = graphene.Field(
        non_null_list(GrapheneRun),
        filter=graphene.Argument(GrapheneRunsFilter),
        cursor=graphene.String(),
        limit=graphene.Int(),
    )
    status = graphene.Field(GrapheneRunStatus)

    class Meta:
        name = "Partition"

    def __init__(self, external_repository_handle, external_partition_set, partition_name):
        self._external_repository_handle = check.inst_param(
            external_repository_handle, "external_respository_handle", RepositoryHandle
        )
        self._external_partition_set = check.inst_param(
            external_partition_set, "external_partition_set", ExternalPartitionSet
        )
        self._partition_name = check.str_param(partition_name, "partition_name")

        super().__init__(
            name=partition_name,
            partition_set_name=external_partition_set.name,
            solid_selection=external_partition_set.solid_selection,
            mode=external_partition_set.mode,
        )

    def resolve_runConfigOrError(self, graphene_info):
        return get_partition_config(
            graphene_info,
            self._external_repository_handle,
            self._external_partition_set.name,
            self._partition_name,
        )

    def resolve_tagsOrError(self, graphene_info):
        return get_partition_tags(
            graphene_info,
            self._external_repository_handle,
            self._external_partition_set.name,
            self._partition_name,
        )

    def resolve_runs(self, graphene_info, **kwargs):
        filters = kwargs.get("filter")
        partition_tags = {
            PARTITION_SET_TAG: self._external_partition_set.name,
            PARTITION_NAME_TAG: self._partition_name,
        }
        if filters is not None:
            filters = filters.to_selector()
            runs_filter = RunsFilter(
                run_ids=filters.run_ids,
                pipeline_name=filters.job_name,
                statuses=filters.statuses,
                tags=merge_dicts(filters.tags, partition_tags),
            )
        else:
            runs_filter = RunsFilter(tags=partition_tags)

        return get_runs(
            graphene_info, runs_filter, cursor=kwargs.get("cursor"), limit=kwargs.get("limit")
        )
コード例 #22
0
class ProductVariantBulkCreate(BaseMutation):
    count = graphene.Int(
        required=True,
        default_value=0,
        description="Returns how many objects were created.",
    )
    product_variants = graphene.List(
        graphene.NonNull(ProductVariant),
        required=True,
        default_value=[],
        description="List of the created variants.",
    )

    class Arguments:
        variants = graphene.List(
            ProductVariantBulkCreateInput,
            required=True,
            description="Input list of product variants to create.",
        )
        product_id = graphene.ID(
            description="ID of the product to create the variants for.",
            name="product",
            required=True,
        )

    class Meta:
        description = "Creates product variants for a given product."
        permissions = (ProductPermissions.MANAGE_PRODUCTS, )
        error_type_class = BulkProductError
        error_type_field = "bulk_product_errors"

    @classmethod
    def clean_variant_input(
        cls,
        info,
        instance: models.ProductVariant,
        data: dict,
        errors: dict,
        variant_index: int,
    ):
        cleaned_input = ModelMutation.clean_input(
            info, instance, data, input_cls=ProductVariantBulkCreateInput)

        attributes = cleaned_input.get("attributes")
        if attributes:
            try:
                cleaned_input[
                    "attributes"] = ProductVariantCreate.clean_attributes(
                        attributes, data["product_type"])
            except ValidationError as exc:
                exc.params = {"index": variant_index}
                errors["attributes"] = exc

        channel_listings = cleaned_input.get("channel_listings")
        if channel_listings:
            cleaned_input["channel_listings"] = cls.clean_channel_listings(
                channel_listings, errors, data["product"], variant_index)

        stocks = cleaned_input.get("stocks")
        if stocks:
            cls.clean_stocks(stocks, errors, variant_index)

        return cleaned_input

    @classmethod
    def clean_price(cls, price, field_name, currency, channel_id,
                    variant_index, errors):
        try:
            validate_price_precision(price, currency)
        except ValidationError as error:
            error.code = ProductErrorCode.INVALID.value
            error.params = {
                "channels": [channel_id],
                "index": variant_index,
            }
            errors[field_name].append(error)

    @classmethod
    def clean_channel_listings(cls, channels_data, errors, product,
                               variant_index):
        channel_ids = [
            channel_listing["channel_id"] for channel_listing in channels_data
        ]
        duplicates = get_duplicated_values(channel_ids)
        if duplicates:
            errors["channel_listings"] = ValidationError(
                "Duplicated channel ID.",
                code=ProductErrorCode.DUPLICATED_INPUT_ITEM.value,
                params={
                    "channels": duplicates,
                    "index": variant_index
                },
            )
            return channels_data
        channels = cls.get_nodes_or_error(channel_ids,
                                          "channel_listings",
                                          only_type=Channel)
        for index, channel_listing_data in enumerate(channels_data):
            channel_listing_data["channel"] = channels[index]

        for channel_listing_data in channels_data:
            price = channel_listing_data.get("price")
            cost_price = channel_listing_data.get("cost_price")
            channel_id = channel_listing_data["channel_id"]
            currency_code = channel_listing_data["channel"].currency_code
            cls.clean_price(price, "price", currency_code, channel_id,
                            variant_index, errors)
            cls.clean_price(
                cost_price,
                "cost_price",
                currency_code,
                channel_id,
                variant_index,
                errors,
            )

        channels_not_assigned_to_product = []
        channels_assigned_to_product = list(
            models.ProductChannelListing.objects.filter(
                product=product.id).values_list("channel_id", flat=True))
        for channel_listing_data in channels_data:
            if not channel_listing_data[
                    "channel"].id in channels_assigned_to_product:
                channels_not_assigned_to_product.append(
                    channel_listing_data["channel_id"])
        if channels_not_assigned_to_product:
            errors["channel_id"].append(
                ValidationError(
                    "Product not available in channels.",
                    code=ProductErrorCode.PRODUCT_NOT_ASSIGNED_TO_CHANNEL.
                    value,
                    params={
                        "index": variant_index,
                        "channels": channels_not_assigned_to_product,
                    },
                ))
        return channels_data

    @classmethod
    def clean_stocks(cls, stocks_data, errors, variant_index):
        warehouse_ids = [stock["warehouse"] for stock in stocks_data]
        duplicates = get_duplicated_values(warehouse_ids)
        if duplicates:
            errors["stocks"] = ValidationError(
                "Duplicated warehouse ID.",
                code=ProductErrorCode.DUPLICATED_INPUT_ITEM.value,
                params={
                    "warehouses": duplicates,
                    "index": variant_index
                },
            )

    @classmethod
    def add_indexes_to_errors(cls, index, error, error_dict):
        """Append errors with index in params to mutation error dict."""
        for key, value in error.error_dict.items():
            for e in value:
                if e.params:
                    e.params["index"] = index
                else:
                    e.params = {"index": index}
            error_dict[key].extend(value)

    @classmethod
    def save(cls, info, instance, cleaned_input):
        instance.save()

        attributes = cleaned_input.get("attributes")
        if attributes:
            AttributeAssignmentMixin.save(instance, attributes)
            generate_and_set_variant_name(instance, cleaned_input.get("sku"))

    @classmethod
    def create_variants(cls, info, cleaned_inputs, product, errors):
        instances = []
        for index, cleaned_input in enumerate(cleaned_inputs):
            if not cleaned_input:
                continue
            try:
                instance = models.ProductVariant()
                cleaned_input["product"] = product
                instance = cls.construct_instance(instance, cleaned_input)
                cls.clean_instance(info, instance)
                instances.append(instance)
            except ValidationError as exc:
                cls.add_indexes_to_errors(index, exc, errors)
        return instances

    @classmethod
    def validate_duplicated_sku(cls, sku, index, sku_list, errors):
        if sku in sku_list:
            errors["sku"].append(
                ValidationError("Duplicated SKU.",
                                ProductErrorCode.UNIQUE,
                                params={"index": index}))
        sku_list.append(sku)

    @classmethod
    def validate_duplicated_attribute_values(cls,
                                             attributes_data,
                                             used_attribute_values,
                                             instance=None):
        attribute_values = defaultdict(list)
        for attr in attributes_data:
            attribute_values[attr.id].extend(attr.values)
        if attribute_values in used_attribute_values:
            raise ValidationError(
                "Duplicated attribute values for product variant.",
                ProductErrorCode.DUPLICATED_INPUT_ITEM,
            )
        used_attribute_values.append(attribute_values)

    @classmethod
    def clean_variants(cls, info, variants, product, errors):
        cleaned_inputs = []
        sku_list = []
        used_attribute_values = get_used_variants_attribute_values(product)
        for index, variant_data in enumerate(variants):
            try:
                cls.validate_duplicated_attribute_values(
                    variant_data.attributes, used_attribute_values)
            except ValidationError as exc:
                errors["attributes"].append(
                    ValidationError(exc.message,
                                    exc.code,
                                    params={"index": index}))

            cleaned_input = None
            variant_data["product_type"] = product.product_type
            variant_data["product"] = product
            cleaned_input = cls.clean_variant_input(info, None, variant_data,
                                                    errors, index)

            cleaned_inputs.append(cleaned_input if cleaned_input else None)

            if not variant_data.sku:
                continue
            cls.validate_duplicated_sku(variant_data.sku, index, sku_list,
                                        errors)
        return cleaned_inputs

    @classmethod
    def create_variant_channel_listings(cls, variant, cleaned_input):
        channel_listings_data = cleaned_input.get("channel_listings")
        if not channel_listings_data:
            return
        variant_channel_listings = []
        for channel_listing_data in channel_listings_data:
            channel = channel_listing_data["channel"]
            price = channel_listing_data["price"]
            cost_price = channel_listing_data.get("cost_price")
            variant_channel_listings.append(
                models.ProductVariantChannelListing(
                    channel=channel,
                    variant=variant,
                    price_amount=price,
                    cost_price_amount=cost_price,
                    currency=channel.currency_code,
                ))
        models.ProductVariantChannelListing.objects.bulk_create(
            variant_channel_listings)

    @classmethod
    @transaction.atomic
    def save_variants(cls, info, instances, product, cleaned_inputs):
        assert len(instances) == len(
            cleaned_inputs
        ), "There should be the same number of instances and cleaned inputs."
        for instance, cleaned_input in zip(instances, cleaned_inputs):
            cls.save(info, instance, cleaned_input)
            cls.create_variant_stocks(instance, cleaned_input)
            cls.create_variant_channel_listings(instance, cleaned_input)
        if not product.default_variant:
            product.default_variant = instances[0]
            product.save(update_fields=["default_variant", "updated_at"])

    @classmethod
    def create_variant_stocks(cls, variant, cleaned_input):
        stocks = cleaned_input.get("stocks")
        if not stocks:
            return
        warehouse_ids = [stock["warehouse"] for stock in stocks]
        warehouses = cls.get_nodes_or_error(warehouse_ids,
                                            "warehouse",
                                            only_type=Warehouse)
        create_stocks(variant, stocks, warehouses)

    @classmethod
    def perform_mutation(cls, root, info, **data):
        product = cls.get_node_or_error(info, data["product_id"],
                                        models.Product)
        errors = defaultdict(list)

        cleaned_inputs = cls.clean_variants(info, data["variants"], product,
                                            errors)
        instances = cls.create_variants(info, cleaned_inputs, product, errors)
        if errors:
            raise ValidationError(errors)
        cls.save_variants(info, instances, product, cleaned_inputs)

        # Recalculate the "discounted price" for the parent product
        update_product_discounted_price_task.delay(product.pk)

        instances = [
            ChannelContext(node=instance, channel_slug=None)
            for instance in instances
        ]
        return ProductVariantBulkCreate(count=len(instances),
                                        product_variants=instances)
コード例 #23
0
ファイル: types.py プロジェクト: Autobot-Asia/saleor
class User(CountableDjangoObjectType):
    addresses = graphene.List(Address, description="List of all user's addresses.")
    checkout = graphene.Field(
        Checkout,
        description="Returns the last open checkout of this user.",
        deprecation_reason=(
            "Use the `checkout_tokens` field to fetch the user checkouts."
        ),
    )
    checkout_tokens = graphene.List(
        graphene.NonNull(UUID),
        description="Returns the checkout UUID's assigned to this user.",
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
    )
    gift_cards = PrefetchingConnectionField(
        "saleor.graphql.giftcard.types.GiftCard",
        description="List of the user gift cards.",
    )
    note = graphene.String(description="A note about the customer.")
    orders = PrefetchingConnectionField(
        "saleor.graphql.order.types.Order", description="List of user's orders."
    )
    # deprecated, to remove in #5389
    permissions = graphene.List(
        Permission,
        description="List of user's permissions.",
        deprecation_reason=(
            "Will be removed in Saleor 2.11." "Use the `userPermissions` instead."
        ),
    )
    user_permissions = graphene.List(
        UserPermission, description="List of user's permissions."
    )
    permission_groups = graphene.List(
        "saleor.graphql.account.types.Group",
        description="List of user's permission groups.",
    )
    editable_groups = graphene.List(
        "saleor.graphql.account.types.Group",
        description="List of user's permission groups which user can manage.",
    )
    avatar = graphene.Field(Image, size=graphene.Int(description="Size of the avatar."))
    events = graphene.List(
        CustomerEvent, description="List of events associated with the user."
    )
    stored_payment_sources = graphene.List(
        "saleor.graphql.payment.types.PaymentSource",
        description="List of stored payment sources.",
    )
    store = graphene.Field(
        Store,
        id=graphene.Argument(graphene.ID, description="ID of the store."),
        slug=graphene.Argument(graphene.String, description="Slug of the store"),
        description="Look up a category by ID or slug.",
    )

    class Meta:
        description = "Represents user data."
        interfaces = [relay.Node, ObjectWithMetadata]
        model = get_user_model()
        only_fields = [
            "date_joined",
            "default_billing_address",
            "default_shipping_address",
            "email",
            "first_name",
            "id",
            "is_active",
            "is_staff",
            "is_supplier",
            "last_login",
            "last_name",
            "note",
            "store",
        ]

    @staticmethod
    def resolve_addresses(root: models.User, _info, **_kwargs):
        return root.addresses.annotate_default(root).all()

    @staticmethod
    def resolve_checkout(root: models.User, _info, **_kwargs):
        return get_user_checkout(root)

    @staticmethod
    def resolve_checkout_tokens(root: models.User, info, channel=None, **_kwargs):
        def return_checkout_tokens(checkouts):
            if not checkouts:
                return []
            checkout_global_ids = []
            for checkout in checkouts:
                checkout_global_ids.append(checkout.token)
            return checkout_global_ids

        if not channel:
            return (
                CheckoutByUserLoader(info.context)
                .load(root.id)
                .then(return_checkout_tokens)
            )
        return (
            CheckoutByUserAndChannelLoader(info.context)
            .load((root.id, channel))
            .then(return_checkout_tokens)
        )

    @staticmethod
    def resolve_gift_cards(root: models.User, info, **_kwargs):
        return root.gift_cards.all()

    @staticmethod
    def resolve_permissions(root: models.User, _info, **_kwargs):
        # deprecated, to remove in #5389
        from .resolvers import resolve_permissions

        return resolve_permissions(root)

    @staticmethod
    def resolve_user_permissions(root: models.User, _info, **_kwargs):
        from .resolvers import resolve_permissions

        return resolve_permissions(root)

    @staticmethod
    def resolve_permission_groups(root: models.User, _info, **_kwargs):
        return root.groups.all()

    @staticmethod
    def resolve_editable_groups(root: models.User, _info, **_kwargs):
        return get_groups_which_user_can_manage(root)

    @staticmethod
    @one_of_permissions_required(
        [AccountPermissions.MANAGE_USERS, AccountPermissions.MANAGE_STAFF]
    )
    def resolve_note(root: models.User, info):
        return root.note

    @staticmethod
    @one_of_permissions_required(
        [AccountPermissions.MANAGE_USERS, AccountPermissions.MANAGE_STAFF]
    )
    def resolve_events(root: models.User, info):
        return root.events.all()

    @staticmethod
    def resolve_orders(root: models.User, info, **_kwargs):
        viewer = info.context.user
        if viewer.has_perm(OrderPermissions.MANAGE_ORDERS):
            return root.orders.all()  # type: ignore
        return root.orders.confirmed()  # type: ignore

    @staticmethod
    def resolve_avatar(root: models.User, info, size=None, **_kwargs):
        if root.avatar:
            return Image.get_adjusted(
                image=root.avatar,
                alt=None,
                size=size,
                rendition_key_set="user_avatars",
                info=info,
            )

    @staticmethod
    def resolve_stored_payment_sources(root: models.User, info):
        from .resolvers import resolve_payment_sources

        if root == info.context.user:
            return resolve_payment_sources(info, root)
        raise PermissionDenied()

    @staticmethod
    def resolve_wishlist(root: models.User, info, **_kwargs):
        return resolve_wishlist_items_from_user(root)

    @staticmethod
    def __resolve_reference(root, _info, **_kwargs):
        if root.id is not None:
            return graphene.Node.get_node_from_global_id(_info, root.id)
        return get_user_model().objects.get(email=root.email)
コード例 #24
0
 class Meta:
     node = graphene.NonNull(self.node)
コード例 #25
0
ファイル: types.py プロジェクト: bpmaurya/djangoseleor
class Checkout(CountableDjangoObjectType):
    available_shipping_methods = graphene.List(
        ShippingMethod,
        required=True,
        description="Shipping methods that can be used with this order.",
    )
    available_payment_gateways = graphene.List(
        graphene.NonNull(PaymentGateway),
        description="List of available payment gateways.",
        required=True,
    )
    email = graphene.String(description="Email of a customer.", required=True)
    gift_cards = graphene.List(
        GiftCard,
        description="List of gift cards associated with this checkout.")
    is_shipping_required = graphene.Boolean(
        description="Returns True, if checkout requires shipping.",
        required=True)
    lines = graphene.List(
        CheckoutLine,
        description=(
            "A list of checkout lines, each containing information about "
            "an item in the checkout."),
    )
    shipping_price = graphene.Field(
        TaxedMoney,
        description="The price of the shipping, with all the taxes included.",
    )
    shipping_method = graphene.Field(
        ShippingMethod,
        description="The shipping method related with checkout.",
    )
    subtotal_price = graphene.Field(
        TaxedMoney,
        description=
        "The price of the checkout before shipping, with taxes included.",
    )
    token = graphene.Field(UUID,
                           description="The checkout's token.",
                           required=True)
    total_price = graphene.Field(
        TaxedMoney,
        description=(
            "The sum of the the checkout line prices, with all the taxes,"
            "shipping costs, and discounts included."),
    )

    class Meta:
        only_fields = [
            "billing_address",
            "created",
            "discount_name",
            "gift_cards",
            "is_shipping_required",
            "last_change",
            "channel",
            "note",
            "quantity",
            "shipping_address",
            "translated_discount_name",
            "user",
            "voucher_code",
            "discount",
        ]
        description = "Checkout object."
        model = models.Checkout
        interfaces = [graphene.relay.Node, ObjectWithMetadata]
        filter_fields = ["token"]

    @staticmethod
    def resolve_shipping_address(root: models.Checkout, info):
        if not root.shipping_address_id:
            return
        return AddressByIdLoader(info.context).load(root.shipping_address_id)

    @staticmethod
    def resolve_billing_address(root: models.Checkout, info):
        if not root.billing_address_id:
            return
        return AddressByIdLoader(info.context).load(root.billing_address_id)

    @staticmethod
    def resolve_user(root: models.Checkout, info):
        requestor = get_user_or_app_from_context(info.context)
        if requestor_has_access(requestor, root.user,
                                AccountPermissions.MANAGE_USERS):
            return root.user
        raise PermissionDenied()

    @staticmethod
    def resolve_email(root: models.Checkout, _info):
        return root.get_customer_email()

    @staticmethod
    def resolve_shipping_method(root: models.Checkout, info):
        if not root.shipping_method_id:
            return None

        def wrap_shipping_method_with_channel_context(data):
            shipping_method, channel = data
            return ChannelContext(node=shipping_method,
                                  channel_slug=channel.slug)

        shipping_method = ShippingMethodByIdLoader(info.context).load(
            root.shipping_method_id)
        channel = ChannelByIdLoader(info.context).load(root.channel_id)

        return Promise.all([shipping_method, channel
                            ]).then(wrap_shipping_method_with_channel_context)

    @staticmethod
    # TODO: We should optimize it in/after PR#5819
    def resolve_total_price(root: models.Checkout, info):
        def calculate_total_price(data):
            address, lines, checkout_info, discounts = data
            taxed_total = (calculations.checkout_total(
                manager=info.context.plugins,
                checkout_info=checkout_info,
                lines=lines,
                address=address,
                discounts=discounts,
            ) - root.get_total_gift_cards_balance())
            return max(taxed_total, zero_taxed_money(root.currency))

        address_id = root.shipping_address_id or root.billing_address_id
        address = (AddressByIdLoader(info.context).load(address_id)
                   if address_id else None)
        lines = CheckoutLinesInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        checkout_info = CheckoutInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        discounts = DiscountsByDateTimeLoader(info.context).load(
            info.context.request_time)
        return Promise.all([address, lines, checkout_info,
                            discounts]).then(calculate_total_price)

    @staticmethod
    # TODO: We should optimize it in/after PR#5819
    def resolve_subtotal_price(root: models.Checkout, info):
        def calculate_subtotal_price(data):
            address, lines, checkout_info, discounts = data
            return calculations.checkout_subtotal(
                manager=info.context.plugins,
                checkout_info=checkout_info,
                lines=lines,
                address=address,
                discounts=discounts,
            )

        address_id = root.shipping_address_id or root.billing_address_id
        address = (AddressByIdLoader(info.context).load(address_id)
                   if address_id else None)
        lines = CheckoutLinesInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        checkout_info = CheckoutInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        discounts = DiscountsByDateTimeLoader(info.context).load(
            info.context.request_time)
        return Promise.all([address, lines, checkout_info,
                            discounts]).then(calculate_subtotal_price)

    @staticmethod
    # TODO: We should optimize it in/after PR#5819
    def resolve_shipping_price(root: models.Checkout, info):
        def calculate_shipping_price(data):
            address, lines, checkout_info, discounts = data
            return calculations.checkout_shipping_price(
                manager=info.context.plugins,
                checkout_info=checkout_info,
                lines=lines,
                address=address,
                discounts=discounts,
            )

        address = (AddressByIdLoader(info.context).load(
            root.shipping_address_id) if root.shipping_address_id else None)
        lines = CheckoutLinesInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        checkout_info = CheckoutInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        discounts = DiscountsByDateTimeLoader(info.context).load(
            info.context.request_time)
        return Promise.all([address, lines, checkout_info,
                            discounts]).then(calculate_shipping_price)

    @staticmethod
    def resolve_lines(root: models.Checkout, info):
        return CheckoutLinesByCheckoutTokenLoader(info.context).load(
            root.token)

    @staticmethod
    # TODO: We should optimize it in/after PR#5819
    def resolve_available_shipping_methods(root: models.Checkout, info):
        def calculate_available_shipping_methods(data):
            address, lines, checkout_info, discounts, channel = data
            channel_slug = channel.slug
            display_gross = info.context.site.settings.display_gross_prices
            manager = info.context.plugins
            subtotal = manager.calculate_checkout_subtotal(
                checkout_info, lines, address, discounts)
            if not address:
                return []
            available = get_valid_shipping_methods_for_checkout(
                checkout_info,
                lines,
                discounts,
                subtotal=subtotal,
                country_code=address.country.code,
            )
            if available is None:
                return []
            available_ids = available.values_list("id", flat=True)

            def map_shipping_method_with_channel(shippings):
                def apply_price_to_shipping_method(channel_listings):
                    channel_listing_map = {
                        channel_listing.shipping_method_id: channel_listing
                        for channel_listing in channel_listings
                    }
                    available_with_channel_context = []
                    for shipping in shippings:
                        shipping_channel_listing = channel_listing_map[
                            shipping.id]
                        taxed_price = info.context.plugins.apply_taxes_to_shipping(
                            shipping_channel_listing.price, address)
                        if display_gross:
                            shipping.price = taxed_price.gross
                        else:
                            shipping.price = taxed_price.net
                        available_with_channel_context.append(
                            ChannelContext(node=shipping,
                                           channel_slug=channel_slug))
                    return available_with_channel_context

                map_shipping_method_and_channel = (
                    (shipping_method_id, channel_slug)
                    for shipping_method_id in available_ids)
                return (
                    ShippingMethodChannelListingByShippingMethodIdAndChannelSlugLoader(
                        info.context).load_many(
                            map_shipping_method_and_channel).then(
                                apply_price_to_shipping_method))

            return (ShippingMethodByIdLoader(info.context).load_many(
                available_ids).then(map_shipping_method_with_channel))

        channel = ChannelByIdLoader(info.context).load(root.channel_id)
        address = (AddressByIdLoader(info.context).load(
            root.shipping_address_id) if root.shipping_address_id else None)
        lines = CheckoutLinesInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        checkout_info = CheckoutInfoByCheckoutTokenLoader(info.context).load(
            root.token)
        discounts = DiscountsByDateTimeLoader(info.context).load(
            info.context.request_time)
        return Promise.all([address, lines, checkout_info, discounts, channel
                            ]).then(calculate_available_shipping_methods)

    @staticmethod
    def resolve_available_payment_gateways(root: models.Checkout, info):
        return info.context.plugins.checkout_available_payment_gateways(
            checkout=root)

    @staticmethod
    def resolve_gift_cards(root: models.Checkout, _info):
        return root.gift_cards.all()

    @staticmethod
    def resolve_is_shipping_required(root: models.Checkout, info):
        def is_shipping_required(lines):
            product_ids = [line_info.product.id for line_info in lines]

            def with_product_types(product_types):
                return any([pt.is_shipping_required for pt in product_types])

            return (ProductTypeByProductIdLoader(
                info.context).load_many(product_ids).then(with_product_types))

        return (CheckoutLinesInfoByCheckoutTokenLoader(info.context).load(
            root.token).then(is_shipping_required))
コード例 #26
0
class Page(CountableDjangoObjectType):
    content_json = graphene.JSONString(
        description="Content of the page (JSON).",
        deprecation_reason=(
            "Will be removed in Saleor 4.0. Use the `content` field instead."
        ),
        required=True,
    )
    translation = TranslationField(PageTranslation, type_name="page")
    attributes = graphene.List(
        graphene.NonNull(SelectedAttribute),
        required=True,
        description="List of attributes assigned to this product.",
    )
    media = graphene.List(
        graphene.NonNull(lambda: PageMedia),
        description="List of media for the page.",
    )
    store = graphene.Field(
        Store,
        id=graphene.Argument(graphene.ID, description="ID of the store."),
        slug=graphene.Argument(graphene.String, description="Slug of the store"),
        description="Look up a store by ID or slug.",
    )

    class Meta:
        description = (
            "A static page that can be manually added by a shop operator through the "
            "dashboard."
        )
        only_fields = [
            "content",
            "created",
            "id",
            "is_published",
            "page_type",
            "publication_date",
            "seo_description",
            "seo_title",
            "slug",
            "title",
            "store",
        ]
        interfaces = [graphene.relay.Node, ObjectWithMetadata]
        model = models.Page

    @staticmethod
    def resolve_page_type(root: models.Page, info):
        return PageTypeByIdLoader(info.context).load(root.page_type_id)

    @staticmethod
    def resolve_content_json(root: models.Page, info):
        content = root.content
        return content if content is not None else {}

    @staticmethod
    def resolve_attributes(root: models.Page, info):
        return SelectedAttributesByPageIdLoader(info.context).load(root.id)

    @staticmethod
    def resolve_media(self, info, page=None, slug=None, channel=None, **_kwargs):
        return models.PageMedia.objects.filter(page_id=self.pk, is_active=True)
コード例 #27
0
class CollectionChannelListingError(ProductError):
    channels = graphene.List(
        graphene.NonNull(graphene.ID),
        description="List of channels IDs which causes the error.",
        required=False,
    )
コード例 #28
0
 class Arguments:
     data = graphene.NonNull(HostInput)
コード例 #29
0
class GraphenePipelineRun(graphene.ObjectType):
    id = graphene.NonNull(graphene.ID)
    runId = graphene.NonNull(graphene.String)
    # Nullable because of historical runs
    pipelineSnapshotId = graphene.String()
    repositoryOrigin = graphene.Field(GrapheneRepositoryOrigin)
    status = graphene.NonNull(GraphenePipelineRunStatus)
    pipeline = graphene.NonNull(GraphenePipelineReference)
    pipelineName = graphene.NonNull(graphene.String)
    solidSelection = graphene.List(graphene.NonNull(graphene.String))
    stats = graphene.NonNull(GraphenePipelineRunStatsOrError)
    stepStats = non_null_list(GraphenePipelineRunStepStats)
    computeLogs = graphene.Field(
        graphene.NonNull(GrapheneComputeLogs),
        stepKey=graphene.Argument(graphene.NonNull(graphene.String)),
        description="""
        Compute logs are the stdout/stderr logs for a given solid step computation
        """,
    )
    executionPlan = graphene.Field(GrapheneExecutionPlan)
    stepKeysToExecute = graphene.List(graphene.NonNull(graphene.String))
    runConfigYaml = graphene.NonNull(graphene.String)
    mode = graphene.NonNull(graphene.String)
    tags = non_null_list(GraphenePipelineTag)
    rootRunId = graphene.Field(graphene.String)
    parentRunId = graphene.Field(graphene.String)
    canTerminate = graphene.NonNull(graphene.Boolean)
    assets = non_null_list(GrapheneAsset)

    class Meta:
        name = "PipelineRun"

    def __init__(self, pipeline_run):
        super().__init__(
            runId=pipeline_run.run_id,
            status=PipelineRunStatus(pipeline_run.status),
            mode=pipeline_run.mode,
        )
        self._pipeline_run = check.inst_param(pipeline_run, "pipeline_run",
                                              PipelineRun)

    def resolve_id(self, _graphene_info):
        return self._pipeline_run.run_id

    def resolve_repositoryOrigin(self, _graphene_info):
        return (GrapheneRepositoryOrigin(
            self._pipeline_run.external_pipeline_origin.
            external_repository_origin)
                if self._pipeline_run.external_pipeline_origin else None)

    def resolve_pipeline(self, graphene_info):
        return get_pipeline_reference_or_raise(graphene_info,
                                               self._pipeline_run)

    def resolve_pipelineName(self, _graphene_info):
        return self._pipeline_run.pipeline_name

    def resolve_solidSelection(self, _graphene_info):
        return self._pipeline_run.solid_selection

    def resolve_pipelineSnapshotId(self, _graphene_info):
        return self._pipeline_run.pipeline_snapshot_id

    def resolve_stats(self, graphene_info):
        return get_stats(graphene_info, self.run_id)

    def resolve_stepStats(self, graphene_info):
        return get_step_stats(graphene_info, self.run_id)

    def resolve_computeLogs(self, _graphene_info, stepKey):
        return GrapheneComputeLogs(runId=self.run_id, stepKey=stepKey)

    def resolve_executionPlan(self, graphene_info):
        if not (self._pipeline_run.execution_plan_snapshot_id
                and self._pipeline_run.pipeline_snapshot_id):
            return None

        instance = graphene_info.context.instance
        historical_pipeline = instance.get_historical_pipeline(
            self._pipeline_run.pipeline_snapshot_id)
        execution_plan_snapshot = instance.get_execution_plan_snapshot(
            self._pipeline_run.execution_plan_snapshot_id)
        return (GrapheneExecutionPlan(
            ExternalExecutionPlan(
                execution_plan_snapshot=execution_plan_snapshot,
                represented_pipeline=historical_pipeline,
            )) if execution_plan_snapshot and historical_pipeline else None)

    def resolve_stepKeysToExecute(self, _graphene_info):
        return self._pipeline_run.step_keys_to_execute

    def resolve_runConfigYaml(self, _graphene_info):
        return yaml.dump(self._pipeline_run.run_config,
                         default_flow_style=False,
                         allow_unicode=True)

    def resolve_tags(self, _graphene_info):
        return [
            GraphenePipelineTag(key=key, value=value)
            for key, value in self._pipeline_run.tags.items()
            if get_tag_type(key) != TagType.HIDDEN
        ]

    def resolve_rootRunId(self, _graphene_info):
        return self._pipeline_run.root_run_id

    def resolve_parentRunId(self, _graphene_info):
        return self._pipeline_run.parent_run_id

    @property
    def run_id(self):
        return self.runId

    def resolve_canTerminate(self, graphene_info):
        # short circuit if the pipeline run is in a terminal state
        if self._pipeline_run.is_finished:
            return False
        return graphene_info.context.instance.run_coordinator.can_cancel_run(
            self.run_id)

    def resolve_assets(self, graphene_info):
        return get_assets_for_run_id(graphene_info, self.run_id)
コード例 #30
0
ファイル: mutation.py プロジェクト: vitorarrais/dagster
class GrapheneTerminatePipelineExecutionFailure(graphene.ObjectType):
    run = graphene.NonNull(GraphenePipelineRun)
    message = graphene.NonNull(graphene.String)

    class Meta:
        name = "TerminatePipelineExecutionFailure"