Skip to content

get SafetyLevel for individual photo #173

Open

Description

@rodmur

Is there a way to query an individual photo's safety level? I don't see a call for that in the Flickr API. They have flickr.photos.setSafetyLevel but no flickr.photos.getSafetyLevel. Basically I want to find all photos with a specific tag, test the safety level, and if it's not set to what I want, then set it.

Activity

  1. beaufour commented on Jul 1, 2026

    @beaufour
    Collaborator

    Hi @rodmur — you're right that there's no flickr.photos.getSafetyLevel endpoint, but the safety level is returned by flickr.photos.getInfo (and by search with extras="safety_level"), so you can read it without any new code.

    With the currently released version

    Load the photo (which calls getInfo under the hood) and read the safety_level attribute. Note it comes back as a string ("0", "1", "2", "3"):

    photo = flickr_api.Photo(id="12345")
    photo.load()
    print(photo.safety_level)   # e.g. "3"

    For your exact use case — find photos by tag, check the level, fix it if wrong — ask search to include the value via extras so you don't need a separate getInfo call per photo:

    for p in flickr_api.Photo.search(tags="mytag", extras="safety_level"):
        if p.safety_level != "3":            # string comparison, or int(p.safety_level)
            p.setSafetyLevel(safety_level=3)

    With the latest code (PR #174, now merged)

    There's now a Photo.getSafetyLevel() helper, and safety_level is converted to an int automatically, so you don't have to deal with strings:

    for p in flickr_api.Photo.search(tags="mytag", extras="safety_level"):
        if p.getSafetyLevel() != 3:         # returns int: 0=none, 1=safe, 2=moderate, 3=restricted
            p.setSafetyLevel(safety_level=3)

    getSafetyLevel() also loads the photo for you if the value isn't already present, so flickr_api.Photo(id="12345").getSafetyLevel() works directly. The integer values match what setSafetyLevel accepts.

    Hope that helps!

  2. rodmur commented on Jul 4, 2026

    @rodmur
    Author

    Thanks! I'm not all that expert with git, how do I build this? I've cloned the repo, but just running make gives me

    ` python-flickr-api git:(master) make
    bash ./release.sh

    • rm -rf ./dist
      ++ uv run python -c 'from flickr_api._version import version as v; print(v)'
    • VERSION=0.8.0
    • git tag v0.8.0
      fatal: tag 'v0.8.0' already exists
      make: *** [release] Error 128
      `

    Should I increment that tab? Or should I just wait for a new release?

    I realize now, I should probably be using uv build, and maybe uv pip install?

  3. beaufour commented on Jul 5, 2026

    @beaufour
    Collaborator

    No sweat. I just released 0.8.1, so you should be able to just install that.

  4. rodmur commented on Jul 6, 2026

    @rodmur
    Author

    Thanks, upgraded.

    I've done a little bit of testing, and off hand it appears getSafetyLevel() returns 0=safe, 1=moderate, 2=restricted, but if you want to set the safety level, setSafetyLevel(safety_level=#) needs 1=safe, 2=moderate, 3=restricted. So everything is offset by 1.

    Also I get to a point where flickr_api.Photo.search() just seems to be loading the same set or page of photos over and over again, is there way to get it to advance? I do provide it a "page=p" argument, but it seems to be ignoring it, like it hit some max and can't continue.

  5. beaufour commented on Jul 7, 2026

    @beaufour
    Collaborator

    Good catches. Thanks for testing!! Two different things going on:

    Safety level. You're right about the offset, but it's not a bug on either side. Flickr's own API is asymmetric: getInfo/search report the level 0-indexed (0=safe, 1=moderate, 2=restricted), while setSafetyLevel wants it 1-indexed (1/2/3). This wrapper passes both through unchanged on purpose, so you inherit Flickr's mismatch. My fault was the 0.8.1 docstring claiming they matched. I've corrected in #175. To round-trip, add one:

    if p.getSafetyLevel() != 2:                     # 2 == restricted (0-indexed)
        p.setSafetyLevel(safety_level=p.getSafetyLevel() + 1)

    Pagination. The library does pass page= through. What you hit is a Flickr limit: flickr.photos.search only lets you page through roughly the first 4,000 results, then keeps returning the last reachable page. The workaround is to narrow each query (e.g. slice by min_upload_date/max_upload_date and walk the windows, with sort="date-posted-asc" for stable ordering) so no single query exceeds the cap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions