ValueError when using cerbot.main.main

I'm working on a certificate management API that will use the python library of certbot to generate certificates. The code still worked on friday but today nothing seems to work anymore. I already saw a thread with a similar issue but it seems like the only solution is to fork the repo. Isn't there a quicker fix to this problem? I can"t seem to find a reason why my program is throwing a ValueError. The error seems to begin when the http01 challenge starts. How can i get around this? Thanks in advance.

My domain is:
example.certiman.inuits.dev
whoami.certiman.inuits.dev

I ran this command:

import certbot.main
from loguru import logger

class AcmeClient:
    def __init__(self, email, staging=False):
        self.email = email
        self.staging = staging

    def generate_cert(self, domain):
        args = ["certonly",
                "--standalone",
                "--agree-tos",
                "-n",
                "--email", self.email,
                "-d", f"{domain}.certiman.inuits.dev",
                "-v"
                ]
        if self.staging:
            args.append("--staging")

        certbot.main.main(args)


class CertGenerator:
    def __init__(self, domains_file):
        self.domains_file = domains_file

    def generate_certs(self):
        with open(self.domains_file) as f:
            for line in f:
                domain = line.rstrip('\n')
                client = AcmeClient(email='andreo@inuits.eu', staging=True)
                logger.info(f"Generating certificate for {domain}")
                client.generate_cert(domain)
                try:
                    client.generate_cert(domain)
                except ValueError as e:
                    logger.critical(f"{e} for {domain}")
                    continue

It produced this output:

# ValueError

ValueError: signal only works in main thread of the main interpreter

## Traceback (most recent call last)

*** #### File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2551, in __call__**

return self.wsgi_app(environ, start_response)

*** #### File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2531, in wsgi_app**

response = self.handle_exception(e)

*** #### File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2528, in wsgi_app**

response = self.full_dispatch_request()

*** #### File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1825, in full_dispatch_request**

rv = self.handle_user_exception(e)

*** #### File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1823, in full_dispatch_request**

rv = self.dispatch_request()

*** #### File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1799, in dispatch_request**

**return self.ensure_sync(self.view_functions[rule.endpoint])(view_args)

*** #### File "/api/main.py", line 33, in generate_certs**

return generate_certificates()

*** #### File "/api/api.py", line 51, in generate_certificates**

cg.generate_certs()

*** #### File "/api/acmeclient.py", line 34, in generate_certs**

client.generate_cert(domain)

*** #### File "/api/acmeclient.py", line 21, in generate_cert**

certbot.main.main(args)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/main.py", line 19, in main**

return internal_main.main(cli_args)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/main.py", line 1864, in main**

return config.func(config, plugins)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/main.py", line 1597, in certonly**

lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/main.py", line 141, in _get_and_save_cert**

lineage = le_client.obtain_and_enroll_certificate(domains, certname)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/client.py", line 516, in obtain_and_enroll_certificate**

cert, chain, key, _ = self.obtain_certificate(domains)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/client.py", line 428, in obtain_certificate**

orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/client.py", line 496, in _get_order_and_authorizations**

authzr = self.auth_handler.handle_authorizations(orderr, self.config, best_effort)

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/auth_handler.py", line 85, in handle_authorizations**

with error_handler.ExitHandler(self._cleanup_challenges, achalls):

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/error_handler.py", line 91, in __enter__**

self._set_signal_handlers()

*** #### File "/usr/local/lib/python3.9/site-packages/certbot/_internal/error_handler.py", line 143, in _set_signal_handlers**

signal.signal(signum, self._signal_handler)

*** #### File "/usr/local/lib/python3.9/signal.py", line 56, in signal**

handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))

> ValueError: signal only works in main thread of the main interpreter

My web server is (include version):
Werkzeug/2.2.3

The operating system my web server runs on is (include version):
Linux Mint Cinnamon 21

My hosting provider, if applicable, is:
i don't know

I can login to a root shell on my machine (yes or no, or I don't know):
yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel):
no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):
2.5.0

I wouldn't try to invoke certbot.main from within a threaded runtime like Flask. We absolutely make no guarantees that this would work. Most likely, it won't work. You'd be better off either implementing a client using the acme module, or create a module that invokes the certbot binary as a separate forked process.

5 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.