{"id":37202633,"url":"https://github.com/patent-dev/epo-bdds","last_synced_at":"2026-01-14T23:22:19.665Z","repository":{"id":320393255,"uuid":"1081806258","full_name":"patent-dev/epo-bdds","owner":"patent-dev","description":"Go client library for the European Patent Office Bulk Data Distribution Service (BDDS)","archived":false,"fork":false,"pushed_at":"2025-10-23T14:00:10.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-23T15:40:01.584Z","etag":null,"topics":["api","patent-data","patents"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patent-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-23T10:09:49.000Z","updated_at":"2025-10-23T14:00:11.000Z","dependencies_parsed_at":"2025-10-23T15:40:14.964Z","dependency_job_id":null,"html_url":"https://github.com/patent-dev/epo-bdds","commit_stats":null,"previous_names":["patent-dev/epo-bdds"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/patent-dev/epo-bdds","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patent-dev%2Fepo-bdds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patent-dev%2Fepo-bdds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patent-dev%2Fepo-bdds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patent-dev%2Fepo-bdds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patent-dev","download_url":"https://codeload.github.com/patent-dev/epo-bdds/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patent-dev%2Fepo-bdds/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28437981,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T22:37:52.437Z","status":"ssl_error","status_checked_at":"2026-01-14T22:37:31.496Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","patent-data","patents"],"created_at":"2026-01-14T23:22:14.372Z","updated_at":"2026-01-14T23:22:18.147Z","avatar_url":"https://github.com/patent-dev.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EPO BDDS Go Client\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/patent-dev/epo-bdds.svg)](https://pkg.go.dev/github.com/patent-dev/epo-bdds)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA Go client library for the European Patent Office Bulk Data Distribution Service (BDDS).\n\n## Getting Started\n\n### Authentication\n\nAuthentication requirements depend on the data you're accessing:\n\n- **Free/Public Products**: Listing and downloading work without authentication\n- **Paid Products**: Require EPO BDDS subscription and authentication for listing and downloading (see [pricing](https://www.epo.org/en/service-support/ordering/patent-knowledge-products-services))\n\n**Authentication Method**: OAuth2 password grant flow\n\n## Installation\n\n```bash\ngo get github.com/patent-dev/epo-bdds\n```\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/patent-dev/epo-bdds\"\n)\n\nfunc main() {\n    // Create client\n    client, err := bdds.NewClient(\u0026bdds.Config{\n        Username: \"your-epo-username\",\n        Password: \"your-epo-password\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    ctx := context.Background()\n\n    // List all products\n    products, err := client.ListProducts(ctx)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Printf(\"Found %d products\\n\", len(products))\n    for _, p := range products {\n        fmt.Printf(\"- [%d] %s\\n\", p.ID, p.Name)\n    }\n}\n```\n\n## API Methods\n\n### Product Discovery\n\n```go\n// List all available products\nListProducts(ctx context.Context) ([]*Product, error)\n\n// Get product details with deliveries\nGetProduct(ctx context.Context, productID int) (*ProductWithDeliveries, error)\n\n// Find product by name\nGetProductByName(ctx context.Context, name string) (*Product, error)\n\n// Get most recent delivery for a product\nGetLatestDelivery(ctx context.Context, productID int) (*Delivery, error)\n```\n\n### File Downloads\n\n```go\n// Download file to writer\nDownloadFile(ctx context.Context, productID, deliveryID, fileID int, dst io.Writer) error\n\n// Download with progress callback\nDownloadFileWithProgress(ctx context.Context, productID, deliveryID, fileID int,\n    dst io.Writer, progressFn func(bytesWritten, totalBytes int64)) error\n```\n\n## Configuration\n\n```go\nconfig := \u0026bdds.Config{\n    Username:   \"your-username\",          // Optional (needed for paid products)\n    Password:   \"your-password\",          // Optional (needed for paid products)\n    BaseURL:    \"https://publication-bdds.apps.epo.org\", // Default\n    UserAgent:  \"YourApp/1.0\",           // Optional\n    MaxRetries: 3,                        // Default: 3\n    RetryDelay: 1,                        // Seconds between retries, default: 1\n    Timeout:    30,                       // Request timeout in seconds, default: 30\n}\n\nclient, err := bdds.NewClient(config)\n```\n\n## Features\n\n### Automatic Token Management\n- OAuth2 authentication handled automatically\n- Tokens cached and refreshed before expiry\n- No manual token management required\n\n### Robust Error Handling\n- Automatic retry with exponential backoff\n- Graceful handling of rate limits\n- Custom error types for different scenarios\n\n### Progress Tracking\n- Download progress callbacks for large files\n- Real-time byte tracking during downloads\n\n## Usage Examples\n\n### Download Without Authentication\n\nIf you only need to download files and already have the product/delivery/file IDs:\n\n```go\n// Create client without credentials\nclient, err := bdds.NewClient(\u0026bdds.Config{})\nif err != nil {\n    log.Fatal(err)\n}\n\n// Download file directly\nfile, err := os.Create(\"download.zip\")\nif err != nil {\n    log.Fatal(err)\n}\ndefer file.Close()\n\nerr = client.DownloadFile(ctx, productID, deliveryID, fileID, file)\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n### List Products\n\n```go\nproducts, err := client.ListProducts(ctx)\nif err != nil {\n    log.Fatal(err)\n}\n\nfor _, p := range products {\n    fmt.Printf(\"Product %d: %s\\n\", p.ID, p.Name)\n    fmt.Printf(\"  %s\\n\", p.Description)\n}\n```\n\n### Get Product with Deliveries\n\n```go\nproduct, err := client.GetProduct(ctx, 3) // EP DocDB front file\nif err != nil {\n    log.Fatal(err)\n}\n\nfmt.Printf(\"Product: %s\\n\", product.Name)\nfmt.Printf(\"Deliveries: %d\\n\", len(product.Deliveries))\n\nfor _, delivery := range product.Deliveries {\n    fmt.Printf(\"  %s - %d files\\n\", delivery.DeliveryName, len(delivery.Files))\n}\n```\n\n### Download File with Progress\n\n```go\nfile, err := os.Create(\"download.zip\")\nif err != nil {\n    log.Fatal(err)\n}\ndefer file.Close()\n\nerr = client.DownloadFileWithProgress(ctx, 3, 12345, 67890, file,\n    func(bytesWritten, totalBytes int64) {\n        percent := float64(bytesWritten) * 100 / float64(totalBytes)\n        fmt.Printf(\"\\rProgress: %.1f%%\", percent)\n    })\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n### Find Product by Name\n\n```go\nproduct, err := client.GetProductByName(ctx, \"EP DocDB front file\")\nif err != nil {\n    log.Fatal(err)\n}\n\nfmt.Printf(\"Found product: %d - %s\\n\", product.ID, product.Name)\n```\n\n### Get Latest Delivery\n\n```go\ndelivery, err := client.GetLatestDelivery(ctx, 3)\nif err != nil {\n    log.Fatal(err)\n}\n\nfmt.Printf(\"Latest delivery: %s\\n\", delivery.DeliveryName)\nfmt.Printf(\"Published: %s\\n\", delivery.DeliveryPublicationDatetime)\nfmt.Printf(\"Files: %d\\n\", len(delivery.Files))\n```\n\n## Common Product IDs\n\n| ID | Name | Description |\n|----|------|-------------|\n| 3  | EP DocDB front file | Bibliographic data (front file) |\n| 4  | EP full-text data - front file | Full-text patent data |\n| 14 | EP DocDB back file | Bibliographic data (back file) |\n| 17 | PATSTAT Global | Patent statistics database |\n| 18 | PATSTAT EP Register | EP register data |\n\n## Error Handling\n\nThe library provides custom error types for different scenarios:\n\n```go\n// Authentication errors\nif authErr, ok := err.(*bdds.AuthError); ok {\n    fmt.Printf(\"Auth failed: %s\\n\", authErr.Message)\n}\n\n// Not found errors\nif notFoundErr, ok := err.(*bdds.NotFoundError); ok {\n    fmt.Printf(\"Resource not found: %s\\n\", notFoundErr.ID)\n}\n\n// Rate limit errors\nif rateLimitErr, ok := err.(*bdds.RateLimitError); ok {\n    fmt.Printf(\"Rate limited, retry after %d seconds\\n\", rateLimitErr.RetryAfter)\n}\n```\n\n## Testing\n\nThis library includes comprehensive test coverage:\n\n### Unit Tests (Mock Server)\n\nOffline tests using mock HTTP server with realistic responses:\n\n```bash\n# Run unit tests\ngo test -v\n\n# Run with coverage\ngo test -v -cover\n\n# Generate coverage report\ngo test -cover -coverprofile=coverage.out\ngo tool cover -html=coverage.out\n```\n\n### Integration Tests (Real API)\n\nTests that make actual requests to the EPO BDDS API:\n\n```bash\n# Set credentials\nexport EPO_BDDS_USERNAME=your-username\nexport EPO_BDDS_PASSWORD=your-password\n\n# Run integration tests\ngo test -tags=integration -v\n\n# Run specific test\ngo test -tags=integration -v -run TestIntegration_ListProducts\n```\n\n**Note**: Integration tests require valid EPO BDDS credentials and will fail gracefully if not set or if specific products are not accessible (based on account).\n\n## Implementation\n\nThis library follows a clean architecture:\n\n1. **OpenAPI Specification**: Unofficial hand-crafted `openapi.yaml` based on actual API behavior\n2. **Code Generation**: Types and client generated using [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen)\n3. **Idiomatic Wrapper**: Clean Go client wrapping generated code\n4. **Automatic Auth**: OAuth2 token management handled transparently\n\n### Package Structure\n\n```\n├── client.go           # Main client implementation\n├── client_test.go     # Unit tests with mock server\n├── integration_test.go # Integration tests with real API\n├── types.go           # Public types\n├── errors.go          # Custom error types\n├── utils.go           # Internal utilities\n├── generated/         # Auto-generated code\n│   ├── types_gen.go   # Generated types\n│   └── client_gen.go  # Generated client\n└── openapi.yaml      # OpenAPI 3.0 specification\n```\n\n## Demo Application\n\nAn interactive demo application is included to showcase all library features:\n\n```bash\n# Set credentials\nexport EPO_BDDS_USERNAME=your-username\nexport EPO_BDDS_PASSWORD=your-password\n\n# Run demo\ncd demo\ngo run demo.go\n```\n\nThe demo provides an interactive menu for:\n- Listing all products\n- Viewing product details with deliveries\n- Finding products by name\n- Getting latest delivery information\n- Downloading files with progress tracking\n\nSee [demo/README.md](demo/README.md) for full documentation.\n\n## Development\n\n### Regenerating from OpenAPI\n\nIf the OpenAPI spec is updated:\n\n```bash\n# Install generator\ngo install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest\n\n# Generate types\noapi-codegen -package generated -generate types openapi.yaml \u003e generated/types_gen.go\n\n# Generate client\noapi-codegen -package generated -generate client openapi.yaml \u003e generated/client_gen.go\n```\n\n## Similar Projects\n\nThis project follows the style and quality standards of:\n- [patent-dev/uspto-odp](https://github.com/patent-dev/uspto-odp) - USPTO Open Data Portal Go client\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Credits\n\n**Developed by:**\n- Wolfgang Stark - [patent.dev](https://patent.dev) - [Funktionslust GmbH](https://funktionslust.digital)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatent-dev%2Fepo-bdds","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatent-dev%2Fepo-bdds","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatent-dev%2Fepo-bdds/lists"}