:py:mod:`airflow.models.param`
==============================

.. py:module:: airflow.models.param


Module Contents
---------------

Classes
~~~~~~~

.. autoapisummary::

   airflow.models.param.Param
   airflow.models.param.ParamsDict
   airflow.models.param.DagParam




.. py:class:: Param(default = NOTSET, description = None, **kwargs)

   Class to hold the default value of a Param and rule set to do the validations. Without the rule set
   it always validates and returns the default value.

   :param default: The value this Param object holds
   :param description: Optional help text for the Param
   :param schema: The validation schema of the Param, if not given then all kwargs except
       default & description will form the schema

   .. py:attribute:: CLASS_IDENTIFIER
      :annotation: = __class

      

   .. py:method:: __copy__()


   .. py:method:: resolve(value = NOTSET, suppress_exception = False)

      Runs the validations and returns the Param's final value.
      May raise ValueError on failed validations, or TypeError
      if no value is passed and no value already exists.
      We first check that value is json-serializable; if not, warn.
      In future release we will require the value to be json-serializable.

      :param value: The value to be updated for the Param
      :param suppress_exception: To raise an exception or not when the validations fails.
          If true and validations fails, the return value would be None.


   .. py:method:: dump()

      Dump the Param as a dictionary


   .. py:method:: has_value()
      :property:



.. py:class:: ParamsDict(dict_obj = None, suppress_exception = False)

   Bases: :py:obj:`MutableMapping`\ [\ :py:obj:`str`\ , :py:obj:`Any`\ ]

   Class to hold all params for dags or tasks. All the keys are strictly string and values
   are converted into Param's object if they are not already. This class is to replace param's
   dictionary implicitly and ideally not needed to be used directly.

   .. py:attribute:: __slots__
      :annotation: = ['__dict', 'suppress_exception']

      

   .. py:method:: __copy__()


   .. py:method:: __deepcopy__(memo)


   .. py:method:: __contains__(o)


   .. py:method:: __len__()


   .. py:method:: __delitem__(v)


   .. py:method:: __iter__()


   .. py:method:: __repr__()

      Return repr(self).


   .. py:method:: __setitem__(key, value)

      Override for dictionary's ``setitem`` method. This method make sure that all values are of
      Param's type only.

      :param key: A key which needs to be inserted or updated in the dict
      :param value: A value which needs to be set against the key. It could be of any
          type but will be converted and stored as a Param object eventually.


   .. py:method:: __getitem__(key)

      Override for dictionary's ``getitem`` method. After fetching the key, it would call the
      resolve method as well on the Param object.

      :param key: The key to fetch


   .. py:method:: get_param(key)

      Get the internal :class:`.Param` object for this key


   .. py:method:: items()

      D.items() -> a set-like object providing a view on D's items


   .. py:method:: values()

      D.values() -> an object providing a view on D's values


   .. py:method:: update(*args, **kwargs)

      D.update([E, ]**F) -> None.  Update D from mapping/iterable E and F.
      If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
      If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
      In either case, this is followed by: for k, v in F.items(): D[k] = v


   .. py:method:: dump()

      Dumps the ParamsDict object as a dictionary, while suppressing exceptions


   .. py:method:: validate()

      Validates & returns all the Params object stored in the dictionary



.. py:class:: DagParam(current_dag, name, default = NOTSET)

   Class that represents a DAG run parameter & binds a simple Param object to a name within a DAG instance,
   so that it can be resolved during the run time via ``{{ context }}`` dictionary. The ideal use case of
   this class is to implicitly convert args passed to a method which is being decorated by ``@dag`` keyword.

   It can be used to parameterize your dags. You can overwrite its value by setting it on conf
   when you trigger your DagRun.

   This can also be used in templates by accessing ``{{context.params}}`` dictionary.

   **Example**:

       with DAG(...) as dag:
         EmailOperator(subject=dag.param('subject', 'Hi from Airflow!'))

   :param current_dag: Dag being used for parameter.
   :param name: key value which is used to set the parameter
   :param default: Default value used if no parameter was set.

   .. py:method:: resolve(context)

      Pull DagParam value from DagRun context. This method is run during ``op.execute()``.



