// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

/*
Airflow API (Stable)

# Overview  To facilitate management, Apache Airflow supports a range of REST API endpoints across its objects. This section provides an overview of the API design, methods, and supported use cases.  Most of the endpoints accept `JSON` as input and return `JSON` responses. This means that you must usually add the following headers to your request: ``` Content-type: application/json Accept: application/json ```  ## Resources  The term `resource` refers to a single type of object in the Airflow metadata. An API is broken up by its endpoint's corresponding resource. The name of a resource is typically plural and expressed in camelCase. Example: `dagRuns`.  Resource names are used as part of endpoint URLs, as well as in API parameters and responses.  ## CRUD Operations  The platform supports **C**reate, **R**ead, **U**pdate, and **D**elete operations on most resources. You can review the standards for these operations and their standard parameters below.  Some endpoints have special behavior as exceptions.  ### Create  To create a resource, you typically submit an HTTP `POST` request with the resource's required metadata in the request body. The response returns a `201 Created` response code upon success with the resource's metadata, including its internal `id`, in the response body.  ### Read  The HTTP `GET` request can be used to read a resource or to list a number of resources.  A resource's `id` can be submitted in the request parameters to read a specific resource. The response usually returns a `200 OK` response code upon success, with the resource's metadata in the response body.  If a `GET` request does not include a specific resource `id`, it is treated as a list request. The response usually returns a `200 OK` response code upon success, with an object containing a list of resources' metadata in the response body.  When reading resources, some common query parameters are usually available. e.g.: ``` v1/connections?limit=25&offset=25 ```  |Query Parameter|Type|Description| |---------------|----|-----------| |limit|integer|Maximum number of objects to fetch. Usually 25 by default| |offset|integer|Offset after which to start returning objects. For use with limit query parameter.|  ### Update  Updating a resource requires the resource `id`, and is typically done using an HTTP `PATCH` request, with the fields to modify in the request body. The response usually returns a `200 OK` response code upon success, with information about the modified resource in the response body.  ### Delete  Deleting a resource requires the resource `id` and is typically executing via an HTTP `DELETE` request. The response usually returns a `204 No Content` response code upon success.  ## Conventions  - Resource names are plural and expressed in camelCase. - Names are consistent between URL parameter name and field name.  - Field names are in snake_case. ```json {     \"name\": \"string\",     \"slots\": 0,     \"occupied_slots\": 0,     \"used_slots\": 0,     \"queued_slots\": 0,     \"open_slots\": 0 } ```  ### Update Mask  Update mask is available as a query parameter in patch endpoints. It is used to notify the API which fields you want to update. Using `update_mask` makes it easier to update objects by helping the server know which fields to update in an object instead of updating all fields. The update request ignores any fields that aren't specified in the field mask, leaving them with their current values.  Example: ```   resource = request.get('/resource/my-id').json()   resource['my_field'] = 'new-value'   request.patch('/resource/my-id?update_mask=my_field', data=json.dumps(resource)) ```  ## Versioning and Endpoint Lifecycle  - API versioning is not synchronized to specific releases of the Apache Airflow. - APIs are designed to be backward compatible. - Any changes to the API will first go through a deprecation phase.  # Trying the API  You can use a third party client, such as [curl](https://curl.haxx.se/), [HTTPie](https://httpie.org/), [Postman](https://www.postman.com/) or [the Insomnia rest client](https://insomnia.rest/) to test the Apache Airflow API.  Note that you will need to pass credentials data.  For e.g., here is how to pause a DAG with [curl](https://curl.haxx.se/), when basic authorization is used: ```bash curl -X PATCH 'https://example.com/api/v1/dags/{dag_id}?update_mask=is_paused' \\ -H 'Content-Type: application/json' \\ --user \"username:password\" \\ -d '{     \"is_paused\": true }' ```  Using a graphical tool such as [Postman](https://www.postman.com/) or [Insomnia](https://insomnia.rest/), it is possible to import the API specifications directly:  1. Download the API specification by clicking the **Download** button at top of this document 2. Import the JSON specification in the graphical tool of your choice.   - In *Postman*, you can click the **import** button at the top   - With *Insomnia*, you can just drag-and-drop the file on the UI  Note that with *Postman*, you can also generate code snippets by selecting a request and clicking on the **Code** button.  ## Enabling CORS  [Cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a browser security feature that restricts HTTP requests that are initiated from scripts running in the browser.  For details on enabling/configuring CORS, see [Enabling CORS](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html).  # Authentication  To be able to meet the requirements of many organizations, Airflow supports many authentication methods, and it is even possible to add your own method.  If you want to check which auth backend is currently set, you can use `airflow config get-value api auth_backends` command as in the example below. ```bash $ airflow config get-value api auth_backends airflow.api.auth.backend.basic_auth ``` The default is to deny all requests.  For details on configuring the authentication, see [API Authorization](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html).  # Errors  We follow the error response format proposed in [RFC 7807](https://tools.ietf.org/html/rfc7807) also known as Problem Details for HTTP APIs. As with our normal API responses, your client must be prepared to gracefully handle additional members of the response.  ## Unauthenticated  This indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. Please check that you have valid credentials.  ## PermissionDenied  This response means that the server understood the request but refuses to authorize it because it lacks sufficient rights to the resource. It happens when you do not have the necessary permission to execute the action you performed. You need to get the appropriate permissions in other to resolve this error.  ## BadRequest  This response means that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). To resolve this, please ensure that your syntax is correct.  ## NotFound  This client error response indicates that the server cannot find the requested resource.  ## MethodNotAllowed  Indicates that the request method is known by the server but is not supported by the target resource.  ## NotAcceptable  The target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request, and the server is unwilling to supply a default representation.  ## AlreadyExists  The request could not be completed due to a conflict with the current state of the target resource, e.g. the resource it tries to create already exists.  ## Unknown  This means that the server encountered an unexpected condition that prevented it from fulfilling the request. 

API version: 2.5.0
Contact: dev@airflow.apache.org
*/

// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.

package airflow

import (
	"encoding/json"
	"time"
)

// ListDagRunsForm struct for ListDagRunsForm
type ListDagRunsForm struct {
	// The name of the field to order the results by. Prefix a field name with `-` to reverse the sort order.  *New in version 2.1.0* 
	OrderBy *string `json:"order_by,omitempty"`
	// The number of items to skip before starting to collect the result set.
	PageOffset *int32 `json:"page_offset,omitempty"`
	// The numbers of items to return.
	PageLimit *int32 `json:"page_limit,omitempty"`
	// Return objects with specific DAG IDs. The value can be repeated to retrieve multiple matching values (OR condition).
	DagIds *[]string `json:"dag_ids,omitempty"`
	// Return objects with specific states. The value can be repeated to retrieve multiple matching values (OR condition).
	States *[]string `json:"states,omitempty"`
	// Returns objects greater or equal to the specified date.  This can be combined with execution_date_lte key to receive only the selected period. 
	ExecutionDateGte *time.Time `json:"execution_date_gte,omitempty"`
	// Returns objects less than or equal to the specified date.  This can be combined with execution_date_gte key to receive only the selected period. 
	ExecutionDateLte *time.Time `json:"execution_date_lte,omitempty"`
	// Returns objects greater or equal the specified date.  This can be combined with start_date_lte key to receive only the selected period. 
	StartDateGte *time.Time `json:"start_date_gte,omitempty"`
	// Returns objects less or equal the specified date.  This can be combined with start_date_gte parameter to receive only the selected period 
	StartDateLte *time.Time `json:"start_date_lte,omitempty"`
	// Returns objects greater or equal the specified date.  This can be combined with end_date_lte parameter to receive only the selected period. 
	EndDateGte *time.Time `json:"end_date_gte,omitempty"`
	// Returns objects less than or equal to the specified date.  This can be combined with end_date_gte parameter to receive only the selected period. 
	EndDateLte *time.Time `json:"end_date_lte,omitempty"`
}

// NewListDagRunsForm instantiates a new ListDagRunsForm object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewListDagRunsForm() *ListDagRunsForm {
	this := ListDagRunsForm{}
	var pageLimit int32 = 100
	this.PageLimit = &pageLimit
	return &this
}

// NewListDagRunsFormWithDefaults instantiates a new ListDagRunsForm object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewListDagRunsFormWithDefaults() *ListDagRunsForm {
	this := ListDagRunsForm{}
	var pageLimit int32 = 100
	this.PageLimit = &pageLimit
	return &this
}

// GetOrderBy returns the OrderBy field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetOrderBy() string {
	if o == nil || o.OrderBy == nil {
		var ret string
		return ret
	}
	return *o.OrderBy
}

// GetOrderByOk returns a tuple with the OrderBy field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetOrderByOk() (*string, bool) {
	if o == nil || o.OrderBy == nil {
		return nil, false
	}
	return o.OrderBy, true
}

// HasOrderBy returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasOrderBy() bool {
	if o != nil && o.OrderBy != nil {
		return true
	}

	return false
}

// SetOrderBy gets a reference to the given string and assigns it to the OrderBy field.
func (o *ListDagRunsForm) SetOrderBy(v string) {
	o.OrderBy = &v
}

// GetPageOffset returns the PageOffset field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetPageOffset() int32 {
	if o == nil || o.PageOffset == nil {
		var ret int32
		return ret
	}
	return *o.PageOffset
}

// GetPageOffsetOk returns a tuple with the PageOffset field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetPageOffsetOk() (*int32, bool) {
	if o == nil || o.PageOffset == nil {
		return nil, false
	}
	return o.PageOffset, true
}

// HasPageOffset returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasPageOffset() bool {
	if o != nil && o.PageOffset != nil {
		return true
	}

	return false
}

// SetPageOffset gets a reference to the given int32 and assigns it to the PageOffset field.
func (o *ListDagRunsForm) SetPageOffset(v int32) {
	o.PageOffset = &v
}

// GetPageLimit returns the PageLimit field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetPageLimit() int32 {
	if o == nil || o.PageLimit == nil {
		var ret int32
		return ret
	}
	return *o.PageLimit
}

// GetPageLimitOk returns a tuple with the PageLimit field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetPageLimitOk() (*int32, bool) {
	if o == nil || o.PageLimit == nil {
		return nil, false
	}
	return o.PageLimit, true
}

// HasPageLimit returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasPageLimit() bool {
	if o != nil && o.PageLimit != nil {
		return true
	}

	return false
}

// SetPageLimit gets a reference to the given int32 and assigns it to the PageLimit field.
func (o *ListDagRunsForm) SetPageLimit(v int32) {
	o.PageLimit = &v
}

// GetDagIds returns the DagIds field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetDagIds() []string {
	if o == nil || o.DagIds == nil {
		var ret []string
		return ret
	}
	return *o.DagIds
}

// GetDagIdsOk returns a tuple with the DagIds field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetDagIdsOk() (*[]string, bool) {
	if o == nil || o.DagIds == nil {
		return nil, false
	}
	return o.DagIds, true
}

// HasDagIds returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasDagIds() bool {
	if o != nil && o.DagIds != nil {
		return true
	}

	return false
}

// SetDagIds gets a reference to the given []string and assigns it to the DagIds field.
func (o *ListDagRunsForm) SetDagIds(v []string) {
	o.DagIds = &v
}

// GetStates returns the States field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetStates() []string {
	if o == nil || o.States == nil {
		var ret []string
		return ret
	}
	return *o.States
}

// GetStatesOk returns a tuple with the States field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetStatesOk() (*[]string, bool) {
	if o == nil || o.States == nil {
		return nil, false
	}
	return o.States, true
}

// HasStates returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasStates() bool {
	if o != nil && o.States != nil {
		return true
	}

	return false
}

// SetStates gets a reference to the given []string and assigns it to the States field.
func (o *ListDagRunsForm) SetStates(v []string) {
	o.States = &v
}

// GetExecutionDateGte returns the ExecutionDateGte field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetExecutionDateGte() time.Time {
	if o == nil || o.ExecutionDateGte == nil {
		var ret time.Time
		return ret
	}
	return *o.ExecutionDateGte
}

// GetExecutionDateGteOk returns a tuple with the ExecutionDateGte field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetExecutionDateGteOk() (*time.Time, bool) {
	if o == nil || o.ExecutionDateGte == nil {
		return nil, false
	}
	return o.ExecutionDateGte, true
}

// HasExecutionDateGte returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasExecutionDateGte() bool {
	if o != nil && o.ExecutionDateGte != nil {
		return true
	}

	return false
}

// SetExecutionDateGte gets a reference to the given time.Time and assigns it to the ExecutionDateGte field.
func (o *ListDagRunsForm) SetExecutionDateGte(v time.Time) {
	o.ExecutionDateGte = &v
}

// GetExecutionDateLte returns the ExecutionDateLte field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetExecutionDateLte() time.Time {
	if o == nil || o.ExecutionDateLte == nil {
		var ret time.Time
		return ret
	}
	return *o.ExecutionDateLte
}

// GetExecutionDateLteOk returns a tuple with the ExecutionDateLte field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetExecutionDateLteOk() (*time.Time, bool) {
	if o == nil || o.ExecutionDateLte == nil {
		return nil, false
	}
	return o.ExecutionDateLte, true
}

// HasExecutionDateLte returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasExecutionDateLte() bool {
	if o != nil && o.ExecutionDateLte != nil {
		return true
	}

	return false
}

// SetExecutionDateLte gets a reference to the given time.Time and assigns it to the ExecutionDateLte field.
func (o *ListDagRunsForm) SetExecutionDateLte(v time.Time) {
	o.ExecutionDateLte = &v
}

// GetStartDateGte returns the StartDateGte field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetStartDateGte() time.Time {
	if o == nil || o.StartDateGte == nil {
		var ret time.Time
		return ret
	}
	return *o.StartDateGte
}

// GetStartDateGteOk returns a tuple with the StartDateGte field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetStartDateGteOk() (*time.Time, bool) {
	if o == nil || o.StartDateGte == nil {
		return nil, false
	}
	return o.StartDateGte, true
}

// HasStartDateGte returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasStartDateGte() bool {
	if o != nil && o.StartDateGte != nil {
		return true
	}

	return false
}

// SetStartDateGte gets a reference to the given time.Time and assigns it to the StartDateGte field.
func (o *ListDagRunsForm) SetStartDateGte(v time.Time) {
	o.StartDateGte = &v
}

// GetStartDateLte returns the StartDateLte field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetStartDateLte() time.Time {
	if o == nil || o.StartDateLte == nil {
		var ret time.Time
		return ret
	}
	return *o.StartDateLte
}

// GetStartDateLteOk returns a tuple with the StartDateLte field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetStartDateLteOk() (*time.Time, bool) {
	if o == nil || o.StartDateLte == nil {
		return nil, false
	}
	return o.StartDateLte, true
}

// HasStartDateLte returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasStartDateLte() bool {
	if o != nil && o.StartDateLte != nil {
		return true
	}

	return false
}

// SetStartDateLte gets a reference to the given time.Time and assigns it to the StartDateLte field.
func (o *ListDagRunsForm) SetStartDateLte(v time.Time) {
	o.StartDateLte = &v
}

// GetEndDateGte returns the EndDateGte field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetEndDateGte() time.Time {
	if o == nil || o.EndDateGte == nil {
		var ret time.Time
		return ret
	}
	return *o.EndDateGte
}

// GetEndDateGteOk returns a tuple with the EndDateGte field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetEndDateGteOk() (*time.Time, bool) {
	if o == nil || o.EndDateGte == nil {
		return nil, false
	}
	return o.EndDateGte, true
}

// HasEndDateGte returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasEndDateGte() bool {
	if o != nil && o.EndDateGte != nil {
		return true
	}

	return false
}

// SetEndDateGte gets a reference to the given time.Time and assigns it to the EndDateGte field.
func (o *ListDagRunsForm) SetEndDateGte(v time.Time) {
	o.EndDateGte = &v
}

// GetEndDateLte returns the EndDateLte field value if set, zero value otherwise.
func (o *ListDagRunsForm) GetEndDateLte() time.Time {
	if o == nil || o.EndDateLte == nil {
		var ret time.Time
		return ret
	}
	return *o.EndDateLte
}

// GetEndDateLteOk returns a tuple with the EndDateLte field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *ListDagRunsForm) GetEndDateLteOk() (*time.Time, bool) {
	if o == nil || o.EndDateLte == nil {
		return nil, false
	}
	return o.EndDateLte, true
}

// HasEndDateLte returns a boolean if a field has been set.
func (o *ListDagRunsForm) HasEndDateLte() bool {
	if o != nil && o.EndDateLte != nil {
		return true
	}

	return false
}

// SetEndDateLte gets a reference to the given time.Time and assigns it to the EndDateLte field.
func (o *ListDagRunsForm) SetEndDateLte(v time.Time) {
	o.EndDateLte = &v
}

func (o ListDagRunsForm) MarshalJSON() ([]byte, error) {
	toSerialize := map[string]interface{}{}
	if o.OrderBy != nil {
		toSerialize["order_by"] = o.OrderBy
	}
	if o.PageOffset != nil {
		toSerialize["page_offset"] = o.PageOffset
	}
	if o.PageLimit != nil {
		toSerialize["page_limit"] = o.PageLimit
	}
	if o.DagIds != nil {
		toSerialize["dag_ids"] = o.DagIds
	}
	if o.States != nil {
		toSerialize["states"] = o.States
	}
	if o.ExecutionDateGte != nil {
		toSerialize["execution_date_gte"] = o.ExecutionDateGte
	}
	if o.ExecutionDateLte != nil {
		toSerialize["execution_date_lte"] = o.ExecutionDateLte
	}
	if o.StartDateGte != nil {
		toSerialize["start_date_gte"] = o.StartDateGte
	}
	if o.StartDateLte != nil {
		toSerialize["start_date_lte"] = o.StartDateLte
	}
	if o.EndDateGte != nil {
		toSerialize["end_date_gte"] = o.EndDateGte
	}
	if o.EndDateLte != nil {
		toSerialize["end_date_lte"] = o.EndDateLte
	}
	return json.Marshal(toSerialize)
}

type NullableListDagRunsForm struct {
	value *ListDagRunsForm
	isSet bool
}

func (v NullableListDagRunsForm) Get() *ListDagRunsForm {
	return v.value
}

func (v *NullableListDagRunsForm) Set(val *ListDagRunsForm) {
	v.value = val
	v.isSet = true
}

func (v NullableListDagRunsForm) IsSet() bool {
	return v.isSet
}

func (v *NullableListDagRunsForm) Unset() {
	v.value = nil
	v.isSet = false
}

func NewNullableListDagRunsForm(val *ListDagRunsForm) *NullableListDagRunsForm {
	return &NullableListDagRunsForm{value: val, isSet: true}
}

func (v NullableListDagRunsForm) MarshalJSON() ([]byte, error) {
	return json.Marshal(v.value)
}

func (v *NullableListDagRunsForm) UnmarshalJSON(src []byte) error {
	v.isSet = true
	return json.Unmarshal(src, &v.value)
}


