{"id":21413475,"url":"https://github.com/feedly/python-api-client","last_synced_at":"2025-10-04T13:40:31.350Z","repository":{"id":45292887,"uuid":"145170923","full_name":"feedly/python-api-client","owner":"feedly","description":"Python client code for the feedly api https://developers.feedly.com/","archived":false,"fork":false,"pushed_at":"2023-06-30T14:45:20.000Z","size":94,"stargazers_count":52,"open_issues_count":7,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-25T16:46:42.760Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","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/feedly.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}},"created_at":"2018-08-17T22:13:54.000Z","updated_at":"2025-07-14T14:27:45.000Z","dependencies_parsed_at":"2024-06-19T01:39:46.439Z","dependency_job_id":"06d4b309-48e6-4e8e-a93d-ad8155b47060","html_url":"https://github.com/feedly/python-api-client","commit_stats":{"total_commits":67,"total_committers":6,"mean_commits":"11.166666666666666","dds":0.5970149253731343,"last_synced_commit":"5affa3916b9b3710caaf0c61a4625fcdab480943"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/feedly/python-api-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedly%2Fpython-api-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedly%2Fpython-api-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedly%2Fpython-api-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedly%2Fpython-api-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/feedly","download_url":"https://codeload.github.com/feedly/python-api-client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedly%2Fpython-api-client/sbom","scorecard":{"id":395633,"data":{"date":"2025-08-11","repo":{"name":"github.com/feedly/python-api-client","commit":"4faea80886f9235fd3afde0e6bf5e026790f5ee0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.19 not signed: https://api.github.com/repos/feedly/python-api-client/releases/14972324","Warn: release artifact v0.19 does not have provenance: https://api.github.com/repos/feedly/python-api-client/releases/14972324"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2023-74 / GHSA-j8r2-6x86-q33q","Warn: Project is vulnerable to: PYSEC-2018-28 / GHSA-x84v-xcm2-53pg"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T18:56:17.370Z","repository_id":45292887,"created_at":"2025-08-18T18:56:17.370Z","updated_at":"2025-08-18T18:56:17.370Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278322184,"owners_count":25967872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-11-22T18:18:35.030Z","updated_at":"2025-10-04T13:40:31.313Z","avatar_url":"https://github.com/feedly.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# python-api-client\nPython client code for the feedly api https://developers.feedly.com/\n\n## Initializing a client\nTo initialize a client, first you need an access token. To just play around,\nlogin to feedly and go to the [console](http://feedly.com/i/console). Then find \nthe `feedlyToken` property. This is your web access token. You can make requests\nwith this token but it will expire. It's not suitable for building an application,\nbut will get you going.\n \nIf you're serious about building an app, you probably want to get a\n [developer token](https://developers.feedly.com/v3/developer/). Check the page for more details.\n\nYou can run [examples/setup_auth.py](examples/setup_auth.py) to get your access token saved into the default config directory, `~/.config/feedly`. Then, you can initialize the client as follows:\n\n```\nfrom feedly.api_client.session import FeedlySession\n\nsess = FeedlySession()\n```\nClients are lightweight -- you can keep a client around for the lifetime of your program,\nor you can create a new one when needed. It's a bit more efficient to keep it around. If you\ndo choose to create clients as needed, you should pass in the user's ID in the constructor, \notherwise you'll incur a `/v3/profile` request. \n\n## Examples\n\n### Setup\n\nTo run the examples we provide, you'll first need to clone and install the project (preferably in a new virtualenv environment):\n\n```bash\ngit clone https://github.com/feedly/python-api-client.git\ncd python-api-client\npip install .\n```\n\n### Auth\n\nWhen running [an example](examples), for the first time, you'll be prompted to enter your token. It will be saved in ~/.config/feedly\n\n## API Oriented Usage\nYou can use the `FeedlySession` object to make arbitrary API requests. E.g.:\n\n```python\nsess.do_api_request('/v3/feeds/feed%2Fhttp%3A%2F%2Fblog.feedly.com%2Ffeed%2F')\n```\n```json\n{\n  \"id\": \"feed/http://blog.feedly.com/feed/\",\n  \"feedId\": \"feed/http://blog.feedly.com/feed/\",\n  \"title\": \"Feedly Blog\",\n  ...\n}\n```\n\n\n## Object Oriented Usage\n\n#### Retrieving Streams\nAlternatively, you can use the object-oriented code, which facilitates common usage patterns.\nE.g. you can list your user categories:\n```\nsess.user.user_categories.name2stream\n```\n\n```json\n{'comics': \u003cUserCategory: user/xxx/category/aaa\u003e,\n 'econ': \u003cUserCategory: user/xxx/category/bbb\u003e,\n 'global.must': \u003cUserCategory: user/xxx/category/ccc\u003e,\n 'politics': \u003cUserCategory: user/xxx/category/ddd\u003e,\n}\n```\nwhere `xxx` is your actual user ID.\n\nIt's not necessary to list categories beforehand, if you know the ones that exist, you can \nget one on the fly, by querying it by id or name:\n```python\nsess.user.user_categories.get('comics')  # From the category name\nsess.user.user_categories.get('aaa')  # From the category id\n```\n```\n\u003cUserCategory: user/xxx/category/aaa\u003e\n```\n\nYou can access:\n - User feeds with `sess.user.user_categories`\n - User boards with `sess.user.user_tags`\n - Team feeds with `sess.user.enterprise_categories`\n - Team boards with `sess.user.enterprise_tags`\n\n\n#### Accessing Entries (articles)\nIf you need to access entries or entry IDs, you can use easily stream them via `stream_contents`\nand `stream_ids`, respectively:\n\n```python\nwith FeedlySession(auth_token=token) as sess:\n    for eid in sess.user.user_categories.get('politics').stream_ids():\n         print(eid)\n\n```\n```\nDz51gkBgvGUvFOfTATCYLB2uqVaBIaGGazzxpZh2WL0=_16549c827dd:1645ba:3da9d93\nDz51gkBgvGUvFOfTATCYLB2uqVaBIaGGazzxpZh2WL0=_16549c827dd:1645bb:3da9d93\nZ/Hzx8NYfSSE8sweA2v5+4r5h7HC5ALdE2YGYB8MYbQ=_1654a26f3fe:79d9ef9:6f86c10b\n...\n```\n\nTake note of the `StreamOptions` class. There are important `max_count` and `count`\nproperties that control streaming. To download all items, something like this could\nbe done:\n\n```python\nopts = StreamOptions(max_count=sys.maxsize) # down all items that exist\nopts.count = sys.maxsize # download as many items as possible in every API request\nwith FeedlySession() as sess:\n    for eid in sess.user.get_category('politics').stream_ids(opts):\n         print(eid)\n\n```\n\n#### Tagging Existing Entries\n```python\nwith FeedlySession() as sess:\n    sess.user.get_tag('politics').tag_entry(eid)\n```\n\n## Odds and Ends\nFeedly APIs are rate limited. Do not make multiple requests concurrently. You can download\nquite a few entries at a time, see the previous section for details. Once you get rate limited,\nthe client will stop any attempted requests until you have available quota.\n\nTo debug things, set the log level to `DEBUG`. This will print log messages on every API request.\n\n### Token Management\nThe above examples assume the auth (access) token is valid. However these tokens do expire. Instead \nof passing the auth token itself, you can create a `feedly.session.Auth` implementation to refresh\nthe auth token. A file based implementation is already provided (`FileAuthStore`). Once this is done\nthe client will automatically try to refresh the auth token if a `401` response is encountered.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeedly%2Fpython-api-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeedly%2Fpython-api-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeedly%2Fpython-api-client/lists"}