Httpie: Agregar opción para ignorar datos estándar

Creado en 23 jul. 2013  ·  15Comentarios  ·  Fuente: httpie/httpie

http: error: Request body (from stdin or a file) and request data (key=value) cannot be mixed.

Este error es bastante críptico. Estoy escribiendo un script de shell para interactuar con una API de descanso y estoy haciendo esto:

http --output subnet --pretty format --form post "${URLHOST}subnets" "cidr=${cidr}" "name=${name}" "description=${name}" "availabilityZoneId=${az}" "networkId=${VPCid}" "$ACCESSKEY" "$SECRETKEY" "$ACCOUNTID" "_providerId=aws" "_regionId=${REGION}"

Lo cual produce (cuando está precedido por 'echo' un comando que funciona perfectamente bien. Sin embargo, esta versión da el error en el asunto.

¿Estoy siendo estúpido, o esto es otra cosa?

FYI: El resultado de lo anterior es el siguiente (desinfectado ligeramente)

http --output subnet --pretty format --form post https://test.grid.domain.com/subnets cidr=10.124.33.128/25 name=Load_balancers description=Load_balancers availabilityZoneId=us-east-1c networkId=vpc-31433e7e x-gridauth-accesskey:DOYOUNEEDTOKNOW x-gridauth-secretaccesskey:WHATISWITHALLTHEQUESTIONS x-gridauth-accountid:11223344556677 _providerId=aws _regionId=us-east-1
feature planned

Comentario más útil

Para referencia futura, ahora hay un argumento CLI --ignore-stdin que se puede usar para decirle explícitamente a HTTPie que los datos de la solicitud (clave=valor) deben preferirse al cuerpo de la solicitud (de stdin).

http --ignore-stdin http://… lorem=ipsum dolor=sit

Cf. https://httpie.org/docs#redirected -entrada

Todos 15 comentarios

Este error ocurre cuando se redirige STDIN de HTTPie y los datos también se especifican en los argumentos al mismo tiempo:

$ echo 'data' | http POST example.org more=data   # This is invalid

No estoy redirigiendo STDIN en absoluto. Aquí hay un poco más de contexto en el guión:

cat keyfile  | while read name az route cidr subnetid rest ; do
    http --output subnet --pretty format --form post \
    "${URLHOST}subnets" \
    "cidr=${cidr}" \
    "name=${name}" \
    "description=${name}"\
    "availabilityZoneId=${az}" \
    "networkId=${VPCid}"\
    "$ACCESSKEY" \
    "$SECRETKEY"\
    "$ACCOUNTID" \
    "_providerId=aws" "_regionId=${REGION}"

(y luego analizo el archivo 'subred' y hago otras cosas)

Lo que PUEDO estar haciendo es mezclar campos de formulario con encabezados http. Sin embargo, tampoco pude hacer que eso funcionara bien (alguna combinación de enviar los datos del formulario a través de STDIN y los encabezados como parámetros... o como encabezados y datos de formulario a través de STDIN, o lo que sea).

Ya veo, el problema es que en el contexto del bucle, HTTPie hereda su STDIN (que se redirige).

Debería poder solucionarlo cambiando el STDIN de HTTPie de nuevo a la entrada del terminal ( < /dev/tty ):

cat file | while read line; do 
    http POST example.org  a="$line" < /dev/tty
done

Guau. Eso funciona. NO tenía idea de que las declaraciones internas de un bucle de shell heredan el stdin del bucle circundante.

Gracias por la ayuda... No estoy seguro de haberlo encontrado por mi cuenta.

(Ahora tengo curiosidad por qué (supongo que todos los proyectiles derivados de SH) tomaron esa decisión de diseño...)

Creo que debería haber una opción para deshabilitar la lectura de STDIN que funcionaría en todas partes, así que mantengo esto abierto y lo etiqueto como una función.

Esto es muy confuso y va en contra de que httpie pueda funcionar en cualquier lugar. Usar un comando de este tipo dentro de un ciclo bash es una aplicación muy común. Httpie no debe quejarse cuando se proporciona la clave/valor y recibe stdin: en su lugar, debe dejar que la clave/valor domine.

Httpie no debe quejarse cuando se proporciona la clave/valor y recibe stdin: en su lugar, debe dejar que la clave/valor domine.

Eso tal vez sea intuitivo para usted, pero para muchos otros, exactamente lo contrario es mucho más intuitivo. Debido a que las herramientas no deben tratar de adivinar, es mucho mejor generar un error y brindarle una escotilla de escape si cree que sabe mejor, lo cual hace.

Me encontré con este problema al usar httpie dentro de una función pasada a GNU paralelo :

function call_api {
    local FOO=`http --json --auth $TOKEN: post $HOST/api/foo name="Ţẽṧẗ" < /dev/tty | python3 -c "import json,sys;obj=json.load(sys.stdin);print(obj['result']['id']);"`
    […]
    http --download --auth $TOKEN: GET $HOST/api/bla > /dev/tty
}

export -f call_api
export HOST=…
export TOKEN=…
parallel --env HOST --env TOKEN ::: call_api call_api call_api call_api call_api

Gracias al comentario anterior , la invocación de la función paralela funciona ahora. Dejando este comentario aquí para futuras referencias 😊

Para referencia futura, ahora hay un argumento CLI --ignore-stdin que se puede usar para decirle explícitamente a HTTPie que los datos de la solicitud (clave=valor) deben preferirse al cuerpo de la solicitud (de stdin).

http --ignore-stdin http://… lorem=ipsum dolor=sit

Cf. https://httpie.org/docs#redirected -entrada

Encontré esto mientras usaba http en un bucle for. Funcionó bien localmente, pero falló en gitlab. --ignore-stdin lo resolvió.

Intenté redirigir stdin a null </dev/null , pero hizo que httpie se comportara de manera extraña. ¿Porque eso? Quiero decir, ¿no debería haber una manera de hacer que un comando ignore la entrada estándar desde el propio shell?

@NightMachinary quiere usar la opción --ignore-stdin . Así es como le dices a HTTPie que no lea STDIN .

$ echo 'this STDIN data is ignored' | http  --ignore-stdin POST httpbin.org/post hello=world

@jakubroztocil Lo sé, estoy diciendo que si http no tuviera --ignore-stdin , ¿cómo podríamos eliminar la entrada estándar que va a http desde el propio shell?

@NightMachinary no puede eliminar STDIN (y las otras transmisiones estándar), pero puede cerrarlo:

$ echo ignored data | http httpbin.org/anything 0<&-

https://superuser.com/questions/813472/how-do-i-close-stdin-in-a-shell-script

@NightMachinary y redireccionar /dev/null es un poco diferente:

$ http httpbin.org/anything < /dev/null

Esto aún invoca a HTTPie con un STDIN abierto y redirigido, por lo que HTTPie lo leerá y terminará con una cadena vacía, que luego usará felizmente como los datos del cuerpo de la solicitud (de forma predeterminada en POST ), a menos que le diga que no lo haga con --ignore-stdin .

Así que es básicamente equivalente a esto:

$ echo -n | http httpbin.org/anything 
¿Fue útil esta página
0 / 5 - 0 calificaciones