Title: Clients do not clean up Requests sessions · Issue #64 · googleapis/python-cloud-core · GitHub
Open Graph Title: Clients do not clean up Requests sessions · Issue #64 · googleapis/python-cloud-core
X Title: Clients do not clean up Requests sessions · Issue #64 · googleapis/python-cloud-core
Description: Environment details OS type and version: macOS Python version: 3.9 google-cloud-core version: 1.4.3 google-cloud-storage version: 1.33.0 (since it's related) Steps to reproduce This is a sibling issue to googleapis/google-auth-library-py...
Open Graph Description: Environment details OS type and version: macOS Python version: 3.9 google-cloud-core version: 1.4.3 google-cloud-storage version: 1.33.0 (since it's related) Steps to reproduce This is a sibling is...
X Description: Environment details OS type and version: macOS Python version: 3.9 google-cloud-core version: 1.4.3 google-cloud-storage version: 1.33.0 (since it's related) Steps to reproduce This is a siblin...
Opengraph URL: https://github.com/googleapis/python-cloud-core/issues/64
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Clients do not clean up Requests sessions","articleBody":"#### Environment details\r\n\r\n - OS type and version: macOS\r\n - Python version: 3.9\r\n - `google-cloud-core` version: 1.4.3\r\n - `google-cloud-storage` version: 1.33.0 (since it's related)\r\n\r\n#### Steps to reproduce\r\n\r\nThis is a sibling issue to https://github.com/googleapis/google-auth-library-python/issues/658 and as such the below is similar to that issue.\r\n\r\n[Py.test 6.2 enables hard errors on unhandled thread exceptions and resource errors](https://docs.pytest.org/en/stable/usage.html#warning-about-unraisable-exceptions-and-unhandled-thread-exceptions) such as leaking sockets/SSL sockets/FDs/.... I've spent the last couple hours debugging various\r\n\r\n```\r\nResourceWarning: unclosed \u003cssl.SSLSocket fd=12, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.1.23', 60522), raddr=('216.58.207.202', 443)\u003e\r\n```\r\n\r\nWhen initiating (e.g.) a [`google-cloud-storage` storage client](https://github.com/googleapis/python-storage) with e.g.\r\n\r\n```python\r\n creds = self.get_client_credentials()\r\n return storage.Client(project=creds.project_id, credentials=creds)\r\n```\r\n\r\nthe client object is initialized with no explicit `_http` object, and the [default code path](https://github.com/googleapis/python-cloud-core/blob/d01c825d4b7638e76d9d2883baba5a91c884e310/google/cloud/client.py#L172-L184) is run, creating a new `requests.Session()` that will be _eventually_ GC'd but is otherwise not [`close()`d](https://requests.readthedocs.io/en/latest/api/#requests.Session.close), leading to the above warning (and a dropped connection and socket, which may have implications down the line).\r\n\r\nSince `google.core.client.Client` doesn't implement e.g. the context manager protocol or `close()`, there's no officially sanctioned way to clean up that session; for a storage Client, I subclassed one as a workaround but it would be nice if Clients had an official `close()`.\r\n\r\n```python\r\n class CloseableStorageClient(storage.Client):\r\n def __enter__(self):\r\n return self\r\n\r\n def __exit__(self, *args):\r\n self._http.close()\r\n```\r\n\r\n#### Resolution suggestion\r\n\r\nAt the very least, add `close()` to `Client`s; by default it should probably only be something like\r\n ```python\r\n def close(self):\r\n if self._http_internal:\r\n self._http_internal.close()\r\n ```\r\n, the semantics being a best-effort cleanup of resources allocated by the client, but not irreversible finalization.\r\n\r\nWith this, `Client`s could be used with [`contextlib.closing()`](https://docs.python.org/3.9/library/contextlib.html#contextlib.closing). Additionally, one could add a minimal context management protocol implementation á la\r\n\r\n```python\r\n def __enter__(self):\r\n return self\r\n\r\n def __exit__(self, *args):\r\n self.close()\r\n```\r\n\r\nIf you folks think this is a good way to go, I can certainly write the PR :)\r\n\r\ncc @busunkim96 (for having triaged the other issue).","author":{"url":"https://github.com/akx","@type":"Person","name":"akx"},"datePublished":"2020-12-22T19:02:03.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/64/python-cloud-core/issues/64"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:fe362e33-eb21-2b56-f147-cacf976597b7 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | D820:23E3E9:9C0C433:9F22EDA:6A507E9A |
| html-safe-nonce | 91965b44d47eb0f4fe47e1988c4725d75f0b79dfa02fdb051916406c7ab6105d |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEODIwOjIzRTNFOTo5QzBDNDMzOjlGMjJFREE6NkE1MDdFOUEiLCJ2aXNpdG9yX2lkIjoiMjUxNzgyNTUwNzA1MzA0MzM1NCIsInJlZ2lvbl9lZGdlIjoic2VhIiwicmVnaW9uX3JlbmRlciI6InNlYSJ9 |
| visitor-hmac | 61db3549c8527c6c5417837468aa4db5f2f199718cf103bbb0f487611de5e71c |
| hovercard-subject-tag | issue:773175159 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/googleapis/python-cloud-core/64/issue_layout |
| twitter:image | https://opengraph.githubassets.com/098671364c284cb9fdb35886a71ebd455156cbc8031da8eb5d21bb7223895902/googleapis/python-cloud-core/issues/64 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/098671364c284cb9fdb35886a71ebd455156cbc8031da8eb5d21bb7223895902/googleapis/python-cloud-core/issues/64 |
| og:image:alt | Environment details OS type and version: macOS Python version: 3.9 google-cloud-core version: 1.4.3 google-cloud-storage version: 1.33.0 (since it's related) Steps to reproduce This is a sibling is... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | akx |
| hostname | github.com |
| expected-hostname | github.com |
| None | d6dc8294eb500fa36bbc57472d61fe87c522f9c3c1d64f70f4926f66a66a7efb |
| turbo-cache-control | no-preview |
| go-import | github.com/googleapis/python-cloud-core git https://github.com/googleapis/python-cloud-core.git |
| octolytics-dimension-user_id | 16785467 |
| octolytics-dimension-user_login | googleapis |
| octolytics-dimension-repository_id | 226992462 |
| octolytics-dimension-repository_nwo | googleapis/python-cloud-core |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 226992462 |
| octolytics-dimension-repository_network_root_nwo | googleapis/python-cloud-core |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7ac0ad2f2c7e4b9056617355fd9e33e22b0c8df9 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width