api

package
v0.3.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2025 License: MIT Imports: 8 Imported by: 0

README

banned.video API Client

A comprehensive Go client library for the banned.video GraphQL API. This package provides a clean, type-safe interface for interacting with banned.video's content management system.

Features

  • Full GraphQL API Coverage: Complete client for banned.video's GraphQL API
  • Type-Safe Operations: Strongly typed Go structs for all API responses
  • Automatic Pagination: Built-in support for recursive data fetching
  • Concurrent Safe: Thread-safe client suitable for concurrent operations
  • Comprehensive Error Handling: Detailed error reporting with GraphQL error support
  • Flexible Configuration: Customizable timeouts, user agents, and base URLs
  • Helper Methods: Convenience methods for common operations
  • Extensive Examples: Complete usage examples and documentation

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/daniel-le97/banned-cli/api"
)

func main() {
    // Create a new API client
    client := api.New()

    ctx := context.Background()

    // Fetch all channels
    channels, err := client.Channels.GetAllChannels(ctx, 0, 10)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Found %d channels\n", len(channels))

    // Fetch videos from the first channel
    if len(channels) > 0 {
        videos, err := client.Channels.GetChannelVideos(ctx, channels[0].ID, 0, 5)
        if err != nil {
            log.Fatal(err)
        }

        fmt.Printf("Channel '%s' has %d videos\n", channels[0].Title, len(videos))
    }
}

API Structure

The client is organized into services for different resource types:

Core Client
  • Client: Low-level GraphQL client with connection management
  • API: High-level interface combining all services
Services
  • ChannelService: Channel management and video fetching
  • VideoService: Video operations and metadata retrieval

Channel Operations

Basic Channel Fetching
// Get all channels with pagination
channels, err := client.Channels.GetAllChannels(ctx, 0, 50)

// Get specific channel by ID
channel, err := client.Channels.GetChannel(ctx, "channel-id")

// Get channel with videos
params := api.ChannelVideosParams{
    ChannelID: "channel-id",
    IncludeUnlisted: false,
    IncludeUnpublished: false,
    IncludeLive: true,
    Offset: 0,
    Limit: 20,
}
channel, err := client.Channels.GetChannelWithVideos(ctx, params)
Recursive Video Fetching
// Fetch ALL videos from a channel (automatic pagination)
allVideos, err := client.Channels.FetchAllChannelVideos(ctx, "channel-id", 50)

// Fetch up to a specific limit
limitedVideos, err := client.Channels.FetchAllChannelVideosWithLimit(ctx, "channel-id", 1000, 50)

// Get hot videos from a channel
hotVideos, err := client.Channels.GetChannelHotVideos(ctx, "channel-id", 0, 10)

Video Operations

Basic Video Fetching
// Get specific video by ID
video, err := client.Videos.GetVideo(ctx, "video-id")

// Get multiple videos by IDs
videos, err := client.Videos.GetVideos(ctx, []string{"id1", "id2", "id3"})

// Get hot/trending videos
hotVideos, err := client.Videos.GetHotVideos(ctx, 0, 20)

// Get newest videos
newVideos, err := client.Videos.GetNewVideos(ctx, 0, 20)
Helper Methods
// Get download URLs from video
downloadURL := client.Videos.GetVideoDownloadURL(video)
posterURL := client.Videos.GetVideoPosterURL(video)
audioURL := client.Videos.GetVideoAudioURL(video)

Advanced Usage

Custom Configuration
import "time"

// Create client with custom settings
client := api.NewWithConfig(
    "https://api.banned.video/graphql",  // Base URL
    "my-app/2.0",                        // User Agent
    60 * time.Second,                    // Timeout
)

// Update settings after creation
client.SetTimeout(30 * time.Second)
client.SetUserAgent("updated-agent/1.0")
Bulk Operations
// Fetch multiple channels with their videos
channelIDs := []string{"id1", "id2", "id3"}
bulkData, err := client.BulkFetchChannelData(ctx, channelIDs, 10)

for _, channelData := range bulkData {
    fmt.Printf("Channel: %s, Videos: %d\n",
        channelData.Title, len(channelData.Videos))
}
Error Handling
channels, err := client.Channels.GetAllChannels(ctx, 0, 10)
if err != nil {
    // Handle GraphQL errors
    fmt.Printf("API Error: %v\n", err)
    return
}

// Check for empty results
if len(channels) == 0 {
    fmt.Println("No channels found")
    return
}

Data Types

Core Types
  • Channel: Complete channel information with metadata
  • Video: Full video details with uploads and statistics
  • AdminUser: Channel creator/admin information
  • Tag: Video categorization tags
  • Upload: File upload details (video, audio, poster)
  • Playlist: Channel playlist information
Utility Types
  • ChannelVideosParams: Parameters for channel video queries
  • Pagination: Pagination helper
  • VideosResponse: Video collection with metadata
  • ChannelsResponse: Channel collection with metadata

Configuration

Environment Variables
# Optional: Override default API endpoint
BANNED_API_URL="https://api.banned.video/graphql"

# Optional: Set default user agent
BANNED_USER_AGENT="my-app/1.0"
Client Configuration
// Default configuration
client := api.New()

// Custom configuration
client := api.NewWithConfig(
    "https://custom.api.url/graphql",
    "custom-agent/1.0",
    30 * time.Second,
)

// Get current configuration
info := client.GetAPIInfo()
fmt.Printf("Base URL: %s\n", info["base_url"])
fmt.Printf("User Agent: %s\n", info["user_agent"])
fmt.Printf("Timeout: %v\n", info["timeout"])

Performance Considerations

Pagination Best Practices
// Use appropriate batch sizes for your use case
const (
    SmallBatch  = 20   // Interactive applications
    MediumBatch = 50   // General purpose (recommended)
    LargeBatch  = 200  // Bulk operations
)

// For large datasets, use recursive fetching
videos, err := client.Channels.FetchAllChannelVideos(ctx, channelID, MediumBatch)
Rate Limiting
import "golang.org/x/time/rate"

// Implement rate limiting for bulk operations
limiter := rate.NewLimiter(rate.Limit(10), 1) // 10 requests per second

for _, channelID := range channelIDs {
    limiter.Wait(ctx) // Wait for rate limit
    videos, err := client.Channels.GetChannelVideos(ctx, channelID, 0, 50)
    // Process videos...
}

Testing

Unit Tests
go test ./api
Integration Tests
# Set environment variable for integration tests
export BANNED_INTEGRATION_TEST=true
go test ./api -tags=integration

Error Types

The client provides detailed error information:

_, err := client.Videos.GetVideo(ctx, "invalid-id")
if err != nil {
    // GraphQL errors contain detailed information
    fmt.Printf("Error: %v\n", err)
}
Common Error Scenarios
  • Network Errors: Connection timeouts, DNS failures
  • HTTP Errors: 4xx/5xx status codes
  • GraphQL Errors: Invalid queries, missing resources
  • Validation Errors: Invalid parameters, malformed IDs

Examples

See examples.go for comprehensive usage examples including:

  • Basic API operations
  • Recursive data fetching
  • Batch processing
  • Error handling patterns
  • Performance optimization

Dependencies

This package uses only Go standard library dependencies:

  • context: Context handling
  • encoding/json: JSON marshaling/unmarshaling
  • net/http: HTTP client
  • time: Timeout management

License

This API client is part of the banned-cli project and follows the same MIT license.

Contributing

  1. Follow Go best practices and conventions
  2. Add tests for new functionality
  3. Update documentation for API changes
  4. Ensure backward compatibility when possible

Changelog

v1.0.0
  • Initial release
  • Complete GraphQL API coverage
  • Channel and video services
  • Recursive pagination support
  • Comprehensive error handling
  • Helper methods for common operations

Documentation

Overview

Package api provides a complete GraphQL client for banned.video API

Index

Constants

View Source
const GetAllChannelsQuery = `` /* 377-byte string literal not displayed */
View Source
const GetChannelHotVideosQuery = `` /* 362-byte string literal not displayed */
View Source
const GetChannelQuery = `` /* 407-byte string literal not displayed */
View Source
const GetChannelWithVideosQuery = `` /* 629-byte string literal not displayed */
View Source
const GetChannelsQuery = `` /* 218-byte string literal not displayed */
View Source
const GetHotVideosQuery = `` /* 284-byte string literal not displayed */
View Source
const GetNewVideosQuery = `` /* 284-byte string literal not displayed */
View Source
const GetVideoQuery = `` /* 236-byte string literal not displayed */
View Source
const GetVideosQuery = `` /* 244-byte string literal not displayed */

Variables

This section is empty.

Functions

func Example

func Example()

Example demonstrates how to use the banned.video API client

func ExampleBatchProcessing

func ExampleBatchProcessing()

ExampleBatchProcessing shows how to process large amounts of data efficiently

Types

type API

type API struct {
	Client   *Client
	Channels *ChannelService
	Videos   *VideoService
}

API provides a high-level interface to the banned.video GraphQL API

func New

func New() *API

New creates a new API instance with default configuration

func NewWithConfig

func NewWithConfig(baseURL, userAgent string, timeout time.Duration) *API

NewWithConfig creates a new API instance with custom configuration

func (*API) BulkFetchChannelData

func (a *API) BulkFetchChannelData(ctx context.Context, channelIDs []string, videoLimit int) (map[string]*Channel, error)

BulkFetchChannelData fetches multiple channels with their videos in parallel

func (*API) GetAPIInfo

func (a *API) GetAPIInfo() map[string]interface{}

GetAPIInfo returns information about the API client

func (*API) Ping

func (a *API) Ping(ctx context.Context) error

Ping tests the API connection

func (*API) SearchChannels

func (a *API) SearchChannels(ctx context.Context, query string) ([]Channel, error)

SearchChannels searches for channels by title (basic implementation) Note: This might need to be adjusted based on actual search capabilities in the API

func (*API) SetTimeout

func (a *API) SetTimeout(timeout time.Duration)

SetTimeout updates the HTTP timeout for API requests

func (*API) SetUserAgent

func (a *API) SetUserAgent(userAgent string)

SetUserAgent updates the user agent for API requests

type AdminUser

type AdminUser struct {
	ID          string     `json:"_id"`
	Email       string     `json:"email"`
	DisplayName string     `json:"displayName"`
	CreatedAt   *time.Time `json:"createdAt"`
	UpdatedAt   *time.Time `json:"updatedAt"`
}

AdminUser represents an admin user

type Channel

type Channel struct {
	ID              string        `json:"_id"`
	Title           string        `json:"title"`
	Summary         string        `json:"summary"`
	TextInfo        string        `json:"textInfo"`
	FeaturedVideo   *Video        `json:"featuredVideo"`
	LiveStreamVideo *Video        `json:"liveStreamVideo"`
	AlwaysLive      bool          `json:"alwaysLive"`
	IsLive          bool          `json:"isLive"`
	Avatar          string        `json:"avatar"`
	CoverImage      string        `json:"coverImage"`
	Creator         *AdminUser    `json:"creator"`
	TotalVideoViews float64       `json:"totalVideoViews"`
	TotalLikes      float64       `json:"totalLikes"`
	Playlists       []Playlist    `json:"playlists"`
	PlaylistOrder   []string      `json:"playlistOrder"`
	TotalVideos     float64       `json:"totalVideos"`
	TotalPlaylists  float64       `json:"totalPlaylists"`
	Links           *ChannelLinks `json:"links"`
	LastUpload      *time.Time    `json:"lastUpload"`
	CreatedAt       *time.Time    `json:"createdAt"`
	UpdatedAt       *time.Time    `json:"updatedAt"`
	Videos          []Video       `json:"videos,omitempty"`
}

Channel represents a banned.video channel

type ChannelLinks struct {
	Website       string `json:"website"`
	Facebook      string `json:"facebook"`
	Twitter       string `json:"twitter"`
	Gab           string `json:"gab"`
	Minds         string `json:"minds"`
	Telegram      string `json:"telegram"`
	SubscribeStar string `json:"subscribeStar"`
}

ChannelLinks represents channel social links

type ChannelService

type ChannelService struct {
	// contains filtered or unexported fields
}

ChannelService provides methods for interacting with channels

func NewChannelService

func NewChannelService(client *Client) *ChannelService

NewChannelService creates a new channel service

func (*ChannelService) FetchAllChannelVideos

func (s *ChannelService) FetchAllChannelVideos(ctx context.Context, channelID string, batchSize int) ([]Video, error)

FetchAllChannelVideos recursively fetches all videos from a channel with pagination

func (*ChannelService) FetchAllChannelVideosWithLimit

func (s *ChannelService) FetchAllChannelVideosWithLimit(ctx context.Context, channelID string, maxVideos, batchSize int) ([]Video, error)

FetchAllChannelVideosWithLimit recursively fetches videos with a maximum limit

func (*ChannelService) GetAllChannels

func (s *ChannelService) GetAllChannels(ctx context.Context, offset, limit int) ([]Channel, error)

GetAllChannels fetches all channels with pagination

func (*ChannelService) GetChannel

func (s *ChannelService) GetChannel(ctx context.Context, channelID string) (*Channel, error)

GetChannel fetches a specific channel by ID

func (*ChannelService) GetChannelHotVideos

func (s *ChannelService) GetChannelHotVideos(ctx context.Context, channelID string, offset, limit int) ([]Video, error)

GetChannelHotVideos fetches hot/trending videos from a specific channel

func (*ChannelService) GetChannelVideos

func (s *ChannelService) GetChannelVideos(ctx context.Context, channelID string, offset, limit int) ([]Video, error)

GetChannelVideos fetches videos from a specific channel (convenience method)

func (*ChannelService) GetChannelWithVideos

func (s *ChannelService) GetChannelWithVideos(ctx context.Context, params ChannelVideosParams) (*Channel, error)

GetChannelWithVideos fetches a channel with its videos

type ChannelVideosParams

type ChannelVideosParams struct {
	ChannelID          string
	IncludeUnlisted    bool
	IncludeUnpublished bool
	IncludeLive        bool
	Offset             int
	Limit              int
}

ChannelVideosParams represents parameters for fetching channel videos

type ChannelsResponse

type ChannelsResponse struct {
	Channels   []Channel `json:"channels"`
	TotalCount int       `json:"totalCount,omitempty"`
	HasMore    bool      `json:"hasMore,omitempty"`
}

ChannelsResponse represents a response containing channels

type Client

type Client struct {
	BaseURL    string
	HTTPClient *http.Client
	UserAgent  string
}

Client represents the GraphQL API client

func NewClient

func NewClient() *Client

NewClient creates a new API client with default settings

func NewClientWithConfig

func NewClientWithConfig(baseURL, userAgent string, timeout time.Duration) *Client

NewClientWithConfig creates a new API client with custom configuration

func (*Client) Execute

func (c *Client) Execute(ctx context.Context, req *GraphQLRequest) (*GraphQLResponse, error)

Execute performs a GraphQL query and returns the response

func (*Client) ExecuteWithResult

func (c *Client) ExecuteWithResult(ctx context.Context, req *GraphQLRequest, result interface{}) error

ExecuteWithResult performs a GraphQL query and unmarshals the result

type Comment

type Comment struct {
	ID        string     `json:"_id"`
	Name      string     `json:"name"`
	User      *User      `json:"user"`
	Video     *Video     `json:"video"`
	Parent    *Comment   `json:"parent"`
	Replies   []Comment  `json:"replies"`
	LikeCount float64    `json:"likeCount"`
	CreatedAt *time.Time `json:"createdAt"`
	UpdatedAt *time.Time `json:"updatedAt"`
}

Comment represents a video comment

type GraphQLError

type GraphQLError struct {
	Message    string                 `json:"message"`
	Locations  []GraphQLErrorLocation `json:"locations,omitempty"`
	Path       []interface{}          `json:"path,omitempty"`
	Extensions map[string]interface{} `json:"extensions,omitempty"`
}

GraphQLError represents a GraphQL error

func (GraphQLError) Error

func (e GraphQLError) Error() string

Error implements the error interface for GraphQLError

type GraphQLErrorLocation

type GraphQLErrorLocation struct {
	Line   int `json:"line"`
	Column int `json:"column"`
}

GraphQLErrorLocation represents the location of a GraphQL error

type GraphQLRequest

type GraphQLRequest struct {
	Query     string                 `json:"query"`
	Variables map[string]interface{} `json:"variables,omitempty"`
}

GraphQLRequest represents a GraphQL request

type GraphQLResponse

type GraphQLResponse struct {
	Data   json.RawMessage `json:"data"`
	Errors []GraphQLError  `json:"errors,omitempty"`
}

GraphQLResponse represents a GraphQL response

type Pagination

type Pagination struct {
	Offset int `json:"offset"`
	Limit  int `json:"limit"`
}

Pagination represents pagination parameters

type Playlist

type Playlist struct {
	ID          string     `json:"_id"`
	Title       string     `json:"title"`
	Summary     string     `json:"summary"`
	Image       string     `json:"image"`
	Channel     *Channel   `json:"channel"`
	Creator     *AdminUser `json:"creator"`
	Videos      []Video    `json:"videos"`
	TotalVideos float64    `json:"totalVideos"`
	CreatedAt   *time.Time `json:"createdAt"`
	UpdatedAt   *time.Time `json:"updatedAt"`
}

Playlist represents a playlist

type ShowInfo

type ShowInfo struct {
	Times string `json:"times"`
	Phone string `json:"phone"`
}

ShowInfo represents show information

type Tag

type Tag struct {
	ID        string     `json:"_id"`
	Name      string     `json:"name"`
	CreatedAt *time.Time `json:"createdAt"`
	UpdatedAt *time.Time `json:"updatedAt"`
}

Tag represents a video tag

type Upload

type Upload struct {
	ID               string     `json:"_id"`
	Name             string     `json:"name"`
	Mimetype         string     `json:"mimetype"`
	Encoding         string     `json:"encoding"`
	OriginalFilename string     `json:"originalFilename"`
	Size             int64      `json:"size"`
	CreatedAt        *time.Time `json:"createdAt"`
	UpdatedAt        *time.Time `json:"updatedAt"`
}

Upload represents an uploaded file

type User

type User struct {
	ID          string     `json:"_id"`
	DisplayName string     `json:"displayName"`
	CreatedAt   *time.Time `json:"createdAt"`
	UpdatedAt   *time.Time `json:"updatedAt"`
}

User represents a regular user

type Video

type Video struct {
	ID             string     `json:"_id"`
	Title          string     `json:"title"`
	Summary        string     `json:"summary"`
	Published      bool       `json:"published"`
	Unlisted       bool       `json:"unlisted"`
	Creator        *AdminUser `json:"creator"`
	Channel        *Channel   `json:"channel"`
	Tags           []Tag      `json:"tags"`
	VideoDuration  float64    `json:"videoDuration"`
	AudioUpload    *Upload    `json:"audioUpload"`
	PosterUpload   *Upload    `json:"posterUpload"`
	VideoUpload    *Upload    `json:"videoUpload"`
	Live           bool       `json:"live"`
	DisableComment bool       `json:"disableComment"`
	LiveStreamUrl  string     `json:"liveStreamUrl"`
	TimeWatched    float64    `json:"timeWatched"`
	IsInWatchLater bool       `json:"isInWatchLater"`
	LargeImage     string     `json:"largeImage"`
	PlayCount      float64    `json:"playCount"`
	LikeCount      float64    `json:"likeCount"`
	AngerCount     float64    `json:"angerCount"`
	ShowInfo       *ShowInfo  `json:"showInfo"`
	CreatedAt      *time.Time `json:"createdAt"`
	UpdatedAt      *time.Time `json:"updatedAt"`
	PublishedAt    *time.Time `json:"publishedAt"`
	LastCommentAt  *time.Time `json:"lastCommentAt"`
	DirectURL      string     `json:"directUrl"`
	EmbedURL       string     `json:"embedUrl"`
}

Video represents a banned.video video

type VideoService

type VideoService struct {
	// contains filtered or unexported fields
}

VideoService provides methods for interacting with videos

func NewVideoService

func NewVideoService(client *Client) *VideoService

NewVideoService creates a new video service

func (*VideoService) FetchAllHotVideos

func (s *VideoService) FetchAllHotVideos(ctx context.Context, batchSize int) ([]Video, error)

FetchAllHotVideos recursively fetches all hot videos with pagination

func (*VideoService) FetchAllHotVideosWithLimit

func (s *VideoService) FetchAllHotVideosWithLimit(ctx context.Context, maxVideos, batchSize int) ([]Video, error)

FetchAllHotVideosWithLimit recursively fetches hot videos with a maximum limit

func (*VideoService) FetchAllNewVideos

func (s *VideoService) FetchAllNewVideos(ctx context.Context, batchSize int) ([]Video, error)

FetchAllNewVideos recursively fetches all new videos with pagination

func (*VideoService) GetHotVideos

func (s *VideoService) GetHotVideos(ctx context.Context, offset, limit int) ([]Video, error)

GetHotVideos fetches trending/hot videos

func (*VideoService) GetNewVideos

func (s *VideoService) GetNewVideos(ctx context.Context, offset, limit int) ([]Video, error)

GetNewVideos fetches the newest videos

func (*VideoService) GetVideo

func (s *VideoService) GetVideo(ctx context.Context, videoID string) (*Video, error)

GetVideo fetches a specific video by ID

func (*VideoService) GetVideoAudioURL

func (s *VideoService) GetVideoAudioURL(video *Video) string

GetVideoAudioURL returns the audio URL for a video (if available)

func (*VideoService) GetVideoDownloadURL

func (s *VideoService) GetVideoDownloadURL(video *Video) string

GetVideoDownloadURL returns the best download URL for a video

func (*VideoService) GetVideoPosterURL

func (s *VideoService) GetVideoPosterURL(video *Video) string

GetVideoPosterURL returns the poster/thumbnail URL for a video

func (*VideoService) GetVideos

func (s *VideoService) GetVideos(ctx context.Context, videoIDs []string) ([]Video, error)

GetVideos fetches multiple videos by their IDs

type VideoView

type VideoView struct {
	ID           string     `json:"_id"`
	Video        *Video     `json:"video"`
	User         *User      `json:"user"`
	Channel      *Channel   `json:"channel"`
	ViewDuration float64    `json:"viewDuration"`
	UserAgent    string     `json:"userAgent"`
	IPAddress    string     `json:"ipAddress"`
	CreatedAt    *time.Time `json:"createdAt"`
}

VideoView represents a video view record

type VideosResponse

type VideosResponse struct {
	Videos     []Video `json:"videos"`
	TotalCount int     `json:"totalCount,omitempty"`
	HasMore    bool    `json:"hasMore,omitempty"`
}

VideosResponse represents a response containing videos with pagination info

type Vote

type Vote struct {
	ID        string     `json:"_id"`
	User      *User      `json:"user"`
	Video     *Video     `json:"video"`
	Comment   *Comment   `json:"comment"`
	Type      string     `json:"type"` // "like", "dislike", "angry"
	CreatedAt *time.Time `json:"createdAt"`
	UpdatedAt *time.Time `json:"updatedAt"`
}

Vote represents a vote (like/dislike)

type VoteCount

type VoteCount struct {
	LikeCount    float64 `json:"likeCount"`
	DislikeCount float64 `json:"dislikeCount"`
	AngerCount   float64 `json:"angerCount"`
}

VoteCount represents vote counts for content

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL