# Parsl Task Submission
## The `Wrapper`
- Class `AppBase`, defines the wrapper with basic attributes
- Class `PythonApp`, implements more attributes and the `__call__()` method to
handle Python function.
## The `Future`
- Inherited from `Future` in `concurrent` module
> An `AppFuture` wraps a sequence of `Futures` which may fail and be retried.
>
> The `AppFuture` will wait for the `DFK` to provide a result from an
> appropriate parent future, through `parent_callback`. It will set its result
> to the result of that parent future, if that parent future completes without
> an exception. This result setting should cause `.result()`, `.exception()` and
> `done` callbacks to fire as expected.
## The `DataFlowKernel`
- ==DFK is the core mechanism!== "The `DataFlowKernel` adds dependency awareness
to an existing executor"
- `app_fut` is a result of `dfk.submit()`
- `dfk.submit()` takes all the arguments in the wrapper, i.e. the
`invocation_kwargs`
- Class `TaskRecord` stores most information about a Parsl task.
## `executor` Choices
- in `submit` of `dfk`, `PythonApp.executors` argument of the task is
interpreted as `choices`
- `DFK` has its own `slef.executors`, which is a `ThreadPoolExecutor` by
default.