{
  "appeals": 1,
  "budgets": {
    "baseline_limit_s": 600,
    "verification_timeout_s": 600,
    "worker": {
      "max_completion_tokens": 96000,
      "max_turns": 60,
      "max_wall_seconds": 1500.0,
      "prompt_token_budget": 160000
    }
  },
  "issue": "Add support for providing credentials via environment variables\nAs an alternative to passing user credentials as arguments to `rest_api.get_access_token()`, it would be useful to also have the option of providing these via shell environment variables, for example:\r\n```\r\nexport INAT_USERNAME=\"\"\r\nexport INAT_PASSWORD=\"\"\r\nexport INAT_APP_ID=\"\"\r\nexport INAT_APP_SECRET=\"\"\r\n```\r\n\r\nThis is a pretty common pattern in other applications (for example, the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)), since environment variables offer a bit more flexibility. For example, creds can be stored in the system keychain or other secure format and then loaded with something like `export INAT_PASSWORD=$(secret-tool lookup ...)`.\r\n\r\nThere is also the python [keyring](https://github.com/jaraco/keyring) package that provides convenient integration with the system keyring, but that could be a separate issue (EDIT: created #69 for this).\r\n\r\nIf both function arguments and environment variables were to be specified, function arguments would take precedence.",
  "source": {
    "image": "docker.io/swerebenchv2/niconoe-pyinaturalist:72-3cd4a4f",
    "platform": "linux/amd64",
    "python": "python",
    "setup": [
      "python -c 'import base64; from pathlib import Path; Path('\"'\"'/tmp/receipts-niconoe__pyinaturalist-72-test.patch'\"'\"').write_bytes(base64.b64decode('\"'\"'ZGlmZiAtLWdpdCBhL3Rlc3QvY29uZnRlc3QucHkgYi90ZXN0L2NvbmZ0ZXN0LnB5CmluZGV4IGIzZTE1NmUuLjM0NzAzYzcgMTAwNjQ0Ci0tLSBhL3Rlc3QvY29uZnRlc3QucHkKKysrIGIvdGVzdC9jb25mdGVzdC5weQpAQCAtMTEsNiArMTEsMTQgQEAgZnJvbSB1bml0dGVzdC5tb2NrIGltcG9ydCBNYWdpY01vY2sKIAogSFRUUF9GVU5DX1BBVFRFUk4gPSByZS5jb21waWxlKHIiKGdldHxwdXR8cG9zdHxkZWxldGUpXy4rIikKIFNBTVBMRV9EQVRBX0RJUiA9IGFic3BhdGgoam9pbihkaXJuYW1lKF9fZmlsZV9fKSwgInNhbXBsZV9kYXRhIikpCisKK01PQ0tfQ1JFRFMgPSB7CisgICAgIklOQVRfVVNFUk5BTUUiOiAidmFsaWRfdXNlcm5hbWUiLAorICAgICJJTkFUX1BBU1NXT1JEIjogInZhbGlkX3Bhc3N3b3JkIiwKKyAgICAiSU5BVF9BUFBfSUQiOiAidmFsaWRfYXBwX2lkIiwKKyAgICAiSU5BVF9BUFBfU0VDUkVUIjogInZhbGlkX2FwcF9zZWNyZXQiLAorfQorCiAjIEVuYWJsZSBsb2dnaW5nIGZvciB1cmxsaWIgYW5kIG90aGVyIGV4dGVybmFsIGxvZ2dlcnMKIGxvZ2dpbmcuYmFzaWNDb25maWcobGV2ZWw9IklORk8iKQogCmRpZmYgLS1naXQgYS90ZXN0L21hbnVhbF90ZXN0cy9vYnNfY3J1ZF90ZXN0LnB5IGIvdGVzdC9tYW51YWxfdGVzdHMvb2JzX2NydWRfdGVzdC5weQppbmRleCAyZGIzYmZmLi5mNjViMjhjIDEwMDY0NAotLS0gYS90ZXN0L21hbnVhbF90ZXN0cy9vYnNfY3J1ZF90ZXN0LnB5CisrKyBiL3Rlc3QvbWFudWFsX3Rlc3RzL29ic19jcnVkX3Rlc3QucHkKQEAgLTEsNiArMSw3IEBACiAjIS91c3IvYmluL2VudiBweXRob24KLSIiIkEgc2VtaS1hdXRvbWF0ZWQgc2NyaXB0IHVzZWQgdG8gdGVzdCBhbGwgb2JzZXJ2YXRpb24gQ1JVRCBlbmRwb2ludHMuCi1NdXN0IHByb3ZpZGUgaU5hdCBjcmVkZW50aWFscyB2aWEgZW52aXJvbm1lbnQgdmFyaWFibGVzLiBVc2FnZSBleGFtcGxlOgorIiIiQSBzZW1pLWF1dG9tYXRlZCBzY3JpcHQgdXNlZCB0byB0ZXN0IGFsbCBvYnNlcnZhdGlvbiBDUlVEIGVuZHBvaW50cy4gTXVzdCBwcm92aWRlIGlOYXQKK2NyZWRlbnRpYWxzIHZpYSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuIFNlZSA6cHk6ZnVuYzpgLmdldF9hY2Nlc3NfdG9rZW5gIGZvciBkZXRhaWxzLgorVXNhZ2UgZXhhbXBsZToKIGBgYAogZXhwb3J0IElOQVRfVVNFUk5BTUU9IiIKIGV4cG9ydCBJTkFUX1BBU1NXT1JEPSIiCkBAIC0yOSwxMyArMzAsNyBAQCBTQU1QTEVfUEhPVE8gPSBqb2luKFNBTVBMRV9EQVRBX0RJUiwgIm9ic19pbWFnZS5qcGciKQogCiAKIGRlZiBydW5fb2JzZXJ2YXRpb25fY3J1ZF90ZXN0KCk6Ci0gICAgIyBUT0RPOiBCdWlsdC1pbiBzdXBwb3J0IGZvciB1c2luZyBlbnZhcnMgZm9yIGF1dGggaW5zdGVhZCBvZiBmdW5jdGlvbiBhcmdzIG1pZ2h0IGJlIHVzZWZ1bAotICAgIHRva2VuID0gZ2V0X2FjY2Vzc190b2tlbigKLSAgICAgICAgdXNlcm5hbWU9Z2V0ZW52KCJJTkFUX1VTRVJOQU1FIiksCi0gICAgICAgIHBhc3N3b3JkPWdldGVudigiSU5BVF9QQVNTV09SRCIpLAotICAgICAgICBhcHBfaWQ9Z2V0ZW52KCJJTkFUX0FQUF9JRCIpLAotICAgICAgICBhcHBfc2VjcmV0PWdldGVudigiSU5BVF9BUFBfU0VDUkVUIiksCi0gICAgKQorICAgIHRva2VuID0gZ2V0X2FjY2Vzc190b2tlbigpCiAgICAgcHJpbnQoIlJlY2VpdmVkIGFjY2VzcyB0b2tlbiIpCiAKICAgICB0ZXN0X29ic19pZCA9IGNyZWF0ZV90ZXN0X29icyh0b2tlbikKQEAgLTc5LDYgKzc0LDcgQEAgZGVmIHVwZGF0ZV90ZXN0X29icyh0ZXN0X29ic19pZCwgdG9rZW4pOgogCiAgICAgcmVzcG9uc2UgPSB1cGRhdGVfb2JzZXJ2YXRpb24oCiAgICAgICAgIHRlc3Rfb2JzX2lkLAorICAgICAgICB0YXhvbl9pZD01NDMyNywKICAgICAgICAgZ2VvcHJpdmFjeT0ib2JzY3VyZWQiLAogICAgICAgICBpZ25vcmVfcGhvdG9zPVRydWUsCiAgICAgICAgIGFjY2Vzc190b2tlbj10b2tlbiwKQEAgLTg4LDE0ICs4NCwxNCBAQCBkZWYgdXBkYXRlX3Rlc3Rfb2JzKHRlc3Rfb2JzX2lkLCB0b2tlbik6CiAgICAgcHJpbnQoIlVwZGF0ZWQgb2JzZXJ2YXRpb24iKQogICAgICMgcHByaW50KHJlc3BvbnNlLCBpbmRlbnQ9MikKIAotICAgIHJlc3BvbnNlID0gcHV0X29ic2VydmF0aW9uX2ZpZWxkX3ZhbHVlcygKLSAgICAgICAgb2JzZXJ2YXRpb25faWQ9dGVzdF9vYnNfaWQsCi0gICAgICAgIG9ic2VydmF0aW9uX2ZpZWxkX2lkPTI5NywKLSAgICAgICAgdmFsdWU9MiwKLSAgICAgICAgYWNjZXNzX3Rva2VuPXRva2VuLAotICAgICkKLSAgICBwcmludCgiQWRkZWQgb2JzZXJ2YXRpb24gZmllbGQgdmFsdWU6IikKLSAgICBwcHJpbnQocmVzcG9uc2UsIGluZGVudD0yKQorICAgICMgcmVzcG9uc2UgPSBwdXRfb2JzZXJ2YXRpb25fZmllbGRfdmFsdWVzKAorICAgICMgICAgIG9ic2VydmF0aW9uX2lkPXRlc3Rfb2JzX2lkLAorICAgICMgICAgIG9ic2VydmF0aW9uX2ZpZWxkX2lkPTI5NywKKyAgICAjICAgICB2YWx1ZT0yLAorICAgICMgICAgIGFjY2Vzc190b2tlbj10b2tlbiwKKyAgICAjICkKKyAgICAjIHByaW50KCJBZGRlZCBvYnNlcnZhdGlvbiBmaWVsZCB2YWx1ZToiKQorICAgICMgcHByaW50KHJlc3BvbnNlLCBpbmRlbnQ9MikKIAogCiBkZWYgZGVsZXRlX3Rlc3Rfb2JzKHRlc3Rfb2JzX2lkLCB0b2tlbik6CmRpZmYgLS1naXQgYS90ZXN0L3Rlc3RfcmVxdWVzdF9wYXJhbXMucHkgYi90ZXN0L3Rlc3RfcmVxdWVzdF9wYXJhbXMucHkKaW5kZXggODg3MWE3ZC4uZDk2ZmM0YSAxMDA2NDQKLS0tIGEvdGVzdC90ZXN0X3JlcXVlc3RfcGFyYW1zLnB5CisrKyBiL3Rlc3QvdGVzdF9yZXF1ZXN0X3BhcmFtcy5weQpAQCAtMSwzICsxLDQgQEAKK2ltcG9ydCBvcwogaW1wb3J0IHB5dGVzdAogZnJvbSBkYXRldGltZSBpbXBvcnQgZGF0ZSwgZGF0ZXRpbWUKIGZyb20gZGF0ZXV0aWwudHogaW1wb3J0IGdldHR6CkBAIC0xOSw4ICsyMCw3IEBAIGZyb20gcHlpbmF0dXJhbGlzdC5yZXF1ZXN0X3BhcmFtcyBpbXBvcnQgKAogKQogaW1wb3J0IHB5aW5hdHVyYWxpc3QucmVzdF9hcGkKIGltcG9ydCBweWluYXR1cmFsaXN0Lm5vZGVfYXBpCi1mcm9tIHRlc3QuY29uZnRlc3QgaW1wb3J0IGdldF9tb2R1bGVfaHR0cF9mdW5jdGlvbnMsIGdldF9tb2NrX2FyZ3NfZm9yX3NpZ25hdHVyZQotCitmcm9tIHRlc3QuY29uZnRlc3QgaW1wb3J0IE1PQ0tfQ1JFRFMsIGdldF9tb2R1bGVfaHR0cF9mdW5jdGlvbnMsIGdldF9tb2NrX2FyZ3NfZm9yX3NpZ25hdHVyZQogCiBURVNUX1BBUkFNUyA9IHsKICAgICAiaXNfYWN0aXZlIjogRmFsc2UsCkBAIC0xNTUsNiArMTU1LDcgQEAgZGVmIHRlc3RfYWxsX25vZGVfcmVxdWVzdHNfdXNlX3BhcmFtX2NvbnZlcnNpb24oCiBAcHl0ZXN0Lm1hcmsucGFyYW1ldHJpemUoCiAgICAgImh0dHBfZnVuY3Rpb24iLCBnZXRfbW9kdWxlX2h0dHBfZnVuY3Rpb25zKHB5aW5hdHVyYWxpc3QucmVzdF9hcGkpLnZhbHVlcygpCiApCitAcGF0Y2guZGljdChvcy5lbnZpcm9uLCBNT0NLX0NSRURTKQogQHBhdGNoKCJweWluYXR1cmFsaXN0LnJlc3RfYXBpLmNvbnZlcnRfbGF0X2xvbmdfdG9fZmxvYXQiKQogQHBhdGNoKCJweWluYXR1cmFsaXN0LnJlc3RfYXBpLnNsZWVwIikKIEBwYXRjaCgicHlpbmF0dXJhbGlzdC5hcGlfcmVxdWVzdHMucHJlcHJvY2Vzc19yZXF1ZXN0X3BhcmFtcyIpCmRpZmYgLS1naXQgYS90ZXN0L3Rlc3RfcmVzdF9hcGkucHkgYi90ZXN0L3Rlc3RfcmVzdF9hcGkucHkKaW5kZXggOTE0M2M4Mi4uYmNmMTQ3YSAxMDA2NDQKLS0tIGEvdGVzdC90ZXN0X3Jlc3RfYXBpLnB5CisrKyBiL3Rlc3QvdGVzdF9yZXN0X2FwaS5weQpAQCAtMSw2ICsxLDcgQEAKIGZyb20gZGF0ZXRpbWUgaW1wb3J0IGRhdGV0aW1lLCB0aW1lZGVsdGEKIGZyb20gaW8gaW1wb3J0IEJ5dGVzSU8KIGZyb20gdW5pdHRlc3QubW9jayBpbXBvcnQgcGF0Y2gKK2ltcG9ydCBvcwogCiBpbXBvcnQgcHl0ZXN0CiBmcm9tIHJlcXVlc3RzIGltcG9ydCBIVFRQRXJyb3IKQEAgLTE5LDcgKzIwLDcgQEAgZnJvbSBweWluYXR1cmFsaXN0LnJlc3RfYXBpIGltcG9ydCAoCiAgICAgZGVsZXRlX29ic2VydmF0aW9uLAogKQogZnJvbSBweWluYXR1cmFsaXN0LmV4Y2VwdGlvbnMgaW1wb3J0IEF1dGhlbnRpY2F0aW9uRXJyb3IsIE9ic2VydmF0aW9uTm90Rm91bmQKLWZyb20gdGVzdC5jb25mdGVzdCBpbXBvcnQgbG9hZF9zYW1wbGVfZGF0YQorZnJvbSB0ZXN0LmNvbmZ0ZXN0IGltcG9ydCBNT0NLX0NSRURTLCBsb2FkX3NhbXBsZV9kYXRhCiAKIFBBR0VfMV9KU09OX1JFU1BPTlNFID0gbG9hZF9zYW1wbGVfZGF0YSgiZ2V0X29ic2VydmF0aW9uX2ZpZWxkc19wYWdlMS5qc29uIikKIFBBR0VfMl9KU09OX1JFU1BPTlNFID0gbG9hZF9zYW1wbGVfZGF0YSgiZ2V0X29ic2VydmF0aW9uX2ZpZWxkc19wYWdlMi5qc29uIikKQEAgLTEyNyw3ICsxMjgsNjIgQEAgZGVmIHRlc3RfcHV0X29ic2VydmF0aW9uX2ZpZWxkX3ZhbHVlcyhyZXF1ZXN0c19tb2NrKToKICAgICBhc3NlcnQgclsidmFsdWUiXSA9PSAiZm91cmFnaW5nIgogCiAKLWRlZiB0ZXN0X2dldF9hY2Nlc3NfdG9rZW5fZmFpbChyZXF1ZXN0c19tb2NrKToKK2FjY2VwdGVkX2pzb24gPSB7CisgICAgImFjY2Vzc190b2tlbiI6ICI2MDRlNWRmMzI5Yjk4ZWVjZDIyYmIwYTg0Zjg4YjY4IiwKKyAgICAidG9rZW5fdHlwZSI6ICJCZWFyZXIiLAorICAgICJzY29wZSI6ICJ3cml0ZSIsCit9CisKKworQHBhdGNoLmRpY3Qob3MuZW52aXJvbiwge30sIGNsZWFyPVRydWUpCitkZWYgdGVzdF9nZXRfYWNjZXNzX3Rva2VuKHJlcXVlc3RzX21vY2spOgorICAgIHJlcXVlc3RzX21vY2sucG9zdCgKKyAgICAgICAgZiJ7SU5BVF9CQVNFX1VSTH0vb2F1dGgvdG9rZW4iLAorICAgICAgICBqc29uPWFjY2VwdGVkX2pzb24sCisgICAgICAgIHN0YXR1c19jb2RlPTIwMCwKKyAgICApCisKKyAgICB0b2tlbiA9IGdldF9hY2Nlc3NfdG9rZW4oInZhbGlkX3VzZXJuYW1lIiwgInZhbGlkX3Bhc3N3b3JkIiwgInZhbGlkX2FwcF9pZCIsICJ2YWxpZF9hcHBfc2VjcmV0IikKKyAgICBhc3NlcnQgdG9rZW4gPT0gIjYwNGU1ZGYzMjliOThlZWNkMjJiYjBhODRmODhiNjgiCisKKworQHBhdGNoLmRpY3Qob3MuZW52aXJvbiwgTU9DS19DUkVEUykKK2RlZiB0ZXN0X2dldF9hY2Nlc3NfdG9rZW5fX2VudmFycyhyZXF1ZXN0c19tb2NrKToKKyAgICByZXF1ZXN0c19tb2NrLnBvc3QoCisgICAgICAgIGYie0lOQVRfQkFTRV9VUkx9L29hdXRoL3Rva2VuIiwKKyAgICAgICAganNvbj1hY2NlcHRlZF9qc29uLAorICAgICAgICBzdGF0dXNfY29kZT0yMDAsCisgICAgKQorCisgICAgdG9rZW4gPSBnZXRfYWNjZXNzX3Rva2VuKCkKKyAgICBhc3NlcnQgdG9rZW4gPT0gIjYwNGU1ZGYzMjliOThlZWNkMjJiYjBhODRmODhiNjgiCisKKworQHBhdGNoLmRpY3QoCisgICAgb3MuZW52aXJvbiwKKyAgICB7CisgICAgICAgICJJTkFUX1VTRVJOQU1FIjogInZhbGlkX3VzZXJuYW1lIiwKKyAgICAgICAgIklOQVRfUEFTU1dPUkQiOiAidmFsaWRfcGFzc3dvcmQiLAorICAgIH0sCispCitkZWYgdGVzdF9nZXRfYWNjZXNzX3Rva2VuX19taXhlZF9hcmdzX2FuZF9lbnZhcnMocmVxdWVzdHNfbW9jayk6CisgICAgcmVxdWVzdHNfbW9jay5wb3N0KAorICAgICAgICBmIntJTkFUX0JBU0VfVVJMfS9vYXV0aC90b2tlbiIsCisgICAgICAgIGpzb249YWNjZXB0ZWRfanNvbiwKKyAgICAgICAgc3RhdHVzX2NvZGU9MjAwLAorICAgICkKKworICAgIHRva2VuID0gZ2V0X2FjY2Vzc190b2tlbihhcHBfaWQ9InZhbGlkX2FwcF9pZCIsIGFwcF9zZWNyZXQ9InZhbGlkX2FwcF9zZWNyZXQiKQorICAgIGFzc2VydCB0b2tlbiA9PSAiNjA0ZTVkZjMyOWI5OGVlY2QyMmJiMGE4NGY4OGI2OCIKKworCitAcGF0Y2guZGljdChvcy5lbnZpcm9uLCB7fSwgY2xlYXI9VHJ1ZSkKK2RlZiB0ZXN0X2dldF9hY2Nlc3NfdG9rZW5fX21pc3NpbmdfY3JlZHMoKToKKyAgICB3aXRoIHB5dGVzdC5yYWlzZXMoQXV0aGVudGljYXRpb25FcnJvcik6CisgICAgICAgIGdldF9hY2Nlc3NfdG9rZW4oInVzZXJuYW1lIikKKworCitkZWYgdGVzdF9nZXRfYWNjZXNzX3Rva2VuX19pbnZhbGlkX2NyZWRzKHJlcXVlc3RzX21vY2spOgogICAgICIiIiBJZiB3ZSBwcm92aWRlIGluY29ycmVjdCBjcmVkZW50aWFscyB0byBnZXRfYWNjZXNzX3Rva2VuKCksIGFuIEF1dGhlbnRpY2F0aW9uRXJyb3IgaXMgcmFpc2VkIiIiCiAKICAgICByZWplY3Rpb25fanNvbiA9IHsKQEAgLTE0NywyNiArMjAzLDYgQEAgZGVmIHRlc3RfZ2V0X2FjY2Vzc190b2tlbl9mYWlsKHJlcXVlc3RzX21vY2spOgogICAgICAgICBnZXRfYWNjZXNzX3Rva2VuKCJ1c2VybmFtZSIsICJwYXNzd29yZCIsICJhcHBfaWQiLCAiYXBwX3NlY3JldCIpCiAKIAotZGVmIHRlc3RfZ2V0X2FjY2Vzc190b2tlbihyZXF1ZXN0c19tb2NrKToKLSAgICAiIiIgVGVzdCBhIHN1Y2Nlc3NmdWwgY2FsbCB0byBnZXRfYWNjZXNzX3Rva2VuKCkgIiIiCi0KLSAgICBhY2NlcHRlZF9qc29uID0gewotICAgICAgICAiYWNjZXNzX3Rva2VuIjogIjYwNGU1ZGYzMjliOThlZWNkMjJiYjBhODRmODhiNjhhMDc1YTAyM2FjNDM3ZjIzMTdiMDJmM2E5YmE0MTRhMDgiLAotICAgICAgICAidG9rZW5fdHlwZSI6ICJCZWFyZXIiLAotICAgICAgICAic2NvcGUiOiAid3JpdGUiLAotICAgICAgICAiY3JlYXRlZF9hdCI6IDE1MzkzNTIxMzUsCi0gICAgfQotICAgIHJlcXVlc3RzX21vY2sucG9zdCgKLSAgICAgICAgZiJ7SU5BVF9CQVNFX1VSTH0vb2F1dGgvdG9rZW4iLAotICAgICAgICBqc29uPWFjY2VwdGVkX2pzb24sCi0gICAgICAgIHN0YXR1c19jb2RlPTIwMCwKLSAgICApCi0KLSAgICB0b2tlbiA9IGdldF9hY2Nlc3NfdG9rZW4oInZhbGlkX3VzZXJuYW1lIiwgInZhbGlkX3Bhc3N3b3JkIiwgInZhbGlkX2FwcF9pZCIsICJ2YWxpZF9hcHBfc2VjcmV0IikKLQotICAgIGFzc2VydCB0b2tlbiA9PSAiNjA0ZTVkZjMyOWI5OGVlY2QyMmJiMGE4NGY4OGI2OGEwNzVhMDIzYWM0MzdmMjMxN2IwMmYzYTliYTQxNGEwOCIKLQotCiBkZWYgdGVzdF91cGRhdGVfb2JzZXJ2YXRpb24ocmVxdWVzdHNfbW9jayk6CiAgICAgcmVxdWVzdHNfbW9jay5wdXQoCiAgICAgICAgIGYie0lOQVRfQkFTRV9VUkx9L29ic2VydmF0aW9ucy8xNzkzMjQyNS5qc29uIiwK'\"'\"'))'",
      "git apply /tmp/receipts-niconoe__pyinaturalist-72-test.patch"
    ],
    "workdir": "/pyinaturalist"
  },
  "spec_paths": [
    "test/conftest.py",
    "test/manual_tests/obs_crud_test.py",
    "test/test_request_params.py",
    "test/test_rest_api.py"
  ],
  "spec_tests": [
    "test/test_rest_api.py::test_get_access_token__envars",
    "test/test_rest_api.py::test_get_access_token__mixed_args_and_envars",
    "test/test_rest_api.py::test_get_access_token__missing_creds"
  ],
  "suite_scope": "--no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning test/conftest.py test/manual_tests/obs_crud_test.py test/test_request_params.py test/test_rest_api.py"
}
