API Endpoints

insert_link API Endpoints

The API provides two ways of browsing the online catalog. Use the id (also known as magic number) for selective searches, or queries to hit a broader range of results. This is the right place if you want to learn more about how this library works.

info Note
Contrary to popular belief, magic numbers don't always consists of six digits. All doujin IDs are enumerated starting from \(1\). However, it is not possible to loop through all IDs without taking some precautions. Sometimes, doujins have been taken down due to DMCA copyright infringements or above-average disturbing imagery, as was the case with doujin \(215600\). In addition to that, France issued a ban for all its citizen as of 2020, requiring users of this nation to use a VPN to access this site, and by extension, utilize this library.

insert_link Hentai URL

Even though, strictly speaking, this is not part of the API, it's still important to note how one can redirect doujins to their URL:

            
                from urllib.parse import urljoin

                id = 177013

                # construct url from id
                url = urljoin('https://nhentai.net/g/', str(id))
            
        

See also the self.url property.

insert_link General Hentai Data

This is the most important API endpoint that contains almost all information available. See also the self.api and self.json properties.

            
                from urllib.parse import urljoin

                id = 177013

                # construct endpoint from id
                api = urljoin('https://nhentai.net/api/gallery/', str(id))
            
        
insert_link Cover Images

The cover image is constructed from the media ID and file extension. You can take a look at the implementation details from self.cover and Extension.convert to learn how to make this from scratch:

            
                @property
                def cover(self) -> str:
                    """
                    Return the cover URL of this `Hentai` object.
                    """
                    cover_ext = Extension.convert(self.json['images']['cover']['t'])
                    return f"https://t.nhentai.net/galleries/{self.media_id}/cover{cover_ext}"
            
        
insert_link Thumbnail Images

The thumbnail image is constructed from the media ID and file extension. You can take a look at the implementation details from self.thumbnail and Extension.convert to learn how to make this from scratch:

            
                @property
                def thumbnail(self) -> str:
                    """
                    Return the thumbnail URL of this `Hentai` object.
                    """
                    thumb_ext = Extension.convert(self.json['images']['thumbnail']['t'])
                    return f"https://t.nhentai.net/galleries/{self.media_id}/thumb{thumb_ext}"
            
        

The general Hentai API does not directly provide the image URLs, i.e. the doujin pages, in its initial response. They have to be constructed from the media ID, the filename and file extension. All file stems are iterated from \(1\) to len(self.json['images']['pages']). See below an example on how this is implemented in the self.image_urls property which in turn is based on the self.pages property that contains additional meta data such as image widths and image heights:

            
                @property
                def pages(self) -> List[Page]:
                    """
                    Return a collection of pages detailing URL, file extension, width and 
                    height of this `Hentai` object.
                    """
                    pages = self.json['images']['pages']
                    extension = lambda num: Extension.convert(pages[num]['t'])
                    image_url = lambda num: f"https://i.nhentai.net/galleries/{self.media_id}/{num}{extension(num - 1)}"
                    return [Page(image_url(num + 1), Extension.convert(_['t']), _['w'], _['h']) for num, _ in enumerate(pages)]

                @property
                def image_urls(self) -> List[str]:
                    """
                    Return all image URLs of this `Hentai` object, excluding cover and thumbnail.
                    """
                    return [image.url for image in self.pages]
            
        
insert_link Comments

The comment section of a doujin can be obtained by appending /comments to this doujin's API property that we discussed here. See also the self.thread property. Interestingly enough, the comment section also includes quite a lot information about the poster (user).

            
                from urllib.parse import urljoin

                id = 177013
        
                # construct endpoint from id
                api = urljoin('https://nhentai.net/api/gallery/', str(id))
                # get comment section endpoint for this id
                cmt_api = urljoin(api, '/comments')
            
        

A list of related doujins can be obtained by appending /related to this doujin's API property that we discussed here. See also the self.related property. This endpoint returns a list of five doujins; as far as I am aware, this list can change over time.

            
                from urllib.parse import urljoin

                id = 177013
        
                # construct endpoint from id
                api = urljoin('https://nhentai.net/api/gallery/', str(id))
                # get related endpoint for this id
                rlt_api = urljoin(api, '/related')
            
        
insert_link Search by Query

Search queries can yield more refined results by specifying the query, the page number and sort value. See also the Sort enum for the other known sort values. Each query returns as much as \(25\) doujins per page. You can skip the query value in the payload below to get doujins from the homepage.

            
                from hentai import RequestHandler

                payload = {'query': 'tag:loli', 'page': 1, 'sort': 'popular'}
                response = RequestHandler().get(url='https://nhentai.net/api/galleries/search', params=payload)

                # the result of this search query, i.e. the first page where tag=loli sorted by popular
                result = response.json()
            
        

Note that these methods are already implemented in the Utils class. Moreover, refer to this site for more information on search queries.

insert_link Search by Tag ID

Another search query makes use of Tag IDs that is accessed by yet another endpoint. This type of query also returns as much as \(25\) doujins per page.

            
                from hentai import RequestHandler

                # 33918 = character id of holo
                payload = {'tag_id': 33918, 'page': 1, 'sort': 'popular'}
                response = RequestHandler().get(urljoin(Hentai.HOME, "api/galleries/tagged"), params=payload)

                # the result of this search query, i.e. the first page where tag_id=33918 sorted by popular
                result = response.json()