{"id":13825099,"url":"https://github.com/umihico/pythonista-chromeless","last_synced_at":"2025-10-23T15:30:30.713Z","repository":{"id":45121157,"uuid":"166235502","full_name":"umihico/pythonista-chromeless","owner":"umihico","description":"Serverless selenium which dynamically execute any given code.","archived":false,"fork":false,"pushed_at":"2022-01-06T23:37:32.000Z","size":105468,"stargazers_count":60,"open_issues_count":7,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-30T19:08:06.263Z","etag":null,"topics":["chrome","chromeless","headless","headless-chrome","integration-testing","python","scraping","selenium","serverless","testing","unit-testing","webtester"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/chromeless/","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/umihico.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}},"created_at":"2019-01-17T14:03:18.000Z","updated_at":"2025-01-18T17:44:51.000Z","dependencies_parsed_at":"2022-09-22T17:21:32.063Z","dependency_job_id":null,"html_url":"https://github.com/umihico/pythonista-chromeless","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umihico%2Fpythonista-chromeless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umihico%2Fpythonista-chromeless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umihico%2Fpythonista-chromeless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umihico%2Fpythonista-chromeless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umihico","download_url":"https://codeload.github.com/umihico/pythonista-chromeless/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237843850,"owners_count":19375215,"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","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":["chrome","chromeless","headless","headless-chrome","integration-testing","python","scraping","selenium","serverless","testing","unit-testing","webtester"],"created_at":"2024-08-04T09:01:14.701Z","updated_at":"2025-10-23T15:30:30.367Z","avatar_url":"https://github.com/umihico.png","language":"Python","readme":"# chromeless\n\nAWS lambda with selenium \u0026 python is powerful solution.\nLet's access this benefit easily!\n\n- Don't create lambda functions every time. Just create this once.\n- Write the method.\n- Selenium dynamically execute your script.\n\n## Example\n\n```python\n# Write the method to a file. (NOT interactive mode.)\ndef get_title(self, url):\n    self.get(url)\n    return self.title\n\n# Attach the method and then call it.\nfrom chromeless import Chromeless\nchrome = Chromeless()\nchrome.attach(get_title)\nprint(chrome.get_title(\"https://google.com\")) # Returns Google\n```\n\n\nYou can also provide boto3 session object if you don't want to use default aws profile:\n```python\nfrom chromeless import Chromeless\nfrom boto3.session import Session\n\nsession = Session(aws_access_key_id='\u003cYOUR ACCESS KEY ID\u003e',\n                  aws_secret_access_key='\u003cYOUR SECRET KEY\u003e',\n                  region_name='\u003cREGION NAME\u003e')\n# or\nsession = Session(profile_name='\u003cYOUR_PROFILE_NAME\u003e')\nchrome = Chromeless(boto3_session=session)\n```\n\nOr also you can just set appropriate environment vars works with boto3,\n so it will auto detect your choice e.g.:\n```\n# In mac or linux\nexport AWS_DEFAULT_REGION=\u003cyour aws region\u003e\n\n# In windows\nset AWS_DEFAULT_REGION=\u003cyour aws region\u003e\n```\n\n## Installing\n\n- `git clone --depth 1 https://github.com/umihico/pythonista-chromeless.git chromeless \u0026\u0026 cd $_`\n- `sls deploy --region YOUR_REGION`\n- `pip install chromeless`\n\nThat's it! Now run the `example.py` and confirm your selenium works in lambda functions!\n\n## Tips\n\n- **Don't call selenium native methods directly.** Solution is wrapping.\n\n```python\n# BAD EXAMPLE\nchrome = Chromeless()\nchrome.get(\"https://google.com\") # Not a attached method. AttributeError will be raised.\nchrome.title # Same. AttributeError.\n\n# SOLUTION\ndef wrapper(self, url):\n    self.get(url)\n    return self.title\n\nchrome = Chromeless()\nchrome.attach(wrapper)\nprint(chrome.wrapper(\"https://google.com\")) # prints 'Google'.\nprint(chrome.wrapper(\"https://microsoft.com\")) # But you can execute as many times as you want.\nprint(chrome.wrapper(\"https://apple.com\")) # Arguments are adjustable each time.\n```\n\n- Multiple methods are also attachable.\n\n```python\ndef login(self):\n    self.get(\"https://example.com/login\")\n    self.find_element_by_id(\"username\").send_keys(\"umihico\")\n    self.find_element_by_id(\"password\").send_keys(\"password\")\n    self.find_element_by_name(\"submit\").click()\n\ndef test1(self):\n    self.login()\n    self.get(\"https://example.com/\")\n\ndef test2(self):\n    self.login()\n    self.get(\"https://example.com/logout\")\n\nchrome = Chromeless()\nchrome.attach(login) # You can attach multiple methods too.\nchrome.attach(test1) # It means you can also refactor the common code.\nchrome.attach(test2)\nprint(chrome.test1())\nprint(chrome.test2())\n```\n\n- To screenshot\n\n```python\n# BAD EXAMPLE\ndef bad_wrapper(self):\n  self.get(\"https://google.com\")\n  self.save_screenshot(\"screenshot.png\")\n  # There's no sense in saving files in AWS Lambda.\n\n# SOLUTION\ndef good_wrapper(self):\n  self.get(\"https://google.com\")\n  return self.get_screenshot_as_png()\n  # return image in binary format.\n\nchrome = Chromeless()\nchrome.attach(good_wrapper)\npng = chrome.good_wrapper()\n# then write then image down locally.\nwith open(\"screenshot.png\", 'wb') as f:\n    f.write(png)\n\n```\n\n### [License](https://github.com/umihico/pythonista-chromeless/blob/master/LICENSE)\n\nThe project is licensed under the MIT license.\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumihico%2Fpythonista-chromeless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumihico%2Fpythonista-chromeless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumihico%2Fpythonista-chromeless/lists"}