Jump to content

make a new user and set access to a library by API


Recommended Posts

Posted (edited)

I have an Emby server running on Ubuntu 22.04, and I’m coding a Python 3.10 Telegram bot to grab YouTube video URLs and download them to the server. Through my Emby server, I want each user to have access to their own folder for managing their files.

i created a library for my private users with name MYUSERS so

My specific challenge is this: When a user (e.g., “test”) sends a message to my bot, my code creates a folder for them on the server, like this: /usr/share/vids/12345

The number “12345” corresponds to the Telegram chat ID for each user. Now, I need to create a user with the name “12345” and set up access for them via the Emby API so that they can only see the path /usr/share/vids/12345.

Actually we need set user access to a library and add this path by API in this library ( MYUSERS) and set access to this library for my each users by API 

How can I achieve this? I’m interested in setting up access and permissions for both the user and the libraries.

 

Edited by maysam
Posted

Hi, have you tried using the browser debugger to monitor the requests that the web app sends to do this?

As we don't have new user creation well documented right now, this is probably your best way to learn.

Happy2Play
Posted

Sound like the same method that was discussed here minus the payload issue.

 

Posted
On 7/11/2024 at 8:41 PM, Luke said:

Hi, have you tried using the browser debugger to monitor the requests that the web app sends to do this?

As we don't have new user creation well documented right now, this is probably your best way to learn.

yes and i didn't understand  anything to debug and change codes to solve it .   But i think it should be easy to make a  user and make some access for it to library's 

also, I can't even add a folder to my libraries by API . 

i just need some python codes to do it simply and i tried for this issue for several days and my project stopped because of this  Ridiculous issue 

Happy2Play
Posted

The linked topic already covers it as you create a user then you adjust policy ie the entire payload setting access to created library.  Just need to know the quid to apply in "EnabledFolders".

Posted (edited)
13 minutes ago, Happy2Play said:

The linked topic already covers it as you create a user then you adjust policy ie the entire payload setting access to created library.  Just need to know the quid to apply in "EnabledFolders".

thanks. im using this code and make a user and access for it to lib but it doesnt owrk

 

import requests
import sys

# Get user_id and password from command-line arguments
if len(sys.argv) != 3:
    print("Usage: mkuser.py <user_id> <password>")
    sys.exit(1)

user_id = sys.argv[1]
password = sys.argv[2]

# Define the Emby server URL and API key
emby_url = '******************'
api_key = '**********************' 

# Create a new user
create_user_url = f'{emby_url}/Users/New'
headers = {
    'X-Emby-Token': api_key,
    'Content-Type': 'application/json'
}
create_payload = {
    'Name': user_id
}
response = requests.post(create_user_url, headers=headers, json=create_payload)
response.raise_for_status()
user_id_response = response.json()['Id']
print(f"User '{user_id}' created successfully with ID: {user_id_response}")

# Set the password for the created user
set_password_url = f'{emby_url}/Users/{user_id_response}/Password'
password_payload = {
    'CurrentPw': None,  # Use None if setting the password for the first time
    'NewPw': password
}
response = requests.post(set_password_url, headers=headers, json=password_payload)
response.raise_for_status()
print(f"Password for user '{user_id}' set successfully to '{password}'")

# Restrict user's access to all libraries
user_policy_url = f'{emby_url}/Users/{user_id_response}/Policy'
policy_payload = {
    "IsAdministrator": False,
    "IsHidden": False,
    "IsDisabled": False,
    "BlockedTags": [],
    "IsTagBlockingModeInclusive": False,
    "EnableUserPreferenceAccess": True,
    "AccessSchedules": [],
    "BlockUnratedItems": [],
    "EnableRemoteControlOfOtherUsers": False,
    "EnableSharedDeviceControl": False,
    "EnableLiveTvManagement": False,
    "EnableLiveTvAccess": False,
    "EnableMediaPlayback": True,
    "EnableAudioPlaybackTranscoding": True,
    "EnableVideoPlaybackTranscoding": True,
    "EnablePlaybackRemuxing": True,
    "EnableContentDeletion": False,
    "EnableContentDeletionFromFolders": [],
    "EnableContentDownloading": False,
    "EnableSyncTranscoding": False,
    "EnableMediaConversion": False,
    "EnabledDevices": [],
    "EnableAllDevices": False,
    "EnabledChannels": [],
    "EnableAllChannels": False,
    "EnabledFolders": [],
    "EnableAllFolders": False,
    "InvalidLoginAttemptCount": 0,
    "EnablePublicSharing": False,
    "BlockedMediaFolders": [],
    "BlockedChannels": [],
    "RemoteClientBitrateLimit": 0,
    "AuthenticationProviderId": "Emby.Server.Implementations.Library.DefaultAuthenticationProvider"
}

response = requests.post(user_policy_url, headers=headers, json=policy_payload)
response.raise_for_status()
print(f"Access to all libraries restricted for user '{user_id}'")
Edited by maysam
Happy2Play
Posted
4 minutes ago, maysam said:

im using this code and make a user and access for it to lib but it doesnt owrk

What does not work as you are not giving access to any folders.

"EnabledFolders": [],

But you have the same issue as other topic and cannot have this.

"BlockedMediaFolders": [],

 

So access nothing, but access all contradicts itself.

Happy2Play
Posted

Need to assign EnabledFolders and remove BlockedMediaFolders.

Posted

"EnabledFolders": [],

do u mean something like this : "EnabledFolders": "/usr/shar/12345"   ?

i think i tested it before but doesnt work 

if u can send a proper code like this 

Happy2Play
Posted
2 minutes ago, maysam said:

"EnabledFolders": [],

do u mean something like this : "EnabledFolders": "/usr/shar/12345"   ?

i think i tested it before but doesnt work 

if u can send a proper code like this 

No when you add a library/folder in Emby it will get a ItemID and Guid and that Guid you want the user to have access to goes in EnabledFolders.

 

This is were I am a little confused as to what content type you will make this per say user folder as a library for them to access.  I will guess Mixed content but have no idea the structure of this user folder if you will break it down with specific media type folders or just dump media into this folder.

 

Posted (edited)
11 minutes ago, Happy2Play said:

No when you add a library/folder in Emby it will get a ItemID and Guid and that Guid you want the user to have access to goes in EnabledFolders.

 

Okay i'll try to make some changes in my code and test it again. Thanks a lot 

I'm using downloaded .mp4 from youtube by telegram bot on my server  and save them in a folder  and need to share this files for each user by the users telegram token ID and every user should see only its downloaded videos (its folder that i need share by library ) so need to make 1 lib and add several folder paths when a new user sends request to download new file for first time)

Edited by maysam
Happy2Play
Posted
1 minute ago, maysam said:

Okay i'll try to make some changes in my code and test it again. Thanks a lot 

I'm using downloaded .mp4 from youtube by telegram bot on my server  and save them in a folder  and need to share this files for each user by the users telegram token ID and every user should see only its downloaded videos 

So what type of library are making for these user folders?  I will guess Home Video and Photo library would be the most appropriate as the content will most likely have no online metadata providers.

But in the end you will need the Guid for the user folder/library.

Posted

im using movies type library .Does this make problem? (lib type)

Posted (edited)

i update my code to set library access ( lib name = bbb for a test user) by this code 

# Get library ID for the library named 'bbb'
libraries_url = f'{emby_url}/Library/Sections'
response = requests.get(libraries_url, headers=headers)
libraries = response.json()

library_id = None
for library in libraries:
    if library['Name'] == 'bbb':
        library_id = library['Id']
        break

if library_id:
    print(f'Library ID for bbb: {library_id}')
else:
    print('Library bbb not found')
    exit(1)

# Set user access to the library
policy_url = f'{emby_url}/Users/{user_id}/Policy'
policy_data = {
    'IsAdministrator': False,
    'IsHidden': False,
    'IsDisabled': False,
    'BlockedTags': [],
    'IsTagBlockingModeInclusive': False,
    'EnableUserPreferenceAccess': True,
    'EnableRemoteControlOfOtherUsers': False,
    'EnableSharedDeviceControl': False,
    'EnableLiveTvManagement': False,
    'EnableLiveTvAccess': False,
    'EnableMediaPlayback': True,
    'EnableAudioPlaybackTranscoding': True,
    'EnableVideoPlaybackTranscoding': True,
    'EnablePlaybackRemuxing': True,
    'EnableContentDeletion': False,
    'EnableContentDownloading': True,
    'EnableSyncTranscoding': True,
    'EnableSync': True,
    'EnableMediaConversion': True,
    'EnabledFolders': [library_id]
}

response = requests.post(policy_url, json=policy_data, headers=headers)

if response.status_code == 204:
    print('Library access set successfully')
else:
    print('Error setting library access:', response.json())

 

and got this error

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/requests/models.py", line 974, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/jet/em.py", line 24, in <module>
    print('Error creating user:', response.json())
  File "/usr/local/lib/python3.10/dist-packages/requests/models.py", line 978, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

and search it in google 

 

The error you're encountering suggests that the response from the server when trying to get the library sections is not a valid JSON. This can happen for various reasons, such as the server returning an empty response, an error page, or a non-JSON response.

To diagnose and handle this issue, you can add some debug prints and checks in your script to understand what the server is returning.

Here's a modified version of your script with additional debug prints and error handling:

 

and changed some lines in my code and again a recived this error : 

Error fetching libraries: HTTP 404 The file &#39;/Library/Sections&#39; cound not be found

 

this is my full code attached here in python . that make a test user password=123 and should access test to library bbb

 

makeus.py

Edited by maysam
Happy2Play
Posted

Don't really know anything about this but you need the library Guid shown in /Library/VirtualFolders/Query endpoint for the library you created.

But only issue I see with a Movie content type library is enabled metadata providers unless you are pushing libraryoptions with all providers disabled.  I believe you are better off with Home Video Library content type.

but example of a library in  library query so I would end up with 'EnabledFolders': ['b8bedd70753af29241b670ac10cfb8ac'] to apply this library to said user.

Spoiler

{
      "Name": "Movies - Kids",
      "Locations": [
        "Z:\\ServerFolders\\Videos\\Movies - Kids"
      ],
      "CollectionType": "movies",
      "LibraryOptions": {
        "EnableArchiveMediaFiles": false,
        "EnablePhotos": true,
        "EnableRealtimeMonitor": true,
        "EnableMarkerDetection": false,
        "EnableMarkerDetectionDuringLibraryScan": false,
        "IntroDetectionFingerprintLength": 10,
        "EnableChapterImageExtraction": true,
        "ExtractChapterImagesDuringLibraryScan": true,
        "DownloadImagesInAdvance": true,
        "CacheImages": false,
        "PathInfos": [
          {
            "Path": "Z:\\ServerFolders\\Videos\\Movies - Kids"
          }
        ],
        "IgnoreHiddenFiles": false,
        "IgnoreFileExtensions": [],
        "SaveLocalMetadata": true,
        "SaveMetadataHidden": false,
        "SaveLocalThumbnailSets": true,
        "ImportPlaylists": true,
        "EnableAutomaticSeriesGrouping": true,
        "ShareEmbeddedMusicAlbumImages": true,
        "EnableEmbeddedTitles": false,
        "EnableAudioResume": false,
        "AutoGenerateChapters": true,
        "AutomaticRefreshIntervalDays": 0,
        "PlaceholderMetadataRefreshIntervalDays": 0,
        "PreferredMetadataLanguage": "",
        "PreferredImageLanguage": "",
        "ContentType": "movies",
        "MetadataCountryCode": "",
        "MetadataSavers": [],
        "DisabledLocalMetadataReaders": [],
        "LocalMetadataReaderOrder": [
          "Emby Xml",
          "Nfo"
        ],
        "DisabledLyricsFetchers": [],
        "SaveLyricsWithMedia": true,
        "LyricsDownloadMaxAgeDays": 180,
        "LyricsFetcherOrder": [],
        "LyricsDownloadLanguages": [],
        "DisabledSubtitleFetchers": [
          "Open Subtitles"
        ],
        "SubtitleFetcherOrder": [
          "Open Subtitles"
        ],
        "SkipSubtitlesIfEmbeddedSubtitlesPresent": false,
        "SkipSubtitlesIfAudioTrackMatches": true,
        "SubtitleDownloadLanguages": [],
        "SubtitleDownloadMaxAgeDays": 180,
        "RequirePerfectSubtitleMatch": true,
        "SaveSubtitlesWithMedia": true,
        "ForcedSubtitlesOnly": false,
        "HearingImpairedSubtitlesOnly": false,
        "TypeOptions": [
          {
            "Type": "Movie",
            "MetadataFetchers": [
              "TheMovieDb",
              "The Open Movie Database",
              "TheTVDB"
            ],
            "MetadataFetcherOrder": [
              "TheMovieDb",
              "The Open Movie Database",
              "TheTVDB"
            ],
            "ImageFetchers": [
              "FanArt",
              "TheMovieDb",
              "TheTVDB",
              "Image Capture"
            ],
            "ImageFetcherOrder": [
              "FanArt",
              "TheMovieDb",
              "TheTVDB",
              "Image Capture",
              "The Open Movie Database"
            ],
            "ImageOptions": [
              {
                "Type": "Primary",
                "Limit": 1,
                "MinWidth": 0
              },
              {
                "Type": "Art",
                "Limit": 1,
                "MinWidth": 0
              },
              {
                "Type": "Banner",
                "Limit": 1,
                "MinWidth": 0
              },
              {
                "Type": "Box",
                "Limit": 0,
                "MinWidth": 0
              },
              {
                "Type": "BoxRear",
                "Limit": 0,
                "MinWidth": 0
              },
              {
                "Type": "Disc",
                "Limit": 1,
                "MinWidth": 0
              },
              {
                "Type": "Logo",
                "Limit": 1,
                "MinWidth": 0
              },
              {
                "Type": "Menu",
                "Limit": 0,
                "MinWidth": 0
              },
              {
                "Type": "Thumb",
                "Limit": 1,
                "MinWidth": 0
              },
              {
                "Type": "Backdrop",
                "Limit": 1,
                "MinWidth": 1280
              }
            ]
          }
        ],
        "CollapseSingleItemFolders": false,
        "EnableAdultMetadata": false,
        "ImportCollections": true,
        "MinCollectionItems": 2,
        "MinResumePct": 5,
        "MaxResumePct": 90,
        "MinResumeDurationSeconds": 180,
        "ThumbnailImagesIntervalSeconds": 10,
        "SampleIgnoreSize": 314572800
      },
      "ItemId": "253615",
      "Id": "253615",
      "Guid": "b8bedd70753af29241b670ac10cfb8ac",
      "PrimaryImageItemId": "253615"
    }

 

Posted
Quote

Hi, have you tried using the browser debugger to monitor the requests that the web app sends to do this?

Hi, how do your requests differ from what the web app is sending?

  • 4 weeks later...
  • 6 months later...
Enrico1203
Posted (edited)
On 13/07/2024 at 08:30, maysam said:

i update my code to set library access ( lib name = bbb for a test user) by this code 

# Get library ID for the library named 'bbb'
libraries_url = f'{emby_url}/Library/Sections'
response = requests.get(libraries_url, headers=headers)
libraries = response.json()

library_id = None
for library in libraries:
    if library['Name'] == 'bbb':
        library_id = library['Id']
        break

if library_id:
    print(f'Library ID for bbb: {library_id}')
else:
    print('Library bbb not found')
    exit(1)

# Set user access to the library
policy_url = f'{emby_url}/Users/{user_id}/Policy'
policy_data = {
    'IsAdministrator': False,
    'IsHidden': False,
    'IsDisabled': False,
    'BlockedTags': [],
    'IsTagBlockingModeInclusive': False,
    'EnableUserPreferenceAccess': True,
    'EnableRemoteControlOfOtherUsers': False,
    'EnableSharedDeviceControl': False,
    'EnableLiveTvManagement': False,
    'EnableLiveTvAccess': False,
    'EnableMediaPlayback': True,
    'EnableAudioPlaybackTranscoding': True,
    'EnableVideoPlaybackTranscoding': True,
    'EnablePlaybackRemuxing': True,
    'EnableContentDeletion': False,
    'EnableContentDownloading': True,
    'EnableSyncTranscoding': True,
    'EnableSync': True,
    'EnableMediaConversion': True,
    'EnabledFolders': [library_id]
}

response = requests.post(policy_url, json=policy_data, headers=headers)

if response.status_code == 204:
    print('Library access set successfully')
else:
    print('Error setting library access:', response.json())

 

and got this error

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/requests/models.py", line 974, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/jet/em.py", line 24, in <module>
    print('Error creating user:', response.json())
  File "/usr/local/lib/python3.10/dist-packages/requests/models.py", line 978, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

and search it in google 

 

The error you're encountering suggests that the response from the server when trying to get the library sections is not a valid JSON. This can happen for various reasons, such as the server returning an empty response, an error page, or a non-JSON response.

To diagnose and handle this issue, you can add some debug prints and checks in your script to understand what the server is returning.

Here's a modified version of your script with additional debug prints and error handling:

 

and changed some lines in my code and again a recived this error : 

Error fetching libraries: HTTP 404 The file &#39;/Library/Sections&#39; cound not be found

 

this is my full code attached here in python . that make a test user password=123 and should access test to library bbb

 

makeus.py 3 kB · 3 downloads

The error is about this line:
 libraries_url = f'{emby_url}/Library/Sections'  

The url does not exist in the API. The correct and working one is:
 libraries_url = f'{emby_url}/Library/SelectableMediaFolders'

by doing a get request you get a json with all info you need:
[{'Name': 'xxxx', 'Id': '5', 'Guid': 'cxxxxxxxx4c21ecd', 'SubFolders': etc..

 

Edited by Enrico1203
  • Thanks 2
Posted

hi after 6 months again 

i make this codes to make users and set permission for access and its great now and work fine for my project :

i'll send it here if anyone need to use it leter

#  Created: 2024/07/04 12:24:41
# Last modified: 2024/08/15 00:49:27

import requests
import sys
from config import API_KEY, EMBY_URL

# Get user_id and password from command-line arguments
if len(sys.argv) != 3:
    print("Usage: mkuser.py <user_id> <password>")
    sys.exit(1)

user_id = sys.argv[1]
password = sys.argv[2]



try:
    # Create a new user
    create_user_url = f'{EMBY_URL}/Users/New'
    headers = {
        'X-Emby-Token': API_KEY,
        'Content-Type': 'application/json'
    }
    create_payload = {
        'Name': user_id
    }
    response = requests.post(create_user_url, headers=headers, json=create_payload)
    response.raise_for_status()
    user_id_response = response.json()['Id']
    print(f"User '{user_id}' created successfully with ID: {user_id_response}")

    # Set the password for the created user
    set_password_url = f'{EMBY_URL}/Users/{user_id_response}/Password'
    password_payload = {
        'CurrentPw': None,  # Use None if setting the password for the first time
        'NewPw': password
    }
    response = requests.post(set_password_url, headers=headers, json=password_payload)
    response.raise_for_status()
    print(f"Password for user '{user_id}' set successfully to '{password}'")

    # Restrict user's access to all libraries
    user_policy_url = f'{EMBY_URL}/Users/{user_id_response}/Policy'
    policy_payload = {
        "IsAdministrator": False,
        "IsHidden": False,
        "IsDisabled": False,
        "BlockedTags": [],
        "IsTagBlockingModeInclusive": False,
        "EnableUserPreferenceAccess": True,
        "AccessSchedules": [],
        "BlockUnratedItems": [],
        "EnableRemoteControlOfOtherUsers": False,
        "EnableSharedDeviceControl": False,
        "EnableLiveTvManagement": False,
        "EnableLiveTvAccess": False,
        "EnableMediaPlayback": True,
        "EnableAudioPlaybackTranscoding": True,
        "EnableVideoPlaybackTranscoding": True,
        "EnablePlaybackRemuxing": True,
        "EnableContentDeletion": False,
        "EnableContentDeletionFromFolders": [],
        "EnableContentDownloading": False,
        "EnableSyncTranscoding": False,
        "EnableMediaConversion": False,
        "EnabledDevices": [],
        "EnableAllDevices": True,
        "EnabledChannels": [],
        "EnableAllChannels": False,
        "EnabledFolders": False,
        "EnableAllFolders": False,
        "InvalidLoginAttemptCount": 0,
        "EnablePublicSharing": False,
        "BlockedMediaFolders": [],
        "BlockedChannels": [],
        "RemoteClientBitrateLimit": 0,
        "AuthenticationProviderId": "Emby.Server.Implementations.Library.DefaultAuthenticationProvider"
    }

    response = requests.post(user_policy_url, headers=headers, json=policy_payload)
    response.raise_for_status()
    print(f"Access to all libraries restricted for user '{user_id}'")
except requests.exceptions.HTTPError as e:
    print(f"HTTP error occurred: {e}")
    print(f"Response content: {response.text}")
    sys.exit(1)
except Exception as e:
    print(f"An error occurred: {e}")
    sys.exit(1)

 

  • Like 2
  • Thanks 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...